From 09ac2d3c4b41f981a969251cc23195b89491b5c0 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Wed, 22 Jan 2020 16:33:42 +0100 Subject: [PATCH 001/180] make NotificationStream event naming consistent (#4712) --- client/network-gossip/src/bridge.rs | 2 +- client/network/src/behaviour.rs | 4 ++-- client/network/src/protocol.rs | 4 ++-- client/network/src/protocol/event.rs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/network-gossip/src/bridge.rs b/client/network-gossip/src/bridge.rs index 2b0b19b876..d6d6805b3e 100644 --- a/client/network-gossip/src/bridge.rs +++ b/client/network-gossip/src/bridge.rs @@ -100,7 +100,7 @@ impl GossipEngine { let inner = &mut *inner; inner.state_machine.new_peer(&mut *inner.network, remote, roles); } - Event::NotificationsStreamClosed { remote, engine_id: msg_engine_id } => { + Event::NotificationStreamClosed { remote, engine_id: msg_engine_id } => { if msg_engine_id != engine_id { continue; } diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index 7cc9eee74d..faaa25c660 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -144,9 +144,9 @@ Behaviour { roles, })); }, - CustomMessageOutcome::NotificationsStreamClosed { remote, protocols } => + CustomMessageOutcome::NotificationStreamClosed { remote, protocols } => for engine_id in protocols { - self.events.push(BehaviourOut::Event(Event::NotificationsStreamClosed { + self.events.push(BehaviourOut::Event(Event::NotificationStreamClosed { remote: remote.clone(), engine_id, })); diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 6914ea9efe..7a9fc7ecfb 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -1792,7 +1792,7 @@ pub enum CustomMessageOutcome { /// 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 }, + NotificationStreamClosed { remote: PeerId, protocols: Vec }, /// Messages have been received on one or more notifications protocols. NotificationsReceived { remote: PeerId, messages: Vec<(ConsensusEngineId, Bytes)> }, None, @@ -1931,7 +1931,7 @@ Protocol { LegacyProtoOut::CustomProtocolClosed { peer_id, .. } => { self.on_peer_disconnected(peer_id.clone()); // Notify all the notification protocols as closed. - CustomMessageOutcome::NotificationsStreamClosed { + CustomMessageOutcome::NotificationStreamClosed { remote: peer_id, protocols: self.registered_notif_protocols.iter().cloned().collect(), } diff --git a/client/network/src/protocol/event.rs b/client/network/src/protocol/event.rs index 47bf057505..e239e9d983 100644 --- a/client/network/src/protocol/event.rs +++ b/client/network/src/protocol/event.rs @@ -61,7 +61,7 @@ pub enum Event { /// Closed a substream with the given node. Always matches a corresponding previous /// `NotificationStreamOpened` message. - NotificationsStreamClosed { + NotificationStreamClosed { /// Node we closed the substream with. remote: PeerId, /// The concerned protocol. Each protocol uses a different substream. -- GitLab From 041f6f0ce3fffa7b755630940447e74f3d344a2c Mon Sep 17 00:00:00 2001 From: Toralf Wittner Date: Wed, 22 Jan 2020 17:34:42 +0100 Subject: [PATCH 002/180] Update soketto to v0.3.2 (#4714) See #4702 for details. --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eadf251f75..79a2721edf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2694,7 +2694,7 @@ dependencies = [ "quicksink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "rw-stream-sink 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "soketto 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "soketto 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", "webpki-roots 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6162,7 +6162,7 @@ dependencies = [ [[package]] name = "soketto" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -8695,7 +8695,7 @@ dependencies = [ "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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "afb767eee7d257ba202f0b9b08673bc13b22281632ef45267b19f13100accd2f" -"checksum soketto 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3caa0ad6b765419f21e4cfa490ec7514a9fae4af986adef168a69477ba528671" +"checksum soketto 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c9dab3f95c9ebdf3a88268c19af668f637a3c5039c2c56ff2d40b1b2d64a25b" "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" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" -- GitLab From 22887d5e9f0b66a0341d071c300e8359c80c8b13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 22 Jan 2020 18:13:17 +0100 Subject: [PATCH 003/180] Move "wasm" allocator into its own crate (#4716) This moves the wasm-allocator (`FreeingBumpHeapAllocator`) into its own crate `sp-allocator`. This new crate can theoretically provide multiple different allocators. Besides moving the allocator, this pr also makes `FreeingBumpHeapAllocator` compile on `no_std`. --- Cargo.lock | 16 ++++++++ Cargo.toml | 1 + client/executor/common/Cargo.toml | 1 + client/executor/common/src/error.rs | 15 ++----- client/executor/common/src/lib.rs | 1 - client/executor/runtime-test/Cargo.toml | 8 +++- client/executor/runtime-test/src/lib.rs | 5 +++ client/executor/src/lib.rs | 2 +- client/executor/wasmi/Cargo.toml | 1 + client/executor/wasmi/src/lib.rs | 14 +++---- client/executor/wasmtime/Cargo.toml | 1 + .../wasmtime/src/function_executor.rs | 6 +-- primitives/allocator/Cargo.toml | 22 ++++++++++ primitives/allocator/src/error.rs | 38 ++++++++++++++++++ .../allocator/src/freeing_bump.rs | 35 ++++++++++------ primitives/allocator/src/lib.rs | 29 ++++++++++++++ primitives/core/src/lib.rs | 40 +++++++++++++++++++ primitives/runtime/src/traits.rs | 28 +++---------- primitives/sandbox/src/lib.rs | 5 +-- primitives/wasm-interface/Cargo.toml | 7 +++- primitives/wasm-interface/src/lib.rs | 25 ++++++++++-- 21 files changed, 230 insertions(+), 70 deletions(-) create mode 100644 primitives/allocator/Cargo.toml create mode 100644 primitives/allocator/src/error.rs rename client/executor/common/src/allocator.rs => primitives/allocator/src/freeing_bump.rs (95%) create mode 100644 primitives/allocator/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 79a2721edf..2e0be7daf9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5424,6 +5424,7 @@ dependencies = [ "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)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-allocator 2.0.0", "sp-core 2.0.0", "sp-runtime-interface 2.0.0", "sp-serializer 2.0.0", @@ -5439,6 +5440,7 @@ dependencies = [ "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)", "sc-executor-common 0.8.0", + "sp-allocator 2.0.0", "sp-core 2.0.0", "sp-runtime-interface 2.0.0", "sp-wasm-interface 2.0.0", @@ -5459,6 +5461,7 @@ dependencies = [ "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)", "sc-executor-common 0.8.0", + "sp-allocator 2.0.0", "sp-core 2.0.0", "sp-runtime-interface 2.0.0", "sp-wasm-interface 2.0.0", @@ -5732,6 +5735,7 @@ dependencies = [ name = "sc-runtime-test" version = "2.0.0" dependencies = [ + "sp-allocator 2.0.0", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -6184,6 +6188,17 @@ name = "sourcefile" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "sp-allocator" +version = "2.0.0" +dependencies = [ + "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)", + "sp-core 2.0.0", + "sp-std 2.0.0", + "sp-wasm-interface 2.0.0", +] + [[package]] name = "sp-api" version = "2.0.0" @@ -6739,6 +6754,7 @@ name = "sp-wasm-interface" version = "2.0.0" dependencies = [ "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-std 2.0.0", "wasmi 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/Cargo.toml b/Cargo.toml index f6e521b9c5..fb15de2ebe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -98,6 +98,7 @@ members = [ "frame/transaction-payment/rpc/runtime-api", "frame/treasury", "frame/utility", + "primitives/allocator", "primitives/application-crypto", "primitives/application-crypto/test", "primitives/authority-discovery", diff --git a/client/executor/common/Cargo.toml b/client/executor/common/Cargo.toml index cae0876217..d3282e4dff 100644 --- a/client/executor/common/Cargo.toml +++ b/client/executor/common/Cargo.toml @@ -10,6 +10,7 @@ derive_more = "0.99.2" codec = { package = "parity-scale-codec", version = "1.0.0" } wasmi = "0.6.2" sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sp-allocator = { version = "2.0.0", path = "../../../primitives/allocator" } sp-wasm-interface = { version = "2.0.0", path = "../../../primitives/wasm-interface" } sp-runtime-interface = { version = "2.0.0", path = "../../../primitives/runtime-interface" } sp-serializer = { version = "2.0.0", path = "../../../primitives/serializer" } diff --git a/client/executor/common/src/error.rs b/client/executor/common/src/error.rs index f7de0af968..b8d40d4d91 100644 --- a/client/executor/common/src/error.rs +++ b/client/executor/common/src/error.rs @@ -72,17 +72,10 @@ 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)] - Allocator(&'static str), - /// The allocator ran out of space. - #[display(fmt="Allocator ran out of space")] - AllocatorOutOfSpace, - /// Someone tried to allocate more memory than the allowed maximum per allocation. - #[display(fmt="Requested allocation size is too large")] - RequestedAllocationTooLarge, + Allocator(sp_allocator::Error), /// Execution of a host function failed. #[display(fmt="Host function {} execution failed with: {}", _0, _1)] FunctionExecution(String, String), @@ -101,9 +94,9 @@ impl std::error::Error for Error { impl wasmi::HostError for Error {} -impl From for Error { - fn from(err: String) -> Error { - Error::Other(err) +impl From<&'static str> for Error { + fn from(err: &'static str) -> Error { + Error::Other(err.into()) } } diff --git a/client/executor/common/src/lib.rs b/client/executor/common/src/lib.rs index 69f6a710b3..cc515dcf9d 100644 --- a/client/executor/common/src/lib.rs +++ b/client/executor/common/src/lib.rs @@ -19,6 +19,5 @@ #![warn(missing_docs)] pub mod sandbox; -pub mod allocator; pub mod error; pub mod wasm_runtime; diff --git a/client/executor/runtime-test/Cargo.toml b/client/executor/runtime-test/Cargo.toml index 835021fec2..80dda384a0 100644 --- a/client/executor/runtime-test/Cargo.toml +++ b/client/executor/runtime-test/Cargo.toml @@ -11,10 +11,16 @@ sp-io = { version = "2.0.0", default-features = false, path = "../../../primitiv sp-sandbox = { version = "0.8.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" } +sp-allocator = { version = "2.0.0", default-features = false, path = "../../../primitives/allocator" } [build-dependencies] wasm-builder-runner = { version = "1.0.4", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } [features] default = [ "std" ] -std = ["sp-io/std", "sp-sandbox/std", "sp-std/std"] +std = [ + "sp-io/std", + "sp-sandbox/std", + "sp-std/std", + "sp-allocator/std", +] diff --git a/client/executor/runtime-test/src/lib.rs b/client/executor/runtime-test/src/lib.rs index a8d329cdd9..c0807197b4 100644 --- a/client/executor/runtime-test/src/lib.rs +++ b/client/executor/runtime-test/src/lib.rs @@ -212,6 +212,11 @@ sp_core::wasm_export_functions! { run().is_some() } + + // Just some test to make sure that `sp-allocator` compiles on `no_std`. + fn test_sp_allocator_compiles() { + sp_allocator::FreeingBumpHeapAllocator::new(0); + } } #[cfg(not(feature = "std"))] diff --git a/client/executor/src/lib.rs b/client/executor/src/lib.rs index 4f97efa9b6..a054f4dc76 100644 --- a/client/executor/src/lib.rs +++ b/client/executor/src/lib.rs @@ -48,7 +48,7 @@ pub use sp_core::traits::Externalities; pub use sp_wasm_interface; pub use wasm_runtime::WasmExecutionMethod; -pub use sc_executor_common::{error, allocator, sandbox}; +pub use sc_executor_common::{error, sandbox}; /// Call the given `function` in the given wasm `code`. /// diff --git a/client/executor/wasmi/Cargo.toml b/client/executor/wasmi/Cargo.toml index dbfdc505c6..6e67c73e56 100644 --- a/client/executor/wasmi/Cargo.toml +++ b/client/executor/wasmi/Cargo.toml @@ -13,3 +13,4 @@ sc-executor-common = { version = "0.8", path = "../common" } sp-wasm-interface = { version = "2.0.0", path = "../../../primitives/wasm-interface" } sp-runtime-interface = { version = "2.0.0", path = "../../../primitives/runtime-interface" } sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sp-allocator = { version = "2.0.0", path = "../../../primitives/allocator" } diff --git a/client/executor/wasmi/src/lib.rs b/client/executor/wasmi/src/lib.rs index c10698fea4..d3d0ee6e1e 100644 --- a/client/executor/wasmi/src/lib.rs +++ b/client/executor/wasmi/src/lib.rs @@ -16,11 +16,7 @@ //! This crate provides an implementation of `WasmRuntime` that is baked by wasmi. -use sc_executor_common::{ - error::{Error, WasmError}, - sandbox, - allocator, -}; +use sc_executor_common::{error::{Error, WasmError}, sandbox}; use std::{str, mem, cell::RefCell}; use wasmi::{ Module, ModuleInstance, MemoryInstance, MemoryRef, TableRef, ImportsBuilder, ModuleRef, @@ -38,7 +34,7 @@ use sc_executor_common::wasm_runtime::WasmRuntime; struct FunctionExecutor<'a> { sandbox_store: sandbox::Store, - heap: allocator::FreeingBumpHeapAllocator, + heap: sp_allocator::FreeingBumpHeapAllocator, memory: MemoryRef, table: Option, host_functions: &'a [&'static dyn Function], @@ -57,7 +53,7 @@ impl<'a> FunctionExecutor<'a> { ) -> Result { Ok(FunctionExecutor { sandbox_store: sandbox::Store::new(), - heap: allocator::FreeingBumpHeapAllocator::new(heap_base), + heap: sp_allocator::FreeingBumpHeapAllocator::new(heap_base), memory: m, table: t, host_functions, @@ -79,13 +75,13 @@ impl<'a> sandbox::SandboxCapabilities for FunctionExecutor<'a> { fn allocate(&mut self, len: WordSize) -> Result, Error> { let heap = &mut self.heap; self.memory.with_direct_access_mut(|mem| { - heap.allocate(mem, len) + heap.allocate(mem, len).map_err(Into::into) }) } fn deallocate(&mut self, ptr: Pointer) -> Result<(), Error> { let heap = &mut self.heap; self.memory.with_direct_access_mut(|mem| { - heap.deallocate(mem, ptr) + heap.deallocate(mem, ptr).map_err(Into::into) }) } fn write_memory(&mut self, ptr: Pointer, data: &[u8]) -> Result<(), Error> { diff --git a/client/executor/wasmtime/Cargo.toml b/client/executor/wasmtime/Cargo.toml index 44912086ea..a8f30a54b3 100644 --- a/client/executor/wasmtime/Cargo.toml +++ b/client/executor/wasmtime/Cargo.toml @@ -13,6 +13,7 @@ sc-executor-common = { version = "0.8", path = "../common" } sp-wasm-interface = { version = "2.0.0", path = "../../../primitives/wasm-interface" } sp-runtime-interface = { version = "2.0.0", path = "../../../primitives/runtime-interface" } sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sp-allocator = { version = "2.0.0", path = "../../../primitives/allocator" } cranelift-codegen = "0.50" cranelift-entity = "0.50" diff --git a/client/executor/wasmtime/src/function_executor.rs b/client/executor/wasmtime/src/function_executor.rs index b398ea8476..bc665f18e4 100644 --- a/client/executor/wasmtime/src/function_executor.rs +++ b/client/executor/wasmtime/src/function_executor.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use sc_executor_common::allocator::FreeingBumpHeapAllocator; +use sp_allocator::FreeingBumpHeapAllocator; use sc_executor_common::error::{Error, Result}; use sc_executor_common::sandbox::{self, SandboxCapabilities, SupervisorFuncIndex}; use crate::util::{ @@ -127,11 +127,11 @@ impl<'a> SandboxCapabilities for FunctionExecutor<'a> { } fn allocate(&mut self, len: WordSize) -> Result> { - self.heap.allocate(self.memory, len) + self.heap.allocate(self.memory, len).map_err(Into::into) } fn deallocate(&mut self, ptr: Pointer) -> Result<()> { - self.heap.deallocate(self.memory, ptr) + self.heap.deallocate(self.memory, ptr).map_err(Into::into) } fn write_memory(&mut self, ptr: Pointer, data: &[u8]) -> Result<()> { diff --git a/primitives/allocator/Cargo.toml b/primitives/allocator/Cargo.toml new file mode 100644 index 0000000000..737fa91273 --- /dev/null +++ b/primitives/allocator/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "sp-allocator" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +sp-std = { version = "2.0.0", path = "../std", default-features = false } +sp-core = { version = "2.0.0", path = "../core", default-features = false } +sp-wasm-interface = { version = "2.0.0", path = "../wasm-interface", default-features = false } +log = { version = "0.4.8", optional = true } +derive_more = { version = "0.99.2", optional = true } + +[features] +default = [ "std" ] +std = [ + "sp-std/std", + "sp-core/std", + "sp-wasm-interface/std", + "log", + "derive_more", +] diff --git a/primitives/allocator/src/error.rs b/primitives/allocator/src/error.rs new file mode 100644 index 0000000000..9357bc4560 --- /dev/null +++ b/primitives/allocator/src/error.rs @@ -0,0 +1,38 @@ +// Copyright 2020 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 . + +/// The error type used by the allocators. +#[derive(sp_core::RuntimeDebug)] +#[cfg_attr(feature = "std", derive(derive_more::Display))] +pub enum Error { + /// Someone tried to allocate more memory than the allowed maximum per allocation. + #[cfg_attr(feature = "std", display(fmt="Requested allocation size is too large"))] + RequestedAllocationTooLarge, + /// Allocator run out of space. + #[cfg_attr(feature = "std", display(fmt="Allocator ran out of space"))] + AllocatorOutOfSpace, + /// Some other error occurred. + Other(&'static str) +} + +#[cfg(feature = "std")] +impl std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + _ => None, + } + } +} diff --git a/client/executor/common/src/allocator.rs b/primitives/allocator/src/freeing_bump.rs similarity index 95% rename from client/executor/common/src/allocator.rs rename to primitives/allocator/src/freeing_bump.rs index feab044f69..46c314c2c2 100644 --- a/client/executor/common/src/allocator.rs +++ b/primitives/allocator/src/freeing_bump.rs @@ -46,10 +46,8 @@ //! To deallocate we use the preceding 8 bytes of the allocation to knit //! back the allocation into the linked list from the head. -use crate::error::{Error, Result}; -use log::trace; -use std::convert::{TryFrom, TryInto}; -use std::ops::Range; +use crate::Error; +use sp_std::{convert::{TryFrom, TryInto}, ops::Range}; use sp_wasm_interface::{Pointer, WordSize}; // The pointers need to be aligned to 8 bytes. This is because the @@ -81,7 +79,18 @@ pub struct FreeingBumpHeapAllocator { /// Create an allocator error. fn error(msg: &'static str) -> Error { - Error::Allocator(msg) + Error::Other(msg) +} + +/// A custom "trace" implementation that is only activated when `feature = std`. +/// +/// Uses `wasm-heap` as default target. +macro_rules! trace { + ( $( $args:expr ),+ ) => { + sp_std::if_std! { + log::trace!(target: "wasm-heap", $( $args ),+); + } + } } impl FreeingBumpHeapAllocator { @@ -113,9 +122,9 @@ impl FreeingBumpHeapAllocator { /// /// - `mem` - a slice representing the linear memory on which this allocator operates. /// - `size` - size in bytes of the allocation request - pub fn allocate(&mut self, mem: &mut [u8], size: WordSize) -> Result> { + pub fn allocate(&mut self, mem: &mut [u8], size: WordSize) -> Result, Error> { let mem_size = u32::try_from(mem.len()) - .expect("size of Wasm linear memory is <2^32"); + .expect("size of Wasm linear memory is <2^32; qed"); let max_heap_size = mem_size - self.ptr_offset; if size > MAX_POSSIBLE_ALLOCATION { @@ -151,7 +160,7 @@ impl FreeingBumpHeapAllocator { self.set_heap_u64(mem, ptr - PREFIX_SIZE, list_index as u64)?; self.total_size = self.total_size + item_size + PREFIX_SIZE; - trace!(target: "wasm-heap", "Heap size is {} bytes after allocation", self.total_size); + trace!("Heap size is {} bytes after allocation", self.total_size); Ok(Pointer::new(self.ptr_offset + ptr)) } @@ -162,7 +171,7 @@ impl FreeingBumpHeapAllocator { /// /// - `mem` - a slice representing the linear memory on which this allocator operates. /// - `ptr` - pointer to the allocated chunk - pub fn deallocate(&mut self, mem: &mut [u8], ptr: Pointer) -> Result<()> { + pub fn deallocate(&mut self, mem: &mut [u8], ptr: Pointer) -> Result<(), Error> { let ptr = u32::from(ptr) - self.ptr_offset; if ptr < PREFIX_SIZE { return Err(error("Invalid pointer for deallocation")); @@ -180,7 +189,7 @@ impl FreeingBumpHeapAllocator { let item_size = Self::get_item_size_from_index(list_index); self.total_size = self.total_size.checked_sub(item_size as u32 + PREFIX_SIZE) .ok_or_else(|| error("Unable to subtract from total heap size without overflow"))?; - trace!(target: "wasm-heap", "Heap size is {} bytes after deallocation", self.total_size); + trace!("Heap size is {} bytes after deallocation", self.total_size); Ok(()) } @@ -190,7 +199,7 @@ impl FreeingBumpHeapAllocator { /// Returns the `bumper` from before the increase. /// Returns an `Error::AllocatorOutOfSpace` if the operation /// would exhaust the heap. - fn bump(&mut self, item_size: u32, max_heap_size: u32) -> Result { + fn bump(&mut self, item_size: u32, max_heap_size: u32) -> Result { if self.bumper + PREFIX_SIZE + item_size > max_heap_size { return Err(Error::AllocatorOutOfSpace); } @@ -206,7 +215,7 @@ impl FreeingBumpHeapAllocator { } // Read a u64 from the heap in LE form. Used to read heap allocation prefixes. - fn get_heap_u64(&self, heap: &[u8], offset: u32) -> Result { + fn get_heap_u64(&self, heap: &[u8], offset: u32) -> Result { let range = self.heap_range(offset, 8, heap.len()) .ok_or_else(|| error("read out of heap bounds"))?; let bytes = heap[range].try_into() @@ -215,7 +224,7 @@ impl FreeingBumpHeapAllocator { } // Write a u64 to the heap in LE form. Used to write heap allocation prefixes. - fn set_heap_u64(&self, heap: &mut [u8], offset: u32, val: u64) -> Result<()> { + fn set_heap_u64(&self, heap: &mut [u8], offset: u32, val: u64) -> Result<(), Error> { let range = self.heap_range(offset, 8, heap.len()) .ok_or_else(|| error("write out of heap bounds"))?; let bytes = val.to_le_bytes(); diff --git a/primitives/allocator/src/lib.rs b/primitives/allocator/src/lib.rs new file mode 100644 index 0000000000..0efadbc7f6 --- /dev/null +++ b/primitives/allocator/src/lib.rs @@ -0,0 +1,29 @@ +// Copyright 2020 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 . + +//! Collection of allocator implementations. +//! +//! This crate provides the following allocator implementations: +//! - A freeing-bump allocator: [`FreeingBumpHeapAllocator`](freeing_bump::FreeingBumpHeapAllocator) + +#![cfg_attr(not(feature = "std"), no_std)] +#![warn(missing_docs)] + +mod error; +mod freeing_bump; + +pub use freeing_bump::FreeingBumpHeapAllocator; +pub use error::Error; diff --git a/primitives/core/src/lib.rs b/primitives/core/src/lib.rs index ee768ee4a6..5bb9a3927f 100644 --- a/primitives/core/src/lib.rs +++ b/primitives/core/src/lib.rs @@ -309,3 +309,43 @@ pub fn to_substrate_wasm_fn_return_value(value: &impl Encode) -> u64 { res } + +/// Macro for creating `Maybe*` marker traits. +/// +/// Such a maybe-marker trait requires the given bound when `feature = std` and doesn't require +/// the bound on `no_std`. This is useful for situations where you require that a type implements +/// a certain trait with `feature = std`, but not on `no_std`. +/// +/// # Example +/// +/// ``` +/// sp_core::impl_maybe_marker! { +/// /// A marker for a type that implements `Debug` when `feature = std`. +/// trait MaybeDebug: std::fmt::Debug; +/// /// A marker for a type that implements `Debug + Display` when `feature = std`. +/// trait MaybeDebugDisplay: std::fmt::Debug, std::fmt::Display; +/// } +/// ``` +#[macro_export] +macro_rules! impl_maybe_marker { + ( + $( + $(#[$doc:meta] )+ + trait $trait_name:ident: $( $trait_bound:path ),+; + )+ + ) => { + $( + $(#[$doc])+ + #[cfg(feature = "std")] + pub trait $trait_name: $( $trait_bound + )+ {} + #[cfg(feature = "std")] + impl $trait_name for T {} + + $(#[$doc])+ + #[cfg(not(feature = "std"))] + pub trait $trait_name {} + #[cfg(not(feature = "std"))] + impl $trait_name for T {} + )+ + } +} diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 2547ce1072..08bbd83ca5 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -458,36 +458,18 @@ impl CheckEqual for super::generic::DigestItem whe } } -macro_rules! impl_maybe_marker { - ( $( $(#[$doc:meta])+ $trait_name:ident: $($trait_bound:path),+ );+ ) => { - $( - $(#[$doc])+ - #[cfg(feature = "std")] - pub trait $trait_name: $($trait_bound +)+ {} - #[cfg(feature = "std")] - impl $trait_name for T {} - - $(#[$doc])+ - #[cfg(not(feature = "std"))] - pub trait $trait_name {} - #[cfg(not(feature = "std"))] - impl $trait_name for T {} - )+ - } -} - -impl_maybe_marker!( +sp_core::impl_maybe_marker!( /// A type that implements Display when in std environment. - MaybeDisplay: Display; + trait MaybeDisplay: Display; /// A type that implements Hash when in std environment. - MaybeHash: sp_std::hash::Hash; + trait MaybeHash: sp_std::hash::Hash; /// A type that implements Serialize when in std environment. - MaybeSerialize: Serialize; + trait MaybeSerialize: Serialize; /// A type that implements Serialize, DeserializeOwned and Debug when in std environment. - MaybeSerializeDeserialize: DeserializeOwned, Serialize + trait MaybeSerializeDeserialize: DeserializeOwned, Serialize; ); /// A type that provides a randomness beacon. diff --git a/primitives/sandbox/src/lib.rs b/primitives/sandbox/src/lib.rs index 86098e73af..2760a46b48 100755 --- a/primitives/sandbox/src/lib.rs +++ b/primitives/sandbox/src/lib.rs @@ -81,10 +81,7 @@ pub type HostFuncType = fn(&mut T, &[TypedValue]) -> Result"] edition = "2018" [dependencies] -wasmi = "0.6.2" +wasmi = { version = "0.6.2", optional = true } impl-trait-for-tuples = "0.1.2" +sp-std = { version = "2.0.0", path = "../std", default-features = false } + +[features] +default = [ "std" ] +std = [ "wasmi", "sp-std/std" ] diff --git a/primitives/wasm-interface/src/lib.rs b/primitives/wasm-interface/src/lib.rs index b0bbbf82db..d6f9bbfbf0 100644 --- a/primitives/wasm-interface/src/lib.rs +++ b/primitives/wasm-interface/src/lib.rs @@ -16,12 +16,20 @@ //! Types and traits for interfacing between the host and the wasm runtime. -use std::{borrow::Cow, marker::PhantomData, mem, iter::Iterator, result}; +#![cfg_attr(not(feature = "std"), no_std)] +use sp_std::{ + borrow::Cow, marker::PhantomData, mem, iter::Iterator, result, vec::Vec, +}; + +#[cfg(feature = "std")] mod wasmi_impl; /// Result type used by traits in this crate. +#[cfg(feature = "std")] pub type Result = result::Result; +#[cfg(not(feature = "std"))] +pub type Result = result::Result; /// Value types supported by Substrate on the boundary between host/Wasm. #[derive(Copy, Clone, PartialEq, Debug, Eq)] @@ -189,11 +197,22 @@ impl Signature { return_value: None, } } - } +/// A trait that requires `RefUnwindSafe` when `feature = std`. +#[cfg(feature = "std")] +pub trait MaybeRefUnwindSafe: std::panic::RefUnwindSafe {} +#[cfg(feature = "std")] +impl MaybeRefUnwindSafe for T {} + +/// A trait that requires `RefUnwindSafe` when `feature = std`. +#[cfg(not(feature = "std"))] +pub trait MaybeRefUnwindSafe {} +#[cfg(not(feature = "std"))] +impl MaybeRefUnwindSafe for T {} + /// Something that provides a function implementation on the host for a wasm function. -pub trait Function: std::panic::RefUnwindSafe + Send + Sync { +pub trait Function: MaybeRefUnwindSafe + Send + Sync { /// Returns the name of this function. fn name(&self) -> &str; /// Returns the signature of this function. -- GitLab From 3a4dce9778d1b0ec3146532dcc4c5f194a7877d8 Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Wed, 22 Jan 2020 18:34:41 +0100 Subject: [PATCH 004/180] Add fool protection and comment construct_block (#4715) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add fool protection and comment construct_block * Update bin/node/executor/tests/common.rs Co-Authored-By: Bastian Köcher Co-authored-by: Bastian Köcher --- bin/node/executor/tests/common.rs | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/bin/node/executor/tests/common.rs b/bin/node/executor/tests/common.rs index 52f8b65654..090d2ee5d4 100644 --- a/bin/node/executor/tests/common.rs +++ b/bin/node/executor/tests/common.rs @@ -21,7 +21,7 @@ use sp_core::{ Blake2Hasher, NeverNativeValue, NativeOrEncoded, traits::CodeExecutor, }; -use sp_runtime::traits::Header as HeaderT; +use sp_runtime::{ApplyExtrinsicResult, traits::Header as HeaderT}; use sc_executor::{NativeExecutor, WasmExecutionMethod}; use sc_executor::error::Result; @@ -92,6 +92,10 @@ pub fn new_test_ext(code: &[u8], support_changes_trie: bool) -> TestExternalitie ext } +/// Construct a fake block. +/// +/// `extrinsics` must be a list of valid extrinsics, i.e. none of the extrinsics for example +/// can report `ExhaustResources`. Otherwise, this function panics. pub fn construct_block( env: &mut TestExternalities, number: BlockNumber, @@ -104,10 +108,10 @@ pub fn construct_block( let extrinsics = extrinsics.into_iter().map(sign).collect::>(); // calculate the header fields that we can. - let extrinsics_root = Layout::::ordered_trie_root( - extrinsics.iter().map(Encode::encode) - ).to_fixed_bytes() - .into(); + let extrinsics_root = + Layout::::ordered_trie_root(extrinsics.iter().map(Encode::encode)) + .to_fixed_bytes() + .into(); let header = Header { parent_hash, @@ -126,14 +130,20 @@ pub fn construct_block( None, ).0.unwrap(); - for i in extrinsics.iter() { - executor_call:: _>( + for extrinsic in extrinsics.iter() { + // Try to apply the `extrinsic`. It should be valid, in the sense that it passes + // all pre-inclusion checks. + let r = executor_call:: _>( env, "BlockBuilder_apply_extrinsic", - &i.encode(), + &extrinsic.encode(), true, None, - ).0.unwrap(); + ).0.expect("application of an extrinsic failed").into_encoded(); + match ApplyExtrinsicResult::decode(&mut &r[..]).expect("apply result deserialization failed") { + Ok(_) => {}, + Err(e) => panic!("Applying extrinsic failed: {:?}", e), + } } let header = match executor_call:: _>( -- GitLab From 7bd0dbf39e4605da1d24b0f1a4ec77c843cd49d8 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Thu, 23 Jan 2020 00:03:38 -0800 Subject: [PATCH 005/180] Default fork choice value and intermediates for block import parameters (#4652) * consensus, pow: intermediate separation and fail * Fix compiles * Update primitives/consensus/common/src/block_import.rs Co-Authored-By: Robert Habermeier * Update primitives/consensus/common/src/block_import.rs Co-Authored-By: Robert Habermeier * Document what None means for `fork_choice` in block import params Co-authored-by: Robert Habermeier --- bin/node/cli/src/service.rs | 3 +- bin/node/transaction-factory/src/lib.rs | 3 +- client/consensus/aura/src/lib.rs | 6 +- client/consensus/babe/src/lib.rs | 16 +- client/consensus/babe/src/tests.rs | 3 +- client/consensus/pow/src/lib.rs | 325 ++++++++++++------ client/finality-grandpa/src/light_import.rs | 3 +- client/finality-grandpa/src/tests.rs | 9 +- client/network/test/src/lib.rs | 3 +- client/src/client.rs | 7 + primitives/blockchain/src/error.rs | 3 + .../consensus/common/src/block_import.rs | 11 +- test-utils/client/src/client_ext.rs | 24 +- 13 files changed, 278 insertions(+), 138 deletions(-) diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index b12dfcdc51..603df5b7d9 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -565,7 +565,8 @@ mod tests { storage_changes: None, finalized: false, auxiliary: Vec::new(), - fork_choice: ForkChoiceStrategy::LongestChain, + intermediates: Default::default(), + fork_choice: Some(ForkChoiceStrategy::LongestChain), allow_missing_state: false, import_existing: false, }; diff --git a/bin/node/transaction-factory/src/lib.rs b/bin/node/transaction-factory/src/lib.rs index f3dcdb0875..a0c6a4f663 100644 --- a/bin/node/transaction-factory/src/lib.rs +++ b/bin/node/transaction-factory/src/lib.rs @@ -202,7 +202,8 @@ fn import_block( finalized: false, justification: None, auxiliary: Vec::new(), - fork_choice: ForkChoiceStrategy::LongestChain, + intermediates: Default::default(), + fork_choice: Some(ForkChoiceStrategy::LongestChain), allow_missing_state: false, import_existing: false, }; diff --git a/client/consensus/aura/src/lib.rs b/client/consensus/aura/src/lib.rs index 95dc08afaf..270bd19422 100644 --- a/client/consensus/aura/src/lib.rs +++ b/client/consensus/aura/src/lib.rs @@ -290,7 +290,8 @@ impl sc_consensus_slots::SimpleSlotWorker for AuraW storage_changes: Some(storage_changes), finalized: false, auxiliary: Vec::new(), - fork_choice: ForkChoiceStrategy::LongestChain, + intermediates: Default::default(), + fork_choice: Some(ForkChoiceStrategy::LongestChain), allow_missing_state: false, import_existing: false, } @@ -644,7 +645,8 @@ impl Verifier for AuraVerifier where finalized: false, justification, auxiliary: Vec::new(), - fork_choice: ForkChoiceStrategy::LongestChain, + intermediates: Default::default(), + fork_choice: Some(ForkChoiceStrategy::LongestChain), allow_missing_state: false, import_existing: false, }; diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index 770f8a4eec..8480972311 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -451,10 +451,8 @@ impl sc_consensus_slots::SimpleSlotWorker for BabeWork storage_changes: Some(storage_changes), finalized: false, auxiliary: Vec::new(), // block-weight is written in block import. - // TODO: block-import handles fork choice and this shouldn't even have the - // option to specify one. - // https://github.com/paritytech/substrate/issues/3623 - fork_choice: ForkChoiceStrategy::LongestChain, + intermediates: Default::default(), + fork_choice: None, allow_missing_state: false, import_existing: false, } @@ -807,10 +805,8 @@ impl Verifier for BabeVerifier BlockImport for BabeBlockImport last_best_weight { + Some(ForkChoiceStrategy::Custom(if total_weight > last_best_weight { true } else if total_weight == last_best_weight { number > last_best_number } else { false - }) + })) }; let import_result = self.inner.import_block(block, new_cache); diff --git a/client/consensus/babe/src/tests.rs b/client/consensus/babe/src/tests.rs index 880e028000..3339c06d65 100644 --- a/client/consensus/babe/src/tests.rs +++ b/client/consensus/babe/src/tests.rs @@ -594,7 +594,8 @@ fn propose_and_import_block( storage_changes: None, finalized: false, auxiliary: Vec::new(), - fork_choice: ForkChoiceStrategy::LongestChain, + intermediates: Default::default(), + fork_choice: Some(ForkChoiceStrategy::LongestChain), allow_missing_state: false, import_existing: false, }, diff --git a/client/consensus/pow/src/lib.rs b/client/consensus/pow/src/lib.rs index 2ea0cbdf0f..ca7285b7fe 100644 --- a/client/consensus/pow/src/lib.rs +++ b/client/consensus/pow/src/lib.rs @@ -32,6 +32,7 @@ use std::sync::Arc; use std::thread; use std::collections::HashMap; +use std::marker::PhantomData; 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; @@ -43,7 +44,8 @@ use sp_consensus_pow::{Seal, TotalDifficulty, POW_ENGINE_ID}; use sp_inherents::{InherentDataProviders, InherentData}; use sp_consensus::{ BlockImportParams, BlockOrigin, ForkChoiceStrategy, SyncOracle, Environment, Proposer, - SelectChain, Error as ConsensusError, CanAuthorWith, RecordProof, + SelectChain, Error as ConsensusError, CanAuthorWith, RecordProof, BlockImport, + BlockCheckParams, ImportResult, }; use sp_consensus::import_queue::{BoxBlockImport, BasicQueue, Verifier}; use codec::{Encode, Decode}; @@ -59,6 +61,10 @@ pub enum Error { HeaderUnsealed(B::Hash), #[display(fmt = "PoW validation error: invalid seal")] InvalidSeal, + #[display(fmt = "PoW validation error: invalid difficulty")] + InvalidDifficulty, + #[display(fmt = "PoW block import expects an intermediate, but not found one")] + NoIntermediate, #[display(fmt = "Rejecting block too far in future")] TooFarInFuture, #[display(fmt = "Fetching best header failed using select chain: {:?}", _0)] @@ -89,6 +95,12 @@ impl std::convert::From> for String { } } +impl std::convert::From> for ConsensusError { + fn from(error: Error) -> ConsensusError { + ConsensusError::ClientImport(error.to_string()) + } +} + /// Auxiliary storage prefix for PoW engine. pub const POW_AUX_PREFIX: [u8; 4] = *b"PoW:"; @@ -97,6 +109,18 @@ fn aux_key>(hash: &T) -> Vec { POW_AUX_PREFIX.iter().chain(hash.as_ref()).copied().collect() } +/// Intermediate value passed to block importer. +#[derive(Encode, Decode, Clone, Debug, Default)] +pub struct PowIntermediate { + /// The header hash with seal, used for auxiliary key. + pub hash: B::Hash, + /// Difficulty of the block, if known. + pub difficulty: Option, +} + +/// Intermediate key for PoW engine. +pub static INTERMEDIATE_KEY: &[u8] = b"pow1"; + /// Auxiliary storage data for PoW. #[derive(Encode, Decode, Clone, Debug, Default)] pub struct PowAux { @@ -126,14 +150,22 @@ pub trait PowAlgorithm { type Difficulty: TotalDifficulty + Default + Encode + Decode + Ord + Clone + Copy; /// Get the next block's difficulty. + /// + /// This function will be called twice during the import process, so the implementation + /// should be properly cached. fn difficulty(&self, parent: &BlockId) -> Result>; - /// Verify proof of work against the given difficulty. - fn verify( + /// Verify that the seal is valid against given pre hash. + fn verify_seal( &self, - parent: &BlockId, pre_hash: &B::Hash, seal: &Seal, + ) -> Result>; + /// Verify that the difficulty is valid against given seal. + fn verify_difficulty( + &self, difficulty: Self::Difficulty, + parent: &BlockId, + seal: &Seal, ) -> Result>; /// Mine a seal that satisfies the given difficulty. fn mine( @@ -145,59 +177,35 @@ pub trait PowAlgorithm { ) -> Result, Error>; } -/// A verifier for PoW blocks. -pub struct PowVerifier { - client: Arc, +/// A block importer for PoW. +pub struct PowBlockImport { algorithm: Algorithm, - inherent_data_providers: sp_inherents::InherentDataProviders, + inner: I, select_chain: Option, + client: Arc, + inherent_data_providers: sp_inherents::InherentDataProviders, check_inherents_after: <::Header as HeaderT>::Number, } -impl PowVerifier { +impl PowBlockImport where + B: BlockT, + I: BlockImport> + Send + Sync, + I::Error: Into, + C: ProvideRuntimeApi + Send + Sync + HeaderBackend + AuxStore + ProvideCache + BlockOf, + C::Api: BlockBuilderApi, + Algorithm: PowAlgorithm, +{ + /// Create a new block import suitable to be used in PoW pub fn new( + inner: I, client: Arc, algorithm: Algorithm, check_inherents_after: <::Header as HeaderT>::Number, select_chain: Option, inherent_data_providers: sp_inherents::InherentDataProviders, ) -> Self { - Self { client, algorithm, inherent_data_providers, select_chain, check_inherents_after } - } - - fn check_header( - &self, - mut header: B::Header, - parent_block_id: BlockId, - ) -> Result<(B::Header, Algorithm::Difficulty, DigestItem), Error> where - Algorithm: PowAlgorithm, - { - let hash = header.hash(); - - let (seal, inner_seal) = match header.digest_mut().pop() { - Some(DigestItem::Seal(id, seal)) => { - if id == POW_ENGINE_ID { - (DigestItem::Seal(id, seal.clone()), seal) - } else { - return Err(Error::WrongEngine(id)) - } - }, - _ => return Err(Error::HeaderUnsealed(hash)), - }; - - let pre_hash = header.hash(); - let difficulty = self.algorithm.difficulty(&parent_block_id)?; - - if !self.algorithm.verify( - &parent_block_id, - &pre_hash, - &inner_seal, - difficulty, - )? { - return Err(Error::InvalidSeal); - } - - Ok((header, difficulty, seal)) + Self { inner, client, algorithm, check_inherents_after, + select_chain, inherent_data_providers } } fn check_inherents( @@ -206,9 +214,7 @@ impl PowVerifier { block_id: BlockId, inherent_data: InherentData, timestamp_now: u64, - ) -> Result<(), Error> where - C: ProvideRuntimeApi, C::Api: BlockBuilderApi - { + ) -> Result<(), Error> { const MAX_TIMESTAMP_DRIFT_SECS: u64 = 60; if *block.header().number() < self.check_inherents_after { @@ -243,55 +249,165 @@ impl PowVerifier { } } -impl Verifier for PowVerifier where +impl BlockImport for PowBlockImport where + B: BlockT, + I: BlockImport> + Send + Sync, + I::Error: Into, + S: SelectChain, C: ProvideRuntimeApi + Send + Sync + HeaderBackend + AuxStore + ProvideCache + BlockOf, C::Api: BlockBuilderApi, - S: SelectChain, - Algorithm: PowAlgorithm + Send + Sync, + Algorithm: PowAlgorithm, { - fn verify( + type Error = ConsensusError; + type Transaction = sp_api::TransactionFor; + + fn check_block( &mut self, - origin: BlockOrigin, - header: B::Header, - justification: Option, - mut body: Option>, - ) -> Result<(BlockImportParams, Option)>>), String> { - let inherent_data = self.inherent_data_providers - .create_inherent_data().map_err(|e| e.into_string())?; - let timestamp_now = inherent_data.timestamp_inherent_data().map_err(|e| e.into_string())?; + block: BlockCheckParams, + ) -> Result { + self.inner.check_block(block).map_err(Into::into) + } + fn import_block( + &mut self, + mut block: BlockImportParams, + new_cache: HashMap>, + ) -> Result { let best_hash = match self.select_chain.as_ref() { Some(select_chain) => select_chain.best_chain() .map_err(|e| format!("Fetch best chain failed via select chain: {:?}", e))? .hash(), None => self.client.info().best_hash, }; - let hash = header.hash(); - let parent_hash = *header.parent_hash(); + + let parent_hash = *block.header.parent_hash(); let best_aux = PowAux::read::<_, B>(self.client.as_ref(), &best_hash)?; let mut aux = PowAux::read::<_, B>(self.client.as_ref(), &parent_hash)?; - let (checked_header, difficulty, seal) = self.check_header( - header, - BlockId::Hash(parent_hash), - )?; - aux.difficulty = difficulty; - aux.total_difficulty.increment(difficulty); + if let Some(inner_body) = block.body.take() { + let inherent_data = self.inherent_data_providers + .create_inherent_data().map_err(|e| e.into_string())?; + let timestamp_now = inherent_data.timestamp_inherent_data().map_err(|e| e.into_string())?; - if let Some(inner_body) = body.take() { - let block = B::new(checked_header.clone(), inner_body); + let check_block = B::new(block.header.clone(), inner_body); self.check_inherents( - block.clone(), + check_block.clone(), BlockId::Hash(parent_hash), inherent_data, timestamp_now )?; - body = Some(block.deconstruct().1); + block.body = Some(check_block.deconstruct().1); } - let key = aux_key(&hash); + let inner_seal = match block.post_digests.last() { + Some(DigestItem::Seal(id, seal)) => { + if id == &POW_ENGINE_ID { + seal.clone() + } else { + return Err(Error::::WrongEngine(*id).into()) + } + }, + _ => return Err(Error::::HeaderUnsealed(block.header.hash()).into()), + }; + + let intermediate = PowIntermediate::::decode( + &mut &block.intermediates.remove(INTERMEDIATE_KEY) + .ok_or(Error::::NoIntermediate)?[..] + ).map_err(|_| Error::::NoIntermediate)?; + + let difficulty = match intermediate.difficulty { + Some(difficulty) => difficulty, + None => self.algorithm.difficulty(&BlockId::hash(parent_hash))?, + }; + + if !self.algorithm.verify_difficulty( + difficulty, + &BlockId::hash(parent_hash), + &inner_seal, + )? { + return Err(Error::::InvalidDifficulty.into()) + } + + aux.difficulty = difficulty; + aux.total_difficulty.increment(difficulty); + + let key = aux_key(&intermediate.hash); + block.auxiliary.push((key, Some(aux.encode()))); + if block.fork_choice.is_none() { + block.fork_choice = Some(ForkChoiceStrategy::Custom( + aux.total_difficulty > best_aux.total_difficulty + )); + } + + self.inner.import_block(block, new_cache).map_err(Into::into) + } +} + +/// A verifier for PoW blocks. +pub struct PowVerifier { + algorithm: Algorithm, + _marker: PhantomData, +} + +impl PowVerifier { + pub fn new( + algorithm: Algorithm, + ) -> Self { + Self { algorithm, _marker: PhantomData } + } + + fn check_header( + &self, + mut header: B::Header, + ) -> Result<(B::Header, DigestItem), Error> where + Algorithm: PowAlgorithm, + { + let hash = header.hash(); + + let (seal, inner_seal) = match header.digest_mut().pop() { + Some(DigestItem::Seal(id, seal)) => { + if id == POW_ENGINE_ID { + (DigestItem::Seal(id, seal.clone()), seal) + } else { + return Err(Error::WrongEngine(id)) + } + }, + _ => return Err(Error::HeaderUnsealed(hash)), + }; + + let pre_hash = header.hash(); + + if !self.algorithm.verify_seal( + &pre_hash, + &inner_seal, + )? { + return Err(Error::InvalidSeal); + } + + Ok((header, seal)) + } +} + +impl Verifier for PowVerifier where + Algorithm: PowAlgorithm + Send + Sync, +{ + fn verify( + &mut self, + origin: BlockOrigin, + header: B::Header, + justification: Option, + body: Option>, + ) -> Result<(BlockImportParams, Option)>>), String> { + let hash = header.hash(); + let (checked_header, seal) = self.check_header(header)?; + + let intermediate = PowIntermediate:: { + hash: hash, + difficulty: None, + }; + let import_block = BlockImportParams { origin, header: checked_header, @@ -300,10 +416,13 @@ impl Verifier for PowVerifier storage_changes: None, finalized: false, justification, - auxiliary: vec![(key, Some(aux.encode()))], - fork_choice: ForkChoiceStrategy::Custom( - aux.total_difficulty > best_aux.total_difficulty - ), + intermediates: { + let mut ret = HashMap::new(); + ret.insert(INTERMEDIATE_KEY.to_vec(), intermediate.encode()); + ret + }, + auxiliary: vec![], + fork_choice: None, allow_missing_state: false, import_existing: false, }; @@ -332,10 +451,7 @@ pub type PowImportQueue = BasicQueue; /// Import queue for PoW engine. pub fn import_queue( block_import: BoxBlockImport>, - client: Arc, algorithm: Algorithm, - check_inherents_after: <::Header as HeaderT>::Number, - select_chain: Option, inherent_data_providers: InherentDataProviders, ) -> Result< PowImportQueue>, @@ -345,18 +461,12 @@ pub fn import_queue( C: ProvideRuntimeApi + HeaderBackend + BlockOf + ProvideCache + AuxStore, C: Send + Sync + AuxStore + 'static, C::Api: BlockBuilderApi, - Algorithm: PowAlgorithm + Send + Sync + 'static, + Algorithm: PowAlgorithm + Clone + Send + Sync + 'static, S: SelectChain + 'static, { register_pow_inherent_data_provider(&inherent_data_providers)?; - let verifier = PowVerifier::new( - client.clone(), - algorithm, - check_inherents_after, - select_chain, - inherent_data_providers, - ); + let verifier = PowVerifier::new(algorithm); Ok(BasicQueue::new( verifier, @@ -485,7 +595,6 @@ fn mine_loop( continue 'outer } - let mut aux = PowAux::read(client, &best_hash)?; let mut proposer = futures::executor::block_on(env.init(&best_header)) .map_err(|e| Error::Environment(format!("{:?}", e)))?; @@ -526,38 +635,36 @@ fn mine_loop( } }; - aux.difficulty = difficulty; - aux.total_difficulty.increment(difficulty); - let hash = { + let (hash, seal) = { + let seal = DigestItem::Seal(POW_ENGINE_ID, seal); let mut header = header.clone(); - header.digest_mut().push(DigestItem::Seal(POW_ENGINE_ID, seal.clone())); - header.hash() + header.digest_mut().push(seal); + let hash = header.hash(); + let seal = header.digest_mut().pop() + .expect("Pushed one seal above; length greater than zero; qed"); + (hash, seal) }; - let key = aux_key(&hash); - let best_hash = match select_chain { - Some(select_chain) => select_chain.best_chain() - .map_err(Error::BestHashSelectChain)? - .hash(), - None => client.info().best_hash, + let intermediate = PowIntermediate:: { + hash, + difficulty: Some(difficulty), }; - let best_aux = PowAux::::read(client, &best_hash)?; - - // if the best block has changed in the meantime drop our proposal - if best_aux.total_difficulty > aux.total_difficulty { - continue 'outer - } let import_block = BlockImportParams { origin: BlockOrigin::Own, header, justification: None, - post_digests: vec![DigestItem::Seal(POW_ENGINE_ID, seal)], + post_digests: vec![seal], body: Some(body), storage_changes: Some(proposal.storage_changes), + intermediates: { + let mut ret = HashMap::new(); + ret.insert(INTERMEDIATE_KEY.to_vec(), intermediate.encode()); + ret + }, finalized: false, - auxiliary: vec![(key, Some(aux.encode()))], - fork_choice: ForkChoiceStrategy::Custom(true), + auxiliary: vec![], + fork_choice: None, allow_missing_state: false, import_existing: false, }; diff --git a/client/finality-grandpa/src/light_import.rs b/client/finality-grandpa/src/light_import.rs index 0da2248778..4ae35167be 100644 --- a/client/finality-grandpa/src/light_import.rs +++ b/client/finality-grandpa/src/light_import.rs @@ -697,7 +697,8 @@ pub mod tests { storage_changes: None, finalized: false, auxiliary: Vec::new(), - fork_choice: ForkChoiceStrategy::LongestChain, + intermediates: Default::default(), + fork_choice: Some(ForkChoiceStrategy::LongestChain), allow_missing_state: true, import_existing: false, }; diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index 9ad12c6c31..889250c54d 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -1032,7 +1032,8 @@ fn allows_reimporting_change_blocks() { storage_changes: None, finalized: false, auxiliary: Vec::new(), - fork_choice: ForkChoiceStrategy::LongestChain, + intermediates: Default::default(), + fork_choice: Some(ForkChoiceStrategy::LongestChain), allow_missing_state: false, import_existing: false, } @@ -1091,7 +1092,8 @@ fn test_bad_justification() { storage_changes: None, finalized: false, auxiliary: Vec::new(), - fork_choice: ForkChoiceStrategy::LongestChain, + intermediates: Default::default(), + fork_choice: Some(ForkChoiceStrategy::LongestChain), allow_missing_state: false, import_existing: false, } @@ -1829,7 +1831,8 @@ fn imports_justification_for_regular_blocks_on_import() { storage_changes: None, finalized: false, auxiliary: Vec::new(), - fork_choice: ForkChoiceStrategy::LongestChain, + intermediates: Default::default(), + fork_choice: Some(ForkChoiceStrategy::LongestChain), allow_missing_state: false, import_existing: false, }; diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 1b13e83343..2369ba4f22 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -95,7 +95,8 @@ impl Verifier for PassThroughVerifier { justification, post_digests: vec![], auxiliary: Vec::new(), - fork_choice: ForkChoiceStrategy::LongestChain, + intermediates: Default::default(), + fork_choice: Some(ForkChoiceStrategy::LongestChain), allow_missing_state: false, import_existing: false, }, maybe_keys)) diff --git a/client/src/client.rs b/client/src/client.rs index c74a005c6f..26b077277f 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -818,12 +818,19 @@ impl Client where finalized, auxiliary, fork_choice, + intermediates, import_existing, .. } = import_block; assert!(justification.is_some() && finalized || justification.is_none()); + if !intermediates.is_empty() { + return Err(Error::IncompletePipeline) + } + + let fork_choice = fork_choice.ok_or(Error::IncompletePipeline)?; + let import_headers = if post_digests.is_empty() { PrePostHeader::Same(header) } else { diff --git a/primitives/blockchain/src/error.rs b/primitives/blockchain/src/error.rs index d51ab787c7..24872448ab 100644 --- a/primitives/blockchain/src/error.rs +++ b/primitives/blockchain/src/error.rs @@ -126,6 +126,9 @@ pub enum Error { /// Invalid calculated state root on block import. #[display(fmt = "Calculated state root does not match.")] InvalidStateRoot, + /// Incomplete block import pipeline. + #[display(fmt = "Incomplete block import pipeline.")] + IncompletePipeline, /// A convenience variant for String #[display(fmt = "{}", _0)] Msg(String), diff --git a/primitives/consensus/common/src/block_import.rs b/primitives/consensus/common/src/block_import.rs index f8d05e1054..71315b63ef 100644 --- a/primitives/consensus/common/src/block_import.rs +++ b/primitives/consensus/common/src/block_import.rs @@ -142,13 +142,21 @@ pub struct BlockImportParams { /// Is this block finalized already? /// `true` implies instant finality. pub finalized: bool, + /// Intermediate values that are interpreted by block importers. Each block importer, + /// upon handling a value, removes it from the intermediate list. The final block importer + /// rejects block import if there are still intermediate values that remain unhandled. + pub intermediates: HashMap, Vec>, /// Auxiliary consensus data produced by the block. /// Contains a list of key-value pairs. If values are `None`, the keys /// will be deleted. pub auxiliary: Vec<(Vec, Option>)>, /// Fork choice strategy of this import. This should only be set by a /// synchronous import, otherwise it may race against other imports. - pub fork_choice: ForkChoiceStrategy, + /// `None` indicates that the current verifier or importer cannot yet + /// determine the fork choice value, and it expects subsequent importer + /// to modify it. If `None` is passed all the way down to bottom block + /// importer, the import fails with an `IncompletePipeline` error. + pub fork_choice: Option, /// Allow importing the block skipping state verification if parent state is missing. pub allow_missing_state: bool, /// Re-validate existing block. @@ -210,6 +218,7 @@ impl BlockImportParams { storage_changes: None, finalized: self.finalized, auxiliary: self.auxiliary, + intermediates: self.intermediates, allow_missing_state: self.allow_missing_state, fork_choice: self.fork_choice, import_existing: self.import_existing, diff --git a/test-utils/client/src/client_ext.rs b/test-utils/client/src/client_ext.rs index aa7383e3ab..e29ee787d0 100644 --- a/test-utils/client/src/client_ext.rs +++ b/test-utils/client/src/client_ext.rs @@ -96,7 +96,8 @@ impl ClientBlockImportExt for std::sync::A storage_changes: None, finalized: false, auxiliary: Vec::new(), - fork_choice: ForkChoiceStrategy::LongestChain, + intermediates: Default::default(), + fork_choice: Some(ForkChoiceStrategy::LongestChain), allow_missing_state: false, import_existing: false, }; @@ -115,7 +116,8 @@ impl ClientBlockImportExt for std::sync::A storage_changes: None, finalized: false, auxiliary: Vec::new(), - fork_choice: ForkChoiceStrategy::Custom(true), + intermediates: Default::default(), + fork_choice: Some(ForkChoiceStrategy::Custom(true)), allow_missing_state: false, import_existing: false, }; @@ -134,7 +136,8 @@ impl ClientBlockImportExt for std::sync::A storage_changes: None, finalized: true, auxiliary: Vec::new(), - fork_choice: ForkChoiceStrategy::Custom(true), + intermediates: Default::default(), + fork_choice: Some(ForkChoiceStrategy::Custom(true)), allow_missing_state: false, import_existing: false, }; @@ -158,7 +161,8 @@ impl ClientBlockImportExt for std::sync::A storage_changes: None, finalized: true, auxiliary: Vec::new(), - fork_choice: ForkChoiceStrategy::LongestChain, + intermediates: Default::default(), + fork_choice: Some(ForkChoiceStrategy::LongestChain), allow_missing_state: false, import_existing: false, }; @@ -182,7 +186,8 @@ impl ClientBlockImportExt for Client ClientBlockImportExt for Client ClientBlockImportExt for Client ClientBlockImportExt for Client Date: Thu, 23 Jan 2020 12:58:36 +0100 Subject: [PATCH 006/180] client/finality-grandpa: Make round_communication use bounded channel (#4691) * clinet/finality-grandpa: Make round_communication use bounded channel `round_communication` returns a `Sink` and a `Stream` for outgoing and incoming messages. The messages send into the `Sink` are forwarded down to the network as well as send back into the `Stream` to ensure the node processes its own messages. So far, to send messages into the `Sink` back into the `Stream`, an unbounded channel was used. This patch updates `round_communication` and `OutgoingMessages` to use a bounded channel. This is part of a greater effort to reduce the number of owners of components within `finality-grandpa` and `network` as well as to reduce the amount of unbounded channels. For details see d4fbb897c and f0c18520a. * client/finality-grandpa: Import futures03::future::ready at the top * client/finality-grandpa: Make tests use compat of future 03 * client/finality-grandpa: Do not import ready into scope Instead of importing futures03::future::ready into the scope, only import futures::future03 into scope and call ready as furure03::ready. --- .../finality-grandpa/src/communication/mod.rs | 89 ++++++++++--------- client/finality-grandpa/src/environment.rs | 9 +- client/finality-grandpa/src/tests.rs | 25 ++++-- 3 files changed, 76 insertions(+), 47 deletions(-) diff --git a/client/finality-grandpa/src/communication/mod.rs b/client/finality-grandpa/src/communication/mod.rs index 18cb14c739..64637c0ed8 100644 --- a/client/finality-grandpa/src/communication/mod.rs +++ b/client/finality-grandpa/src/communication/mod.rs @@ -27,12 +27,13 @@ //! In the future, there will be a fallback for allowing sending the same message //! under certain conditions that are used to un-stick the protocol. -use futures::{prelude::*, sync::mpsc}; +use futures::prelude::*; use futures03::{ channel::mpsc as mpsc03, compat::Compat, - future::{Future as Future03}, - stream::StreamExt, + future::{self as future03, Future as Future03}, + sink::Sink as Sink03, + stream::{Stream as Stream03, StreamExt}, }; use log::{debug, trace}; use parking_lot::Mutex; @@ -276,8 +277,8 @@ impl> NetworkBridge { local_key: Option, has_voted: HasVoted, ) -> ( - impl Stream,Error=Error>, - impl Sink,SinkError=Error>, + impl Stream03> + Unpin, + OutgoingMessages, ) { self.note_round( round, @@ -295,22 +296,20 @@ impl> NetworkBridge { }); let topic = round_topic::(round.0, set_id.0); - let incoming = Compat::new(self.gossip_engine.messages_for(topic) - .map(|item| Ok::<_, ()>(item))) - .filter_map(|notification| { + let incoming = self.gossip_engine.messages_for(topic) + .filter_map(move |notification| { let decoded = GossipMessage::::decode(&mut ¬ification.message[..]); - if let Err(ref e) = decoded { - debug!(target: "afg", "Skipping malformed message {:?}: {}", notification, e); - } - decoded.ok() - }) - .and_then(move |msg| { - match msg { - GossipMessage::Vote(msg) => { + + match decoded { + Err(ref e) => { + debug!(target: "afg", "Skipping malformed message {:?}: {}", notification, e); + return future03::ready(None); + } + Ok(GossipMessage::Vote(msg)) => { // check signature. if !voters.contains_key(&msg.message.id) { debug!(target: "afg", "Skipping message from unknown voter {}", msg.message.id); - return Ok(None); + return future03::ready(None); } if voters.len() <= TELEMETRY_VOTERS_LIMIT { @@ -339,18 +338,16 @@ impl> NetworkBridge { }; } - Ok(Some(msg.message)) + future03::ready(Some(msg.message)) } _ => { debug!(target: "afg", "Skipping unknown message type"); - return Ok(None); + return future03::ready(None); } } - }) - .filter_map(|x| x) - .map_err(|()| Error::Network(format!("Failed to receive message on unbounded stream"))); + }); - let (tx, out_rx) = mpsc::unbounded(); + let (tx, out_rx) = mpsc03::channel(0); let outgoing = OutgoingMessages:: { round: round.0, set_id: set_id.0, @@ -360,14 +357,10 @@ impl> NetworkBridge { has_voted, }; - let out_rx = out_rx.map_err(move |()| Error::Network( - format!("Failed to receive on unbounded receiver for round {}", round.0) - )); - // Combine incoming votes from external GRANDPA nodes with outgoing // votes from our own GRANDPA voter to have a single // vote-import-pipeline. - let incoming = incoming.select(out_rx); + let incoming = futures03::stream::select(incoming, out_rx); (incoming, outgoing) } @@ -690,21 +683,29 @@ pub(crate) fn check_message_sig_with_buffer( /// 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 { +pub(crate) struct OutgoingMessages { round: RoundNumber, set_id: SetIdNumber, locals: Option<(AuthorityPair, AuthorityId)>, - sender: mpsc::UnboundedSender>, + sender: mpsc03::Sender>, network: GossipEngine, has_voted: HasVoted, } -impl Sink for OutgoingMessages +impl Unpin for OutgoingMessages {} + +impl Sink03> for OutgoingMessages { - type SinkItem = Message; - type SinkError = Error; + type Error = Error; + + fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll03> { + Sink03::poll_ready(Pin::new(&mut self.sender), cx) + .map(|elem| { elem.map_err(|e| { + Error::Network(format!("Failed to poll_ready channel sender: {:?}", e)) + })}) + } - fn start_send(&mut self, mut msg: Message) -> StartSend, Error> { + fn start_send(mut self: Pin<&mut Self>, mut msg: Message) -> Result<(), Self::Error> { // if we've voted on this round previously under the same key, send that vote instead match &mut msg { finality_grandpa::Message::PrimaryPropose(ref mut vote) => @@ -760,17 +761,23 @@ impl Sink for OutgoingMessages self.network.gossip_message(topic, message.encode(), false); // forward the message to the inner sender. - let _ = self.sender.unbounded_send(signed); - } + return self.sender.start_send(signed).map_err(|e| { + Error::Network(format!("Failed to start_send on channel sender: {:?}", e)) + }); + }; - Ok(AsyncSink::Ready) + Ok(()) } - fn poll_complete(&mut self) -> Poll<(), Error> { Ok(Async::Ready(())) } + fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context) -> Poll03> { + Poll03::Ready(Ok(())) + } - fn close(&mut self) -> Poll<(), Error> { - // ignore errors since we allow this inner sender to be closed already. - self.sender.close().or_else(|_| Ok(Async::Ready(()))) + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll03> { + Sink03::poll_close(Pin::new(&mut self.sender), cx) + .map(|elem| { elem.map_err(|e| { + Error::Network(format!("Failed to poll_close channel sender: {:?}", e)) + })}) } } diff --git a/client/finality-grandpa/src/environment.rs b/client/finality-grandpa/src/environment.rs index 372229001d..c5c6291dc0 100644 --- a/client/finality-grandpa/src/environment.rs +++ b/client/finality-grandpa/src/environment.rs @@ -22,7 +22,11 @@ use std::time::Duration; use log::{debug, warn, info}; use parity_scale_codec::{Decode, Encode}; use futures::prelude::*; -use futures03::future::{FutureExt as _, TryFutureExt as _}; +use futures03::{ + compat::{Compat, CompatSink}, + future::{FutureExt as _, TryFutureExt as _}, + stream::StreamExt as _, +}; use futures_timer::Delay; use parking_lot::RwLock; use sp_blockchain::{HeaderBackend, Error as ClientError}; @@ -608,6 +612,9 @@ where has_voted, ); + let incoming = Compat::new(incoming.map(|item| Ok::<_, Error>(item))); + let outgoing = CompatSink::new(outgoing); + // schedule incoming messages from the network to be held until // corresponding blocks are imported. let incoming = Box::new(UntilVoteTargetImported::new( diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index 889250c54d..fdfb2fd808 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -37,15 +37,17 @@ use sp_consensus::{ BlockOrigin, ForkChoiceStrategy, ImportedAux, BlockImportParams, ImportResult, BlockImport, import_queue::{BoxJustificationImport, BoxFinalityProofImport}, }; -use std::collections::{HashMap, HashSet}; -use std::result; +use std::{ + collections::{HashMap, HashSet}, + result, + pin::Pin, task, +}; use parity_scale_codec::Decode; -use sp_runtime::traits::{Header as HeaderT, HasherFor}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT, HasherFor}; use sp_runtime::generic::{BlockId, DigestItem}; use sp_core::{H256, NativeOrEncoded, ExecutionContext, crypto::Public}; use sp_finality_grandpa::{GRANDPA_ENGINE_ID, AuthorityList, GrandpaApi}; use sp_state_machine::{InMemoryBackend, prove_read, read_proof_check}; -use std::{pin::Pin, task}; use authorities::AuthoritySet; use finality_proof::{ @@ -1282,6 +1284,9 @@ fn voter_persists_its_votes() { HasVoted::No, ); + let round_rx = futures03::compat::Compat::new(round_rx.map(|item| Ok::<_, Error>(item))); + let round_tx = futures03::compat::CompatSink::new(round_tx); + let round_tx = Arc::new(Mutex::new(round_tx)); let exit_tx = Arc::new(Mutex::new(Some(exit_tx))); @@ -1332,7 +1337,17 @@ fn voter_persists_its_votes() { target_hash: block_30_hash, }; - round_tx.lock().start_send(finality_grandpa::Message::Prevote(prevote)).unwrap(); + // One should either be calling `Sink::send` or `Sink::start_send` followed + // by `Sink::poll_complete` to make sure items are being flushed. Given that + // we send in a loop including a delay until items are received, this can be + // ignored for the sake of reduced complexity. + if !round_tx.lock() + .start_send(finality_grandpa::Message::Prevote(prevote)) + .unwrap() + .is_ready() { + panic!("expected sink to be ready to write to."); + } + Ok(()) }).map_err(|_| panic!())) -- GitLab From fcd4391b9a86a289aa46893afcc582e498ec5218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 23 Jan 2020 14:35:04 +0100 Subject: [PATCH 007/180] Expose `Error` in metadata for `pallet-utility` (#4721) --- frame/utility/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index 9ab2975e29..7344294684 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -318,6 +318,8 @@ impl TypeId for IndexedUtilityModuleId { decl_module! { pub struct Module for enum Call where origin: T::Origin { + type Error = Error; + /// Deposit one of this module's events by using the default implementation. fn deposit_event() = default; -- GitLab From 3fab0c77f935873121b6a0c6f442ddaa197353e4 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Thu, 23 Jan 2020 05:41:22 -0800 Subject: [PATCH 008/180] Refactor and test spec block rules (#4670) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refactor and test spec block rules * address review * Update client/src/block_rules.rs Co-Authored-By: André Silva Co-authored-by: André Silva --- bin/node/testing/src/client.rs | 1 + client/block-builder/src/lib.rs | 2 - client/src/block_rules.rs | 72 ++++++++++++++ client/src/client.rs | 142 ++++++++++++++++++++++----- client/src/lib.rs | 1 + test-utils/client/src/lib.rs | 41 +++++--- test-utils/runtime/client/src/lib.rs | 7 +- 7 files changed, 225 insertions(+), 41 deletions(-) create mode 100644 client/src/block_rules.rs diff --git a/bin/node/testing/src/client.rs b/bin/node/testing/src/client.rs index 140d1cbfc3..1dddd8ba5a 100644 --- a/bin/node/testing/src/client.rs +++ b/bin/node/testing/src/client.rs @@ -57,6 +57,7 @@ pub trait TestClientBuilderExt: Sized { } impl TestClientBuilderExt for substrate_test_client::TestClientBuilder< + node_primitives::Block, sc_client::LocalCallExecutor, Backend, GenesisParameters, diff --git a/client/block-builder/src/lib.rs b/client/block-builder/src/lib.rs index 9b403dead4..d0eb8b2892 100644 --- a/client/block-builder/src/lib.rs +++ b/client/block-builder/src/lib.rs @@ -197,8 +197,6 @@ where )?; let parent_hash = self.parent_hash; - // The unsafe is required because the consume requires that we drop/consume the inner api - // (what we do here). let storage_changes = self.api.into_storage_changes( &state, changes_trie_state.as_ref(), diff --git a/client/src/block_rules.rs b/client/src/block_rules.rs new file mode 100644 index 0000000000..e561451181 --- /dev/null +++ b/client/src/block_rules.rs @@ -0,0 +1,72 @@ +// Copyright 2020 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 . + +//! Client fixed chain specification rules + +use std::collections::{HashMap, HashSet}; + +use sp_runtime::{ + traits::{Block as BlockT, NumberFor}, +}; + +use sc_client_api::{ForkBlocks, BadBlocks}; + +/// Chain specification rules lookup result. +pub enum LookupResult { + /// Specification rules do not contain any special rules about this block + NotSpecial, + /// The bock is known to be bad and should not be imported + KnownBad, + /// There is a specified canonical block hash for the given height + Expected(B::Hash) +} + +/// Chain-specific block filtering rules. +/// +/// This holds known bad blocks and known good forks, and +/// is usually part of the chain spec. +pub struct BlockRules { + bad: HashSet, + forks: HashMap, B::Hash>, +} + +impl BlockRules { + /// New block rules with provided black and white lists. + pub fn new( + fork_blocks: ForkBlocks, + bad_blocks: BadBlocks, + ) -> Self { + Self { + bad: bad_blocks.unwrap_or(HashSet::new()), + forks: fork_blocks.unwrap_or(vec![]).into_iter().collect(), + } + } + + /// Check if there's any rule affecting the given block. + pub fn lookup(&self, number: NumberFor, hash: &B::Hash) -> LookupResult { + if let Some(hash_for_height) = self.forks.get(&number) { + if hash_for_height != hash { + return LookupResult::Expected(hash_for_height.clone()); + } + } + + if self.bad.contains(hash) { + return LookupResult::KnownBad; + } + + LookupResult::NotSpecial + } +} diff --git a/client/src/client.rs b/client/src/client.rs index 26b077277f..a3bbf84f7d 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -82,7 +82,7 @@ use sp_blockchain::Error; use crate::{ call_executor::LocalCallExecutor, light::{call_executor::prove_execution, fetcher::ChangesProof}, - in_mem, genesis, cht, + in_mem, genesis, cht, block_rules::{BlockRules, LookupResult as BlockLookupResult}, }; /// Substrate Client @@ -94,8 +94,7 @@ pub struct Client where Block: BlockT { finality_notification_sinks: Mutex>>>, // holds the block hash currently being imported. TODO: replace this with block queue importing_block: RwLock>, - fork_blocks: ForkBlocks, - bad_blocks: BadBlocks, + block_rules: BlockRules, execution_extensions: ExecutionExtensions, _phantom: PhantomData, } @@ -219,8 +218,7 @@ impl Client where import_notification_sinks: Default::default(), finality_notification_sinks: Default::default(), importing_block: Default::default(), - fork_blocks, - bad_blocks, + block_rules: BlockRules::new(fork_blocks, bad_blocks), execution_extensions, _phantom: Default::default(), }) @@ -1551,32 +1549,25 @@ impl sp_consensus::BlockImport for &Client { + trace!( + "Rejecting known bad block: #{} {:?}", + number, + hash, + ); + return Ok(ImportResult::KnownBad); + }, + BlockLookupResult::Expected(expected_hash) => { trace!( "Rejecting block from known invalid fork. Got {:?}, expected: {:?} at height {}", hash, - h, + expected_hash, number ); return Ok(ImportResult::KnownBad); - } - } - - let bad_block = self.bad_blocks.as_ref() - .filter(|bs| bs.contains(&hash)) - .is_some(); - - if bad_block { - trace!( - "Rejecting known bad block: #{} {:?}", - number, - hash, - ); - return Ok(ImportResult::KnownBad); + }, + BlockLookupResult::NotSpecial => {} } // Own status must be checked first. If the block and ancestry is pruned @@ -3009,6 +3000,107 @@ pub(crate) mod tests { ); } + + #[test] + fn respects_block_rules() { + + fn run_test( + record_only: bool, + known_bad: &mut HashSet, + fork_rules: &mut Vec<(u64, H256)>, + ) { + let mut client = if record_only { + TestClientBuilder::new().build() + } else { + TestClientBuilder::new() + .set_block_rules( + Some(fork_rules.clone()), + Some(known_bad.clone()), + ) + .build() + }; + + let block_ok = client.new_block_at(&BlockId::Number(0), Default::default(), false) + .unwrap().build().unwrap().block; + + let params = BlockCheckParams { + hash: block_ok.hash().clone(), + number: 0, + parent_hash: block_ok.header().parent_hash().clone(), + allow_missing_state: false, + import_existing: false, + }; + assert_eq!(client.check_block(params).unwrap(), ImportResult::imported(false)); + + // this is 0x0d6d6612a10485370d9e085aeea7ec427fb3f34d961c6a816cdbe5cde2278864 + let mut block_not_ok = client.new_block_at(&BlockId::Number(0), Default::default(), false) + .unwrap(); + block_not_ok.push_storage_change(vec![0], Some(vec![1])).unwrap(); + let block_not_ok = block_not_ok.build().unwrap().block; + + let params = BlockCheckParams { + hash: block_not_ok.hash().clone(), + number: 0, + parent_hash: block_not_ok.header().parent_hash().clone(), + allow_missing_state: false, + import_existing: false, + }; + if record_only { + known_bad.insert(block_not_ok.hash()); + } else { + assert_eq!(client.check_block(params).unwrap(), ImportResult::KnownBad); + } + + // Now going to the fork + client.import_as_final(BlockOrigin::Own, block_ok).unwrap(); + + // And check good fork + let mut block_ok = client.new_block_at(&BlockId::Number(1), Default::default(), false) + .unwrap(); + block_ok.push_storage_change(vec![0], Some(vec![2])).unwrap(); + let block_ok = block_ok.build().unwrap().block; + + let params = BlockCheckParams { + hash: block_ok.hash().clone(), + number: 1, + parent_hash: block_ok.header().parent_hash().clone(), + allow_missing_state: false, + import_existing: false, + }; + if record_only { + fork_rules.push((1, block_ok.hash().clone())); + } + assert_eq!(client.check_block(params).unwrap(), ImportResult::imported(false)); + + // And now try bad fork + let mut block_not_ok = client.new_block_at(&BlockId::Number(1), Default::default(), false) + .unwrap(); + block_not_ok.push_storage_change(vec![0], Some(vec![3])).unwrap(); + let block_not_ok = block_not_ok.build().unwrap().block; + + let params = BlockCheckParams { + hash: block_not_ok.hash().clone(), + number: 1, + parent_hash: block_not_ok.header().parent_hash().clone(), + allow_missing_state: false, + import_existing: false, + }; + + if !record_only { + assert_eq!(client.check_block(params).unwrap(), ImportResult::KnownBad); + } + } + + let mut known_bad = HashSet::new(); + let mut fork_rules = Vec::new(); + + // records what bad_blocks and fork_blocks hashes should be + run_test(true, &mut known_bad, &mut fork_rules); + + // enforces rules and actually makes assertions + run_test(false, &mut known_bad, &mut fork_rules); + } + #[test] fn returns_status_for_pruned_blocks() { let _ = env_logger::try_init(); diff --git a/client/src/lib.rs b/client/src/lib.rs index 8aa71c5ec5..4caabfa201 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -83,6 +83,7 @@ pub mod light; pub mod leaves; mod call_executor; mod client; +mod block_rules; pub use sc_client_api::{ blockchain, diff --git a/test-utils/client/src/lib.rs b/test-utils/client/src/lib.rs index 8603b26d50..76aa1acd8a 100644 --- a/test-utils/client/src/lib.rs +++ b/test-utils/client/src/lib.rs @@ -21,7 +21,10 @@ pub mod client_ext; pub use sc_client::{blockchain, self}; -pub use sc_client_api::execution_extensions::{ExecutionStrategies, ExecutionExtensions}; +pub use sc_client_api::{ + execution_extensions::{ExecutionStrategies, ExecutionExtensions}, + ForkBlocks, BadBlocks, +}; pub use sc_client_db::{Backend, self}; pub use sp_consensus; pub use sc_executor::{NativeExecutor, WasmExecutionMethod, self}; @@ -33,7 +36,6 @@ pub use sp_keyring::{ 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, ClientBlockImportExt}; use std::sync::Arc; @@ -61,23 +63,25 @@ impl GenesisInit for () { } /// A builder for creating a test client instance. -pub struct TestClientBuilder { +pub struct TestClientBuilder { execution_strategies: ExecutionStrategies, genesis_init: G, child_storage_extension: HashMap, StorageChild>, backend: Arc, _executor: std::marker::PhantomData, keystore: Option, + fork_blocks: ForkBlocks, + bad_blocks: BadBlocks, } impl Default - for TestClientBuilder, G> { + for TestClientBuilder, G> { fn default() -> Self { Self::with_default_backend() } } -impl TestClientBuilder, G> { +impl TestClientBuilder, G> { /// Create new `TestClientBuilder` with default backend. pub fn with_default_backend() -> Self { let backend = Arc::new(Backend::new_test(std::u32::MAX, std::u64::MAX)); @@ -91,7 +95,7 @@ impl TestClientBuilder TestClientBuilder { +impl TestClientBuilder { /// Create a new instance of the test client builder. pub fn with_backend(backend: Arc) -> Self { TestClientBuilder { @@ -101,6 +105,8 @@ impl TestClientBuilder genesis_init: Default::default(), _executor: Default::default(), keystore: None, + fork_blocks: None, + bad_blocks: None, } } @@ -152,8 +158,18 @@ impl TestClientBuilder self } + /// Sets custom block rules. + pub fn set_block_rules(mut self, + fork_blocks: ForkBlocks, + bad_blocks: BadBlocks, + ) -> Self { + self.fork_blocks = fork_blocks; + self.bad_blocks = bad_blocks; + self + } + /// Build the test client with the given native executor. - pub fn build_with_executor( + pub fn build_with_executor( self, executor: Executor, ) -> ( @@ -167,7 +183,6 @@ impl TestClientBuilder ) where Executor: sc_client::CallExecutor + 'static, Backend: sc_client_api::backend::Backend, - Block: BlockT, { let storage = { @@ -191,8 +206,8 @@ impl TestClientBuilder self.backend.clone(), executor, &storage, - Default::default(), - Default::default(), + self.fork_blocks, + self.bad_blocks, ExecutionExtensions::new( self.execution_strategies, self.keystore.clone(), @@ -205,13 +220,14 @@ impl TestClientBuilder } } -impl TestClientBuilder< +impl TestClientBuilder< + Block, sc_client::LocalCallExecutor>, Backend, G, > { /// Build the test client with the given native executor. - pub fn build_with_native_executor( + pub fn build_with_native_executor( self, executor: I, ) -> ( @@ -226,7 +242,6 @@ impl TestClientBuilder< I: Into>>, E: sc_executor::NativeExecutionDispatch + 'static, Backend: sc_client_api::backend::Backend + 'static, - Block: BlockT, { let executor = executor.into().unwrap_or_else(|| NativeExecutor::new(WasmExecutionMethod::Interpreted, None) diff --git a/test-utils/runtime/client/src/lib.rs b/test-utils/runtime/client/src/lib.rs index 7646f4a960..21cf94dfa6 100644 --- a/test-utils/runtime/client/src/lib.rs +++ b/test-utils/runtime/client/src/lib.rs @@ -140,7 +140,12 @@ impl substrate_test_client::GenesisInit for GenesisParameters { } /// A `TestClient` with `test-runtime` builder. -pub type TestClientBuilder = substrate_test_client::TestClientBuilder; +pub type TestClientBuilder = substrate_test_client::TestClientBuilder< + substrate_test_runtime::Block, + E, + B, + GenesisParameters, +>; /// Test client type with `LocalExecutor` and generic Backend. pub type Client = sc_client::Client< -- GitLab From 96027d1f6d0bb8a408966eaeb5c60d0ce43acdb5 Mon Sep 17 00:00:00 2001 From: Hero Bird Date: Thu, 23 Jan 2020 15:13:49 +0100 Subject: [PATCH 009/180] [contracts] Add ext_tombstone_deposit (#4722) * [contracts] add ext_tombstone_deposit * [contracts] update tombstone_deposit docs --- frame/contracts/src/exec.rs | 7 +++ frame/contracts/src/lib.rs | 2 + frame/contracts/src/wasm/mod.rs | 66 +++++++++++++++++++++++++++++ frame/contracts/src/wasm/runtime.rs | 17 ++++++++ 4 files changed, 92 insertions(+) diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index 9d786c320b..ceaccd35cb 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -161,6 +161,9 @@ pub trait Ext { /// Returns the minimum balance that is required for creating an account. fn minimum_balance(&self) -> BalanceOf; + /// Returns the deposit required to create a tombstone upon contract eviction. + fn tombstone_deposit(&self) -> BalanceOf; + /// Returns a random number for the current block with the given subject. fn random(&self, subject: &[u8]) -> SeedOf; @@ -779,6 +782,10 @@ where self.ctx.config.existential_deposit } + fn tombstone_deposit(&self) -> BalanceOf { + self.ctx.config.tombstone_deposit + } + fn deposit_event(&mut self, topics: Vec, data: Vec) { self.ctx.deferred.push(DeferredAction::DepositEvent { topics, diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index 40ce86518a..d16462d8bf 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -969,6 +969,7 @@ impl OnFreeBalanceZero for Module { pub struct Config { pub schedule: Schedule, pub existential_deposit: BalanceOf, + pub tombstone_deposit: BalanceOf, pub max_depth: u32, pub max_value_size: u32, pub contract_account_instantiate_fee: BalanceOf, @@ -981,6 +982,7 @@ impl Config { Config { schedule: >::current_schedule(), existential_deposit: T::Currency::minimum_balance(), + tombstone_deposit: T::TombstoneDeposit::get(), max_depth: T::MaxDepth::get(), max_value_size: T::MaxValueSize::get(), contract_account_instantiate_fee: T::ContractFee::get(), diff --git a/frame/contracts/src/wasm/mod.rs b/frame/contracts/src/wasm/mod.rs index 60402cf3a0..1ea2067a8d 100644 --- a/frame/contracts/src/wasm/mod.rs +++ b/frame/contracts/src/wasm/mod.rs @@ -299,6 +299,10 @@ mod tests { 666 } + fn tombstone_deposit(&self) -> u64 { + 16 + } + fn random(&self, subject: &[u8]) -> H256 { H256::from_slice(subject) } @@ -397,6 +401,9 @@ mod tests { fn minimum_balance(&self) -> u64 { (**self).minimum_balance() } + fn tombstone_deposit(&self) -> u64 { + (**self).tombstone_deposit() + } fn random(&self, subject: &[u8]) -> H256 { (**self).random(subject) } @@ -1271,6 +1278,65 @@ mod tests { ).unwrap(); } + const CODE_TOMBSTONE_DEPOSIT: &str = r#" +(module + (import "env" "ext_tombstone_deposit" (func $ext_tombstone_deposit)) + (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) + (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "env" "memory" (memory 1 1)) + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "call") + (call $ext_tombstone_deposit) + + ;; assert $ext_scratch_size == 8 + (call $assert + (i32.eq + (call $ext_scratch_size) + (i32.const 8) + ) + ) + + ;; copy contents of the scratch buffer into the contract's memory. + (call $ext_scratch_read + (i32.const 8) ;; Pointer in memory to the place where to copy. + (i32.const 0) ;; Offset from the start of the scratch buffer. + (i32.const 8) ;; Count of bytes to copy. + ) + + ;; assert that contents of the buffer is equal to the i64 value of 16. + (call $assert + (i64.eq + (i64.load + (i32.const 8) + ) + (i64.const 16) + ) + ) + ) + (func (export "deploy")) +) +"#; + + #[test] + fn tombstone_deposit() { + let mut gas_meter = GasMeter::with_limit(50_000, 1); + let _ = execute( + CODE_TOMBSTONE_DEPOSIT, + vec![], + MockExt::default(), + &mut gas_meter, + ).unwrap(); + } + const CODE_RANDOM: &str = r#" (module (import "env" "ext_random" (func $ext_random (param i32 i32))) diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index 75751b6d35..07cb8cb524 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -623,6 +623,23 @@ define_env!(Env, , Ok(()) }, + // Stores the tombstone deposit into the scratch buffer. + // + // The data is encoded as T::Balance. The current contents of the scratch + // buffer are overwritten. + // + // # Note + // + // The tombstone deposit is on top of the existential deposit. So in order for + // a contract to leave a tombstone the balance of the contract must not go + // below the sum of existential deposit and the tombstone deposit. The sum + // is commonly referred as subsistence threshold in code. + ext_tombstone_deposit(ctx) => { + ctx.scratch_buf.clear(); + ctx.ext.tombstone_deposit().encode_to(&mut ctx.scratch_buf); + Ok(()) + }, + // Decodes the given buffer as a `T::Call` and adds it to the list // of to-be-dispatched calls. // -- GitLab From bc85d352681018e5b19369b758c013a52c5c3032 Mon Sep 17 00:00:00 2001 From: Hero Bird Date: Thu, 23 Jan 2020 16:59:00 +0100 Subject: [PATCH 010/180] [contracts] minor follow-up on PR #4722 (#4723) --- bin/node/runtime/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index e158cbe2cb..ecc16ee143 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -80,8 +80,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: 204, - impl_version: 204, + spec_version: 205, + impl_version: 205, apis: RUNTIME_API_VERSIONS, }; -- GitLab From 219fad62273d5221d53a048f7bcd6c981d85a45d Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Fri, 24 Jan 2020 10:02:55 +0100 Subject: [PATCH 011/180] Expose recovery module errors in metadata (#4727) --- frame/recovery/src/lib.rs | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/frame/recovery/src/lib.rs b/frame/recovery/src/lib.rs index d0b5783587..f63f216fc7 100644 --- a/frame/recovery/src/lib.rs +++ b/frame/recovery/src/lib.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . //! # Recovery Pallet -//! +//! //! - [`recovery::Trait`](./trait.Trait.html) //! - [`Call`](./enum.Call.html) //! @@ -82,7 +82,7 @@ //! permissionless. However, the recovery deposit is an economic deterrent that //! should disincentivize would-be attackers from trying to maliciously recover //! accounts. -//! +//! //! The recovery deposit can always be claimed by the account which is trying to //! to be recovered. In the case of a malicious recovery attempt, the account //! owner who still has access to their account can claim the deposit and @@ -121,14 +121,14 @@ //! change as well. //! //! ## Interface -//! +//! //! ### Dispatchable Functions -//! +//! //! #### For General Users -//! +//! //! * `create_recovery` - Create a recovery configuration for your account and make it recoverable. //! * `initiate_recovery` - Start the recovery process for a recoverable account. -//! +//! //! #### For Friends of a Recoverable Account //! * `vouch_recovery` - As a `friend` of a recoverable account, vouch for a recovery attempt on the account. //! @@ -141,7 +141,7 @@ //! //! * `close_recovery` - Close an active recovery process for your account and reclaim the recovery deposit. //! * `remove_recovery` - Remove the recovery configuration from the account, making it un-recoverable. -//! +//! //! #### For Super Users //! //! * `set_recovered` - The ROOT origin is able to skip the recovery process and directly allow @@ -314,9 +314,11 @@ decl_error! { decl_module! { pub struct Module for enum Call where origin: T::Origin { + type Error = Error; + /// Deposit one of this module's events by using the default implementation. fn deposit_event() = default; - + /// Send a call through a recovered account. /// /// The dispatch origin for this call must be _Signed_ and registered to @@ -340,7 +342,7 @@ decl_module! { ensure!(Self::recovered_account(&account) == Some(who), Error::::NotAllowed); call.dispatch(frame_system::RawOrigin::Signed(account).into()) } - + /// Allow ROOT to bypass the recovery process and set an a rescuer account /// for a lost account directly. /// @@ -361,7 +363,7 @@ decl_module! { >::insert(&lost, &rescuer); Self::deposit_event(RawEvent::AccountRecovered(lost, rescuer)); } - + /// Create a recovery configuration for your account. This makes your account recoverable. /// /// Payment: `ConfigDepositBase` + `FriendDepositFactor` * #_of_friends balance @@ -425,7 +427,7 @@ decl_module! { >::insert(&who, recovery_config); Self::deposit_event(RawEvent::RecoveryCreated(who)); } - + /// Initiate the process for recovering a recoverable account. /// /// Payment: `RecoveryDeposit` balance will be reserved for initiating the @@ -468,7 +470,7 @@ decl_module! { >::insert(&account, &who, recovery_status); Self::deposit_event(RawEvent::RecoveryInitiated(account, who)); } - + /// Allow a "friend" of a recoverable account to vouch for an active recovery /// process for that account. /// @@ -512,7 +514,7 @@ decl_module! { >::insert(&lost, &rescuer, active_recovery); Self::deposit_event(RawEvent::RecoveryVouched(lost, rescuer, who)); } - + /// Allow a successful rescuer to claim their recovered account. /// /// The dispatch origin for this call must be _Signed_ and must be a "rescuer" @@ -555,7 +557,7 @@ decl_module! { >::insert(&account, &who); Self::deposit_event(RawEvent::AccountRecovered(account, who)); } - + /// As the controller of a recoverable account, close an active recovery /// process for your account. /// @@ -586,7 +588,7 @@ decl_module! { let _ = T::Currency::repatriate_reserved(&rescuer, &who, active_recovery.deposit); Self::deposit_event(RawEvent::RecoveryClosed(who, rescuer)); } - + /// Remove the recovery process for your account. /// /// NOTE: The user must make sure to call `close_recovery` on all active -- GitLab From e5fed334b070e75ad47053e7f65e046a3c2b4dce Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Fri, 24 Jan 2020 04:21:24 -0800 Subject: [PATCH 012/180] Refactor tx-pool maintenance and other high-level api (#4629) * Reduction. * Reformation. * add locked timer stuff * fix issues and introduce full pool * arrange together * fix benches * fix new_light * Add revalidation test case * review fixes * review fixes * use just ready future * address review --- bin/node-template/src/service.rs | 13 +- bin/node/cli/src/service.rs | 24 +- client/service/src/builder.rs | 6 +- client/service/src/lib.rs | 8 +- .../transaction-pool/graph/benches/basics.rs | 17 +- client/transaction-pool/graph/src/pool.rs | 22 +- .../graph/src/validated_pool.rs | 4 +- client/transaction-pool/src/api.rs | 42 +- client/transaction-pool/src/lib.rs | 231 ++++++- client/transaction-pool/src/maintainer.rs | 645 ------------------ client/transaction-pool/src/tests.rs | 123 +++- primitives/transaction-pool/src/pool.rs | 115 +--- 12 files changed, 423 insertions(+), 827 deletions(-) delete mode 100644 client/transaction-pool/src/maintainer.rs diff --git a/bin/node-template/src/service.rs b/bin/node-template/src/service.rs index ed2299e30f..458656d836 100644 --- a/bin/node-template/src/service.rs +++ b/bin/node-template/src/service.rs @@ -43,9 +43,7 @@ macro_rules! new_full_start { .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) + Ok(pool) })? .with_import_queue(|_config, client, mut select_chain, transaction_pool| { let select_chain = select_chain.take() @@ -207,11 +205,12 @@ pub fn new_light(config: Configuration; #[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 - > +type ConcreteTransactionPool = sc_transaction_pool::BasicPool< + sc_transaction_pool::FullChainApi, + ConcreteBlock >; /// A specialized configuration object for setting up the node.. @@ -322,10 +314,10 @@ pub fn new_light(config: NodeConfiguration) 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) + let pool = sc_transaction_pool::BasicPool::with_revalidation_type( + config, pool_api, sc_transaction_pool::RevalidationType::Light, + ); + Ok(pool) })? .with_import_queue_and_fprb(|_config, client, backend, fetcher, _select_chain, _tx_pool| { let fetch_checker = fetcher diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 044798701c..194bd09e24 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -49,7 +49,7 @@ use std::{ }; use sysinfo::{get_current_pid, ProcessExt, System, SystemExt}; use sc_telemetry::{telemetry, SUBSTRATE_INFO}; -use sp_transaction_pool::{TransactionPool, TransactionPoolMaintainer}; +use sp_transaction_pool::MaintainedTransactionPool; use sp_blockchain; use grafana_data_source::{self, record_metrics}; @@ -740,9 +740,7 @@ ServiceBuilder< TSc: Clone, TImpQu: 'static + ImportQueue, TNetP: NetworkSpecialization, - TExPool: 'static - + TransactionPool::Hash> - + TransactionPoolMaintainer::Hash>, + TExPool: MaintainedTransactionPool::Hash> + 'static, TRpc: sc_rpc::RpcExtension + Clone, { diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index c1b87e4491..1b2e7bcd3c 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -61,7 +61,7 @@ pub use self::builder::{ }; pub use config::{Configuration, Roles, PruningMode}; pub use sc_chain_spec::{ChainSpec, Properties, RuntimeGenesis, Extension as ChainSpecExtension}; -pub use sp_transaction_pool::{TransactionPool, TransactionPoolMaintainer, InPoolTransaction, error::IntoPoolError}; +pub use sp_transaction_pool::{TransactionPool, InPoolTransaction, error::IntoPoolError}; pub use sc_transaction_pool::txpool::Options as TransactionPoolOptions; pub use sc_client::FinalityNotifications; pub use sc_rpc::Metadata as RpcMetadata; @@ -148,8 +148,7 @@ pub trait AbstractService: 'static + Future> + /// Chain selection algorithm. type SelectChain: sp_consensus::SelectChain; /// Transaction pool. - type TransactionPool: TransactionPool - + TransactionPoolMaintainer; + type TransactionPool: TransactionPool; /// Network specialization. type NetworkSpecialization: NetworkSpecialization; @@ -213,8 +212,7 @@ where TExec: 'static + sc_client::CallExecutor + Send + Sync + Clone, TRtApi: 'static + Send + Sync, TSc: sp_consensus::SelectChain + 'static + Clone + Send + Unpin, - TExPool: 'static + TransactionPool - + TransactionPoolMaintainer, + TExPool: 'static + TransactionPool, TOc: 'static + Send + Sync, TNetSpec: NetworkSpecialization, { diff --git a/client/transaction-pool/graph/benches/basics.rs b/client/transaction-pool/graph/benches/basics.rs index 557a2ca3d1..75d15cc1f1 100644 --- a/client/transaction-pool/graph/benches/basics.rs +++ b/client/transaction-pool/graph/benches/basics.rs @@ -16,7 +16,7 @@ use criterion::{criterion_group, criterion_main, Criterion}; -use futures::executor::block_on; +use futures::{future::{ready, Ready}, executor::block_on}; use sc_transaction_graph::*; use sp_runtime::transaction_validity::{ValidTransaction, InvalidTransaction}; use codec::Encode; @@ -49,7 +49,8 @@ impl ChainApi for TestApi { type Block = Block; type Hash = H256; type Error = sp_transaction_pool::error::Error; - type ValidationFuture = futures::future::Ready>; + type ValidationFuture = Ready>; + type BodyFuture = Ready>>>; fn validate_transaction( &self, @@ -61,14 +62,14 @@ impl ChainApi for TestApi { match self.block_id_to_number(at) { Ok(Some(num)) if num > 5 => { - return futures::future::ready( + return ready( Ok(Err(InvalidTransaction::Stale.into())) ) }, _ => {}, } - futures::future::ready( + ready( Ok(Ok(ValidTransaction { priority: 4, requires: if nonce > 1 && self.nonce_dependant { @@ -105,6 +106,10 @@ impl ChainApi for TestApi { let encoded = uxt.encode(); (blake2_256(&encoded).into(), encoded.len()) } + + fn block_body(&self, _id: &BlockId) -> Self::BodyFuture { + ready(Ok(None)) + } } fn uxt(transfer: Transfer) -> Extrinsic { @@ -150,13 +155,13 @@ fn benchmark_main(c: &mut Criterion) { c.bench_function("sequential 50 tx", |b| { b.iter(|| { - bench_configured(Pool::new(Default::default(), TestApi::new_dependant()), 50); + bench_configured(Pool::new(Default::default(), TestApi::new_dependant().into()), 50); }); }); c.bench_function("random 100 tx", |b| { b.iter(|| { - bench_configured(Pool::new(Default::default(), TestApi::default()), 100); + bench_configured(Pool::new(Default::default(), TestApi::default().into()), 100); }); }); } diff --git a/client/transaction-pool/graph/src/pool.rs b/client/transaction-pool/graph/src/pool.rs index 629bd0a9a9..5be879f079 100644 --- a/client/transaction-pool/graph/src/pool.rs +++ b/client/transaction-pool/graph/src/pool.rs @@ -68,6 +68,8 @@ pub trait ChainApi: Send + Sync { type Error: From + error::IntoPoolError; /// Validate transaction future. type ValidationFuture: Future> + Send + Unpin; + /// Body future (since block body might be remote) + type BodyFuture: Future::Extrinsic>>, Self::Error>> + Unpin + Send + 'static; /// Verify extrinsic at given block. fn validate_transaction( @@ -84,6 +86,9 @@ pub trait ChainApi: Send + Sync { /// Returns hash and encoding length of the extrinsic. fn hash_and_length(&self, uxt: &ExtrinsicFor) -> (Self::Hash, usize); + + /// Returns a block body given the block id. + fn block_body(&self, at: &BlockId) -> Self::BodyFuture; } /// Pool configuration options. @@ -120,7 +125,7 @@ pub struct Pool { impl Pool { /// Create a new transaction pool. - pub fn new(options: Options, api: B) -> Self { + pub fn new(options: Options, api: Arc) -> Self { Pool { validated_pool: Arc::new(ValidatedPool::new(options, api)), } @@ -488,6 +493,7 @@ mod tests { type Hash = u64; type Error = error::Error; type ValidationFuture = futures::future::Ready>; + type BodyFuture = futures::future::Ready>>>; /// Verify extrinsic at given block. fn validate_transaction( @@ -560,6 +566,10 @@ mod tests { len ) } + + fn block_body(&self, _id: &BlockId) -> Self::BodyFuture { + futures::future::ready(Ok(None)) + } } fn uxt(transfer: Transfer) -> Extrinsic { @@ -567,7 +577,7 @@ mod tests { } fn pool() -> Pool { - Pool::new(Default::default(), TestApi::default()) + Pool::new(Default::default(), TestApi::default().into()) } #[test] @@ -713,7 +723,7 @@ mod tests { ready: limit.clone(), future: limit.clone(), ..Default::default() - }, TestApi::default()); + }, TestApi::default().into()); let hash1 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), @@ -748,7 +758,7 @@ mod tests { ready: limit.clone(), future: limit.clone(), ..Default::default() - }, TestApi::default()); + }, TestApi::default().into()); // when block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { @@ -924,7 +934,7 @@ mod tests { ready: limit.clone(), future: limit.clone(), ..Default::default() - }, TestApi::default()); + }, TestApi::default().into()); let xt = uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), @@ -958,7 +968,7 @@ mod tests { let (tx, rx) = std::sync::mpsc::sync_channel(1); let mut api = TestApi::default(); api.delay = Arc::new(Mutex::new(rx.into())); - let pool = Arc::new(Pool::new(Default::default(), api)); + let pool = Arc::new(Pool::new(Default::default(), api.into())); // when let xt = uxt(Transfer { diff --git a/client/transaction-pool/graph/src/validated_pool.rs b/client/transaction-pool/graph/src/validated_pool.rs index 29f82fb894..34f34d5806 100644 --- a/client/transaction-pool/graph/src/validated_pool.rs +++ b/client/transaction-pool/graph/src/validated_pool.rs @@ -63,7 +63,7 @@ pub type ValidatedTransactionFor = ValidatedTransaction< /// Pool that deals with validated transactions. pub(crate) struct ValidatedPool { - api: B, + api: Arc, options: Options, listener: RwLock, BlockHash>>, pool: RwLock { impl ValidatedPool { /// Create a new transaction pool. - pub fn new(options: Options, api: B) -> Self { + pub fn new(options: Options, api: Arc) -> Self { let base_pool = base::BasePool::new(options.reject_future_transactions); ValidatedPool { api, diff --git a/client/transaction-pool/src/api.rs b/client/transaction-pool/src/api.rs index 8495b8b65f..1bf6348214 100644 --- a/client/transaction-pool/src/api.rs +++ b/client/transaction-pool/src/api.rs @@ -19,12 +19,13 @@ use std::{marker::PhantomData, pin::Pin, sync::Arc}; use codec::{Decode, Encode}; use futures::{ - channel::oneshot, executor::{ThreadPool, ThreadPoolBuilder}, future::{Future, FutureExt, ready}, + channel::oneshot, executor::{ThreadPool, ThreadPoolBuilder}, future::{Future, FutureExt, ready, Ready}, }; use sc_client_api::{ blockchain::HeaderBackend, - light::{Fetcher, RemoteCallRequest} + light::{Fetcher, RemoteCallRequest, RemoteBodyRequest}, + BlockBody, }; use sp_core::Hasher; use sp_runtime::{ @@ -63,7 +64,7 @@ impl FullChainApi where impl sc_transaction_graph::ChainApi for FullChainApi where Block: BlockT, - Client: ProvideRuntimeApi + BlockIdTo + 'static + Send + Sync, + Client: ProvideRuntimeApi + BlockBody + BlockIdTo + 'static + Send + Sync, Client::Api: TaggedTransactionQueue, sp_api::ApiErrorFor: Send, { @@ -71,6 +72,11 @@ impl sc_transaction_graph::ChainApi for FullChainApi> + Send>>; + type BodyFuture = Ready::Extrinsic>>>>; + + fn block_body(&self, id: &BlockId) -> Self::BodyFuture { + ready(self.client.block_body(&id).map_err(|e| error::Error::from(e))) + } fn validate_transaction( &self, @@ -149,6 +155,7 @@ impl sc_transaction_graph::ChainApi for LightChainApi> + Send + Unpin>; + type BodyFuture = Pin::Extrinsic>>>> + Send>>; fn validate_transaction( &self, @@ -197,4 +204,33 @@ impl sc_transaction_graph::ChainApi for LightChainApi::Hashing as HashT>::hash(x), x.len()) }) } + + fn block_body(&self, id: &BlockId) -> Self::BodyFuture { + 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) => { + log::warn!(target: "txpool", "Failed to query header: {:?}", err); + return Box::pin(ready(Ok(None))); + } + }; + + let fetcher = self.fetcher.clone(); + async move { + let transactions = fetcher.remote_body({ + RemoteBodyRequest { + header, + retry_count: None, + } + }) + .await + .unwrap_or_else(|e| { + log::warn!(target: "txpool", "Failed to fetch block body: {:?}", e); + Vec::new() + }); + + Ok(Some(transactions)) + }.boxed() + } } diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index 4d71307c0a..f6f7774935 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -20,26 +20,26 @@ #![warn(unused_extern_crates)] mod api; -mod maintainer; - pub mod error; + #[cfg(test)] mod tests; 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 std::{collections::HashMap, sync::Arc, pin::Pin, time::Instant}; +use futures::{Future, FutureExt, future::ready}; +use parking_lot::Mutex; use sp_runtime::{ generic::BlockId, - traits::Block as BlockT, + traits::{Block as BlockT, NumberFor, SimpleArithmetic, Extrinsic}, }; use sp_transaction_pool::{ TransactionPool, PoolStatus, ImportNotificationStream, - TxHash, TransactionFor, TransactionStatusStreamFor, + TxHash, TransactionFor, TransactionStatusStreamFor, BlockHash, + MaintainedTransactionPool, }; /// Basic implementation of transaction pool that can be customized by providing PoolApi. @@ -49,6 +49,25 @@ pub struct BasicPool PoolApi: sc_transaction_graph::ChainApi, { pool: Arc>, + api: Arc, + revalidation_strategy: Arc>>>, +} + +/// Type of revalidation. +pub enum RevalidationType { + /// Light revalidation type. + /// + /// During maintenance, transaction pool makes periodic revalidation + /// of all transactions depending on number of blocks or time passed. + /// Also this kind of revalidation does not resubmit transactions from + /// retracted blocks, since it is too expensive. + Light, + + /// Full revalidation type. + /// + /// During maintenance, transaction pool revalidates some fixed amount of + /// transactions from the pool of valid transactions. + Full, } impl BasicPool @@ -57,16 +76,44 @@ impl BasicPool 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 { + pub fn new( + options: sc_transaction_graph::Options, + pool_api: PoolApi, + ) -> Self { + Self::with_revalidation_type(options, pool_api, RevalidationType::Full) + } + + /// Create new basic transaction pool with provided api and custom + /// revalidation type. + pub fn with_revalidation_type( + options: sc_transaction_graph::Options, + pool_api: PoolApi, + revalidation_type: RevalidationType, + ) -> Self { + let api = Arc::new(pool_api); + let cloned_api = api.clone(); BasicPool { - pool: Arc::new(sc_transaction_graph::Pool::new(options, pool_api)), + api: cloned_api, + pool: Arc::new(sc_transaction_graph::Pool::new(options, api)), + revalidation_strategy: Arc::new(Mutex::new( + match revalidation_type { + RevalidationType::Light => RevalidationStrategy::Light(RevalidationStatus::NotScheduled), + RevalidationType::Full => RevalidationStrategy::Always, + } + )), } + } /// Gets shared reference to the underlying pool. pub fn pool(&self) -> &Arc> { &self.pool } + + #[cfg(test)] + pub fn api(&self) -> &Arc { + &self.api + } } impl TransactionPool for BasicPool @@ -130,3 +177,169 @@ impl TransactionPool for BasicPool self.pool.on_broadcasted(propagations) } } + +#[cfg_attr(test, derive(Debug))] +enum RevalidationStatus { + /// The revalidation has never been completed. + NotScheduled, + /// The revalidation is scheduled. + Scheduled(Option, Option), + /// The revalidation is in progress. + InProgress, +} + +enum RevalidationStrategy { + Always, + Light(RevalidationStatus) +} + +struct RevalidationAction { + revalidate: bool, + resubmit: bool, + revalidate_amount: Option, +} + +impl RevalidationStrategy { + pub fn clear(&mut self) { + if let Self::Light(status) = self { + status.clear() + } + } + + pub fn next( + &mut self, + block: N, + revalidate_time_period: Option, + revalidate_block_period: Option, + ) -> RevalidationAction { + match self { + Self::Light(status) => RevalidationAction { + revalidate: status.next_required( + block, + revalidate_time_period, + revalidate_block_period + ), + resubmit: false, + revalidate_amount: None, + }, + Self::Always => RevalidationAction { + revalidate: true, + resubmit: true, + revalidate_amount: Some(16), + } + } + } +} + +impl RevalidationStatus { + /// Called when revalidation is completed. + pub fn clear(&mut self) { + *self = Self::NotScheduled; + } + + /// Returns true if revalidation is required. + pub fn next_required( + &mut self, + block: N, + revalidate_time_period: Option, + revalidate_block_period: Option, + ) -> bool { + match *self { + Self::NotScheduled => { + *self = Self::Scheduled( + revalidate_time_period.map(|period| Instant::now() + period), + revalidate_block_period.map(|period| block + period), + ); + false + }, + Self::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 = Self::InProgress; + } + is_required + }, + Self::InProgress => false, + } + } +} + +impl MaintainedTransactionPool for BasicPool +where + Block: BlockT, + PoolApi: 'static + sc_transaction_graph::ChainApi, +{ + fn maintain(&self, id: &BlockId, retracted: &[BlockHash]) + -> Pin + Send>> + { + let id = id.clone(); + let pool = self.pool.clone(); + let api = self.api.clone(); + + let block_number = match api.block_id_to_number(&id) { + Ok(Some(number)) => number, + _ => { + log::trace!(target: "txqueue", "Skipping chain event - no number for that block {:?}", id); + return Box::pin(ready(())); + } + }; + + let next_action = self.revalidation_strategy.lock().next( + block_number, + Some(std::time::Duration::from_secs(60)), + Some(20.into()), + ); + let revalidation_strategy = self.revalidation_strategy.clone(); + let retracted = retracted.to_vec(); + + async move { + // We don't query block if we won't prune anything + if !pool.status().is_empty() { + let hashes = api.block_body(&id).await + .unwrap_or_else(|e| { + log::warn!("Prune known transactions: error request {:?}!", e); + None + }) + .unwrap_or_default() + .into_iter() + .map(|tx| pool.hash_of(&tx)) + .collect::>(); + + if let Err(e) = pool.prune_known(&id, &hashes) { + log::error!("Cannot prune known in the pool {:?}!", e); + } + } + + if next_action.resubmit { + let mut resubmit_transactions = Vec::new(); + + for retracted_hash in retracted { + let block_transactions = api.block_body(&BlockId::hash(retracted_hash.clone())).await + .unwrap_or_else(|e| { + log::warn!("Failed to fetch block body {:?}!", e); + None + }) + .unwrap_or_default() + .into_iter() + .filter(|tx| tx.is_signed().unwrap_or(true)); + + resubmit_transactions.extend(block_transactions); + } + if let Err(e) = pool.submit_at(&id, resubmit_transactions, true).await { + log::debug!(target: "txpool", + "[{:?}] Error re-submitting transactions: {:?}", id, e + ) + } + } + + if next_action.revalidate { + if let Err(e) = pool.revalidate_ready(&id, next_action.revalidate_amount).await { + log::warn!("Revalidate ready failed {:?}", e); + } + } + + revalidation_strategy.lock().clear(); + }.boxed() + } +} diff --git a/client/transaction-pool/src/maintainer.rs b/client/transaction-pool/src/maintainer.rs deleted file mode 100644 index 97dc7e10a6..0000000000 --- a/client/transaction-pool/src/maintainer.rs +++ /dev/null @@ -1,645 +0,0 @@ -// Copyright 2019-2020 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_runtime::{ - generic::BlockId, - traits::{Block as BlockT, Extrinsic, Header, NumberFor, SimpleArithmetic}, -}; -use sp_blockchain::HeaderBackend; -use sp_transaction_pool::{TransactionPoolMaintainer, runtime_api::TaggedTransactionQueue}; -use sp_api::ProvideRuntimeApi; - -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, - 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, - 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, - 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::*, Client, runtime::{Block, Transfer}, sp_consensus::{BlockOrigin, SelectChain}, - LongestChain, - }; - use sp_transaction_pool::PoolStatus; - use crate::api::{FullChainApi, LightChainApi}; - - struct TestSetup { - client: Arc>, - longest_chain: LongestChain, - pool: Arc>, - } - - impl TestSetup { - fn new() -> TestSetup, Block>> { - let (client, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); - let client = Arc::new(client); - let pool = Arc::new( - sc_transaction_graph::Pool::new(Default::default(), FullChainApi::new(client.clone())), - ); - TestSetup { - client, - longest_chain, - pool, - } - } - - fn new_light(fetcher: Arc) -> TestSetup, F, Block>> - where F: Fetcher + 'static, - { - let (client, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); - let client = Arc::new(client); - let pool = Arc::new( - sc_transaction_graph::Pool::new( - Default::default(), - LightChainApi::new(client.clone(), fetcher) - ), - ); - TestSetup { - client, - longest_chain, - pool, - } - } - } - - fn setup() -> TestSetup, Block>> { - TestSetup::, Block>>::new() - } - - fn setup_light(fetcher: Arc) -> TestSetup, F, Block>> - where F: Fetcher + 'static, - { - TestSetup::, F, Block>>::new_light(fetcher) - } - - #[test] - fn should_remove_transactions_from_the_full_pool() { - let mut setup = setup(); - - let transaction = Transfer { - amount: 5, - nonce: 0, - from: AccountKeyring::Alice.into(), - to: Default::default(), - }.into_signed_tx(); - let best = setup.longest_chain.best_chain().unwrap(); - - // store the transaction in the pool - block_on(setup.pool.submit_one(&BlockId::hash(best.hash()), transaction.clone())).unwrap(); - - // import the block - let mut builder = setup.client.new_block(Default::default()).unwrap(); - builder.push(transaction.clone()).unwrap(); - let block = builder.build().unwrap().block; - let id = BlockId::hash(block.header().hash()); - setup.client.import(BlockOrigin::Own, block).unwrap(); - - // fire notification - this should clean up the queue - assert_eq!(setup.pool.status().ready, 1); - block_on(FullBasicPoolMaintainer::new(setup.pool.clone(), setup.client.clone()).maintain(&id, &[])); - - // then - assert_eq!(setup.pool.status().ready, 0); - assert_eq!(setup.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 setup = setup_light(fetcher.clone()); - let best = setup.longest_chain.best_chain().unwrap(); - - // store the transaction in the pool - block_on(setup.pool.submit_one(&BlockId::hash(best.hash()), transaction.clone())).unwrap(); - - // fire notification - this should clean up the queue - assert_eq!(setup.pool.status().ready, 1); - block_on(LightBasicPoolMaintainer::with_defaults(setup.pool.clone(), setup.client.clone(), fetcher).maintain( - &BlockId::Number(0), - &[], - )); - - // then - assert_eq!(setup.pool.status().ready, 0); - assert_eq!(setup.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 setup = setup_light(fetcher.clone()); - let best = setup.longest_chain.best_chain().unwrap(); - - // let's prepare maintainer - let maintainer = LightBasicPoolMaintainer::new( - setup.pool.clone(), - setup.client.clone(), - fetcher, - revalidate_time_period, - revalidate_block_period, - ); - prepare_maintainer(&*maintainer.revalidation_status); - - // store the transaction in the pool - block_on(setup.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), &[])); - - setup.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 mut setup = setup(); - - let transaction = Transfer { - amount: 5, - nonce: 0, - from: AccountKeyring::Alice.into(), - to: Default::default(), - }.into_signed_tx(); - let best = setup.longest_chain.best_chain().unwrap(); - - // store the transaction in the pool - block_on(setup.pool.submit_one(&BlockId::hash(best.hash()), transaction.clone())).unwrap(); - - // import the block - let mut builder = setup.client.new_block(Default::default()).unwrap(); - builder.push(transaction.clone()).unwrap(); - let block = builder.build().unwrap().block; - let block1_hash = block.header().hash(); - let id = BlockId::hash(block1_hash.clone()); - setup.client.import(BlockOrigin::Own, block).unwrap(); - - // fire notification - this should clean up the queue - assert_eq!(setup.pool.status().ready, 1); - block_on(FullBasicPoolMaintainer::new(setup.pool.clone(), setup.client.clone()).maintain(&id, &[])); - - // then - assert_eq!(setup.pool.status().ready, 0); - assert_eq!(setup.pool.status().future, 0); - - // import second block - let builder = setup.client.new_block_at( - &BlockId::hash(best.hash()), - Default::default(), - false, - ).unwrap(); - let block = builder.build().unwrap().block; - let id = BlockId::hash(block.header().hash()); - setup.client.import(BlockOrigin::Own, block).unwrap(); - - // fire notification - this should add the transaction back to the pool. - block_on(FullBasicPoolMaintainer::new(setup.pool.clone(), setup.client.clone()).maintain(&id, &[block1_hash])); - - // then - assert_eq!(setup.pool.status().ready, 1); - assert_eq!(setup.pool.status().future, 0); - } -} diff --git a/client/transaction-pool/src/tests.rs b/client/transaction-pool/src/tests.rs index 1199e41cf8..778536b7b9 100644 --- a/client/transaction-pool/src/tests.rs +++ b/client/transaction-pool/src/tests.rs @@ -14,29 +14,53 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . - use super::*; +use crate::{BasicPool, MaintainedTransactionPool}; use codec::Encode; use futures::executor::block_on; -use sc_transaction_graph::{self, Pool}; -use substrate_test_runtime_client::{runtime::{AccountId, Block, Hash, Index, Extrinsic, Transfer}, AccountKeyring::{self, *}}; +use parking_lot::RwLock; +use sc_transaction_graph::{self, ExHash, Pool}; use sp_runtime::{ generic::{self, BlockId}, - traits::{Hash as HashT, BlakeTwo256}, - transaction_validity::{TransactionValidity, ValidTransaction}, + traits::{BlakeTwo256, Hash as HashT}, + transaction_validity::{TransactionValidity, ValidTransaction, TransactionValidityError, InvalidTransaction}, +}; +use std::collections::HashSet; +use substrate_test_runtime_client::{ + runtime::{AccountId, Block, BlockNumber, Extrinsic, Hash, Header, Index, Transfer}, + AccountKeyring::{self, *}, }; struct TestApi { - pub modifier: Box, + pub modifier: RwLock>, + pub chain_block_by_number: RwLock>>, + pub chain_headers_by_number: RwLock>, + pub invalid_hashes: RwLock>>, + pub validation_requests: RwLock>, } impl TestApi { fn default() -> Self { TestApi { - modifier: Box::new(|_| {}), + modifier: RwLock::new(Box::new(|_| {})), + chain_block_by_number: RwLock::new(HashMap::new()), + invalid_hashes: RwLock::new(HashSet::new()), + chain_headers_by_number: RwLock::new(HashMap::new()), + validation_requests: RwLock::new(Default::default()), } } + + fn push_block(&self, block_number: BlockNumber, xts: Vec) { + self.chain_block_by_number.write().insert(block_number, xts); + self.chain_headers_by_number.write().insert(block_number, Header { + number: block_number, + digest: Default::default(), + extrinsics_root: Default::default(), + parent_hash: Default::default(), + state_root: Default::default(), + }); + } } impl sc_transaction_graph::ChainApi for TestApi { @@ -44,12 +68,16 @@ impl sc_transaction_graph::ChainApi for TestApi { type Hash = Hash; type Error = error::Error; type ValidationFuture = futures::future::Ready>; + type BodyFuture = futures::future::Ready>>>; fn validate_transaction( &self, at: &BlockId, uxt: sc_transaction_graph::ExtrinsicFor, ) -> Self::ValidationFuture { + + self.validation_requests.write().push(uxt.clone()); + let expected = index(at); let requires = if expected == uxt.transfer().nonce { vec![] @@ -58,6 +86,12 @@ impl sc_transaction_graph::ChainApi for TestApi { }; let provides = vec![vec![uxt.transfer().nonce as u8]]; + if self.invalid_hashes.read().contains(&self.hash_and_length(&uxt).0) { + return futures::future::ready(Ok( + Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(0))) + )) + } + let mut validity = ValidTransaction { priority: 1, requires, @@ -66,29 +100,43 @@ impl sc_transaction_graph::ChainApi for TestApi { propagate: true, }; - (self.modifier)(&mut validity); + (self.modifier.read())(&mut validity); - futures::future::ready(Ok( - Ok(validity) - )) + futures::future::ready(Ok(Ok(validity))) } - 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: &sc_transaction_graph::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()) } + fn block_body(&self, id: &BlockId) -> Self::BodyFuture { + futures::future::ready(Ok(if let BlockId::Number(num) = id { + self.chain_block_by_number.read().get(num).cloned() + } else { + None + })) + } } fn index(at: &BlockId) -> u64 { @@ -114,7 +162,11 @@ fn uxt(who: AccountKeyring, nonce: Index) -> Extrinsic { } fn pool() -> Pool { - Pool::new(Default::default(), TestApi::default()) + Pool::new(Default::default(), TestApi::default().into()) +} + +fn maintained_pool() -> BasicPool { + BasicPool::new(Default::default(), TestApi::default()) } #[test] @@ -192,11 +244,11 @@ fn should_ban_invalid_transactions() { #[test] fn should_correctly_prune_transactions_providing_more_than_one_tag() { - let mut api = TestApi::default(); - api.modifier = Box::new(|v: &mut ValidTransaction| { + let api = TestApi::default(); + *api.modifier.write() = Box::new(|v: &mut ValidTransaction| { v.provides.push(vec![155]); }); - let pool = Pool::new(Default::default(), api); + let pool = Pool::new(Default::default(), Arc::new(api)); let xt = uxt(Alice, 209); block_on(pool.submit_one(&BlockId::number(0), xt.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 1); @@ -220,3 +272,38 @@ fn should_correctly_prune_transactions_providing_more_than_one_tag() { assert_eq!(pool.status().ready, 0); assert_eq!(pool.status().future, 2); } + +#[test] +fn should_prune_old_during_maintenance() { + let xt = uxt(Alice, 209); + + let pool = maintained_pool(); + + block_on(pool.submit_one(&BlockId::number(0), xt.clone())).expect("1. Imported"); + assert_eq!(pool.status().ready, 1); + + pool.api.push_block(1, vec![xt.clone()]); + + block_on(pool.maintain(&BlockId::number(1), &[])); + assert_eq!(pool.status().ready, 0); +} + + +#[test] +fn should_revalidate_during_maintenance() { + let xt1 = uxt(Alice, 209); + let xt2 = uxt(Alice, 210); + + let pool = maintained_pool(); + block_on(pool.submit_one(&BlockId::number(0), xt1.clone())).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(0), xt2.clone())).expect("2. Imported"); + assert_eq!(pool.status().ready, 2); + assert_eq!(pool.api.validation_requests.read().len(), 2); + + pool.api.push_block(1, vec![xt1.clone()]); + + block_on(pool.maintain(&BlockId::number(1), &[])); + assert_eq!(pool.status().ready, 1); + // test that pool revalidated transaction that left ready and not included in the block + assert_eq!(pool.api.validation_requests.read().len(), 3); +} diff --git a/primitives/transaction-pool/src/pool.rs b/primitives/transaction-pool/src/pool.rs index e67a989075..ed24ad0619 100644 --- a/primitives/transaction-pool/src/pool.rs +++ b/primitives/transaction-pool/src/pool.rs @@ -20,6 +20,7 @@ use std::{ collections::HashMap, hash::Hash, sync::Arc, + pin::Pin, }; use futures::{ Future, Stream, @@ -225,6 +226,13 @@ pub trait TransactionPool: Send + Sync { fn hash_of(&self, xt: &TransactionFor) -> TxHash; } +/// Trait for transaction pool maintenance. +pub trait MaintainedTransactionPool : TransactionPool { + /// Perform maintenance + fn maintain(&self, block: &BlockId, retracted: &[BlockHash]) + -> Pin + Send>>; +} + /// An abstraction for transaction pool. /// /// This trait is used by offchain calls to be able to submit transactions. @@ -264,109 +272,4 @@ impl OffchainSubmitTransaction for TPool { 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) - } -} +} \ No newline at end of file -- GitLab From fca8058f0f8ba88c0d057befd70ea63f571011aa Mon Sep 17 00:00:00 2001 From: Ashley Date: Fri, 24 Jan 2020 13:34:42 +0100 Subject: [PATCH 013/180] Switch GrandPa to std futures (replaces #3909) (#4612) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Switch GrandPa to new futures * Work on making tests work * until_imported tests working again * Work on switching tests to stable futures * Modifications * Re-add test as #[ignore] * Don't ignore * Add manual unpins * Remove Header import * Return concrete Sink type * Switch to crates.io finality-grandpa version * Remove use statement that slipped in * Fix some nitpicks * Remove unpin from i * Fixed typo * Move futures01 to dev-deps * Fix nitpicks * Update client/finality-grandpa/src/communication/mod.rs Co-Authored-By: André Silva * nitpicking Co-authored-by: Pierre Krieger Co-authored-by: André Silva --- Cargo.lock | 11 +- bin/node-template/src/service.rs | 4 +- bin/node/cli/src/service.rs | 9 +- client/finality-grandpa/Cargo.toml | 9 +- .../src/communication/gossip.rs | 3 +- .../finality-grandpa/src/communication/mod.rs | 111 +++-- .../src/communication/periodic.rs | 2 +- .../src/communication/tests.rs | 82 ++-- client/finality-grandpa/src/environment.rs | 34 +- client/finality-grandpa/src/import.rs | 2 +- client/finality-grandpa/src/lib.rs | 115 +++-- client/finality-grandpa/src/observer.rs | 77 ++-- client/finality-grandpa/src/tests.rs | 398 +++++++++--------- client/finality-grandpa/src/until_imported.rs | 142 +++---- client/service/src/builder.rs | 2 +- client/service/src/lib.rs | 8 +- 16 files changed, 482 insertions(+), 527 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e0be7daf9..e69ee8e6e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1232,14 +1232,16 @@ dependencies = [ [[package]] name = "finality-grandpa" -version = "0.10.3" +version = "0.11.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)", + "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)", "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.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.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5476,7 +5478,7 @@ name = "sc-finality-grandpa" version = "0.8.0" dependencies = [ "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "finality-grandpa 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "finality-grandpa 0.11.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)", @@ -5484,6 +5486,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "sc-client 0.8.0", "sc-client-api 2.0.0", @@ -8406,7 +8409,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.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d9ad6bb0e42865b2d79fc9c8a08f22c39127310ed3334f2a1119ca25ed69dfb" +"checksum finality-grandpa 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "52c48f8a628193ba18639b2f727c32132d75f167a4b32f44b252ea8b937f154c" "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" diff --git a/bin/node-template/src/service.rs b/bin/node-template/src/service.rs index 458656d836..8a5c660b23 100644 --- a/bin/node-template/src/service.rs +++ b/bin/node-template/src/service.rs @@ -161,7 +161,7 @@ pub fn new_full(config: Configuration { // start the full GRANDPA voter @@ -178,7 +178,7 @@ pub fn new_full(config: Configuration { grandpa::setup_disabled_grandpa( diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index 75cb6ac4c4..2aaca315b9 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -110,10 +110,7 @@ macro_rules! new_full_start { /// concrete types instead. macro_rules! new_full { ($config:expr, $with_startup_data: expr) => {{ - use futures::{ - prelude::*, - compat::Future01CompatExt - }; + use futures::prelude::*; use sc_network::Event; let ( @@ -220,7 +217,7 @@ macro_rules! new_full { service.network(), service.on_exit(), service.spawn_task_handle(), - )?.compat().map(drop)); + )?); }, (true, false) => { // start the full GRANDPA voter @@ -237,7 +234,7 @@ macro_rules! new_full { // the GRANDPA voter task is considered infallible, i.e. // if it fails we take down the service with it. service.spawn_essential_task( - grandpa::run_grandpa_voter(grandpa_config)?.compat().map(drop) + grandpa::run_grandpa_voter(grandpa_config)? ); }, (_, true) => { diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index 2c0a10857c..a26b2e7a41 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -6,8 +6,7 @@ edition = "2018" [dependencies] fork-tree = { version = "2.0.0", path = "../../utils/fork-tree" } -futures = "0.1.29" -futures03 = { package = "futures", version = "0.3.1", features = ["compat"] } +futures = "0.3.1" futures-timer = "2.0.2" log = "0.4.8" parking_lot = "0.9.0" @@ -28,10 +27,11 @@ sc-network = { version = "0.8", path = "../network" } sc-network-gossip = { version = "0.8", 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.3", features = ["derive-codec"] } +finality-grandpa = { version = "0.11.0", features = ["derive-codec"] } +pin-project = "0.4.6" [dev-dependencies] -finality-grandpa = { version = "0.10.3", features = ["derive-codec", "test-helpers"] } +finality-grandpa = { version = "0.11.0", features = ["derive-codec", "test-helpers"] } sc-network = { version = "0.8", path = "../network" } sc-network-test = { version = "0.8.0", path = "../network/test" } sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } @@ -42,3 +42,4 @@ env_logger = "0.7.0" tokio = "0.1.22" tempfile = "3.1.0" sp-api = { version = "2.0.0", path = "../../primitives/api" } +futures01 = { package = "futures", version = "0.1.29" } diff --git a/client/finality-grandpa/src/communication/gossip.rs b/client/finality-grandpa/src/communication/gossip.rs index 7b21c1d079..7fef47867f 100644 --- a/client/finality-grandpa/src/communication/gossip.rs +++ b/client/finality-grandpa/src/communication/gossip.rs @@ -90,8 +90,7 @@ use sp_finality_grandpa::AuthorityId; use sc_telemetry::{telemetry, CONSENSUS_DEBUG}; use log::{trace, debug}; -use futures::prelude::*; -use futures03::channel::mpsc; +use futures::channel::mpsc; use rand::seq::SliceRandom; use crate::{environment, CatchUp, CompactCommit, SignedMessage}; diff --git a/client/finality-grandpa/src/communication/mod.rs b/client/finality-grandpa/src/communication/mod.rs index 64637c0ed8..42f26aa77e 100644 --- a/client/finality-grandpa/src/communication/mod.rs +++ b/client/finality-grandpa/src/communication/mod.rs @@ -27,17 +27,10 @@ //! In the future, there will be a fallback for allowing sending the same message //! under certain conditions that are used to un-stick the protocol. -use futures::prelude::*; -use futures03::{ - channel::mpsc as mpsc03, - compat::Compat, - future::{self as future03, Future as Future03}, - sink::Sink as Sink03, - stream::{Stream as Stream03, StreamExt}, -}; +use futures::{prelude::*, channel::mpsc}; use log::{debug, trace}; use parking_lot::Mutex; -use std::{pin::Pin, sync::Arc, task::{Context, Poll as Poll03}}; +use std::{pin::Pin, sync::Arc, task::{Context, Poll}}; use finality_grandpa::Message::{Prevote, Precommit, PrimaryPropose}; use finality_grandpa::{voter, voter_set::VoterSet}; @@ -49,8 +42,8 @@ use sp_runtime::traits::{Block as BlockT, Hash as HashT, Header as HeaderT, Numb use sc_telemetry::{telemetry, CONSENSUS_DEBUG, CONSENSUS_INFO}; use crate::{ - CatchUp, Commit, CommunicationIn, CommunicationOut, CompactCommit, Error, - Message, SignedMessage, + CatchUp, Commit, CommunicationIn, CommunicationOutH, + CompactCommit, Error, Message, SignedMessage, }; use crate::environment::HasVoted; use gossip::{ @@ -171,7 +164,7 @@ pub(crate) struct NetworkBridge> { // thus one has to wrap gossip_validator_report_stream with an `Arc` `Mutex`. Given that it is // just an `UnboundedReceiver`, one could also switch to a multi-producer-*multi*-consumer // channel implementation. - gossip_validator_report_stream: Arc>>, + gossip_validator_report_stream: Arc>>, } impl> Unpin for NetworkBridge {} @@ -185,7 +178,7 @@ impl> NetworkBridge { service: N, config: crate::Config, set_state: crate::environment::SharedVoterSetState, - executor: &impl futures03::task::Spawn, + executor: &impl futures::task::Spawn, ) -> Self { let (validator, report_stream) = GossipValidator::new( config, @@ -277,7 +270,7 @@ impl> NetworkBridge { local_key: Option, has_voted: HasVoted, ) -> ( - impl Stream03> + Unpin, + impl Stream> + Unpin, OutgoingMessages, ) { self.note_round( @@ -303,13 +296,13 @@ impl> NetworkBridge { match decoded { Err(ref e) => { debug!(target: "afg", "Skipping malformed message {:?}: {}", notification, e); - return future03::ready(None); + return future::ready(None); } Ok(GossipMessage::Vote(msg)) => { // check signature. if !voters.contains_key(&msg.message.id) { debug!(target: "afg", "Skipping message from unknown voter {}", msg.message.id); - return future03::ready(None); + return future::ready(None); } if voters.len() <= TELEMETRY_VOTERS_LIMIT { @@ -338,16 +331,16 @@ impl> NetworkBridge { }; } - future03::ready(Some(msg.message)) + future::ready(Some(msg.message)) } _ => { debug!(target: "afg", "Skipping unknown message type"); - return future03::ready(None); + return future::ready(None); } } }); - let (tx, out_rx) = mpsc03::channel(0); + let (tx, out_rx) = mpsc::channel(0); let outgoing = OutgoingMessages:: { round: round.0, set_id: set_id.0, @@ -360,7 +353,7 @@ impl> NetworkBridge { // Combine incoming votes from external GRANDPA nodes with outgoing // votes from our own GRANDPA voter to have a single // vote-import-pipeline. - let incoming = futures03::stream::select(incoming, out_rx); + let incoming = stream::select(incoming, out_rx); (incoming, outgoing) } @@ -372,8 +365,8 @@ impl> NetworkBridge { voters: Arc>, is_voter: bool, ) -> ( - impl Stream, Error = Error>, - impl Sink, SinkError = Error>, + impl Stream>, + impl Sink, Error = Error> + Unpin, ) { self.validator.note_set( set_id, @@ -401,7 +394,7 @@ impl> NetworkBridge { let outgoing = outgoing.with(|out| { let voter::CommunicationOut::Commit(round, commit) = out; - Ok((round, commit)) + future::ok((round, commit)) }); (incoming, outgoing) @@ -423,35 +416,35 @@ impl> NetworkBridge { } } -impl> Future03 for NetworkBridge { +impl> Future for NetworkBridge { type Output = Result<(), Error>; - fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll03 { + fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { loop { match self.neighbor_packet_worker.lock().poll_next_unpin(cx) { - Poll03::Ready(Some((to, packet))) => { + Poll::Ready(Some((to, packet))) => { self.gossip_engine.send_message(to, packet.encode()); }, - Poll03::Ready(None) => return Poll03::Ready( + Poll::Ready(None) => return Poll::Ready( Err(Error::Network("Neighbor packet worker stream closed.".into())) ), - Poll03::Pending => break, + Poll::Pending => break, } } loop { match self.gossip_validator_report_stream.lock().poll_next_unpin(cx) { - Poll03::Ready(Some(PeerReport { who, cost_benefit })) => { + Poll::Ready(Some(PeerReport { who, cost_benefit })) => { self.gossip_engine.report(who, cost_benefit); }, - Poll03::Ready(None) => return Poll03::Ready( + Poll::Ready(None) => return Poll::Ready( Err(Error::Network("Gossip validator report stream closed.".into())) ), - Poll03::Pending => break, + Poll::Pending => break, } } - Poll03::Pending + Poll::Pending } } @@ -461,7 +454,7 @@ fn incoming_global( voters: Arc>, gossip_validator: Arc>, neighbor_sender: periodic::NeighborPacketSender, -) -> impl Stream, Error = Error> { +) -> impl Stream> { let process_commit = move | msg: FullCommitMessage, mut notification: sc_network_gossip::TopicNotification, @@ -564,29 +557,27 @@ fn incoming_global( Some(voter::CommunicationIn::CatchUp(msg.message, cb)) }; - Compat::new(gossip_engine.messages_for(topic) - .map(|m| Ok::<_, ()>(m))) + gossip_engine.messages_for(topic) .filter_map(|notification| { // this could be optimized by decoding piecewise. let decoded = GossipMessage::::decode(&mut ¬ification.message[..]); if let Err(ref e) = decoded { trace!(target: "afg", "Skipping malformed commit message {:?}: {}", notification, e); } - decoded.map(move |d| (notification, d)).ok() + future::ready(decoded.map(move |d| (notification, d)).ok()) }) .filter_map(move |(notification, msg)| { - match msg { + future::ready(match msg { GossipMessage::Commit(msg) => process_commit(msg, notification, &mut gossip_engine, &gossip_validator, &*voters), GossipMessage::CatchUp(msg) => process_catch_up(msg, notification, &mut gossip_engine, &gossip_validator, &*voters), _ => { debug!(target: "afg", "Skipping unknown message type"); - return None; + None } - } + }) }) - .map_err(|()| Error::Network(format!("Failed to receive message on unbounded stream"))) } impl> Clone for NetworkBridge { @@ -687,19 +678,19 @@ pub(crate) struct OutgoingMessages { round: RoundNumber, set_id: SetIdNumber, locals: Option<(AuthorityPair, AuthorityId)>, - sender: mpsc03::Sender>, + sender: mpsc::Sender>, network: GossipEngine, has_voted: HasVoted, } impl Unpin for OutgoingMessages {} -impl Sink03> for OutgoingMessages +impl Sink> for OutgoingMessages { type Error = Error; - fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll03> { - Sink03::poll_ready(Pin::new(&mut self.sender), cx) + fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + Sink::poll_ready(Pin::new(&mut self.sender), cx) .map(|elem| { elem.map_err(|e| { Error::Network(format!("Failed to poll_ready channel sender: {:?}", e)) })}) @@ -769,12 +760,12 @@ impl Sink03> for OutgoingMessages Ok(()) } - fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context) -> Poll03> { - Poll03::Ready(Ok(())) + fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context) -> Poll> { + Poll::Ready(Ok(())) } - fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll03> { - Sink03::poll_close(Pin::new(&mut self.sender), cx) + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + Sink::poll_close(Pin::new(&mut self.sender), cx) .map(|elem| { elem.map_err(|e| { Error::Network(format!("Failed to poll_close channel sender: {:?}", e)) })}) @@ -985,13 +976,16 @@ impl CommitsOut { } } -impl Sink for CommitsOut { - type SinkItem = (RoundNumber, Commit); - type SinkError = Error; +impl Sink<(RoundNumber, Commit)> for CommitsOut { + type Error = Error; + + fn poll_ready(self: Pin<&mut Self>, _: &mut Context) -> Poll> { + Poll::Ready(Ok(())) + } - fn start_send(&mut self, input: (RoundNumber, Commit)) -> StartSend { + fn start_send(self: Pin<&mut Self>, input: (RoundNumber, Commit)) -> Result<(), Self::Error> { if !self.is_voter { - return Ok(AsyncSink::Ready); + return Ok(()); } let (round, commit) = input; @@ -1027,9 +1021,14 @@ impl Sink for CommitsOut { ); self.network.gossip_message(topic, message.encode(), false); - Ok(AsyncSink::Ready) + Ok(()) + } + + fn poll_close(self: Pin<&mut Self>, _: &mut Context) -> Poll> { + Poll::Ready(Ok(())) } - fn close(&mut self) -> Poll<(), Error> { Ok(Async::Ready(())) } - fn poll_complete(&mut self) -> Poll<(), Error> { Ok(Async::Ready(())) } + fn poll_flush(self: Pin<&mut Self>, _: &mut Context) -> Poll> { + Poll::Ready(Ok(())) + } } diff --git a/client/finality-grandpa/src/communication/periodic.rs b/client/finality-grandpa/src/communication/periodic.rs index d5c8c1e0b8..4635899690 100644 --- a/client/finality-grandpa/src/communication/periodic.rs +++ b/client/finality-grandpa/src/communication/periodic.rs @@ -17,7 +17,7 @@ //! Periodic rebroadcast of neighbor packets. use futures_timer::Delay; -use futures03::{channel::mpsc, future::{FutureExt as _}, prelude::*, ready, stream::Stream}; +use futures::{channel::mpsc, future::{FutureExt as _}, prelude::*, ready, stream::Stream}; use log::debug; use std::{pin::Pin, task::{Context, Poll}, time::{Instant, Duration}}; diff --git a/client/finality-grandpa/src/communication/tests.rs b/client/finality-grandpa/src/communication/tests.rs index c104af0339..a5435bdfdc 100644 --- a/client/finality-grandpa/src/communication/tests.rs +++ b/client/finality-grandpa/src/communication/tests.rs @@ -16,12 +16,11 @@ //! Tests for the communication portion of the GRANDPA crate. -use futures::sync::mpsc; +use futures::channel::mpsc; use futures::prelude::*; 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 sp_keyring::Ed25519Keyring; use parity_scale_codec::Encode; @@ -44,11 +43,19 @@ struct TestNetwork { sender: mpsc::UnboundedSender, } -impl sc_network_gossip::Network for TestNetwork { - fn event_stream(&self) -> Box + Send> { +impl TestNetwork { + fn event_stream_03(&self) -> Pin + Send>> { let (tx, rx) = mpsc::unbounded(); let _ = self.sender.unbounded_send(Event::EventStream(tx)); - Box::new(rx) + Box::pin(rx) + } +} + +impl sc_network_gossip::Network for TestNetwork { + fn event_stream(&self) -> Box + Send> { + Box::new( + self.event_stream_03().map(Ok::<_, ()>).compat() + ) } fn report_peer(&self, who: sc_network::PeerId, cost_benefit: sc_network::ReputationChange) { @@ -101,17 +108,17 @@ struct Tester { } impl Tester { - fn filter_network_events(self, mut pred: F) -> impl Future + fn filter_network_events(self, mut pred: F) -> impl Future where F: FnMut(Event) -> bool { let mut s = Some(self); - futures::future::poll_fn(move || loop { - match s.as_mut().unwrap().events.poll().expect("concluded early") { - Async::Ready(None) => panic!("concluded early"), - Async::Ready(Some(item)) => if pred(item) { - return Ok(Async::Ready(s.take().unwrap())) + futures::future::poll_fn(move |cx| loop { + match Stream::poll_next(Pin::new(&mut s.as_mut().unwrap().events), cx) { + Poll::Ready(None) => panic!("concluded early"), + Poll::Ready(Some(item)) => if pred(item) { + return Poll::Ready(s.take().unwrap()) }, - Async::NotReady => return Ok(Async::NotReady), + Poll::Pending => return Poll::Pending, } }) } @@ -149,8 +156,8 @@ fn voter_set_state() -> SharedVoterSetState { } // needs to run in a tokio runtime. -fn make_test_network(executor: &impl futures03::task::Spawn) -> ( - impl Future, +fn make_test_network(executor: &impl futures::task::Spawn) -> ( + impl Future, TestNetwork, ) { let (tx, rx) = mpsc::unbounded(); @@ -159,7 +166,7 @@ fn make_test_network(executor: &impl futures03::task::Spawn) -> ( #[derive(Clone)] struct Exit; - impl futures03::Future for Exit { + impl futures::Future for Exit { type Output = (); fn poll(self: Pin<&mut Self>, _: &mut Context) -> Poll<()> { @@ -175,7 +182,7 @@ fn make_test_network(executor: &impl futures03::task::Spawn) -> ( ); ( - futures::future::ok(Tester { + futures::future::ready(Tester { gossip_validator: bridge.validator.clone(), net_handle: bridge, events: rx, @@ -245,14 +252,14 @@ fn good_commit_leads_to_relay() { let id = sc_network::PeerId::random(); let global_topic = super::global_topic::(set_id); - let threads_pool = futures03::executor::ThreadPool::new().unwrap(); + let threads_pool = futures::executor::ThreadPool::new().unwrap(); let test = make_test_network(&threads_pool).0 - .and_then(move |tester| { + .then(move |tester| { // register a peer. tester.gossip_validator.new_peer(&mut NoopContext, &id, sc_network::config::Roles::FULL); - Ok((tester, id)) + future::ready((tester, id)) }) - .and_then(move |(tester, id)| { + .then(move |(tester, id)| { // start round, dispatch commit, and wait for broadcast. let (commits_in, _) = tester.net_handle.global_communication(SetId(1), voter_set, false); @@ -305,12 +312,11 @@ fn good_commit_leads_to_relay() { }, _ => panic!("commit expected"), } - }) - .map_err(|_| panic!("could not process commit")); + }); // once the message is sent and commit is "handled" we should have // a repropagation event coming from the network. - send_message.join(handle_commit).and_then(move |(tester, ())| { + future::join(send_message, handle_commit).then(move |(tester, ())| { tester.filter_network_events(move |event| match event { Event::WriteNotification(_, data) => { data == encoded_commit @@ -318,11 +324,10 @@ fn good_commit_leads_to_relay() { _ => false, }) }) - .map_err(|_| panic!("could not watch for gossip message")) .map(|_| ()) }); - current_thread::Runtime::new().unwrap().block_on(test).unwrap(); + futures::executor::block_on(test); } #[test] @@ -371,14 +376,14 @@ fn bad_commit_leads_to_report() { let id = sc_network::PeerId::random(); let global_topic = super::global_topic::(set_id); - let threads_pool = futures03::executor::ThreadPool::new().unwrap(); + let threads_pool = futures::executor::ThreadPool::new().unwrap(); let test = make_test_network(&threads_pool).0 - .and_then(move |tester| { + .map(move |tester| { // register a peer. tester.gossip_validator.new_peer(&mut NoopContext, &id, sc_network::config::Roles::FULL); - Ok((tester, id)) + (tester, id) }) - .and_then(move |(tester, id)| { + .then(move |(tester, id)| { // start round, dispatch commit, and wait for broadcast. let (commits_in, _) = tester.net_handle.global_communication(SetId(1), voter_set, false); @@ -422,12 +427,11 @@ fn bad_commit_leads_to_report() { }, _ => panic!("commit expected"), } - }) - .map_err(|_| panic!("could not process commit")); + }); // once the message is sent and commit is "handled" we should have // a report event coming from the network. - send_message.join(handle_commit).and_then(move |(tester, ())| { + future::join(send_message, handle_commit).then(move |(tester, ())| { tester.filter_network_events(move |event| match event { Event::Report(who, cost_benefit) => { who == id && cost_benefit == super::cost::INVALID_COMMIT @@ -435,26 +439,25 @@ fn bad_commit_leads_to_report() { _ => false, }) }) - .map_err(|_| panic!("could not watch for peer report")) .map(|_| ()) }); - current_thread::Runtime::new().unwrap().block_on(test).unwrap(); + futures::executor::block_on(test); } #[test] fn peer_with_higher_view_leads_to_catch_up_request() { let id = sc_network::PeerId::random(); - let threads_pool = futures03::executor::ThreadPool::new().unwrap(); + let threads_pool = futures::executor::ThreadPool::new().unwrap(); let (tester, mut net) = make_test_network(&threads_pool); let test = tester - .and_then(move |tester| { + .map(move |tester| { // register a peer with authority role. tester.gossip_validator.new_peer(&mut NoopContext, &id, sc_network::config::Roles::AUTHORITY); - Ok((tester, id)) + ((tester, id)) }) - .and_then(move |(tester, id)| { + .then(move |(tester, id)| { // send neighbor message at round 10 and height 50 let result = tester.gossip_validator.validate( &mut net, @@ -494,9 +497,8 @@ fn peer_with_higher_view_leads_to_catch_up_request() { }, _ => false, }) - .map_err(|_| panic!("could not watch for peer send message")) .map(|_| ()) }); - current_thread::Runtime::new().unwrap().block_on(test).unwrap(); + futures::executor::block_on(test); } diff --git a/client/finality-grandpa/src/environment.rs b/client/finality-grandpa/src/environment.rs index c5c6291dc0..fd88113776 100644 --- a/client/finality-grandpa/src/environment.rs +++ b/client/finality-grandpa/src/environment.rs @@ -16,17 +16,13 @@ use std::collections::BTreeMap; use std::iter::FromIterator; +use std::pin::Pin; use std::sync::Arc; use std::time::Duration; use log::{debug, warn, info}; use parity_scale_codec::{Decode, Encode}; use futures::prelude::*; -use futures03::{ - compat::{Compat, CompatSink}, - future::{FutureExt as _, TryFutureExt as _}, - stream::StreamExt as _, -}; use futures_timer::Delay; use parking_lot::RwLock; use sp_blockchain::{HeaderBackend, Error as ClientError}; @@ -568,19 +564,18 @@ where NumberFor: BlockNumberOps, Client: AuxStore, { - type Timer = Box + Send>; + type Timer = Pin> + Send>>; type Id = AuthorityId; type Signature = AuthoritySignature; // regular round message streams - type In = Box, Self::Signature, Self::Id>, + type In = Pin, Self::Signature, Self::Id>, Self::Error> + > + Send>>; + type Out = Pin>, Error = Self::Error, - > + Send>; - type Out = Box>, - SinkError = Self::Error, - > + Send>; + > + Send>>; type Error = CommandOrError>; @@ -612,12 +607,9 @@ where has_voted, ); - let incoming = Compat::new(incoming.map(|item| Ok::<_, Error>(item))); - let outgoing = CompatSink::new(outgoing); - // schedule incoming messages from the network to be held until // corresponding blocks are imported. - let incoming = Box::new(UntilVoteTargetImported::new( + let incoming = Box::pin(UntilVoteTargetImported::new( self.client.import_notification_stream(), self.network.clone(), self.client.clone(), @@ -626,12 +618,12 @@ where ).map_err(Into::into)); // schedule network message cleanup when sink drops. - let outgoing = Box::new(outgoing.sink_map_err(Into::into)); + let outgoing = Box::pin(outgoing.sink_err_into()); voter::RoundData { voter_id: local_key.map(|pair| pair.public()), - prevote_timer: Box::new(prevote_timer.map(Ok).compat()), - precommit_timer: Box::new(precommit_timer.map(Ok).compat()), + prevote_timer: Box::pin(prevote_timer.map(Ok)), + precommit_timer: Box::pin(precommit_timer.map(Ok)), incoming, outgoing, } @@ -905,7 +897,7 @@ where //random between 0-1 seconds. let delay: u64 = thread_rng().gen_range(0, 1000); - Box::new(Delay::new(Duration::from_millis(delay)).map(Ok).compat()) + Box::pin(Delay::new(Duration::from_millis(delay)).map(Ok)) } fn prevote_equivocation( diff --git a/client/finality-grandpa/src/import.rs b/client/finality-grandpa/src/import.rs index ad1b2b1a87..64fc62bfe7 100644 --- a/client/finality-grandpa/src/import.rs +++ b/client/finality-grandpa/src/import.rs @@ -18,7 +18,7 @@ use std::{sync::Arc, collections::HashMap}; use log::{debug, trace, info}; use parity_scale_codec::Encode; -use futures::sync::mpsc; +use futures::channel::mpsc; use parking_lot::RwLockWriteGuard; use sp_blockchain::{HeaderBackend, BlockStatus, well_known_cache_keys}; diff --git a/client/finality-grandpa/src/lib.rs b/client/finality-grandpa/src/lib.rs index 071214961f..a86a97c0da 100644 --- a/client/finality-grandpa/src/lib.rs +++ b/client/finality-grandpa/src/lib.rs @@ -53,9 +53,9 @@ //! included in the newly-finalized chain. use futures::prelude::*; -use futures03::{StreamExt, future::ready}; -use log::{debug, error, info}; -use futures::sync::mpsc; +use futures::StreamExt; +use log::{debug, info}; +use futures::channel::mpsc; use sc_client_api::{BlockchainEvents, CallExecutor, backend::{AuxStore, Backend}, ExecutionStrategy}; use sp_blockchain::{HeaderBackend, Error as ClientError}; use sc_client::Client; @@ -66,7 +66,7 @@ use sc_keystore::KeyStorePtr; use sp_inherents::InherentDataProviders; use sp_consensus::SelectChain; use sp_core::Pair; -use sc_telemetry::{telemetry, CONSENSUS_INFO, CONSENSUS_DEBUG, CONSENSUS_WARN}; +use sc_telemetry::{telemetry, CONSENSUS_INFO, CONSENSUS_DEBUG}; use serde_json; use sp_finality_tracker; @@ -77,6 +77,8 @@ use finality_grandpa::{voter, BlockNumberOps, voter_set::VoterSet}; use std::{fmt, io}; use std::sync::Arc; use std::time::Duration; +use std::pin::Pin; +use std::task::{Poll, Context}; mod authorities; mod aux_schema; @@ -456,13 +458,12 @@ fn global_communication( keystore: &Option, ) -> ( impl Stream< - Item = CommunicationInH, - Error = CommandOrError>, + Item = Result, CommandOrError>>, >, impl Sink< - SinkItem = CommunicationOutH, - SinkError = CommandOrError>, - >, + CommunicationOutH, + Error = CommandOrError>, + > + Unpin, ) where B: Backend, E: CallExecutor + Send + Sync, @@ -536,7 +537,7 @@ pub struct GrandpaParams { /// Handle to a future that will resolve on exit. pub on_exit: X, /// If supplied, can be used to hook on telemetry connection established events. - pub telemetry_on_connect: Option>, + pub telemetry_on_connect: Option>, /// A voting rule used to potentially restrict target votes. pub voting_rule: VR, /// How to spawn background tasks. @@ -547,7 +548,7 @@ pub struct GrandpaParams { /// block import worker that has already been instantiated with `block_import`. pub fn run_grandpa_voter( grandpa_params: GrandpaParams, -) -> sp_blockchain::Result + Send + 'static> where +) -> sp_blockchain::Result + Unpin + Send + 'static> where Block::Hash: Ord, B: Backend + 'static, E: CallExecutor + Send + Sync + 'static, @@ -557,9 +558,9 @@ pub fn run_grandpa_voter( NumberFor: BlockNumberOps, DigestFor: Encode, RA: Send + Sync + 'static, - X: futures03::Future + Clone + Send + Unpin + 'static, + X: futures::Future + Clone + Send + Unpin + 'static, Client: AuxStore, - Sp: futures03::task::Spawn + 'static, + Sp: futures::task::Spawn + 'static, { let GrandpaParams { config, @@ -608,13 +609,11 @@ pub fn run_grandpa_voter( .expect("authorities is always at least an empty vector; elements are always of type string") } ); - ready(()) - }) - .unit_error() - .compat(); - futures::future::Either::A(events) + future::ready(()) + }); + future::Either::Left(events) } else { - futures::future::Either::B(futures::future::empty()) + future::Either::Right(future::pending()) }; let voter_work = VoterWork::new( @@ -628,28 +627,22 @@ pub fn run_grandpa_voter( ); let voter_work = voter_work - .map(|_| ()) - .map_err(|e| { - error!("GRANDPA Voter failed: {:?}", e); - telemetry!(CONSENSUS_WARN; "afg.voter_failed"; "e" => ?e); - }); + .map(|_| ()); // Make sure that `telemetry_task` doesn't accidentally finish and kill grandpa. let telemetry_task = telemetry_task - .then(|_| futures::future::empty::<(), ()>()); + .then(|_| future::pending::<()>()); - use futures03::{FutureExt, TryFutureExt}; - - Ok(voter_work.select(on_exit.map(Ok).compat()).select2(telemetry_task).then(|_| Ok(()))) + Ok(future::select(future::select(voter_work, on_exit), telemetry_task).map(drop)) } /// Future that powers the voter. #[must_use] struct VoterWork, RA, SC, VR> { - voter: Box>> + Send>, + voter: Pin>>> + Send>>, env: Arc>, voter_commands_rx: mpsc::UnboundedReceiver>>, - network: futures03::compat::Compat>, + network: NetworkBridge, } impl VoterWork @@ -691,10 +684,10 @@ where let mut work = VoterWork { // `voter` is set to a temporary value and replaced below when // calling `rebuild_voter`. - voter: Box::new(futures::empty()) as Box<_>, + voter: Box::pin(future::pending()), env, voter_commands_rx, - network: futures03::future::TryFutureExt::compat(network), + network, }; work.rebuild_voter(); work @@ -757,10 +750,10 @@ where last_finalized, ); - self.voter = Box::new(voter); + self.voter = Box::pin(voter); }, VoterSetState::Paused { .. } => - self.voter = Box::new(futures::empty()), + self.voter = Box::pin(future::pending()), }; } @@ -841,61 +834,47 @@ where VR: VotingRule> + Clone + 'static, Client: AuxStore, { - type Item = (); - type Error = Error; + type Output = Result<(), Error>; - fn poll(&mut self) -> Poll { - match self.voter.poll() { - Ok(Async::NotReady) => {} - Ok(Async::Ready(())) => { + fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { + match Future::poll(Pin::new(&mut self.voter), cx) { + Poll::Pending => {} + Poll::Ready(Ok(())) => { // voters don't conclude naturally - return Err(Error::Safety("GRANDPA voter has concluded.".into())) + return Poll::Ready(Err(Error::Safety("GRANDPA voter has concluded.".into()))) } - Err(CommandOrError::Error(e)) => { + Poll::Ready(Err(CommandOrError::Error(e))) => { // return inner observer error - return Err(e) + return Poll::Ready(Err(e)) } - Err(CommandOrError::VoterCommand(command)) => { + Poll::Ready(Err(CommandOrError::VoterCommand(command))) => { // some command issued internally self.handle_voter_command(command)?; - futures::task::current().notify(); + cx.waker().wake_by_ref(); } } - match self.voter_commands_rx.poll() { - Ok(Async::NotReady) => {} - Err(_) => { - // the `voter_commands_rx` stream should not fail. - return Ok(Async::Ready(())) - } - Ok(Async::Ready(None)) => { + match Stream::poll_next(Pin::new(&mut self.voter_commands_rx), cx) { + Poll::Pending => {} + Poll::Ready(None) => { // the `voter_commands_rx` stream should never conclude since it's never closed. - return Ok(Async::Ready(())) + return Poll::Ready(Ok(())) } - Ok(Async::Ready(Some(command))) => { + Poll::Ready(Some(command)) => { // some command issued externally self.handle_voter_command(command)?; - futures::task::current().notify(); + cx.waker().wake_by_ref(); } } - match self.network.poll() { - Ok(Async::NotReady) => {}, - Ok(Async::Ready(())) => { - // the network bridge future should never conclude. - return Ok(Async::Ready(())) - } - e @ Err(_) => return e, - }; - - Ok(Async::NotReady) + Future::poll(Pin::new(&mut self.network), cx) } } #[deprecated(since = "1.1.0", note = "Please switch to run_grandpa_voter.")] pub fn run_grandpa( grandpa_params: GrandpaParams, -) -> sp_blockchain::Result + Send + 'static> where +) -> sp_blockchain::Result + Send + 'static> where Block::Hash: Ord, B: Backend + 'static, E: CallExecutor + Send + Sync + 'static, @@ -905,9 +884,9 @@ pub fn run_grandpa( DigestFor: Encode, RA: Send + Sync + 'static, VR: VotingRule> + Clone + 'static, - X: futures03::Future + Clone + Send + Unpin + 'static, + X: futures::Future + Clone + Send + Unpin + 'static, Client: AuxStore, - Sp: futures03::task::Spawn + 'static, + Sp: futures::task::Spawn + 'static, { run_grandpa_voter(grandpa_params) } diff --git a/client/finality-grandpa/src/observer.rs b/client/finality-grandpa/src/observer.rs index 989a1e1655..418bd570c0 100644 --- a/client/finality-grandpa/src/observer.rs +++ b/client/finality-grandpa/src/observer.rs @@ -14,10 +14,11 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +use std::pin::Pin; use std::sync::Arc; +use std::task::{Context, Poll}; -use futures::prelude::*; -use futures::{future, sync::mpsc}; +use futures::{prelude::*, channel::mpsc}; use finality_grandpa::{ BlockNumberOps, Error as GrandpaError, voter, voter_set::VoterSet @@ -64,14 +65,13 @@ fn grandpa_observer( last_finalized_number: NumberFor, commits: S, note_round: F, -) -> impl Future>> where +) -> impl Future>>> where NumberFor: BlockNumberOps, B: Backend, E: CallExecutor + Send + Sync + 'static, RA: Send + Sync, S: Stream< - Item = CommunicationIn, - Error = CommandOrError>, + Item = Result, CommandOrError>>, >, F: Fn(u64), { @@ -80,7 +80,7 @@ fn grandpa_observer( let client = client.clone(); let voters = voters.clone(); - let observer = commits.fold(last_finalized_number, move |last_finalized_number, global| { + let observer = commits.try_fold(last_finalized_number, move |last_finalized_number, global| { let (round, commit, callback) = match global { voter::CommunicationIn::Commit(round, commit, callback) => { let commit = finality_grandpa::Commit::from(commit); @@ -143,7 +143,7 @@ fn grandpa_observer( } }); - observer.map(|_| ()) + observer.map_ok(|_| ()) } /// Run a GRANDPA observer as a task, the observer will finalize blocks only by @@ -154,16 +154,16 @@ pub fn run_grandpa_observer( config: Config, link: LinkHalf, network: N, - on_exit: impl futures03::Future + Clone + Send + Unpin + 'static, + on_exit: impl futures::Future + Clone + Send + Unpin + 'static, executor: Sp, -) -> sp_blockchain::Result + Send + 'static> where +) -> sp_blockchain::Result + Unpin + Send + 'static> where B: Backend + 'static, E: CallExecutor + Send + Sync + 'static, N: NetworkT + Send + Clone + 'static, SC: SelectChain + 'static, NumberFor: BlockNumberOps, RA: Send + Sync + 'static, - Sp: futures03::task::Spawn + 'static, + Sp: futures::task::Spawn + 'static, Client: AuxStore, { let LinkHalf { @@ -189,20 +189,18 @@ pub fn run_grandpa_observer( ); let observer_work = observer_work - .map(|_| ()) + .map_ok(|_| ()) .map_err(|e| { warn!("GRANDPA Observer failed: {:?}", e); }); - use futures03::{FutureExt, TryFutureExt}; - - Ok(observer_work.select(on_exit.map(Ok).compat()).map(|_| ()).map_err(|_| ())) + Ok(future::select(observer_work, on_exit).map(drop)) } /// Future that powers the observer. #[must_use] struct ObserverWork, E, Backend, RA> { - observer: Box>> + Send>, + observer: Pin>>> + Send>>, client: Arc>, network: NetworkBridge, persistent_data: PersistentData, @@ -231,7 +229,7 @@ where let mut work = ObserverWork { // `observer` is set to a temporary value and replaced below when // calling `rebuild_observer`. - observer: Box::new(futures::empty()) as Box<_>, + observer: Box::pin(future::pending()) as Pin>, client, network, persistent_data, @@ -286,7 +284,7 @@ where note_round, ); - self.observer = Box::new(observer); + self.observer = Box::pin(observer); } fn handle_voter_command( @@ -336,44 +334,41 @@ where Bk: Backend + 'static, Client: AuxStore, { - type Item = (); - type Error = Error; + type Output = Result<(), Error>; + + fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { + let this = Pin::into_inner(self); - fn poll(&mut self) -> Poll { - match self.observer.poll() { - Ok(Async::NotReady) => {} - Ok(Async::Ready(())) => { + match Future::poll(Pin::new(&mut this.observer), cx) { + Poll::Pending => {} + Poll::Ready(Ok(())) => { // observer commit stream doesn't conclude naturally; this could reasonably be an error. - return Ok(Async::Ready(())) + return Poll::Ready(Ok(())) } - Err(CommandOrError::Error(e)) => { + Poll::Ready(Err(CommandOrError::Error(e))) => { // return inner observer error - return Err(e) + return Poll::Ready(Err(e)) } - Err(CommandOrError::VoterCommand(command)) => { + Poll::Ready(Err(CommandOrError::VoterCommand(command))) => { // some command issued internally - self.handle_voter_command(command)?; - futures::task::current().notify(); + this.handle_voter_command(command)?; + cx.waker().wake_by_ref(); } } - match self.voter_commands_rx.poll() { - Ok(Async::NotReady) => {} - Err(_) => { - // the `voter_commands_rx` stream should not fail. - return Ok(Async::Ready(())) - } - Ok(Async::Ready(None)) => { + match Stream::poll_next(Pin::new(&mut this.voter_commands_rx), cx) { + Poll::Pending => {} + Poll::Ready(None) => { // the `voter_commands_rx` stream should never conclude since it's never closed. - return Ok(Async::Ready(())) + return Poll::Ready(Ok(())) } - Ok(Async::Ready(Some(command))) => { + Poll::Ready(Some(command)) => { // some command issued externally - self.handle_voter_command(command)?; - futures::task::current().notify(); + this.handle_voter_command(command)?; + cx.waker().wake_by_ref(); } } - Ok(Async::NotReady) + Poll::Pending } } diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index fdfb2fd808..0d7cf0541f 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -25,7 +25,6 @@ use sc_network_test::{ use sc_network::config::{ProtocolConfig, Roles, BoxFinalityProofRequestBuilder}; use parking_lot::Mutex; use futures_timer::Delay; -use futures03::TryStreamExt as _; use tokio::runtime::current_thread; use sp_keyring::Ed25519Keyring; use sc_client::LongestChain; @@ -48,6 +47,8 @@ use sp_runtime::generic::{BlockId, DigestItem}; use sp_core::{H256, NativeOrEncoded, ExecutionContext, crypto::Public}; use sp_finality_grandpa::{GRANDPA_ENGINE_ID, AuthorityList, GrandpaApi}; use sp_state_machine::{InMemoryBackend, prove_read, read_proof_check}; +use futures01::Async; +use futures::compat::Future01CompatExt; use authorities::AuthoritySet; use finality_proof::{ @@ -196,7 +197,7 @@ impl TestNetFactory for GrandpaTestNet { #[derive(Clone)] struct Exit; -impl futures03::Future for Exit { +impl futures::Future for Exit { type Output = (); fn poll(self: Pin<&mut Self>, _: &mut task::Context) -> task::Poll<()> { @@ -371,17 +372,28 @@ fn create_keystore(authority: Ed25519Keyring) -> (KeyStorePtr, tempfile::TempDir (keystore, keystore_path) } +fn block_until_complete(future: impl Future + Unpin, net: &Arc>, runtime: &mut current_thread::Runtime) { + let drive_to_completion = futures01::future::poll_fn(|| { + net.lock().poll(); Ok::, ()>(Async::NotReady) + }); + runtime.block_on( + future::select(future, drive_to_completion.compat()) + .map(|_| Ok::<(), ()>(())) + .compat() + ).unwrap(); +} + // run the voters to completion. provide a closure to be invoked after // the voters are spawned but before blocking on them. fn run_to_completion_with( runtime: &mut current_thread::Runtime, - threads_pool: &futures03::executor::ThreadPool, + threads_pool: &futures::executor::ThreadPool, blocks: u64, net: Arc>, peers: &[Ed25519Keyring], with: F, ) -> u64 where - F: FnOnce(current_thread::Handle) -> Option>> + F: FnOnce(current_thread::Handle) -> Option>>> { use parking_lot::RwLock; @@ -411,17 +423,16 @@ fn run_to_completion_with( }; wait_for.push( - Box::new( + Box::pin( client.finality_notification_stream() - .map(|v| Ok::<_, ()>(v)).compat() .take_while(move |n| { let mut highest_finalized = highest_finalized.write(); if *n.header.number() > *highest_finalized { *highest_finalized = *n.header.number(); } - Ok(n.header.number() < &blocks) + future::ready(n.header.number() < &blocks) }) - .collect() + .collect::>() .map(|_| ()) ) ); @@ -449,24 +460,20 @@ fn run_to_completion_with( assert_send(&voter); - runtime.spawn(voter); + runtime.spawn(voter.unit_error().compat()); } // wait for all finalized on each. - let wait_for = ::futures::future::join_all(wait_for) - .map(|_| ()) - .map_err(|_| ()); - - let drive_to_completion = futures::future::poll_fn(|| { net.lock().poll(); Ok(Async::NotReady) }); - let _ = runtime.block_on(wait_for.select(drive_to_completion).map_err(|_| ())).unwrap(); + let wait_for = ::futures::future::join_all(wait_for); + block_until_complete(wait_for, &net, runtime); let highest_finalized = *highest_finalized.read(); highest_finalized } fn run_to_completion( runtime: &mut current_thread::Runtime, - threads_pool: &futures03::executor::ThreadPool, + threads_pool: &futures::executor::ThreadPool, blocks: u64, net: Arc>, peers: &[Ed25519Keyring] @@ -496,7 +503,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 threads_pool = futures::executor::ThreadPool::new().unwrap(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let voters = make_ids(peers); @@ -522,7 +529,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 threads_pool = futures::executor::ThreadPool::new().unwrap(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let voters = make_ids(peers); @@ -555,9 +562,8 @@ fn finalize_3_voters_1_full_observer() { }; finality_notifications.push( client.finality_notification_stream() - .map(|v| Ok::<_, ()>(v)).compat() - .take_while(|n| Ok(n.header.number() < &20)) - .for_each(move |_| Ok(())) + .take_while(|n| future::ready(n.header.number() < &20)) + .for_each(move |_| future::ready(())) ); let keystore = if let Some(local_key) = local_key { @@ -590,16 +596,14 @@ fn finalize_3_voters_1_full_observer() { } for voter in voters { - runtime.spawn(voter); + runtime.spawn(voter.unit_error().compat()); } // wait for all finalized on each. let wait_for = futures::future::join_all(finality_notifications) - .map(|_| ()) - .map_err(|_| ()); + .map(|_| ()); - let drive_to_completion = futures::future::poll_fn(|| { net.lock().poll(); Ok(Async::NotReady) }); - let _ = runtime.block_on(wait_for.select(drive_to_completion).map_err(|_| ())).unwrap(); + block_until_complete(wait_for, &net, &mut runtime); } #[test] @@ -631,7 +635,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(); + let threads_pool = futures::executor::ThreadPool::new().unwrap(); net.lock().peer(0).push_blocks(1, false); net.lock().block_until_sync(&mut runtime); @@ -654,8 +658,7 @@ fn transition_3_voters_twice_1_full_observer() { // wait for blocks to be finalized before generating new ones let block_production = client.finality_notification_stream() - .map(|v| Ok::<_, ()>(v)).compat() - .take_while(|n| Ok(n.header.number() < &30)) + .take_while(|n| future::ready(n.header.number() < &30)) .for_each(move |n| { match n.header.number() { 1 => { @@ -692,10 +695,10 @@ fn transition_3_voters_twice_1_full_observer() { _ => {}, } - Ok(()) + future::ready(()) }); - runtime.spawn(block_production); + runtime.spawn(block_production.unit_error().compat()); } let mut finality_notifications = Vec::new(); @@ -725,9 +728,8 @@ fn transition_3_voters_twice_1_full_observer() { finality_notifications.push( client.finality_notification_stream() - .map(|v| Ok::<_, ()>(v)).compat() - .take_while(|n| Ok(n.header.number() < &30)) - .for_each(move |_| Ok(())) + .take_while(|n| future::ready(n.header.number() < &30)) + .for_each(move |_| future::ready(())) .map(move |()| { let full_client = client.as_full().expect("only full clients are used in test"); let set: AuthoritySet = crate::aux_schema::load_authorities(&*full_client).unwrap(); @@ -756,22 +758,19 @@ fn transition_3_voters_twice_1_full_observer() { }; let voter = run_grandpa_voter(grandpa_params).expect("all in order with client and network"); - runtime.spawn(voter); + runtime.spawn(voter.unit_error().compat()); } // wait for all finalized on each. - let wait_for = ::futures::future::join_all(finality_notifications) - .map(|_| ()) - .map_err(|_| ()); + let wait_for = ::futures::future::join_all(finality_notifications); - let drive_to_completion = futures::future::poll_fn(|| { net.lock().poll(); Ok(Async::NotReady) }); - let _ = runtime.block_on(wait_for.select(drive_to_completion).map_err(|_| ())).unwrap(); + block_until_complete(wait_for, &net, &mut runtime); } #[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 threads_pool = futures::executor::ThreadPool::new().unwrap(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 3); @@ -790,7 +789,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 threads_pool = futures::executor::ThreadPool::new().unwrap(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let voters = make_ids(peers); @@ -830,7 +829,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 threads_pool = futures::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); @@ -871,21 +870,21 @@ fn sync_justifications_on_change_blocks() { } // the last peer should get the justification by syncing from other peers - runtime.block_on(futures::future::poll_fn(move || -> std::result::Result<_, ()> { + futures::executor::block_on(futures::future::poll_fn(move |_| { if net.lock().peer(3).client().justification(&BlockId::Number(21)).unwrap().is_none() { net.lock().poll(); - Ok(Async::NotReady) + Poll::Pending } else { - Ok(Async::Ready(())) + Poll::Ready(()) } - })).unwrap() + })) } #[test] 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 threads_pool = futures::executor::ThreadPool::new().unwrap(); let peers_a = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let peers_b = &[Ed25519Keyring::Dave, Ed25519Keyring::Eve, Ed25519Keyring::Ferdie]; @@ -946,7 +945,7 @@ fn finalizes_multiple_pending_changes_in_order() { 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(); + let threads_pool = futures::executor::ThreadPool::new().unwrap(); // two of these guys are offline. let genesis_authorities = &[ Ed25519Keyring::Alice, @@ -1123,11 +1122,11 @@ fn voter_persists_its_votes() { use std::iter::FromIterator; use std::sync::atomic::{AtomicUsize, Ordering}; use futures::future; - use futures::sync::mpsc; + use futures::channel::mpsc; let _ = env_logger::try_init(); let mut runtime = current_thread::Runtime::new().unwrap(); - let threads_pool = futures03::executor::ThreadPool::new().unwrap(); + let threads_pool = futures::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 @@ -1161,56 +1160,56 @@ fn voter_persists_its_votes() { keystore_paths.push(keystore_path); struct ResettableVoter { - voter: Box + Send>, + voter: Pin + Send + Unpin>>, voter_rx: mpsc::UnboundedReceiver<()>, net: Arc>, client: PeersClient, keystore: KeyStorePtr, - threads_pool: futures03::executor::ThreadPool, + threads_pool: futures::executor::ThreadPool, } impl Future for ResettableVoter { - type Item = (); - type Error = (); + type Output = (); - fn poll(&mut self) -> Poll { - match self.voter.poll() { - Ok(Async::Ready(())) | Err(_) => panic!("error in the voter"), - Ok(Async::NotReady) => {}, + fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { + let this = Pin::into_inner(self); + + if let Poll::Ready(()) = Pin::new(&mut this.voter).poll(cx) { + panic!("error in the voter"); } - match self.voter_rx.poll() { - Err(_) | Ok(Async::Ready(None)) => return Ok(Async::Ready(())), - Ok(Async::NotReady) => {} - Ok(Async::Ready(Some(()))) => { + match Pin::new(&mut this.voter_rx).poll_next(cx) { + Poll::Pending => return Poll::Pending, + Poll::Ready(None) => return Poll::Ready(()), + Poll::Ready(Some(())) => { let (_block_import, _, _, _, link) = - self.net.lock() + this.net.lock() .make_block_import::< TransactionFor - >(self.client.clone()); + >(this.client.clone()); let link = link.lock().take().unwrap(); let grandpa_params = GrandpaParams { config: Config { gossip_duration: TEST_GOSSIP_DURATION, justification_period: 32, - keystore: Some(self.keystore.clone()), + keystore: Some(this.keystore.clone()), name: Some(format!("peer#{}", 0)), is_authority: true, observer_enabled: true, }, link, - network: self.net.lock().peers[0].network_service().clone(), + network: this.net.lock().peers[0].network_service().clone(), inherent_data_providers: InherentDataProviders::new(), on_exit: Exit, telemetry_on_connect: None, voting_rule: VotingRulesBuilder::default().build(), - executor: self.threads_pool.clone(), + executor: this.threads_pool.clone(), }; let voter = run_grandpa_voter(grandpa_params) .expect("all in order with client and network") - .then(move |r| { + .map(move |r| { // we need to keep the block_import alive since it owns the // sender for the voter commands channel, if that gets dropped // then the voter will stop @@ -1218,30 +1217,30 @@ fn voter_persists_its_votes() { r }); - self.voter = Box::new(voter); + this.voter = Box::pin(voter); // notify current task in order to poll the voter - futures::task::current().notify(); + cx.waker().wake_by_ref(); } }; - Ok(Async::NotReady) + Poll::Pending } } - // we create a "dummy" voter by setting it to `empty` and triggering the `tx`. + // we create a "dummy" voter by setting it to `pending` and triggering the `tx`. // this way, the `ResettableVoter` will reset its `voter` field to a value ASAP. voter_tx.unbounded_send(()).unwrap(); runtime.spawn(ResettableVoter { - voter: Box::new(futures::future::empty()), + voter: Box::pin(futures::future::pending()), voter_rx, net: net.clone(), client: client.clone(), keystore, threads_pool: threads_pool.clone(), - }); + }.unit_error().compat()); } - let (exit_tx, exit_rx) = futures::sync::oneshot::channel::<()>(); + let (exit_tx, exit_rx) = futures::channel::oneshot::channel::<()>(); // create the communication layer for bob, but don't start any // voter. instead we'll listen for the prevote that alice casts @@ -1284,122 +1283,107 @@ fn voter_persists_its_votes() { HasVoted::No, ); - let round_rx = futures03::compat::Compat::new(round_rx.map(|item| Ok::<_, Error>(item))); - let round_tx = futures03::compat::CompatSink::new(round_tx); - let round_tx = Arc::new(Mutex::new(round_tx)); let exit_tx = Arc::new(Mutex::new(Some(exit_tx))); let net = net.clone(); - let state = AtomicUsize::new(0); + let state = Arc::new(AtomicUsize::new(0)); runtime.spawn(round_rx.for_each(move |signed| { - 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 { - finality_grandpa::Message::Prevote(prevote) => prevote, - _ => panic!("voter should prevote."), - }; - - // its chain has 20 blocks and the voter targets 3/4 of the - // unfinalized chain, so the vote should be for block 15 - assert!(prevote.target_number == 15); - - // we push 20 more blocks to alice's chain - net.lock().peer(0).push_blocks(20, false); - - let net2 = net.clone(); - let net = net.clone(); - let voter_tx = voter_tx.clone(); - let round_tx = round_tx.clone(); - - 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().best_number != 40) - }) - .for_each(|_| Ok(())) - .and_then(move |_| { - let block_30_hash = - net.lock().peer(0).client().as_full().unwrap().hash(30).unwrap().unwrap(); - - // we restart alice's voter - voter_tx.unbounded_send(()).unwrap(); - - // and we push our own prevote for block 30 - let prevote = finality_grandpa::Prevote { - target_number: 30, - target_hash: block_30_hash, - }; - - // One should either be calling `Sink::send` or `Sink::start_send` followed - // by `Sink::poll_complete` to make sure items are being flushed. Given that - // we send in a loop including a delay until items are received, this can be - // ignored for the sake of reduced complexity. - if !round_tx.lock() - .start_send(finality_grandpa::Message::Prevote(prevote)) - .unwrap() - .is_ready() { - panic!("expected sink to be ready to write to."); - } - - 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 { - finality_grandpa::Message::Prevote(prevote) => prevote, - _ => panic!("We should receive our own prevote."), - }; - - // targeting block 30 - assert!(prevote.target_number == 30); - - // after alice restarts it should send its previous prevote - // therefore we won't ever receive it again since it will be a - // known message on the gossip layer - - future::Either::B(future::ok(())) - - } else if state.compare_and_swap(2, 3, Ordering::SeqCst) == 2 { - // we then receive a precommit from alice for block 15 - // even though we casted a prevote for block 30 - let precommit = match signed.message { - finality_grandpa::Message::Precommit(precommit) => precommit, - _ => panic!("voter should precommit."), - }; - - assert!(precommit.target_number == 15); - - // signal exit - exit_tx.clone().lock().take().unwrap().send(()).unwrap(); - - future::Either::B(future::ok(())) - - } else { - panic!() + let net2 = net.clone(); + let net = net.clone(); + let voter_tx = voter_tx.clone(); + let round_tx = round_tx.clone(); + let state = state.clone(); + let exit_tx = exit_tx.clone(); + + async move { + 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 { + finality_grandpa::Message::Prevote(prevote) => prevote, + _ => panic!("voter should prevote."), + }; + + // its chain has 20 blocks and the voter targets 3/4 of the + // unfinalized chain, so the vote should be for block 15 + assert!(prevote.target_number == 15); + + // we push 20 more blocks to alice's chain + net.lock().peer(0).push_blocks(20, false); + + let interval = futures::stream::unfold(Delay::new(Duration::from_millis(200)), |delay| + Box::pin(async move { + delay.await; + Some(((), Delay::new(Duration::from_millis(200)))) + }) + ); + + interval + .take_while(move |_| { + future::ready(net2.lock().peer(1).client().info().best_number != 40) + }) + .for_each(|_| future::ready(())) + .await; + + let block_30_hash = + net.lock().peer(0).client().as_full().unwrap().hash(30).unwrap().unwrap(); + + // we restart alice's voter + voter_tx.unbounded_send(()).unwrap(); + + // and we push our own prevote for block 30 + let prevote = finality_grandpa::Prevote { + target_number: 30, + target_hash: block_30_hash, + }; + + // One should either be calling `Sink::send` or `Sink::start_send` followed + // by `Sink::poll_complete` to make sure items are being flushed. Given that + // we send in a loop including a delay until items are received, this can be + // ignored for the sake of reduced complexity. + Pin::new(&mut *round_tx.lock()).start_send(finality_grandpa::Message::Prevote(prevote)).unwrap(); + } 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 { + finality_grandpa::Message::Prevote(prevote) => prevote, + _ => panic!("We should receive our own prevote."), + }; + + // targeting block 30 + assert!(prevote.target_number == 30); + + // after alice restarts it should send its previous prevote + // therefore we won't ever receive it again since it will be a + // known message on the gossip layer + + } else if state.compare_and_swap(2, 3, Ordering::SeqCst) == 2 { + // we then receive a precommit from alice for block 15 + // even though we casted a prevote for block 30 + let precommit = match signed.message { + finality_grandpa::Message::Precommit(precommit) => precommit, + _ => panic!("voter should precommit."), + }; + + assert!(precommit.target_number == 15); + + // signal exit + exit_tx.clone().lock().take().unwrap().send(()).unwrap(); + } else { + panic!() + } } - - }).map_err(|_| ())); + }).map(Ok).boxed().compat()); } - let drive_to_completion = futures::future::poll_fn(|| { net.lock().poll(); Ok(Async::NotReady) }); - let exit = exit_rx.into_future().map(|_| ()).map_err(|_| ()); - - runtime.block_on(drive_to_completion.select(exit).map(|_| ()).map_err(|_| ())).unwrap(); + block_until_complete(exit_rx.into_future(), &net, &mut runtime); } #[test] 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 threads_pool = futures::executor::ThreadPool::new().unwrap(); let authorities = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let voters = make_ids(authorities); @@ -1416,9 +1400,8 @@ fn finalize_3_voters_1_light_observer() { let link = net.lock().peer(3).data.lock().take().expect("link initialized on startup; qed"); let finality_notifications = net.lock().peer(3).client().finality_notification_stream() - .map(|v| Ok::<_, ()>(v)).compat() - .take_while(|n| Ok(n.header.number() < &20)) - .collect(); + .take_while(|n| future::ready(n.header.number() < &20)) + .collect::>(); run_to_completion_with(&mut runtime, &threads_pool, 20, net.clone(), authorities, |executor| { executor.spawn( @@ -1435,10 +1418,10 @@ fn finalize_3_voters_1_light_observer() { net.lock().peers[3].network_service().clone(), Exit, threads_pool.clone(), - ).unwrap() + ).unwrap().unit_error().compat() ).unwrap(); - Some(Box::new(finality_notifications.map(|_| ()))) + Some(Box::pin(finality_notifications.map(|_| ()))) }); } @@ -1446,7 +1429,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 threads_pool = futures::executor::ThreadPool::new().unwrap(); let peers = &[Ed25519Keyring::Alice]; let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 1); @@ -1460,14 +1443,15 @@ fn finality_proof_is_fetched_by_light_client_when_consensus_data_changes() { net.lock().block_until_sync(&mut runtime); // check that the block#1 is finalized on light client - runtime.block_on(futures::future::poll_fn(move || -> std::result::Result<_, ()> { + let mut runtime = current_thread::Runtime::new().unwrap(); + let _ = runtime.block_on(futures::future::poll_fn(move |_| { if net.lock().peer(1).client().info().finalized_number == 1 { - Ok(Async::Ready(())) + Poll::Ready(()) } else { net.lock().poll(); - Ok(Async::NotReady) + Poll::Pending } - })).unwrap() + }).unit_error().compat()); } #[test] @@ -1477,7 +1461,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(); + let threads_pool = futures::executor::ThreadPool::new().unwrap(); // two of these guys are offline. let genesis_authorities = if FORCE_CHANGE { @@ -1542,7 +1526,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 threads_pool = futures::executor::ThreadPool::new().unwrap(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob]; let voters = make_ids(peers); @@ -1554,7 +1538,7 @@ fn voter_catches_up_to_latest_round_when_behind() { let net = Arc::new(Mutex::new(net)); let mut finality_notifications = Vec::new(); - let voter = |keystore, peer_id, link, net: Arc>| -> Box + Send> { + let voter = |keystore, peer_id, link, net: Arc>| -> Pin + Send>> { let grandpa_params = GrandpaParams { config: Config { gossip_duration: TEST_GOSSIP_DURATION, @@ -1573,7 +1557,7 @@ fn voter_catches_up_to_latest_round_when_behind() { executor: threads_pool.clone(), }; - Box::new(run_grandpa_voter(grandpa_params).expect("all in order with client and network")) + Box::pin(run_grandpa_voter(grandpa_params).expect("all in order with client and network")) }; let mut keystore_paths = Vec::new(); @@ -1591,9 +1575,8 @@ fn voter_catches_up_to_latest_round_when_behind() { finality_notifications.push( client.finality_notification_stream() - .map(|v| Ok::<_, ()>(v)).compat() - .take_while(|n| Ok(n.header.number() < &50)) - .for_each(move |_| Ok(())) + .take_while(|n| future::ready(n.header.number() < &50)) + .for_each(move |_| future::ready(())) ); let (keystore, keystore_path) = create_keystore(*key); @@ -1601,14 +1584,13 @@ fn voter_catches_up_to_latest_round_when_behind() { let voter = voter(Some(keystore), peer_id, link, net.clone()); - runtime.spawn(voter); + runtime.spawn(voter.unit_error().compat()); } // wait for them to finalize block 50. since they'll vote on 3/4 of the // unfinalized chain it will take at least 4 rounds to do it. let wait_for_finality = ::futures::future::join_all(finality_notifications) - .map(|_| ()) - .map_err(|_| ()); + .map(|_| ()); // spawn a new voter, it should be behind by at least 4 rounds and should be // able to catch up to the latest round @@ -1616,7 +1598,7 @@ fn voter_catches_up_to_latest_round_when_behind() { let net = net.clone(); let runtime = runtime.handle(); - wait_for_finality.and_then(move |_| { + wait_for_finality.then(move |_| { let peer_id = 2; let link = { let net = net.lock(); @@ -1628,20 +1610,20 @@ fn voter_catches_up_to_latest_round_when_behind() { let voter = voter(None, peer_id, link, net); - runtime.spawn(voter).unwrap(); + runtime.spawn(voter.unit_error().compat()).unwrap(); let start_time = std::time::Instant::now(); let timeout = Duration::from_secs(5 * 60); - let wait_for_catch_up = futures::future::poll_fn(move || { + let wait_for_catch_up = futures::future::poll_fn(move |_| { // The voter will start at round 1 and since everyone else is // already at a later round the only way to get to round 4 (or // later) is by issuing a catch up request. if set_state.read().last_completed_round().number >= 4 { - Ok(Async::Ready(())) + Poll::Ready(()) } else if start_time.elapsed() > timeout { panic!("Timed out while waiting for catch up to happen") } else { - Ok(Async::NotReady) + Poll::Pending } }); @@ -1649,8 +1631,14 @@ fn voter_catches_up_to_latest_round_when_behind() { }) }; - let drive_to_completion = futures::future::poll_fn(|| { net.lock().poll(); Ok(Async::NotReady) }); - let _ = runtime.block_on(test.select(drive_to_completion).map_err(|_| ())).unwrap(); + let drive_to_completion = futures01::future::poll_fn(|| { + net.lock().poll(); Ok::, ()>(Async::NotReady) + }); + runtime.block_on( + future::select(test, drive_to_completion.compat()) + .map(|_| Ok::<(), ()>(())) + .compat() + ).unwrap(); } #[test] @@ -1658,7 +1646,7 @@ fn grandpa_environment_respects_voting_rules() { use finality_grandpa::Chain; use sc_network_test::TestClient; - let threads_pool = futures03::executor::ThreadPool::new().unwrap(); + let threads_pool = futures::executor::ThreadPool::new().unwrap(); let peers = &[Ed25519Keyring::Alice]; let voters = make_ids(peers); diff --git a/client/finality-grandpa/src/until_imported.rs b/client/finality-grandpa/src/until_imported.rs index f53b651bcf..c3a52fcf56 100644 --- a/client/finality-grandpa/src/until_imported.rs +++ b/client/finality-grandpa/src/until_imported.rs @@ -33,13 +33,15 @@ use sc_client_api::{BlockImportNotification, ImportNotifications}; use futures::prelude::*; use futures::stream::Fuse; use futures_timer::Delay; -use futures03::{StreamExt as _, TryStreamExt as _}; +use futures::channel::mpsc::UnboundedReceiver; use finality_grandpa::voter; use parking_lot::Mutex; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; use std::collections::{HashMap, VecDeque}; +use std::pin::Pin; use std::sync::{atomic::{AtomicUsize, Ordering}, Arc}; +use std::task::{Context, Poll}; use std::time::{Duration, Instant}; use sp_finality_grandpa::AuthorityId; @@ -70,13 +72,15 @@ pub(crate) trait BlockUntilImported: Sized { } /// Buffering imported messages until blocks with given hashes are imported. +#[pin_project::pin_project] pub(crate) struct UntilImported> { - import_notifications: Fuse, Error = ()> + Send>>, + import_notifications: Fuse>>, block_sync_requester: BlockSyncRequester, status_check: BlockStatus, + #[pin] inner: Fuse, ready: VecDeque, - check_pending: Box + Send>, + check_pending: Pin> + 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. @@ -87,8 +91,9 @@ pub(crate) struct UntilImported UntilImported where Block: BlockT, BlockStatus: BlockStatusT, + BlockSyncRequester: BlockSyncRequesterT, + I: Stream, M: BlockUntilImported, - I: Stream, { /// Create a new `UntilImported` wrapper. pub(crate) fn new( @@ -105,22 +110,19 @@ impl UntilImported _>(|v| Ok::<_, ()>(v)).compat(); - Box::new(stream) as Box + Send> - }.fuse(), + import_notifications: import_notifications.fuse(), block_sync_requester, status_check, inner: stream.fuse(), ready: VecDeque::new(), - check_pending: Box::new(check_pending), + check_pending: Box::pin(check_pending), pending: HashMap::new(), identifier, } @@ -131,24 +133,27 @@ impl Stream for UntilImported, BSyncRequester: BlockSyncRequesterT, - I: Stream, + I: Stream, M: BlockUntilImported, { - type Item = M::Blocked; - type Error = Error; + type Item = Result; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + // We are using a `this` variable in order to allow multiple simultaneous mutable borrow + // to `self`. + let mut this = self.project(); - fn poll(&mut self) -> Poll, Error> { loop { - match self.inner.poll()? { - Async::Ready(None) => return Ok(Async::Ready(None)), - Async::Ready(Some(input)) => { + match Stream::poll_next(Pin::new(&mut this.inner), cx) { + Poll::Ready(None) => return Poll::Ready(None), + Poll::Ready(Some(input)) => { // new input: schedule wait of any parts which require // blocks to be known. - let ready = &mut self.ready; - let pending = &mut self.pending; + let ready = &mut this.ready; + let pending = &mut this.pending; M::schedule_wait( input, - &self.status_check, + this.status_check, |target_hash, target_number, wait| pending .entry(target_hash) .or_insert_with(|| (target_number, Instant::now(), Vec::new())) @@ -157,37 +162,36 @@ impl Stream for UntilImported break, + Poll::Pending => break, } } loop { - match self.import_notifications.poll() { - Err(_) => return Err(Error::Network(format!("Failed to get new message"))), - Ok(Async::Ready(None)) => return Ok(Async::Ready(None)), - Ok(Async::Ready(Some(notification))) => { + match Stream::poll_next(Pin::new(&mut this.import_notifications), cx) { + Poll::Ready(None) => return Poll::Ready(None), + Poll::Ready(Some(notification)) => { // new block imported. queue up all messages tied to that hash. - if let Some((_, _, messages)) = self.pending.remove(¬ification.hash) { + if let Some((_, _, messages)) = this.pending.remove(¬ification.hash) { let canon_number = notification.header.number().clone(); let ready_messages = messages.into_iter() .filter_map(|m| m.wait_completed(canon_number)); - self.ready.extend(ready_messages); + this.ready.extend(ready_messages); } } - Ok(Async::NotReady) => break, + Poll::Pending => break, } } let mut update_interval = false; - while let Async::Ready(Some(_)) = self.check_pending.poll().map_err(Error::Timer)? { + while let Poll::Ready(Some(Ok(()))) = this.check_pending.poll_next_unpin(cx) { update_interval = true; } if update_interval { let mut known_keys = Vec::new(); - for (&block_hash, &mut (block_number, ref mut last_log, ref v)) in &mut self.pending { - if let Some(number) = self.status_check.block_number(block_hash)? { + for (&block_hash, &mut (block_number, ref mut last_log, ref v)) in this.pending.iter_mut() { + if let Some(number) = this.status_check.block_number(block_hash)? { known_keys.push((block_hash, number)); } else { let next_log = *last_log + LOG_PENDING_INTERVAL; @@ -199,13 +203,13 @@ impl Stream for UntilImported Stream for UntilImported { target_number: NumberFor, } +impl Unpin for BlockGlobalMessage {} + impl BlockUntilImported for BlockGlobalMessage { type Blocked = CommunicationIn; @@ -474,13 +480,12 @@ pub(crate) type UntilGlobalMessageBlocksImported( @@ -615,13 +619,13 @@ mod tests { let (chain_state, import_notifications) = TestChainState::new(); let block_status = chain_state.block_status(); - let (global_tx, global_rx) = futures::sync::mpsc::unbounded(); + let (global_tx, global_rx) = futures::channel::mpsc::unbounded(); let until_imported = UntilGlobalMessageBlocksImported::new( import_notifications, TestBlockSyncRequester::default(), block_status, - global_rx.map_err(|_| panic!("should never error")), + global_rx, "global", ); @@ -630,13 +634,10 @@ mod tests { // NOTE: needs to be cloned otherwise it is moved to the stream and // dropped too early. let inner_chain_state = chain_state.clone(); - let work = until_imported - .into_future() - .select2(Delay::new(Duration::from_millis(100)).unit_error().compat()) + let work = future::select(until_imported.into_future(), Delay::new(Duration::from_millis(100))) .then(move |res| match res { - Err(_) => panic!("neither should have had error"), - Ok(Either::A(_)) => panic!("timeout should have fired first"), - Ok(Either::B((_, until_imported))) => { + Either::Left(_) => panic!("timeout should have fired first"), + Either::Right((_, until_imported)) => { // timeout fired. push in the headers. enact_dependencies(&inner_chain_state); @@ -644,8 +645,7 @@ mod tests { } }); - let mut runtime = Runtime::new().unwrap(); - runtime.block_on(work).map_err(|(e, _)| e).unwrap().0.unwrap() + futures::executor::block_on(work).0.unwrap().unwrap() } #[test] @@ -871,7 +871,7 @@ mod tests { let (chain_state, import_notifications) = TestChainState::new(); let block_status = chain_state.block_status(); - let (global_tx, global_rx) = futures::sync::mpsc::unbounded(); + let (global_tx, global_rx) = futures::channel::mpsc::unbounded(); let block_sync_requester = TestBlockSyncRequester::default(); @@ -879,7 +879,7 @@ mod tests { import_notifications, block_sync_requester.clone(), block_status, - global_rx.map_err(|_| panic!("should never error")), + global_rx, "global", ); @@ -914,31 +914,31 @@ mod tests { // we send the commit message and spawn the until_imported stream global_tx.unbounded_send(unknown_commit()).unwrap(); - let mut runtime = Runtime::new().unwrap(); - runtime.spawn(until_imported.into_future().map(|_| ()).map_err(|_| ())); + let threads_pool = futures::executor::ThreadPool::new().unwrap(); + threads_pool.spawn_ok(until_imported.into_future().map(|_| ())); // assert that we will make sync requests - let assert = futures::future::poll_fn::<(), (), _>(|| { + let assert = futures::future::poll_fn(|_| { let block_sync_requests = block_sync_requester.requests.lock(); // we request blocks targeted by the precommits that aren't imported if block_sync_requests.contains(&(h2.hash(), *h2.number())) && block_sync_requests.contains(&(h3.hash(), *h3.number())) { - return Ok(Async::Ready(())); + return Poll::Ready(()); } - Ok(Async::NotReady) + Poll::Pending }); // the `until_imported` stream doesn't request the blocks immediately, // but it should request them after a small timeout - 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"), - }).map_err(|_| ()); + let timeout = Delay::new(Duration::from_secs(60)); + let test = future::select(assert, timeout).map(|res| match res { + Either::Left(_) => {}, + Either::Right(_) => panic!("timed out waiting for block sync request"), + }).map(drop); - runtime.block_on(test).unwrap(); + futures::executor::block_on(test); } } diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 194bd09e24..caf97438ad 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -1067,7 +1067,7 @@ ServiceBuilder< has_bootnodes, ), exit.clone()).map(drop))); - let telemetry_connection_sinks: Arc>>> = Default::default(); + let telemetry_connection_sinks: Arc>>> = Default::default(); // Telemetry let telemetry = config.telemetry_endpoints.clone().map(|endpoints| { diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 1b2e7bcd3c..57e1462f64 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -100,7 +100,7 @@ pub struct Service { rpc_handlers: sc_rpc_server::RpcHandler, _rpc: Box, _telemetry: Option, - _telemetry_on_connect_sinks: Arc>>>, + _telemetry_on_connect_sinks: Arc>>>, _offchain_workers: Option>, keystore: sc_keystore::KeyStorePtr, marker: PhantomData, @@ -153,7 +153,7 @@ pub trait AbstractService: 'static + Future> + type NetworkSpecialization: NetworkSpecialization; /// Get event stream for telemetry connection established events. - fn telemetry_on_connect_stream(&self) -> mpsc::UnboundedReceiver<()>; + fn telemetry_on_connect_stream(&self) -> futures::channel::mpsc::UnboundedReceiver<()>; /// return a shared instance of Telemetry (if enabled) fn telemetry(&self) -> Option; @@ -224,8 +224,8 @@ where type TransactionPool = TExPool; type NetworkSpecialization = TNetSpec; - fn telemetry_on_connect_stream(&self) -> mpsc::UnboundedReceiver<()> { - let (sink, stream) = mpsc::unbounded(); + fn telemetry_on_connect_stream(&self) -> futures::channel::mpsc::UnboundedReceiver<()> { + let (sink, stream) = futures::channel::mpsc::unbounded(); self._telemetry_on_connect_sinks.lock().push(sink); stream } -- GitLab From 6ae4f5956b871fb8c6fbf3261e12c9c8ccb80e7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 24 Jan 2020 13:38:45 +0100 Subject: [PATCH 014/180] Deposit event on `frame-system::set_code` (#4726) * Deposit event on `frame-system::set_code` * Update frame/system/src/lib.rs Co-authored-by: thiolliere --- frame/system/src/lib.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 478fd780b9..ac51ef70e3 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -281,6 +281,7 @@ decl_module! { } storage::unhashed::put_raw(well_known_keys::CODE, &code); + Self::deposit_event(Event::CodeUpdated); } /// Set the new runtime code without doing any checks of the given `code`. @@ -288,6 +289,7 @@ decl_module! { pub fn set_code_without_checks(origin, code: Vec) { ensure_root(origin)?; storage::unhashed::put_raw(well_known_keys::CODE, &code); + Self::deposit_event(Event::CodeUpdated); } /// Set the new changes trie configuration. @@ -364,6 +366,8 @@ decl_event!( ExtrinsicSuccess(DispatchInfo), /// An extrinsic failed. ExtrinsicFailed(DispatchError, DispatchInfo), + /// `:code` was updated. + CodeUpdated, } ); @@ -1282,6 +1286,7 @@ mod tests { match e { Event::ExtrinsicSuccess(..) => 100, Event::ExtrinsicFailed(..) => 101, + Event::CodeUpdated => 102, } } } @@ -1688,6 +1693,11 @@ mod tests { RawOrigin::Root.into(), substrate_test_runtime_client::runtime::WASM_BINARY.to_vec(), ).unwrap(); + + assert_eq!( + System::events(), + vec![EventRecord { phase: Phase::ApplyExtrinsic(0), event: 102u16, topics: vec![] }], + ); }); } } -- GitLab From e2eda0e5634a1d2b9fc0133398758426e9a82a9d Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Fri, 24 Jan 2020 05:22:39 -0800 Subject: [PATCH 015/180] Async/await in transaction-graph (#4645) * async/await in tx graph * review notes * remove unused typedef --- client/transaction-pool/graph/src/pool.rs | 229 ++++++++++------------ client/transaction-pool/src/lib.rs | 34 +++- primitives/transaction-pool/src/pool.rs | 37 ++-- 3 files changed, 144 insertions(+), 156 deletions(-) diff --git a/client/transaction-pool/graph/src/pool.rs b/client/transaction-pool/graph/src/pool.rs index 5be879f079..d0f14ad40a 100644 --- a/client/transaction-pool/graph/src/pool.rs +++ b/client/transaction-pool/graph/src/pool.rs @@ -27,7 +27,6 @@ use serde::Serialize; use futures::{ Future, FutureExt, channel::mpsc, - future::{Either, ready, join_all}, }; use sp_runtime::{ generic::BlockId, @@ -132,8 +131,8 @@ impl Pool { } /// Imports a bunch of unverified extrinsics to the pool - pub fn submit_at(&self, at: &BlockId, xts: T, force: bool) - -> impl Future, B::Error>>, B::Error>> + pub async fn submit_at(&self, at: &BlockId, xts: T, force: bool) + -> Result, B::Error>>, B::Error> where T: IntoIterator> { @@ -143,48 +142,43 @@ impl Pool { .map(|validated_transactions| validated_pool.submit(validated_transactions .into_iter() .map(|(_, tx)| tx)))) + .await } /// Imports one unverified extrinsic to the pool - pub fn submit_one( + pub async fn submit_one( &self, at: &BlockId, xt: ExtrinsicFor, - ) -> impl Future, B::Error>> { + ) -> Result, B::Error> { self.submit_at(at, std::iter::once(xt), false) .map(|import_result| import_result.and_then(|mut import_result| import_result .pop() .expect("One extrinsic passed; one result returned; qed") )) + .await } /// Import a single extrinsic and starts to watch their progress in the pool. - pub fn submit_and_watch( + pub async fn submit_and_watch( &self, at: &BlockId, xt: ExtrinsicFor, - ) -> impl Future, BlockHash>, B::Error>> { - let block_number = match self.resolve_block_number(at) { - Ok(block_number) => block_number, - Err(err) => return Either::Left(ready(Err(err))) - }; - - 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.1)) - ) + ) -> Result, BlockHash>, B::Error> { + let block_number = self.resolve_block_number(at)?; + let (_, tx) = self.verify_one(at, block_number, xt, false).await; + self.validated_pool.submit_and_watch(tx) } /// 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( + pub async fn revalidate_ready( &self, at: &BlockId, max: Option, - ) -> impl Future> { + ) -> Result<(), B::Error> { use std::time::Instant; log::debug!(target: "txpool", "Fetching ready transactions (up to: {})", @@ -196,23 +190,20 @@ impl Pool { .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 - }) + let revalidated_transactions = self.verify(at, ready, false).await?; + log::debug!(target: "txpool", + "Re-verified transactions, took {} ms. Resubmitting.", + now.elapsed().as_millis() + ); + + let now = Instant::now(); + self.validated_pool.resubmit(revalidated_transactions); + log::debug!(target: "txpool", + "Resubmitted. Took {} ms. Status: {:?}", + now.elapsed().as_millis(), + validated_pool.status() + ); + Ok(()) } /// Prunes known ready transactions. @@ -238,12 +229,12 @@ impl Pool { /// To perform pruning we need the tags that each extrinsic provides and to avoid calling /// into runtime too often we first lookup all extrinsics that are in the pool and get /// their provided tags from there. Otherwise we query the runtime at the `parent` block. - pub fn prune( + pub async fn prune( &self, at: &BlockId, parent: &BlockId, extrinsics: &[ExtrinsicFor], - ) -> impl Future> { + ) -> Result<(), B::Error> { log::debug!( target: "txpool", "Starting pruning of block {:?} (extrinsics: {})", @@ -257,34 +248,26 @@ impl Pool { // 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()); - // Prepare future that collect tags for all extrinsics - let future_tags = join_all(all - .map(|(extrinsic, in_pool_tags)| - match in_pool_tags { - // reuse the tags for extrinsics that were found in the pool - Some(tags) => Either::Left( - ready(tags) - ), - // if it's not found in the pool query the runtime at parent block - // to get validity info and tags that the extrinsic provides. - None => Either::Right(self.validated_pool.api().validate_transaction(parent, extrinsic.clone()) - .then(|validity| ready(match validity { - Ok(Ok(validity)) => validity.provides, - // silently ignore invalid extrinsics, - // cause they might just be inherent - _ => Vec::new(), - }))), - } - )); + let mut future_tags = Vec::new(); + for (extrinsic, in_pool_tags) in all { + match in_pool_tags { + // reuse the tags for extrinsics that were found in the pool + Some(tags) => future_tags.extend(tags), + // if it's not found in the pool query the runtime at parent block + // to get validity info and tags that the extrinsic provides. + None => { + let validity = self.validated_pool.api() + .validate_transaction(parent, extrinsic.clone()) + .await; + + if let Ok(Ok(validity)) = validity { + future_tags.extend(validity.provides); + } + }, + } + } - // Prune transactions by tags - let at = at.clone(); - let self_clone = self.clone(); - future_tags.then(move |tags| self_clone.prune_tags( - &at, - tags.into_iter().flat_map(|tags| tags), - in_pool_hashes, - )) + self.prune_tags(at, future_tags, in_pool_hashes).await } /// Prunes ready transactions that provide given list of tags. @@ -308,17 +291,17 @@ impl Pool { /// the second parameter of `known_imported_hashes`. These transactions /// (if pruned) are not revalidated and become temporarily banned to /// prevent importing them in the (near) future. - pub fn prune_tags( + pub async fn prune_tags( &self, at: &BlockId, tags: impl IntoIterator, known_imported_hashes: impl IntoIterator> + Clone, - ) -> impl Future> { + ) -> Result<(), B::Error> { 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, - Err(e) => return Either::Left(ready(Err(e))), + Err(e) => return Err(e), }; // Make sure that we don't revalidate extrinsics that were part of the recently @@ -330,21 +313,18 @@ impl Pool { // note that `known_imported_hashes` will be rejected here due to temporary ban. let pruned_hashes = prune_status.pruned.iter().map(|tx| tx.hash.clone()).collect::>(); let pruned_transactions = prune_status.pruned.into_iter().map(|tx| tx.data.clone()); - let reverify_future = self.verify(at, pruned_transactions, false); + + let reverified_transactions = self.verify(at, pruned_transactions, false).await?; log::trace!(target: "txpool", "Prunning at {:?}. Resubmitting transactions.", at); // And finally - submit reverified transactions back to the pool - let at = at.clone(); - let validated_pool = self.validated_pool.clone(); - Either::Right(reverify_future.then(move |reverified_transactions| - ready(reverified_transactions.and_then(|reverified_transactions| - validated_pool.resubmit_pruned( - &at, - known_imported_hashes, - pruned_hashes, - reverified_transactions.into_iter().map(|(_, xt)| xt).collect(), - )) - ))) + + self.validated_pool.resubmit_pruned( + &at, + known_imported_hashes, + pruned_hashes, + reverified_transactions.into_iter().map(|(_, xt)| xt).collect(), + ) } /// Return an event stream of notifications for when transactions are imported to the pool. @@ -388,69 +368,74 @@ impl Pool { } /// Returns future that validates a bunch of transactions at given block. - fn verify( + async fn verify( &self, at: &BlockId, xts: impl IntoIterator>, force: bool, - ) -> impl Future, ValidatedTransactionFor>, B::Error>> { + ) -> Result, 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, - Err(err) => return Either::Left(ready(Err(err))), - }; + let block_number = self.resolve_block_number(at)?; + let mut result = HashMap::new(); - // for each xt, prepare a validation future - let validation_futures = xts.into_iter().map(move |xt| - self.verify_one(at, block_number, xt, force) - ); + for xt in xts { + let (hash, validated_tx) = self.verify_one(at, block_number, xt, force).await; + result.insert(hash, validated_tx); + } - // make single validation future that waits all until all extrinsics are validated - Either::Right(join_all(validation_futures).then(|x| ready(Ok(x.into_iter().collect())))) + Ok(result) } /// Returns future that validates single transaction at given block. - fn verify_one( + async fn verify_one( &self, block_id: &BlockId, block_number: NumberFor, xt: ExtrinsicFor, force: bool, - ) -> impl Future, ValidatedTransactionFor)> { + ) -> (ExHash, ValidatedTransactionFor) { let (hash, bytes) = self.validated_pool.api().hash_and_length(&xt); if !force && self.validated_pool.is_banned(&hash) { - return Either::Left(ready(( + return ( 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((hash.clone(), match validation_result { - Ok(validity) => match validity { - Ok(validity) => if validity.provides.is_empty() { - ValidatedTransaction::Invalid(hash, error::Error::NoTagsProvided.into()) - } else { - ValidatedTransaction::Valid(base::Transaction { - data: xt, - bytes, - hash, - priority: validity.priority, - requires: validity.requires, - provides: validity.provides, - propagate: validity.propagate, - valid_till: block_number - .saturated_into::() - .saturating_add(validity.longevity), - }) - }, - Err(TransactionValidityError::Invalid(e)) => - ValidatedTransaction::Invalid(hash, error::Error::InvalidTransaction(e).into()), - Err(TransactionValidityError::Unknown(e)) => - ValidatedTransaction::Unknown(hash, error::Error::UnknownTransaction(e).into()), - }, - Err(e) => ValidatedTransaction::Invalid(hash, e), - })))) + let validation_result = self.validated_pool.api().validate_transaction(block_id, xt.clone()).await; + + let status = match validation_result { + Ok(status) => status, + Err(e) => return (hash.clone(), ValidatedTransaction::Invalid(hash, e)), + }; + + let validity = match status { + Ok(validity) => { + if validity.provides.is_empty() { + ValidatedTransaction::Invalid(hash.clone(), error::Error::NoTagsProvided.into()) + } else { + ValidatedTransaction::Valid(base::Transaction { + data: xt, + bytes, + hash: hash.clone(), + priority: validity.priority, + requires: validity.requires, + provides: validity.provides, + propagate: validity.propagate, + valid_till: block_number + .saturated_into::() + .saturating_add(validity.longevity), + }) + } + }, + + Err(TransactionValidityError::Invalid(e)) => + ValidatedTransaction::Invalid(hash.clone(), error::Error::InvalidTransaction(e).into()), + Err(TransactionValidityError::Unknown(e)) => + ValidatedTransaction::Unknown(hash.clone(), error::Error::UnknownTransaction(e).into()), + }; + + (hash, validity) } } diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index f6f7774935..b085dba279 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -39,9 +39,11 @@ use sp_runtime::{ use sp_transaction_pool::{ TransactionPool, PoolStatus, ImportNotificationStream, TxHash, TransactionFor, TransactionStatusStreamFor, BlockHash, - MaintainedTransactionPool, + MaintainedTransactionPool, PoolFuture, }; +type PoolResult = PoolFuture; + /// Basic implementation of transaction pool that can be customized by providing PoolApi. pub struct BasicPool where @@ -129,28 +131,40 @@ impl TransactionPool for BasicPool 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)) + xts: Vec>, + ) -> PoolResult, Self::Error>>> { + let pool = self.pool.clone(); + let at = *at; + async move { + pool.submit_at(&at, xts, false).await + }.boxed() } fn submit_one( &self, at: &BlockId, xt: TransactionFor, - ) -> Box, Self::Error>> + Send + Unpin> { - Box::new(self.pool.submit_one(at, xt)) + ) -> PoolResult> { + let pool = self.pool.clone(); + let at = *at; + async move { + pool.submit_one(&at, xt).await + }.boxed() } fn submit_and_watch( &self, at: &BlockId, xt: TransactionFor, - ) -> Box>, Self::Error>> + Send + Unpin> { - Box::new( - self.pool.submit_and_watch(at, xt) + ) -> PoolResult>> { + let at = *at; + let pool = self.pool.clone(); + + async move { + pool.submit_and_watch(&at, xt) .map(|result| result.map(|watcher| Box::new(watcher.into_stream()) as _)) - ) + .await + }.boxed() } fn remove_invalid(&self, hashes: &[TxHash]) -> Vec> { diff --git a/primitives/transaction-pool/src/pool.rs b/primitives/transaction-pool/src/pool.rs index ed24ad0619..92a0c4b5c3 100644 --- a/primitives/transaction-pool/src/pool.rs +++ b/primitives/transaction-pool/src/pool.rs @@ -124,6 +124,9 @@ pub type TransactionFor

= <

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

= TransactionStatusStream, BlockHash

>; +/// Typical future type used in transaction pool api. +pub type PoolFuture = std::pin::Pin> + Send>>; + /// In-pool transaction interface. /// /// The pool is container of transactions that are implementing this trait. @@ -170,55 +173,41 @@ pub trait TransactionPool: Send + Sync { fn submit_at( &self, at: &BlockId, - xts: impl IntoIterator> + 'static, - ) -> Box, Self::Error>>, - Self::Error - >> + Send + Unpin>; + xts: Vec>, + ) -> PoolFuture, Self::Error>>, Self::Error>; /// Returns a future that imports one unverified transaction to the pool. fn submit_one( &self, at: &BlockId, xt: TransactionFor, - ) -> Box, - Self::Error - >> + Send + Unpin>; - - // RPC + ) -> PoolFuture, Self::Error>; + // *** RPC /// 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>; - - - // Block production / Networking + ) -> PoolFuture>, Self::Error>; + // *** Block production / Networking /// Get an iterator for ready transactions ordered by priority fn ready(&self) -> Box>>; - - // Block production - + // *** Block production /// Remove transactions identified by given hashes (and dependent transactions) from the pool. fn remove_invalid(&self, hashes: &[TxHash]) -> Vec>; - // logging - + // *** logging /// Returns pool status. fn status(&self) -> PoolStatus; - // logging / RPC / networking - + // *** logging / RPC / networking /// Return an event stream of transactions imported to the pool. fn import_notification_stream(&self) -> ImportNotificationStream; - // networking - + // *** networking /// Notify the pool about transactions broadcast. fn on_broadcasted(&self, propagations: HashMap, Vec>); -- GitLab From 82428e085759e6727d965492d30e91785d861f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 24 Jan 2020 15:20:45 +0100 Subject: [PATCH 016/180] Introduces `author_hasKey` and `author_hasSessionKeys` rpc endpoints (#4720) * Introduces `author_hasKey` and `author_hasSessionKeys` rpc endpoints Both endpoints can be used to check if a key is present in the keystore. - `hasKey` works on with an individual public key and key type. It checks if a private key for the given combination exists in the keystore. - `hasSessionKeys` works with the full encoded session key blob stored on-chain in `nextKeys`. This requires that the given blob can be decoded by the runtime. It will return `true`, iff all public keys of the session key exist in the storage. Fixes: https://github.com/paritytech/substrate/issues/4696 * Update client/rpc-api/src/author/error.rs Co-Authored-By: Nikolay Volf * Indentation Co-authored-by: Nikolay Volf --- Cargo.lock | 1 + bin/node-template/runtime/src/lib.rs | 6 ++ bin/node/runtime/src/lib.rs | 6 ++ client/keystore/src/lib.rs | 50 +++++++++------- client/rpc-api/src/author/error.rs | 3 + client/rpc-api/src/author/mod.rs | 17 +++++- client/rpc/src/author/mod.rs | 16 +++++ client/rpc/src/author/tests.rs | 62 +++++++++++++++++++- primitives/application-crypto/src/ed25519.rs | 4 ++ primitives/application-crypto/src/lib.rs | 4 ++ primitives/application-crypto/src/sr25519.rs | 4 ++ primitives/application-crypto/src/traits.rs | 8 ++- primitives/core/src/crypto.rs | 4 +- primitives/core/src/testing.rs | 4 ++ primitives/core/src/traits.rs | 5 ++ primitives/offchain/src/lib.rs | 4 +- primitives/runtime/src/testing.rs | 4 ++ primitives/runtime/src/traits.rs | 33 +++++++++++ primitives/session/Cargo.toml | 3 +- primitives/session/src/lib.rs | 7 +++ test-utils/runtime/src/lib.rs | 12 ++++ 21 files changed, 223 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e69ee8e6e7..6ec2225830 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6642,6 +6642,7 @@ name = "sp-session" version = "2.0.0" dependencies = [ "sp-api 2.0.0", + "sp-core 2.0.0", "sp-runtime 2.0.0", "sp-std 2.0.0", ] diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 4416cbf13e..1276f20d17 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -360,6 +360,12 @@ impl_runtime_apis! { fn generate_session_keys(seed: Option>) -> Vec { opaque::SessionKeys::generate(seed) } + + fn decode_session_keys( + encoded: Vec, + ) -> Option, sp_core::crypto::KeyTypeId)>> { + opaque::SessionKeys::decode_into_raw_public_keys(&encoded) + } } impl fg_primitives::GrandpaApi for Runtime { diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index ecc16ee143..23cd7405dd 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -798,6 +798,12 @@ impl_runtime_apis! { fn generate_session_keys(seed: Option>) -> Vec { SessionKeys::generate(seed) } + + fn decode_session_keys( + encoded: Vec, + ) -> Option, sp_core::crypto::KeyTypeId)>> { + SessionKeys::decode_into_raw_public_keys(&encoded) + } } } diff --git a/client/keystore/src/lib.rs b/client/keystore/src/lib.rs index f8794aa05e..ef81c40c10 100644 --- a/client/keystore/src/lib.rs +++ b/client/keystore/src/lib.rs @@ -72,7 +72,8 @@ impl std::error::Error for Error { /// Every pair that is being generated by a `seed`, will be placed in memory. pub struct Store { path: Option, - additional: HashMap<(KeyTypeId, Vec), Vec>, + /// Map over `(KeyTypeId, Raw public key)` -> `Key phrase/seed` + additional: HashMap<(KeyTypeId, Vec), String>, password: Option>, } @@ -97,25 +98,22 @@ impl Store { })) } - /// Get the public/private key pair for the given public key and key type. - fn get_additional_pair( + /// Get the key phrase for the given public key and key type from the in-memory store. + fn get_additional_pair( &self, - public: &Pair::Public, + public: &[u8], key_type: KeyTypeId, - ) -> Result> { - let key = (key_type, public.to_raw_vec()); - self.additional - .get(&key) - .map(|bytes| Pair::from_seed_slice(bytes).map_err(|_| Error::InvalidSeed)) - .transpose() + ) -> Option<&String> { + let key = (key_type, public.to_vec()); + self.additional.get(&key) } /// Insert the given public/private key pair with the given key type. /// /// Does not place it into the file system store. - fn insert_ephemeral_pair(&mut self, pair: &Pair, key_type: KeyTypeId) { + fn insert_ephemeral_pair(&mut self, pair: &Pair, seed: &str, key_type: KeyTypeId) { let key = (key_type, pair.public().to_raw_vec()); - self.additional.insert(key, pair.to_raw_vec()); + self.additional.insert(key, seed.into()); } /// Insert a new key with anonymous crypto. @@ -179,7 +177,7 @@ impl Store { key_type: KeyTypeId, ) -> Result { let pair = Pair::from_string(seed, None).map_err(|_| Error::InvalidSeed)?; - self.insert_ephemeral_pair(&pair, key_type); + self.insert_ephemeral_pair(&pair, seed, key_type); Ok(pair) } @@ -190,20 +188,24 @@ impl Store { self.insert_ephemeral_from_seed_by_type::(seed, Pair::ID).map(Into::into) } + /// Get the key phrase for a given public key and key type. + fn key_phrase_by_type(&self, public: &[u8], key_type: KeyTypeId) -> Result { + if let Some(phrase) = self.get_additional_pair(public, key_type) { + return Ok(phrase.clone()) + } + + let path = self.key_file_path(public, key_type).ok_or_else(|| Error::Unavailable)?; + let file = File::open(path)?; + + serde_json::from_reader(&file).map_err(Into::into) + } + /// Get a key pair for the given public key and key type. pub fn key_pair_by_type(&self, public: &Pair::Public, key_type: KeyTypeId, ) -> Result { - if let Some(pair) = self.get_additional_pair(public, key_type)? { - return Ok(pair) - } - - let path = self.key_file_path(public.as_slice(), key_type) - .ok_or_else(|| Error::Unavailable)?; - let file = File::open(path)?; - - let phrase: String = serde_json::from_reader(&file)?; + let phrase = self.key_phrase_by_type(public.as_slice(), key_type)?; let pair = Pair::from_string( &phrase, self.password.as_ref().map(|p| &***p), @@ -328,6 +330,10 @@ impl BareCryptoStore for Store { fn password(&self) -> Option<&str> { self.password.as_ref().map(|x| x.as_str()) } + + fn has_keys(&self, public_keys: &[(Vec, KeyTypeId)]) -> bool { + public_keys.iter().all(|(p, t)| self.key_phrase_by_type(&p, *t).is_ok()) + } } #[cfg(test)] diff --git a/client/rpc-api/src/author/error.rs b/client/rpc-api/src/author/error.rs index 8ebd06f8de..f1b5691008 100644 --- a/client/rpc-api/src/author/error.rs +++ b/client/rpc-api/src/author/error.rs @@ -54,6 +54,9 @@ pub enum Error { /// Some random issue with the key store. Shouldn't happen. #[display(fmt="The key store is unavailable")] KeyStoreUnavailable, + /// Invalid session keys encoding. + #[display(fmt="Session keys are not encoded correctly")] + InvalidSessionKeys, } impl std::error::Error for Error { diff --git a/client/rpc-api/src/author/mod.rs b/client/rpc-api/src/author/mod.rs index cbdbd38154..4fbf0c73a3 100644 --- a/client/rpc-api/src/author/mod.rs +++ b/client/rpc-api/src/author/mod.rs @@ -39,7 +39,8 @@ pub trait AuthorApi { /// Insert a key into the keystore. #[rpc(name = "author_insertKey")] - fn insert_key(&self, + fn insert_key( + &self, key_type: String, suri: String, public: Bytes, @@ -49,6 +50,20 @@ pub trait AuthorApi { #[rpc(name = "author_rotateKeys")] fn rotate_keys(&self) -> Result; + /// Checks if the keystore has private keys for the given session public keys. + /// + /// `session_keys` is the SCALE encoded session keys object from the runtime. + /// + /// Returns `true` iff all private keys could be found. + #[rpc(name = "author_hasSessionKeys")] + fn has_session_keys(&self, session_keys: Bytes) -> Result; + + /// Checks if the keystore has private keys for the given public key and key type. + /// + /// Returns `true` if a private key could be found. + #[rpc(name = "author_hasKey")] + fn has_key(&self, public_key: Bytes, key_type: String) -> Result; + /// Returns all pending extrinsics, potentially grouped by sender. #[rpc(name = "author_pendingExtrinsics")] fn pending_extrinsics(&self) -> Result>; diff --git a/client/rpc/src/author/mod.rs b/client/rpc/src/author/mod.rs index 9891abc47d..06bdcf883c 100644 --- a/client/rpc/src/author/mod.rs +++ b/client/rpc/src/author/mod.rs @@ -112,6 +112,22 @@ where ).map(Into::into).map_err(|e| Error::Client(Box::new(e))) } + fn has_session_keys(&self, session_keys: Bytes) -> Result { + let best_block_hash = self.client.chain_info().best_hash; + let keys = self.client.runtime_api().decode_session_keys( + &generic::BlockId::Hash(best_block_hash), + session_keys.to_vec(), + ).map_err(|e| Error::Client(Box::new(e)))? + .ok_or_else(|| Error::InvalidSessionKeys)?; + + Ok(self.keystore.read().has_keys(&keys)) + } + + fn has_key(&self, public_key: Bytes, key_type: String) -> Result { + let key_type = key_type.as_str().try_into().map_err(|_| Error::BadKeyType)?; + Ok(self.keystore.read().has_keys(&[(public_key.to_vec(), key_type)])) + } + fn submit_extrinsic(&self, ext: Bytes) -> FutureResult> { let xt = match Decode::decode(&mut &ext[..]) { Ok(xt) => xt, diff --git a/client/rpc/src/author/tests.rs b/client/rpc/src/author/tests.rs index 9fe51d62f5..7de109bc5d 100644 --- a/client/rpc/src/author/tests.rs +++ b/client/rpc/src/author/tests.rs @@ -16,12 +16,12 @@ use super::*; -use std::sync::Arc; +use std::{mem, sync::Arc}; use assert_matches::assert_matches; use codec::Encode; use sp_core::{ - H256, blake2_256, hexdisplay::HexDisplay, testing::{ED25519, SR25519, KeyStore}, traits::BareCryptoStorePtr, ed25519, - crypto::Pair, + H256, blake2_256, hexdisplay::HexDisplay, testing::{ED25519, SR25519, KeyStore}, + traits::BareCryptoStorePtr, ed25519, crypto::{Pair, Public}, }; use rpc::futures::Stream as _; use substrate_test_runtime_client::{ @@ -237,3 +237,59 @@ fn should_rotate_keys() { assert_eq!(session_keys.ed25519, ed25519_key_pair.public().into()); assert_eq!(session_keys.sr25519, sr25519_key_pair.public().into()); } + +#[test] +fn test_has_session_keys() { + let setup = TestSetup::default(); + let p = setup.author(); + + let non_existent_public_keys = TestSetup::default() + .author() + .rotate_keys() + .expect("Rotates the keys"); + + let public_keys = p.rotate_keys().expect("Rotates the keys"); + let test_vectors = vec![ + (public_keys, Ok(true)), + (vec![1, 2, 3].into(), Err(Error::InvalidSessionKeys)), + (non_existent_public_keys, Ok(false)), + ]; + + for (keys, result) in test_vectors { + assert_eq!( + result.map_err(|e| mem::discriminant(&e)), + p.has_session_keys(keys).map_err(|e| mem::discriminant(&e)), + ); + } +} + +#[test] +fn test_has_key() { + let setup = TestSetup::default(); + let p = setup.author(); + + let suri = "//Alice"; + let alice_key_pair = ed25519::Pair::from_string(suri, None).expect("Generates keypair"); + p.insert_key( + String::from_utf8(ED25519.0.to_vec()).expect("Keytype is a valid string"), + suri.to_string(), + alice_key_pair.public().0.to_vec().into(), + ).expect("Insert key"); + let bob_key_pair = ed25519::Pair::from_string("//Bob", None).expect("Generates keypair"); + + let test_vectors = vec![ + (alice_key_pair.public().to_raw_vec().into(), ED25519, Ok(true)), + (alice_key_pair.public().to_raw_vec().into(), SR25519, Ok(false)), + (bob_key_pair.public().to_raw_vec().into(), ED25519, Ok(false)), + ]; + + for (key, key_type, result) in test_vectors { + assert_eq!( + result.map_err(|e| mem::discriminant(&e)), + p.has_key( + key, + String::from_utf8(key_type.0.to_vec()).expect("Keytype is a valid string"), + ).map_err(|e| mem::discriminant(&e)), + ); + } +} diff --git a/primitives/application-crypto/src/ed25519.rs b/primitives/application-crypto/src/ed25519.rs index c92c70495e..414715a106 100644 --- a/primitives/application-crypto/src/ed25519.rs +++ b/primitives/application-crypto/src/ed25519.rs @@ -53,4 +53,8 @@ impl RuntimePublic for Public { fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool { sp_io::crypto::ed25519_verify(&signature, msg.as_ref(), self) } + + fn to_raw_vec(&self) -> Vec { + sp_core::crypto::Public::to_raw_vec(self) + } } diff --git a/primitives/application-crypto/src/lib.rs b/primitives/application-crypto/src/lib.rs index db1bdf0c7a..fed4a6bf8e 100644 --- a/primitives/application-crypto/src/lib.rs +++ b/primitives/application-crypto/src/lib.rs @@ -301,6 +301,10 @@ macro_rules! app_crypto_public_common { fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool { <$public as $crate::RuntimePublic>::verify(self.as_ref(), msg, &signature.as_ref()) } + + fn to_raw_vec(&self) -> $crate::Vec { + <$public as $crate::RuntimePublic>::to_raw_vec(&self.0) + } } } } diff --git a/primitives/application-crypto/src/sr25519.rs b/primitives/application-crypto/src/sr25519.rs index 34d9797bd4..59c6f19b6f 100644 --- a/primitives/application-crypto/src/sr25519.rs +++ b/primitives/application-crypto/src/sr25519.rs @@ -53,4 +53,8 @@ impl RuntimePublic for Public { fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool { sp_io::crypto::sr25519_verify(&signature, msg.as_ref(), self) } + + fn to_raw_vec(&self) -> Vec { + sp_core::crypto::Public::to_raw_vec(self) + } } diff --git a/primitives/application-crypto/src/traits.rs b/primitives/application-crypto/src/traits.rs index 4b500bb2a6..2af039a88d 100644 --- a/primitives/application-crypto/src/traits.rs +++ b/primitives/application-crypto/src/traits.rs @@ -106,10 +106,13 @@ pub trait RuntimePublic: Sized { /// Verify that the given signature matches the given message using this public key. fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool; + + /// Returns `Self` as raw vec. + fn to_raw_vec(&self) -> Vec; } /// A runtime interface for an application's public key. -pub trait RuntimeAppPublic: Sized { +pub trait RuntimeAppPublic: Sized { /// An identifier for this application-specific key type. const ID: KeyTypeId; @@ -136,6 +139,9 @@ pub trait RuntimeAppPublic: Sized { /// Verify that the given signature matches the given message using this public key. fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool; + + /// Returns `Self` as raw vec. + fn to_raw_vec(&self) -> Vec; } /// Something that bound to a fixed `RuntimeAppPublic`. diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index ce2b75c375..3cc6c50f76 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -19,7 +19,6 @@ // end::description[] use sp_std::hash::Hash; -#[cfg(feature = "full_crypto")] use sp_std::vec::Vec; #[cfg(feature = "std")] use sp_std::convert::TryInto; @@ -520,8 +519,7 @@ pub trait Public: AsRef<[u8]> + AsMut<[u8]> + Default + Derive + CryptoType + Pa fn from_slice(data: &[u8]) -> Self; /// Return a `Vec` filled with raw data. - #[cfg(feature = "std")] - fn to_raw_vec(&self) -> Vec { self.as_slice().to_owned() } + fn to_raw_vec(&self) -> Vec { self.as_slice().to_vec() } /// Return a slice filled with raw data. fn as_slice(&self) -> &[u8] { self.as_ref() } diff --git a/primitives/core/src/testing.rs b/primitives/core/src/testing.rs index 35286acb63..0def3454bc 100644 --- a/primitives/core/src/testing.rs +++ b/primitives/core/src/testing.rs @@ -127,6 +127,10 @@ impl crate::traits::BareCryptoStore for KeyStore { fn password(&self) -> Option<&str> { None } + + fn has_keys(&self, public_keys: &[(Vec, KeyTypeId)]) -> bool { + public_keys.iter().all(|(k, t)| self.keys.get(&t).and_then(|s| s.get(k)).is_some()) + } } /// Macro for exporting functions from wasm in with the expected signature for using it with the diff --git a/primitives/core/src/traits.rs b/primitives/core/src/traits.rs index 020b5e2dc5..bd02d39fb5 100644 --- a/primitives/core/src/traits.rs +++ b/primitives/core/src/traits.rs @@ -69,6 +69,11 @@ pub trait BareCryptoStore: Send + Sync { /// Get the password for this store. fn password(&self) -> Option<&str>; + + /// Checks if the private keys for the given public key and key type combinations exist. + /// + /// Returns `true` iff all private keys could be found. + fn has_keys(&self, public_keys: &[(Vec, KeyTypeId)]) -> bool; } /// A pointer to the key store. diff --git a/primitives/offchain/src/lib.rs b/primitives/offchain/src/lib.rs index 1dd20db0dd..ae02fed496 100644 --- a/primitives/offchain/src/lib.rs +++ b/primitives/offchain/src/lib.rs @@ -19,8 +19,6 @@ #![cfg_attr(not(feature = "std"), no_std)] #![warn(missing_docs)] -use sp_runtime::traits::NumberFor; - /// Local Storage Prefix used by the Offchain Worker API to pub const STORAGE_PREFIX: &[u8] = b"storage"; @@ -31,7 +29,7 @@ sp_api::decl_runtime_apis! { /// Starts the off-chain task for given block number. #[skip_initialize_block] #[changed_in(2)] - fn offchain_worker(number: NumberFor); + fn offchain_worker(number: sp_runtime::traits::NumberFor); /// Starts the off-chain task for given block header. #[skip_initialize_block] diff --git a/primitives/runtime/src/testing.rs b/primitives/runtime/src/testing.rs index 516d581126..c86638b57b 100644 --- a/primitives/runtime/src/testing.rs +++ b/primitives/runtime/src/testing.rs @@ -115,6 +115,10 @@ impl sp_application_crypto::RuntimeAppPublic for UintAuthorityId { u64::from_le_bytes(msg_signature) == *signature } + + fn to_raw_vec(&self) -> Vec { + AsRef::<[u8]>::as_ref(self).to_vec() + } } impl OpaqueKeys for UintAuthorityId { diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 08bbd83ca5..7d889cae9b 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -1106,12 +1106,14 @@ macro_rules! count { #[macro_export] macro_rules! impl_opaque_keys { ( + $( #[ $attr:meta ] )* pub struct $name:ident { $( pub $field:ident: $type:ty, )* } ) => { + $( #[ $attr ] )* #[derive( Default, Clone, PartialEq, Eq, $crate::codec::Encode, @@ -1143,6 +1145,37 @@ macro_rules! impl_opaque_keys { }; $crate::codec::Encode::encode(&keys) } + + /// Converts `Self` into a `Vec` of `(raw public key, KeyTypeId)`. + pub fn into_raw_public_keys( + self, + ) -> $crate::sp_std::vec::Vec<($crate::sp_std::vec::Vec, $crate::KeyTypeId)> { + let mut keys = Vec::new(); + $( + keys.push(( + $crate::RuntimeAppPublic::to_raw_vec(&self.$field), + < + < + $type as $crate::BoundToRuntimeAppPublic + >::Public as $crate::RuntimeAppPublic + >::ID, + )); + )* + + keys + } + + /// Decode `Self` from the given `encoded` slice and convert `Self` into the raw public + /// keys (see [`Self::into_raw_public_keys`]). + /// + /// Returns `None` when the decoding failed, otherwise `Some(_)`. + pub fn decode_into_raw_public_keys( + encoded: &[u8], + ) -> Option<$crate::sp_std::vec::Vec<($crate::sp_std::vec::Vec, $crate::KeyTypeId)>> { + ::decode(&mut &encoded[..]) + .ok() + .map(|s| s.into_raw_public_keys()) + } } impl $crate::traits::OpaqueKeys for $name { diff --git a/primitives/session/Cargo.toml b/primitives/session/Cargo.toml index b7c72e0c68..24475e9414 100644 --- a/primitives/session/Cargo.toml +++ b/primitives/session/Cargo.toml @@ -7,8 +7,9 @@ edition = "2018" [dependencies] sp-api = { version = "2.0.0", default-features = false, path = "../api" } sp-std = { version = "2.0.0", default-features = false, path = "../std" } +sp-core = { version = "2.0.0", default-features = false, path = "../core" } sp-runtime = { version = "2.0.0", optional = true, path = "../runtime" } [features] default = [ "std" ] -std = [ "sp-api/std", "sp-std/std", "sp-runtime" ] +std = [ "sp-api/std", "sp-std/std", "sp-runtime", "sp-core/std" ] diff --git a/primitives/session/src/lib.rs b/primitives/session/src/lib.rs index c61218ca6b..8e2a68d050 100644 --- a/primitives/session/src/lib.rs +++ b/primitives/session/src/lib.rs @@ -25,6 +25,8 @@ use sp_runtime::{generic::BlockId, traits::Block as BlockT}; #[cfg(feature = "std")] use sp_api::ProvideRuntimeApi; +use sp_core::crypto::KeyTypeId; + sp_api::decl_runtime_apis! { /// Session keys runtime api. pub trait SessionKeys { @@ -36,6 +38,11 @@ sp_api::decl_runtime_apis! { /// /// Returns the concatenated SCALE encoded public keys. fn generate_session_keys(seed: Option>) -> Vec; + + /// Decode the given public session keys. + /// + /// Returns the list of public raw public keys + key type. + fn decode_session_keys(encoded: Vec) -> Option, KeyTypeId)>>; } } diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index e68ed5f6fc..b8e858c3a4 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -631,6 +631,12 @@ cfg_if! { fn generate_session_keys(_: Option>) -> Vec { SessionKeys::generate(None) } + + fn decode_session_keys( + encoded: Vec, + ) -> Option, sp_core::crypto::KeyTypeId)>> { + SessionKeys::decode_into_raw_public_keys(&encoded) + } } impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { @@ -847,6 +853,12 @@ cfg_if! { fn generate_session_keys(_: Option>) -> Vec { SessionKeys::generate(None) } + + fn decode_session_keys( + encoded: Vec, + ) -> Option, sp_core::crypto::KeyTypeId)>> { + SessionKeys::decode_into_raw_public_keys(&encoded) + } } impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { -- GitLab From 6cd538f8f77862c5c5379a1808871e0a28347baf Mon Sep 17 00:00:00 2001 From: thiolliere Date: Fri, 24 Jan 2020 20:04:11 +0100 Subject: [PATCH 017/180] Improve decl storage parsing (#4731) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * improve decl storage parsing * remove hidding detail macro * Apply suggestions from code review Co-authored-by: Bastian Köcher --- frame/support/procedural/src/storage/parse.rs | 128 ++++++++++++++++-- .../procedural/tools/derive/src/lib.rs | 74 +--------- frame/support/procedural/tools/src/syn_ext.rs | 33 ----- 3 files changed, 116 insertions(+), 119 deletions(-) diff --git a/frame/support/procedural/src/storage/parse.rs b/frame/support/procedural/src/storage/parse.rs index 5d91fbcc0e..04af85a312 100644 --- a/frame/support/procedural/src/storage/parse.rs +++ b/frame/support/procedural/src/storage/parse.rs @@ -38,10 +38,37 @@ mod keyword { syn::custom_keyword!(hasher); } +/// Specific `Opt` to implement structure with optional parsing +#[derive(Debug, Clone)] +pub struct Opt

{ + pub inner: Option

, +} +impl syn::export::ToTokens for Opt

{ + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + if let Some(ref p) = self.inner { + p.to_tokens(tokens); + } + } +} + +macro_rules! impl_parse_for_opt { + ($struct:ident => $token:path) => { + impl syn::parse::Parse for Opt<$struct> { + fn parse(input: syn::parse::ParseStream) -> syn::parse::Result { + if input.peek($token) { + input.parse().map(|p| Opt { inner: Some(p) }) + } else { + Ok(Opt { inner: None }) + } + } + } + }; +} + /// Parsing usage only #[derive(Parse, ToTokens, Debug)] struct StorageDefinition { - pub hidden_crate: ext::Opt, + pub hidden_crate: Opt, pub visibility: syn::Visibility, pub trait_token: Token![trait], pub ident: Ident, @@ -62,7 +89,7 @@ struct StorageDefinition { pub crate_ident: Ident, pub where_clause: Option, pub content: ext::Braces>, - pub extra_genesis: ext::Opt, + pub extra_genesis: Opt, } #[derive(Parse, ToTokens, Debug)] @@ -70,6 +97,7 @@ struct SpecificHiddenCrate { pub keyword: keyword::hiddencrate, pub ident: ext::Parens, } +impl_parse_for_opt!(SpecificHiddenCrate => keyword::hiddencrate); #[derive(Parse, ToTokens, Debug)] struct AddExtraGenesis { @@ -77,17 +105,36 @@ struct AddExtraGenesis { pub content: ext::Braces, } +impl_parse_for_opt!(AddExtraGenesis => keyword::add_extra_genesis); + #[derive(Parse, ToTokens, Debug)] struct AddExtraGenesisContent { pub lines: ext::Punctuated, } -#[derive(Parse, ToTokens, Debug)] +#[derive(ToTokens, Debug)] enum AddExtraGenesisLineEnum { AddExtraGenesisLine(AddExtraGenesisLine), AddExtraGenesisBuild(DeclStorageBuild), } +impl syn::parse::Parse for AddExtraGenesisLineEnum { + fn parse(input: syn::parse::ParseStream) -> syn::parse::Result { + let input_fork = input.fork(); + // OuterAttributes are forbidden for build variant, + // However to have better documentation we match against the keyword after those attributes. + let _: ext::OuterAttributes = input_fork.parse()?; + let lookahead = input_fork.lookahead1(); + if lookahead.peek(keyword::build) { + Ok(Self::AddExtraGenesisBuild(input.parse()?)) + } else if lookahead.peek(keyword::config) { + Ok(Self::AddExtraGenesisLine(input.parse()?)) + } else { + Err(lookahead.error()) + } + } +} + #[derive(Parse, ToTokens, Debug)] struct AddExtraGenesisLine { pub attrs: ext::OuterAttributes, @@ -95,7 +142,7 @@ struct AddExtraGenesisLine { pub extra_field: ext::Parens, pub coldot_token: Token![:], pub extra_type: syn::Type, - pub default_value: ext::Opt, + pub default_value: Opt, } #[derive(Parse, ToTokens, Debug)] @@ -106,12 +153,12 @@ struct DeclStorageLine { pub visibility: syn::Visibility, // name pub name: Ident, - pub getter: ext::Opt, - pub config: ext::Opt, - pub build: ext::Opt, + pub getter: Opt, + pub config: Opt, + pub build: Opt, pub coldot_token: Token![:], pub storage_type: DeclStorageType, - pub default_value: ext::Opt, + pub default_value: Opt, } #[derive(Parse, ToTokens, Debug)] @@ -126,19 +173,25 @@ struct DeclStorageGetter { pub getfn: ext::Parens, } +impl_parse_for_opt!(DeclStorageGetter => keyword::get); + #[derive(Parse, ToTokens, Debug)] struct DeclStorageConfig { pub config_keyword: keyword::config, pub expr: ext::Parens>, } +impl_parse_for_opt!(DeclStorageConfig => keyword::config); + #[derive(Parse, ToTokens, Debug)] struct DeclStorageBuild { pub build_keyword: keyword::build, pub expr: ext::Parens, } -#[derive(Parse, ToTokens, Debug)] +impl_parse_for_opt!(DeclStorageBuild => keyword::build); + +#[derive(ToTokens, Debug)] enum DeclStorageType { Map(DeclStorageMap), LinkedMap(DeclStorageLinkedMap), @@ -146,10 +199,24 @@ enum DeclStorageType { Simple(syn::Type), } +impl syn::parse::Parse for DeclStorageType { + fn parse(input: syn::parse::ParseStream) -> syn::parse::Result { + if input.peek(keyword::map) { + Ok(Self::Map(input.parse()?)) + } else if input.peek(keyword::linked_map) { + Ok(Self::LinkedMap(input.parse()?)) + } else if input.peek(keyword::double_map) { + Ok(Self::DoubleMap(input.parse()?)) + } else { + Ok(Self::Simple(input.parse()?)) + } + } +} + #[derive(Parse, ToTokens, Debug)] struct DeclStorageMap { pub map_keyword: keyword::map, - pub hasher: ext::Opt, + pub hasher: Opt, pub key: syn::Type, pub ass_keyword: Token![=>], pub value: syn::Type, @@ -158,7 +225,7 @@ struct DeclStorageMap { #[derive(Parse, ToTokens, Debug)] struct DeclStorageLinkedMap { pub map_keyword: keyword::linked_map, - pub hasher: ext::Opt, + pub hasher: Opt, pub key: syn::Type, pub ass_keyword: Token![=>], pub value: syn::Type, @@ -167,16 +234,16 @@ struct DeclStorageLinkedMap { #[derive(Parse, ToTokens, Debug)] struct DeclStorageDoubleMap { pub map_keyword: keyword::double_map, - pub hasher1: ext::Opt, + pub hasher1: Opt, pub key1: syn::Type, pub comma_keyword: Token![,], - pub hasher2: ext::Opt, + pub hasher2: Opt, pub key2: syn::Type, pub ass_keyword: Token![=>], pub value: syn::Type, } -#[derive(Parse, ToTokens, Debug)] +#[derive(ToTokens, Debug)] enum Hasher { Blake2_256(keyword::blake2_256), Blake2_128(keyword::blake2_128), @@ -186,18 +253,51 @@ enum Hasher { Twox64Concat(keyword::twox_64_concat), } +impl syn::parse::Parse for Hasher { + fn parse(input: syn::parse::ParseStream) -> syn::parse::Result { + let lookahead = input.lookahead1(); + if lookahead.peek(keyword::blake2_256) { + Ok(Self::Blake2_256(input.parse()?)) + } else if lookahead.peek(keyword::blake2_128) { + Ok(Self::Blake2_128(input.parse()?)) + } else if lookahead.peek(keyword::blake2_128_concat) { + Ok(Self::Blake2_128Concat(input.parse()?)) + } else if lookahead.peek(keyword::twox_256) { + Ok(Self::Twox256(input.parse()?)) + } else if lookahead.peek(keyword::twox_128) { + Ok(Self::Twox128(input.parse()?)) + } else if lookahead.peek(keyword::twox_64_concat) { + Ok(Self::Twox64Concat(input.parse()?)) + } else { + Err(lookahead.error()) + } + } +} + #[derive(Parse, ToTokens, Debug)] struct DeclStorageDefault { pub equal_token: Token![=], pub expr: syn::Expr, } +impl syn::parse::Parse for Opt { + fn parse(input: syn::parse::ParseStream) -> syn::parse::Result { + if input.peek(Token![=]) { + input.parse().map(|p| Opt { inner: Some(p) }) + } else { + Ok(Opt { inner: None }) + } + } +} + #[derive(Parse, ToTokens, Debug)] struct SetHasher { pub hasher_keyword: keyword::hasher, pub inner: ext::Parens, } +impl_parse_for_opt!(SetHasher => keyword::hasher); + impl From for super::HasherKind { fn from(set_hasher: SetHasher) -> Self { set_hasher.inner.content.into() diff --git a/frame/support/procedural/tools/derive/src/lib.rs b/frame/support/procedural/tools/derive/src/lib.rs index e130ffbfa0..f020c2a2fa 100644 --- a/frame/support/procedural/tools/derive/src/lib.rs +++ b/frame/support/procedural/tools/derive/src/lib.rs @@ -52,18 +52,13 @@ pub(crate) fn fields_access( }) } -/// self defined parsing struct or enum. -/// not meant for any struct/enum, just for fast +/// self defined parsing struct. +/// not meant for any struct, just for fast /// parse implementation. -/// For enums: -/// variant are tested in order of definition. -/// Empty variant is always true. -/// Please use carefully, this will fully parse successful variant twice. #[proc_macro_derive(Parse)] pub fn derive_parse(input: TokenStream) -> TokenStream { let item = parse_macro_input!(input as syn::Item); match item { - syn::Item::Enum(input) => derive_parse_enum(input), syn::Item::Struct(input) => derive_parse_struct(input), _ => TokenStream::new(), // ignore } @@ -100,71 +95,6 @@ fn derive_parse_struct(input: syn::ItemStruct) -> TokenStream { tokens.into() } -fn derive_parse_enum(input: syn::ItemEnum) -> TokenStream { - let syn::ItemEnum { - ident, - generics, - variants, - .. - } = input; - let variants = variants.iter().map(|v| { - let variant_ident = v.ident.clone(); - let fields_build = if v.fields.iter().count() > 0 { - let fields_id = fields_idents(v.fields.iter().map(Clone::clone)); - quote!( (#(#fields_id), *) ) - } else { - quote!() - }; - - let fields_procs = fields_idents(v.fields.iter().map(Clone::clone)) - .map(|fident| { - quote!{ - let mut #fident = match fork.parse() { - Ok(r) => r, - Err(_e) => break, - }; - } - }); - let fields_procs_again = fields_idents(v.fields.iter().map(Clone::clone)) - .map(|fident| { - quote!{ - #fident = input.parse().expect("was parsed just before"); - } - }); - - // double parse to update input cursor position - // next syn crate version should be checked for a way - // to copy position/state from a fork - quote!{ - let mut fork = input.fork(); - loop { - #(#fields_procs)* - #(#fields_procs_again)* - return Ok(#ident::#variant_ident#fields_build); - } - } - }); - - let tokens = quote! { - impl #generics syn::parse::Parse for #ident #generics { - fn parse(input: syn::parse::ParseStream) -> syn::parse::Result { - #( - #variants - )* - // no early return from any variants - Err( - syn::parse::Error::new( - proc_macro2::Span::call_site(), - "derived enum no matching variants" - ) - ) - } - } - - }; - tokens.into() -} - /// self defined parsing struct or enum. /// not meant for any struct/enum, just for fast /// parse implementation. diff --git a/frame/support/procedural/tools/src/syn_ext.rs b/frame/support/procedural/tools/src/syn_ext.rs index d0a5066b80..7b0a2cb93f 100644 --- a/frame/support/procedural/tools/src/syn_ext.rs +++ b/frame/support/procedural/tools/src/syn_ext.rs @@ -164,39 +164,6 @@ impl ToTokens for OuterAttributes { } } -#[derive(Debug)] -pub struct Opt

{ - pub inner: Option

, -} - -impl Parse for Opt

{ - // Note that it cost a double parsing (same as enum derive) - fn parse(input: ParseStream) -> Result { - let inner = match input.fork().parse::

() { - Ok(_item) => Some(input.parse().expect("Same parsing ran before")), - Err(_e) => None, - }; - - Ok(Opt { inner }) - } -} - -impl ToTokens for Opt

{ - fn to_tokens(&self, tokens: &mut TokenStream) { - if let Some(ref p) = self.inner { - p.to_tokens(tokens); - } - } -} - -impl Clone for Opt

{ - 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()?; -- GitLab From d56db2b99273de08b95ef890362d29b3bd63925e Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Sat, 25 Jan 2020 23:53:08 +0100 Subject: [PATCH 018/180] Cursed implementation of allowing missing imports on wasmtime (#4730) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Quick and dirty impl. * Clean up * Check the signatures. * Fix tests. * Apply suggestions from code review Co-Authored-By: Bastian Köcher * Ignore non function members. Co-authored-by: Bastian Köcher --- client/executor/src/integration_tests/mod.rs | 90 +++++------- client/executor/src/lib.rs | 8 +- client/executor/src/wasm_runtime.rs | 6 +- client/executor/wasmi/src/lib.rs | 34 ++--- client/executor/wasmtime/src/runtime.rs | 140 ++++++++++++++++++- client/executor/wasmtime/src/util.rs | 18 +++ 6 files changed, 215 insertions(+), 81 deletions(-) diff --git a/client/executor/src/integration_tests/mod.rs b/client/executor/src/integration_tests/mod.rs index 00f4eb33b0..5b2fc5ca0c 100644 --- a/client/executor/src/integration_tests/mod.rs +++ b/client/executor/src/integration_tests/mod.rs @@ -31,48 +31,6 @@ use sp_trie::{TrieConfiguration, trie_types::Layout}; use crate::WasmExecutionMethod; pub type TestExternalities = CoreTestExternalities; - -#[cfg(feature = "wasmtime")] -mod wasmtime_missing_externals { - use sp_wasm_interface::{Function, FunctionContext, HostFunctions, Result, Signature, Value}; - - pub struct WasmtimeHostFunctions; - - impl HostFunctions for WasmtimeHostFunctions { - fn host_functions() -> Vec<&'static dyn Function> { - vec![MISSING_EXTERNAL_FUNCTION, YET_ANOTHER_MISSING_EXTERNAL_FUNCTION] - } - } - - struct MissingExternalFunction(&'static str); - - impl Function for MissingExternalFunction { - fn name(&self) -> &str { self.0 } - - fn signature(&self) -> Signature { - Signature::new(vec![], None) - } - - fn execute( - &self, - _context: &mut dyn FunctionContext, - _args: &mut dyn Iterator, - ) -> Result> { - panic!("should not be called"); - } - } - - static MISSING_EXTERNAL_FUNCTION: &'static MissingExternalFunction = - &MissingExternalFunction("missing_external"); - static YET_ANOTHER_MISSING_EXTERNAL_FUNCTION: &'static MissingExternalFunction = - &MissingExternalFunction("yet_another_missing_external"); -} - -#[cfg(feature = "wasmtime")] -type HostFunctions = - (wasmtime_missing_externals::WasmtimeHostFunctions, sp_io::SubstrateHostFunctions); - -#[cfg(not(feature = "wasmtime"))] type HostFunctions = sp_io::SubstrateHostFunctions; fn call_in_wasm( @@ -114,40 +72,66 @@ fn returning_should_work(wasm_method: WasmExecutionMethod) { #[test_case(WasmExecutionMethod::Interpreted)] #[cfg_attr(feature = "wasmtime", test_case(WasmExecutionMethod::Compiled))] -#[should_panic(expected = "Function `missing_external` is only a stub. Calling a stub is not allowed.")] -#[cfg(not(feature = "wasmtime"))] fn call_not_existing_function(wasm_method: WasmExecutionMethod) { - let mut ext = TestExternalities::default(); - let mut ext = ext.ext(); - let test_code = WASM_BINARY; + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); + let test_code = WASM_BINARY; - call_in_wasm( + match call_in_wasm( "test_calling_missing_external", &[], wasm_method, &mut ext, &test_code[..], 8, - ).unwrap(); + ) { + Ok(_) => panic!("was expected an `Err`"), + Err(e) => { + match wasm_method { + WasmExecutionMethod::Interpreted => assert_eq!( + &format!("{:?}", e), + "Wasmi(Trap(Trap { kind: Host(Other(\"Function `missing_external` is only a stub. Calling a stub is not allowed.\")) }))" + ), + #[cfg(feature = "wasmtime")] + WasmExecutionMethod::Compiled => assert_eq!( + &format!("{:?}", e), + "Other(\"call to undefined external function with index 67\")" + ), + } + } + } } #[test_case(WasmExecutionMethod::Interpreted)] #[cfg_attr(feature = "wasmtime", test_case(WasmExecutionMethod::Compiled))] -#[should_panic(expected = "Function `yet_another_missing_external` is only a stub. Calling a stub is not allowed.")] -#[cfg(not(feature = "wasmtime"))] fn call_yet_another_not_existing_function(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); let mut ext = ext.ext(); let test_code = WASM_BINARY; - call_in_wasm( + match call_in_wasm( "test_calling_yet_another_missing_external", &[], wasm_method, &mut ext, &test_code[..], 8, - ).unwrap(); + ) { + Ok(_) => panic!("was expected an `Err`"), + Err(e) => { + match wasm_method { + WasmExecutionMethod::Interpreted => assert_eq!( + &format!("{:?}", e), + "Wasmi(Trap(Trap { kind: Host(Other(\"Function `yet_another_missing_external` is only a stub. Calling a stub is not allowed.\")) }))" + ), + #[cfg(feature = "wasmtime")] + WasmExecutionMethod::Compiled => assert_eq!( + &format!("{:?}", e), + "Other(\"call to undefined external function with index 68\")" + ), + } + } + } } #[test_case(WasmExecutionMethod::Interpreted)] diff --git a/client/executor/src/lib.rs b/client/executor/src/lib.rs index a054f4dc76..152e3a4984 100644 --- a/client/executor/src/lib.rs +++ b/client/executor/src/lib.rs @@ -68,7 +68,7 @@ pub fn call_in_wasm( ext: &mut dyn Externalities, code: &[u8], heap_pages: u64, - allow_missing_imports: bool, + allow_missing_func_imports: bool, ) -> error::Result> { call_in_wasm_with_host_functions( function, @@ -78,7 +78,7 @@ pub fn call_in_wasm( code, heap_pages, HF::host_functions(), - allow_missing_imports, + allow_missing_func_imports, ) } @@ -92,14 +92,14 @@ pub fn call_in_wasm_with_host_functions( code: &[u8], heap_pages: u64, host_functions: Vec<&'static dyn sp_wasm_interface::Function>, - allow_missing_imports: bool, + allow_missing_func_imports: bool, ) -> error::Result> { let instance = wasm_runtime::create_wasm_runtime_with_code( execution_method, heap_pages, code, host_functions, - allow_missing_imports, + allow_missing_func_imports, )?; // It is safe, as we delete the instance afterwards. diff --git a/client/executor/src/wasm_runtime.rs b/client/executor/src/wasm_runtime.rs index 036b28f764..b8966c3af2 100644 --- a/client/executor/src/wasm_runtime.rs +++ b/client/executor/src/wasm_runtime.rs @@ -191,15 +191,15 @@ pub fn create_wasm_runtime_with_code( heap_pages: u64, code: &[u8], host_functions: Vec<&'static dyn Function>, - allow_missing_imports: bool, + allow_missing_func_imports: bool, ) -> Result, WasmError> { match wasm_method { WasmExecutionMethod::Interpreted => - sc_executor_wasmi::create_instance(code, heap_pages, host_functions, allow_missing_imports) + sc_executor_wasmi::create_instance(code, heap_pages, host_functions, allow_missing_func_imports) .map(|runtime| -> Box { Box::new(runtime) }), #[cfg(feature = "wasmtime")] WasmExecutionMethod::Compiled => - sc_executor_wasmtime::create_instance(code, heap_pages, host_functions) + sc_executor_wasmtime::create_instance(code, heap_pages, host_functions, allow_missing_func_imports) .map(|runtime| -> Box { Box::new(runtime) }), } } diff --git a/client/executor/wasmi/src/lib.rs b/client/executor/wasmi/src/lib.rs index d3d0ee6e1e..cf8125e774 100644 --- a/client/executor/wasmi/src/lib.rs +++ b/client/executor/wasmi/src/lib.rs @@ -38,7 +38,7 @@ struct FunctionExecutor<'a> { memory: MemoryRef, table: Option, host_functions: &'a [&'static dyn Function], - allow_missing_imports: bool, + allow_missing_func_imports: bool, missing_functions: &'a [String], } @@ -48,7 +48,7 @@ impl<'a> FunctionExecutor<'a> { heap_base: u32, t: Option, host_functions: &'a [&'static dyn Function], - allow_missing_imports: bool, + allow_missing_func_imports: bool, missing_functions: &'a [String], ) -> Result { Ok(FunctionExecutor { @@ -57,7 +57,7 @@ impl<'a> FunctionExecutor<'a> { memory: m, table: t, host_functions, - allow_missing_imports, + allow_missing_func_imports, missing_functions, }) } @@ -273,15 +273,15 @@ impl<'a> Sandbox for FunctionExecutor<'a> { struct Resolver<'a> { host_functions: &'a[&'static dyn Function], - allow_missing_imports: bool, + allow_missing_func_imports: bool, missing_functions: RefCell>, } impl<'a> Resolver<'a> { - fn new(host_functions: &'a[&'static dyn Function], allow_missing_imports: bool) -> Resolver<'a> { + fn new(host_functions: &'a[&'static dyn Function], allow_missing_func_imports: bool) -> Resolver<'a> { Resolver { host_functions, - allow_missing_imports, + allow_missing_func_imports, missing_functions: RefCell::new(Vec::new()), } } @@ -311,7 +311,7 @@ impl<'a> wasmi::ModuleImportResolver for Resolver<'a> { } } - if self.allow_missing_imports { + if self.allow_missing_func_imports { trace!(target: "wasm-executor", "Could not find function `{}`, a stub will be provided instead.", name); let id = self.missing_functions.borrow().len() + self.host_functions.len(); self.missing_functions.borrow_mut().push(name.to_string()); @@ -336,7 +336,7 @@ impl<'a> wasmi::Externals for FunctionExecutor<'a> { .map_err(|msg| Error::FunctionExecution(function.name().to_string(), msg)) .map_err(wasmi::Trap::from) .map(|v| v.map(Into::into)) - } else if self.allow_missing_imports + } else if self.allow_missing_func_imports && index >= self.host_functions.len() && index < self.host_functions.len() + self.missing_functions.len() { @@ -381,7 +381,7 @@ fn call_in_wasm_module( method: &str, data: &[u8], host_functions: &[&'static dyn Function], - allow_missing_imports: bool, + allow_missing_func_imports: bool, missing_functions: &Vec, ) -> Result, Error> { // extract a reference to a linear memory, optional reference to a table @@ -397,7 +397,7 @@ fn call_in_wasm_module( heap_base, table, host_functions, - allow_missing_imports, + allow_missing_func_imports, missing_functions, )?; @@ -433,9 +433,9 @@ fn instantiate_module( heap_pages: usize, module: &Module, host_functions: &[&'static dyn Function], - allow_missing_imports: bool, + allow_missing_func_imports: bool, ) -> Result<(ModuleRef, Vec), Error> { - let resolver = Resolver::new(host_functions, allow_missing_imports); + let resolver = Resolver::new(host_functions, allow_missing_func_imports); // start module instantiation. Don't run 'start' function yet. let intermediate_instance = ModuleInstance::new( module, @@ -575,7 +575,7 @@ pub struct WasmiRuntime { host_functions: Vec<&'static dyn Function>, /// Enable stub generation for functions that are not available in `host_functions`. /// These stubs will error when the wasm blob tries to call them. - allow_missing_imports: bool, + allow_missing_func_imports: bool, /// List of missing functions detected during function resolution missing_functions: Vec, } @@ -607,7 +607,7 @@ impl WasmRuntime for WasmiRuntime { method, data, &self.host_functions, - self.allow_missing_imports, + self.allow_missing_func_imports, &self.missing_functions, ) } @@ -617,7 +617,7 @@ pub fn create_instance( code: &[u8], heap_pages: u64, host_functions: Vec<&'static dyn Function>, - allow_missing_imports: bool, + allow_missing_func_imports: bool, ) -> Result { let module = Module::from_buffer(&code).map_err(|_| WasmError::InvalidModule)?; @@ -632,7 +632,7 @@ pub fn create_instance( heap_pages as usize, &module, &host_functions, - allow_missing_imports, + allow_missing_func_imports, ).map_err(|e| WasmError::Instantiation(e.to_string()))?; // Take state snapshot before executing anything. @@ -648,7 +648,7 @@ pub fn create_instance( instance, state_snapshot, host_functions, - allow_missing_imports, + allow_missing_func_imports, missing_functions, }) } diff --git a/client/executor/wasmtime/src/runtime.rs b/client/executor/wasmtime/src/runtime.rs index f9b1b6209c..77a11ddc7d 100644 --- a/client/executor/wasmtime/src/runtime.rs +++ b/client/executor/wasmtime/src/runtime.rs @@ -18,7 +18,12 @@ use crate::function_executor::FunctionExecutorState; use crate::trampoline::{EnvState, make_trampoline}; -use crate::util::{cranelift_ir_signature, read_memory_into, write_memory_from}; +use crate::util::{ + cranelift_ir_signature, + convert_parity_wasm_signature, + read_memory_into, + write_memory_from +}; use sc_executor_common::{ error::{Error, Result, WasmError}, @@ -86,8 +91,9 @@ pub fn create_instance( code: &[u8], heap_pages: u64, host_functions: Vec<&'static dyn Function>, + allow_missing_func_imports: bool, ) -> std::result::Result { - let (compiled_module, context) = create_compiled_unit(code, &host_functions)?; + let (compiled_module, context) = create_compiled_unit(code, &host_functions, allow_missing_func_imports)?; // Inspect the module for the min and max memory sizes. let (min_memory_size, max_memory_size) = { @@ -115,9 +121,95 @@ pub fn create_instance( }) } +#[derive(Debug)] +struct MissingFunction { + name: String, + sig: cranelift_codegen::ir::Signature, +} + +#[derive(Debug)] +struct MissingFunctionStubs { + stubs: HashMap>, +} + +impl MissingFunctionStubs { + fn new() -> Self { + Self { + stubs: HashMap::new(), + } + } + + fn insert(&mut self, module: String, name: String, sig: cranelift_codegen::ir::Signature) { + self.stubs.entry(module).or_insert_with(Vec::new).push(MissingFunction { + name, + sig, + }); + } +} + +fn scan_missing_functions( + code: &[u8], + host_functions: &[&'static dyn Function], +) -> std::result::Result { + let isa = target_isa()?; + let call_conv = isa.default_call_conv(); + + let module = parity_wasm::elements::Module::from_bytes(code) + .map_err(|e| WasmError::Other(format!("cannot deserialize error: {}", e)))?; + + let types = module.type_section().map(|ts| ts.types()).unwrap_or(&[]); + let import_entries = module + .import_section() + .map(|is| is.entries()) + .unwrap_or(&[]); + + let mut missing_functions = MissingFunctionStubs::new(); + for import_entry in import_entries { + let func_ty = match import_entry.external() { + parity_wasm::elements::External::Function(func_ty_idx) => { + let parity_wasm::elements::Type::Function(ref func_ty) = + types.get(*func_ty_idx as usize).ok_or_else(|| { + WasmError::Other(format!("corrupted module, type out of bounds")) + })?; + func_ty + } + _ => { + // We are looking only for missing **functions** here. Any other items, be they + // missing or not, will be handled at the resolution stage later. + continue; + } + }; + let signature = convert_parity_wasm_signature(func_ty); + + if import_entry.module() == "env" { + if let Some(hf) = host_functions + .iter() + .find(|hf| hf.name() == import_entry.field()) + { + if signature == hf.signature() { + continue; + } + } + } + + // This function is either not from the env module, or doesn't have a corresponding host + // function, or the signature is not matching. Add it to the list. + let sig = cranelift_ir_signature(signature, &call_conv); + + missing_functions.insert( + import_entry.module().to_string(), + import_entry.field().to_string(), + sig, + ); + } + + Ok(missing_functions) +} + fn create_compiled_unit( code: &[u8], host_functions: &[&'static dyn Function], + allow_missing_func_imports: bool, ) -> std::result::Result<(CompiledModule, Context), WasmError> { let compilation_strategy = CompilationStrategy::Cranelift; @@ -130,8 +222,27 @@ fn create_compiled_unit( // Instantiate and link the env module. let global_exports = context.get_global_exports(); let compiler = new_compiler(compilation_strategy)?; - let env_module = instantiate_env_module(global_exports, compiler, host_functions)?; - context.name_instance("env".to_owned(), env_module); + + let mut missing_functions_stubs = if allow_missing_func_imports { + scan_missing_functions(code, host_functions)? + } else { + // If there are in fact missing functions they will be detected at the instantiation time + // and the module will be rejected. + MissingFunctionStubs::new() + }; + + let env_missing_functions = missing_functions_stubs.stubs.remove("env").unwrap_or_else(|| Vec::new()); + context.name_instance( + "env".to_owned(), + instantiate_env_module(global_exports, compiler, host_functions, env_missing_functions)?, + ); + + for (module, missing_functions_stubs) in missing_functions_stubs.stubs { + let compiler = new_compiler(compilation_strategy)?; + let global_exports = context.get_global_exports(); + let instance = instantiate_env_module(global_exports, compiler, &[], missing_functions_stubs)?; + context.name_instance(module, instance); + } // Compile the wasm module. let module = context.compile_module(&code) @@ -199,6 +310,7 @@ fn instantiate_env_module( global_exports: Rc>>>, compiler: Compiler, host_functions: &[&'static dyn Function], + missing_functions_stubs: Vec, ) -> std::result::Result { let isa = target_isa()?; @@ -231,6 +343,26 @@ fn instantiate_env_module( finished_functions.push(trampoline); } + for MissingFunction { name, sig } in missing_functions_stubs { + let sig = translate_signature( + sig, + pointer_type, + ); + let sig_id = module.signatures.push(sig.clone()); + let func_id = module.functions.push(sig_id); + module + .exports + .insert(name, wasmtime_environ::Export::Function(func_id)); + let trampoline = make_trampoline( + isa.as_ref(), + &mut code_memory, + &mut fn_builder_ctx, + func_id.index() as u32, + &sig, + )?; + finished_functions.push(trampoline); + } + code_memory.publish(); let imports = Imports::none(); diff --git a/client/executor/wasmtime/src/util.rs b/client/executor/wasmtime/src/util.rs index 551295911a..77fb8af386 100644 --- a/client/executor/wasmtime/src/util.rs +++ b/client/executor/wasmtime/src/util.rs @@ -51,6 +51,24 @@ pub fn checked_range(offset: usize, len: usize, max: usize) -> Option Signature { + fn convert_value_type(val_ty: parity_wasm::elements::ValueType) -> ValueType { + use parity_wasm::elements::ValueType::*; + match val_ty { + I32 => ValueType::I32, + I64 => ValueType::I64, + F32 => ValueType::F32, + F64 => ValueType::F64, + } + } + + Signature::new( + func_ty.params().iter().cloned().map(convert_value_type).collect::>(), + func_ty.return_type().map(convert_value_type), + ) +} + /// Convert a wasm_interface Signature into a cranelift_codegen Signature. pub fn cranelift_ir_signature(signature: Signature, call_conv: &isa::CallConv) -> ir::Signature { ir::Signature { -- GitLab From 03ffa5a501acab0c1d6ae5c41d291941fb8a79af Mon Sep 17 00:00:00 2001 From: Seun LanLege Date: Mon, 27 Jan 2020 10:59:40 +0100 Subject: [PATCH 019/180] Manual Seal (#4143) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * instant/manual seal unbounded queues are evil Apply suggestions from code review Co-Authored-By: Robert Habermeier add fork tests, docs, remove todos moar docs Update client/consensus/manual-seal/src/rpc.rs Co-Authored-By: Robert Habermeier remove unbound generic, parameter, docs, deps, code style changes Apply suggestions from code review Co-Authored-By: Tomasz Drwięga code style chnges remove unused deps, remove dep renames, check if block is empty before importing, use ? for error propagation fix tests log errors for instant seal use debug code style changes, updated copyright dates use txpool::Pool instead of BasicPool, code style changes fixed tests * fix tests * requested changes from review * check inherents len * rebase --- .maintain/rename-crates-for-2.0.sh | 0 Cargo.lock | 636 +++++++++--------- Cargo.toml | 1 + bin/node/cli/src/browser.rs | 2 +- bin/node/cli/src/cli.rs | 2 +- client/consensus/manual-seal/Cargo.toml | 32 + client/consensus/manual-seal/src/error.rs | 98 +++ .../manual-seal/src/finalize_block.rs | 64 ++ client/consensus/manual-seal/src/lib.rs | 467 +++++++++++++ client/consensus/manual-seal/src/rpc.rs | 163 +++++ .../manual-seal/src/seal_new_block.rs | 148 ++++ client/transaction-pool/Cargo.toml | 19 +- client/transaction-pool/src/lib.rs | 2 + client/transaction-pool/src/testing.rs | 185 +++++ client/transaction-pool/src/tests.rs | 156 +---- primitives/consensus/common/Cargo.toml | 1 + .../consensus/common/src/block_import.rs | 9 +- primitives/inherents/src/lib.rs | 5 + 18 files changed, 1521 insertions(+), 469 deletions(-) mode change 100644 => 100755 .maintain/rename-crates-for-2.0.sh create mode 100644 client/consensus/manual-seal/Cargo.toml create mode 100644 client/consensus/manual-seal/src/error.rs create mode 100644 client/consensus/manual-seal/src/finalize_block.rs create mode 100644 client/consensus/manual-seal/src/lib.rs create mode 100644 client/consensus/manual-seal/src/rpc.rs create mode 100644 client/consensus/manual-seal/src/seal_new_block.rs create mode 100644 client/transaction-pool/src/testing.rs diff --git a/.maintain/rename-crates-for-2.0.sh b/.maintain/rename-crates-for-2.0.sh old mode 100644 new mode 100755 diff --git a/Cargo.lock b/Cargo.lock index 6ec2225830..b2bf3f6265 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -138,21 +138,11 @@ name = "assert_matches" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "async-macros" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "async-std" -version = "1.2.0" +version = "1.3.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)", "async-task 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "broadcaster 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -162,7 +152,7 @@ dependencies = [ "futures-io 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)", "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)", + "log 0.4.10 (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.21 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -259,7 +249,7 @@ version = "1.2.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)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -275,7 +265,7 @@ dependencies = [ "env_logger 0.6.2 (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)", + "log 0.4.10 (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)", @@ -378,17 +368,17 @@ dependencies = [ "console_log 0.1.2 (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)", - "js-sys 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-web 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (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)", "sc-chain-spec 2.0.0", "sc-network 0.8.0", "sc-service 0.8.0", - "wasm-bindgen 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -409,7 +399,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.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -422,7 +412,7 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.1.1" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -479,8 +469,8 @@ 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.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 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -533,7 +523,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.41 (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)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -591,7 +581,7 @@ version = "0.1.6" 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)", - "wasm-bindgen 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -599,8 +589,8 @@ name = "console_log" 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)", - "web-sys 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -658,8 +648,8 @@ dependencies = [ "cranelift-codegen-meta 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "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.103 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -684,7 +674,7 @@ name = "cranelift-entity" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -693,7 +683,7 @@ version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cranelift-codegen 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)", + "log 0.4.10 (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)", ] @@ -716,8 +706,8 @@ dependencies = [ "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)", - "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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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)", ] @@ -749,8 +739,8 @@ dependencies = [ "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.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 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.104 (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)", @@ -773,8 +763,8 @@ dependencies = [ "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.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 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.104 (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)", @@ -887,7 +877,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.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1069,7 +1059,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1081,7 +1071,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1096,7 +1086,7 @@ name = "erased-serde" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1128,7 +1118,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)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1176,7 +1166,7 @@ dependencies = [ "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)", + "log 0.4.10 (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)", @@ -1227,7 +1217,7 @@ version = "0.1.2" 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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1237,7 +1227,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" 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)", + "log 0.4.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1309,7 +1299,7 @@ dependencies = [ "pallet-indices 2.0.0", "pallet-transaction-payment 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -1321,7 +1311,7 @@ name = "frame-metadata" version = "10.0.0" dependencies = [ "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-std 2.0.0", ] @@ -1335,12 +1325,12 @@ dependencies = [ "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)", + "log 0.4.10 (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.2 (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)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-arithmetic 2.0.0", "sp-core 2.0.0", "sp-inherents 2.0.0", @@ -1388,7 +1378,7 @@ dependencies = [ "frame-support 2.0.0", "parity-scale-codec 1.1.2 (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)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-inherents 2.0.0", "sp-io 2.0.0", @@ -1405,7 +1395,7 @@ dependencies = [ "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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-externalities 0.8.0", "sp-io 2.0.0", @@ -1667,7 +1657,7 @@ dependencies = [ "cfg-if 0.1.10 (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.57 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1700,7 +1690,7 @@ dependencies = [ "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", "bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1709,7 +1699,7 @@ name = "goblin" 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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "scroll 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1718,16 +1708,16 @@ dependencies = [ name = "grafana-data-source" version = "0.8.0" dependencies = [ - "async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-std 1.3.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)", "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)", + "log 0.4.10 (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 1.0.104 (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)", ] @@ -1753,7 +1743,7 @@ dependencies = [ "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)", "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)", + "log 0.4.10 (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-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1771,7 +1761,7 @@ dependencies = [ "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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (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)", @@ -1823,7 +1813,7 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1955,7 +1945,7 @@ dependencies = [ "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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1984,7 +1974,7 @@ dependencies = [ "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)", "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)", + "log 0.4.10 (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 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2061,7 +2051,7 @@ name = "impl-serde" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2125,15 +2115,15 @@ 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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "js-sys" -version = "0.3.34" +version = "0.3.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "wasm-bindgen 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2147,8 +2137,8 @@ dependencies = [ "hyper-tls 0.3.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)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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)", @@ -2161,9 +2151,9 @@ 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.103 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2194,7 +2184,7 @@ dependencies = [ "hyper 0.12.35 (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)", + "log 0.4.10 (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)", "unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2206,9 +2196,9 @@ version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "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)", + "log 0.4.10 (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 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2220,7 +2210,7 @@ dependencies = [ "globset 0.4.4 (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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2233,7 +2223,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "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)", + "log 0.4.10 (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)", "ws 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2268,7 +2258,7 @@ name = "kv-log-macro" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2299,7 +2289,7 @@ dependencies = [ "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.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2315,14 +2305,14 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "send_wrapper 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2406,7 +2396,7 @@ dependencies = [ "futures-timer 2.0.2 (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.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "multistream-select 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2451,7 +2441,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2481,7 +2471,7 @@ dependencies = [ "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-swarm 0.4.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2502,7 +2492,7 @@ dependencies = [ "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-swarm 0.4.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2520,7 +2510,7 @@ name = "libp2p-mdns" version = "0.14.0-alpha.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-std 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "dns-parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2528,7 +2518,7 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-swarm 0.4.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2547,7 +2537,7 @@ dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2562,7 +2552,7 @@ dependencies = [ "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)", "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "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)", @@ -2580,7 +2570,7 @@ dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-swarm 0.4.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2596,7 +2586,7 @@ dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "rw-stream-sink 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2612,10 +2602,10 @@ dependencies = [ "ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "quicksink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2626,9 +2616,9 @@ dependencies = [ "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2648,14 +2638,14 @@ name = "libp2p-tcp" version = "0.14.0-alpha.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-std 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.5.3 (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)", "get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "ipnet 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2663,10 +2653,10 @@ name = "libp2p-uds" version = "0.14.0-alpha.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-std 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2675,11 +2665,11 @@ version = "0.7.0-alpha.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2692,11 +2682,11 @@ dependencies = [ "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "quicksink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "rw-stream-sink 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "soketto 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "soketto 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", "webpki-roots 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2709,7 +2699,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "yamux 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2786,12 +2776,12 @@ name = "log" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "log" -version = "0.4.8" +version = "0.4.10" 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)", @@ -2911,7 +2901,7 @@ dependencies = [ "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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (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)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2924,7 +2914,7 @@ 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)", + "log 0.4.10 (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)", ] @@ -2967,7 +2957,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.3 (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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.0.0 (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.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2988,7 +2978,7 @@ 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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (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.53 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3031,7 +3021,7 @@ dependencies = [ "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)", "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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "node-executor 2.0.0", "node-primitives 2.0.0", "node-rpc 2.0.0", @@ -3063,7 +3053,7 @@ dependencies = [ "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)", + "serde 1.0.104 (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", @@ -3081,8 +3071,8 @@ dependencies = [ "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3151,7 +3141,7 @@ dependencies = [ "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.5 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "node-primitives 2.0.0", "sc-rpc 2.0.0", ] @@ -3196,7 +3186,7 @@ dependencies = [ "pallet-utility 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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", @@ -3221,7 +3211,7 @@ version = "2.0.0" dependencies = [ "ctrlc 3.1.3 (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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "node-template-runtime 2.0.0", "sc-basic-authorship 0.8.0", "sc-cli 0.8.0", @@ -3260,7 +3250,7 @@ dependencies = [ "pallet-timestamp 2.0.0", "pallet-transaction-payment 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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", @@ -3310,7 +3300,7 @@ dependencies = [ name = "node-transaction-factory" version = "0.8.0" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "sc-cli 0.8.0", "sc-client 0.8.0", @@ -3386,7 +3376,7 @@ name = "num_cpus" 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)", + "hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3475,7 +3465,7 @@ dependencies = [ "frame-support 2.0.0", "frame-system 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -3493,7 +3483,7 @@ dependencies = [ "pallet-timestamp 2.0.0", "parity-scale-codec 1.1.2 (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 1.0.104 (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", @@ -3512,7 +3502,7 @@ dependencies = [ "frame-system 2.0.0", "pallet-session 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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", @@ -3550,7 +3540,7 @@ dependencies = [ "pallet-timestamp 2.0.0", "parity-scale-codec 1.1.2 (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 1.0.104 (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", @@ -3571,7 +3561,7 @@ dependencies = [ "frame-system 2.0.0", "pallet-transaction-payment 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -3587,7 +3577,7 @@ dependencies = [ "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-balances 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -3608,7 +3598,7 @@ dependencies = [ "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "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)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -3627,7 +3617,7 @@ dependencies = [ "jsonrpc-derive 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-contracts-rpc-runtime-api 0.8.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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-blockchain 2.0.0", @@ -3654,7 +3644,7 @@ dependencies = [ "frame-system 2.0.0", "pallet-balances 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -3670,7 +3660,7 @@ dependencies = [ "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-balances 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -3686,7 +3676,7 @@ dependencies = [ "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-balances 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-phragmen 2.0.0", @@ -3707,7 +3697,7 @@ dependencies = [ "parity-scale-codec 1.1.2 (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)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", @@ -3723,7 +3713,7 @@ dependencies = [ "frame-system 2.0.0", "pallet-balances 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -3738,7 +3728,7 @@ dependencies = [ "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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-finality-tracker 2.0.0", "sp-inherents 2.0.0", @@ -3754,7 +3744,7 @@ dependencies = [ "frame-support 2.0.0", "frame-system 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -3770,7 +3760,7 @@ dependencies = [ "pallet-finality-tracker 2.0.0", "pallet-session 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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", @@ -3788,7 +3778,7 @@ dependencies = [ "frame-system 2.0.0", "pallet-balances 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -3804,7 +3794,7 @@ dependencies = [ "pallet-authorship 2.0.0", "pallet-session 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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", @@ -3820,7 +3810,7 @@ dependencies = [ "frame-support 2.0.0", "frame-system 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-keyring 2.0.0", @@ -3835,7 +3825,7 @@ dependencies = [ "frame-support 2.0.0", "frame-system 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -3850,7 +3840,7 @@ dependencies = [ "frame-system 2.0.0", "pallet-balances 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -3865,7 +3855,7 @@ dependencies = [ "frame-system 2.0.0", "pallet-balances 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -3896,7 +3886,7 @@ dependencies = [ "frame-system 2.0.0", "pallet-balances 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -3911,7 +3901,7 @@ dependencies = [ "frame-system 2.0.0", "pallet-balances 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -3928,7 +3918,7 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-timestamp 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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", @@ -3947,7 +3937,7 @@ dependencies = [ "pallet-balances 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -3966,7 +3956,7 @@ dependencies = [ "pallet-staking-reward-curve 2.0.0", "pallet-timestamp 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-keyring 2.0.0", @@ -3995,7 +3985,7 @@ dependencies = [ "frame-support 2.0.0", "frame-system 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -4010,7 +4000,7 @@ dependencies = [ "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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-inherents 2.0.0", "sp-io 2.0.0", @@ -4043,7 +4033,7 @@ dependencies = [ "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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-api 2.0.0", "sp-blockchain 2.0.0", "sp-core 2.0.0", @@ -4057,7 +4047,7 @@ version = "2.0.0" dependencies = [ "frame-support 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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", @@ -4072,7 +4062,7 @@ dependencies = [ "frame-system 2.0.0", "pallet-balances 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -4087,7 +4077,7 @@ dependencies = [ "frame-system 2.0.0", "pallet-balances 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -4111,7 +4101,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.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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)", ] @@ -4127,7 +4117,7 @@ dependencies = [ "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.2.1 (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.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4169,13 +4159,13 @@ dependencies = [ "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "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.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parity-scale-codec-derive" -version = "1.1.1" +version = "1.1.0" 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)", @@ -4515,7 +4505,7 @@ 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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (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)", "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4568,7 +4558,7 @@ 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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4583,7 +4573,7 @@ version = "0.9.0" 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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4748,7 +4738,7 @@ dependencies = [ "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.57 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4904,7 +4894,7 @@ dependencies = [ "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.34 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4968,7 +4958,7 @@ version = "0.16.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)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", "sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5029,7 +5019,7 @@ 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)", "libp2p 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5053,7 +5043,7 @@ name = "sc-basic-authorship" version = "0.8.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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (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 0.8.0", @@ -5095,7 +5085,7 @@ dependencies = [ "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 1.0.104 (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", @@ -5124,7 +5114,7 @@ dependencies = [ "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)", + "log 0.4.10 (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)", @@ -5158,7 +5148,7 @@ dependencies = [ "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (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 0.8.0", @@ -5193,7 +5183,7 @@ dependencies = [ "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.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (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 0.8.0", @@ -5224,7 +5214,7 @@ dependencies = [ "kvdb-memorydb 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.4.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)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5253,7 +5243,7 @@ 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)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (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 0.8.0", @@ -5293,7 +5283,7 @@ 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)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (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)", @@ -5332,13 +5322,40 @@ dependencies = [ "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sc-consensus-manual-seal" +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.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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-basic-authorship 0.8.0", + "sc-client 0.8.0", + "sc-client-api 2.0.0", + "sc-transaction-pool 2.0.0", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-blockchain 2.0.0", + "sp-consensus 0.8.0", + "sp-inherents 2.0.0", + "sp-runtime 2.0.0", + "sp-transaction-pool 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.2.4 (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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "sc-client-api 2.0.0", "sp-api 2.0.0", @@ -5358,7 +5375,7 @@ 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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (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", @@ -5377,7 +5394,7 @@ dependencies = [ name = "sc-consensus-uncles" version = "0.8.0" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (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", @@ -5395,7 +5412,7 @@ 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)", "libsecp256k1 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (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)", @@ -5424,7 +5441,7 @@ name = "sc-executor-common" version = "0.8.0" dependencies = [ "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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "sp-allocator 2.0.0", "sp-core 2.0.0", @@ -5438,7 +5455,7 @@ dependencies = [ name = "sc-executor-wasmi" version = "0.8.0" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)", "sc-executor-common 0.8.0", @@ -5459,7 +5476,7 @@ dependencies = [ "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)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)", "sc-executor-common 0.8.0", @@ -5483,7 +5500,7 @@ 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 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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5546,7 +5563,7 @@ dependencies = [ "libp2p 0.14.0-alpha.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)", + "log 0.4.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5557,7 +5574,7 @@ dependencies = [ "sc-client 0.8.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 1.0.104 (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)", @@ -5586,7 +5603,7 @@ dependencies = [ "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.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (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", @@ -5602,7 +5619,7 @@ dependencies = [ "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.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (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 0.8.0", @@ -5632,7 +5649,7 @@ dependencies = [ "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)", + "log 0.4.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5658,7 +5675,7 @@ version = "2.0.0" dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (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)", ] @@ -5673,7 +5690,7 @@ dependencies = [ "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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (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.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5709,10 +5726,10 @@ dependencies = [ "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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (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 1.0.104 (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", @@ -5728,8 +5745,8 @@ dependencies = [ "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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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", ] @@ -5758,7 +5775,7 @@ dependencies = [ "futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "grafana-data-source 0.8.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)", + "log 0.4.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5776,7 +5793,7 @@ dependencies = [ "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 1.0.104 (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", @@ -5806,7 +5823,7 @@ dependencies = [ "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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "sc-client 0.8.0", "sc-network 0.8.0", "sc-service 0.8.0", @@ -5823,7 +5840,7 @@ name = "sc-state-db" version = "0.8.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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (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", @@ -5837,11 +5854,11 @@ 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)", "libp2p 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.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 1.0.104 (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)", @@ -5855,10 +5872,10 @@ version = "2.0.0" dependencies = [ "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "grafana-data-source 0.8.0", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (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 1.0.104 (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)", @@ -5873,10 +5890,10 @@ dependencies = [ "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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (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 1.0.104 (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", @@ -5889,7 +5906,7 @@ 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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (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", @@ -5998,7 +6015,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.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6018,15 +6035,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "1.0.103" +version = "1.0.104" 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)", @@ -6041,7 +6058,7 @@ 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.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6117,7 +6134,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "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 1.0.104 (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)", ] @@ -6169,7 +6186,7 @@ dependencies = [ [[package]] name = "soketto" -version = "0.3.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6178,7 +6195,7 @@ dependencies = [ "futures 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)", "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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6196,7 +6213,7 @@ name = "sp-allocator" version = "2.0.0" dependencies = [ "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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-std 2.0.0", "sp-wasm-interface 2.0.0", @@ -6250,7 +6267,7 @@ name = "sp-application-crypto" version = "2.0.0" dependencies = [ "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-io 2.0.0", "sp-std 2.0.0", @@ -6277,7 +6294,7 @@ dependencies = [ "parity-scale-codec 1.1.2 (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.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-debug-derive 2.0.0", "sp-std 2.0.0", ] @@ -6319,7 +6336,7 @@ name = "sp-blockchain" version = "2.0.0" dependencies = [ "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)", + "log 0.4.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6337,9 +6354,10 @@ dependencies = [ "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.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-inherents 2.0.0", "sp-runtime 2.0.0", @@ -6404,7 +6422,7 @@ dependencies = [ "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.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6414,7 +6432,7 @@ dependencies = [ "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.1.0 (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.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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", @@ -6454,7 +6472,7 @@ name = "sp-finality-grandpa" version = "2.0.0" dependencies = [ "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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", @@ -6487,7 +6505,7 @@ version = "2.0.0" dependencies = [ "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "libsecp256k1 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-externalities 0.8.0", @@ -6520,7 +6538,7 @@ name = "sp-panic-handler" 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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6528,7 +6546,7 @@ name = "sp-phragmen" version = "2.0.0" dependencies = [ "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 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-io 2.0.0", "sp-runtime 2.0.0", "sp-std 2.0.0", @@ -6539,7 +6557,7 @@ dependencies = [ name = "sp-rpc" version = "2.0.0" dependencies = [ - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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", ] @@ -6549,11 +6567,11 @@ name = "sp-runtime" 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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (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.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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", @@ -6633,7 +6651,7 @@ dependencies = [ name = "sp-serializer" version = "2.0.0" dependencies = [ - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6662,7 +6680,7 @@ version = "0.8.0" dependencies = [ "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)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6684,7 +6702,7 @@ name = "sp-storage" version = "2.0.0" dependencies = [ "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)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-debug-derive 2.0.0", "sp-std 2.0.0", ] @@ -6694,7 +6712,7 @@ name = "sp-test-primitives" version = "2.0.0" dependencies = [ "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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", @@ -6718,9 +6736,9 @@ 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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-api 2.0.0", "sp-runtime 2.0.0", ] @@ -6748,7 +6766,7 @@ version = "2.0.0" dependencies = [ "impl-serde 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-runtime 2.0.0", "sp-std 2.0.0", ] @@ -6798,7 +6816,7 @@ name = "string-interner" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6900,7 +6918,7 @@ dependencies = [ "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "sc-rpc-api 0.8.0", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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)", ] @@ -6915,11 +6933,11 @@ dependencies = [ "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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "sc-client 0.8.0", "sc-transaction-pool 2.0.0", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-api 2.0.0", "sp-blockchain 2.0.0", "sp-core 2.0.0", @@ -6956,14 +6974,14 @@ dependencies = [ "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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "memory-db 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-babe 2.0.0", "pallet-timestamp 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "sc-client 0.8.0", "sc-executor 0.8.0", - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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", @@ -7233,7 +7251,7 @@ name = "tinytemplate" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7270,6 +7288,7 @@ dependencies = [ "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.11.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)", + "tokio-macros 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7337,7 +7356,16 @@ 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)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-macros" +version = "0.2.0" +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.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7348,7 +7376,7 @@ 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)", + "log 0.4.10 (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)", @@ -7413,7 +7441,7 @@ 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)", + "log 0.4.10 (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.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7447,7 +7475,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)", "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)", + "log 0.4.10 (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)", @@ -7463,7 +7491,7 @@ dependencies = [ "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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (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)", @@ -7479,7 +7507,7 @@ dependencies = [ "bytes 0.5.3 (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)", + "log 0.4.10 (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)", ] @@ -7489,7 +7517,7 @@ name = "toml" version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7553,7 +7581,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7588,7 +7616,7 @@ 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.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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)", @@ -7765,8 +7793,8 @@ name = "wabt" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "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 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.104 (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)", ] @@ -7797,7 +7825,7 @@ 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)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7806,7 +7834,7 @@ name = "want" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7817,76 +7845,76 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wasm-bindgen" -version = "0.2.57" +version = "0.2.58" 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)", - "wasm-bindgen-macro 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.57" +version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bumpalo 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bumpalo 3.1.2 (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)", + "log 0.4.10 (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)", - "wasm-bindgen-shared 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.7" +version = "0.4.8" 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)", - "js-sys 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.57" +version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro-support 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro-support 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.57" +version = "0.2.58" 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)", - "wasm-bindgen-backend 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.57" +version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wasm-bindgen-webidl" -version = "0.2.57" +version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "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)", + "log 0.4.10 (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)", - "wasm-bindgen-backend 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7895,7 +7923,7 @@ name = "wasm-gc-api" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7906,13 +7934,13 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", "send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7976,10 +8004,10 @@ dependencies = [ "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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (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.103 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -8032,14 +8060,14 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.34" +version = "0.3.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.35 (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.57 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-webidl 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-webidl 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -8177,7 +8205,7 @@ 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)", "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)", + "log 0.4.10 (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)", @@ -8217,7 +8245,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.3 (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)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "nohash-hasher 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -8294,8 +8322,7 @@ dependencies = [ "checksum asn1_der 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6fce6b6a0ffdafebd82c87e79e3f40e8d2c523e5fea5566ff6b90509bf98d638" "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.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "513ee3c49800679a319912340f5601afda9e72848d7dea3a48bab489e8c1a46f" +"checksum async-std 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94ef4b71b2f56d7f8793c2a353fa0aa254833c55ab611dc6f3e0bd63db487e2d" "checksum async-task 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de6bd58f7b9cc49032559422595c81cbfcf04db2f2133592f70af19e258a1ced" "checksum async-tls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce6977f57fa68da77ffe5542950d47e9c23d65f5bc7cb0a9f8700996913eec7" "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" @@ -8322,7 +8349,7 @@ dependencies = [ "checksum bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b170cd256a3f9fa6b9edae3e44a7dfdfc77e8124dbc3e2612d75f9c3e2396dae" "checksum bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6c2c5b58ab920a4f5aeaaca34b4488074e8cc7596af94e6f8c6ff247c60245" "checksum build-helper 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdce191bf3fa4995ce948c8c83b4640a1745457a149e73c6db75b4ffe36aad5f" -"checksum bumpalo 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fe2567a8d8a3aedb4e39aa39e186d5673acfd56393c6ac83b2bc5bd82f4369c" +"checksum bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb8038c1ddc0a5f73787b130f4cc75151e96ed33e417fde765eb5a81e3532f4" "checksum byte-slice-cast 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f6209f3b2c1edea170002e016d5ead6903d3bb0a846477f53bbeb614967a52a9" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" @@ -8459,7 +8486,7 @@ dependencies = [ "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 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 hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f629dc602392d3ec14bfc8a09b5e644d7ffd725102b48b81e59f90f2633621d7" "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" @@ -8490,7 +8517,7 @@ dependencies = [ "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.34 (registry+https://github.com/rust-lang/crates.io-index)" = "c40e7a4fafb6cf0be06d25662fc99aacb25f526eb6e1bc0c24100bde5d6a834e" +"checksum js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "7889c7c36282151f6bf465be4700359318aef36baa951462382eae49e9577cf9" "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" @@ -8540,7 +8567,7 @@ dependencies = [ "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "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 log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "1b9ad466a945c9c40f6f9a449c55675547e59bc75a2722d4689042ab3ae80c9c" "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" @@ -8589,7 +8616,7 @@ dependencies = [ "checksum parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df3a17dc27848fd99e4f87eb0f8c9baba6ede0a6d555400c850ca45254ef4ce3" "checksum parity-multihash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70a4d7b05e51bff5ae2c29c7b8c3d889985bbd8f4e15b3542fcc1f6f9666d292" "checksum parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f747c06d9f3b2ad387ac881b9667298c81b1243aa9833f086e05996937c35507" -"checksum parity-scale-codec-derive 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34e513ff3e406f3ede6796dcdc83d0b32ffb86668cea1ccf7363118abeb00476" +"checksum parity-scale-codec-derive 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "492ac3aa93d6caa5d20e4e3e0b75d08e2dcd9dd8a50d19529548b6fe11b3f295" "checksum parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" "checksum parity-util-mem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8174d85e62c4d615fddd1ef67966bdc5757528891d0742f15b131ad04667b3f9" "checksum parity-util-mem 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "900dd84654b048e5bad420bb341658fc2c4d7fea628c22bcf4621733e54859b4" @@ -8698,8 +8725,8 @@ dependencies = [ "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 send_wrapper 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "686ef91cf020ad8d4aca9a7047641fd6add626b7b89e14546c2b6a76781cf822" -"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 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" +"checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" "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" @@ -8715,7 +8742,7 @@ dependencies = [ "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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "afb767eee7d257ba202f0b9b08673bc13b22281632ef45267b19f13100accd2f" -"checksum soketto 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c9dab3f95c9ebdf3a88268c19af668f637a3c5039c2c56ff2d40b1b2d64a25b" +"checksum soketto 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3caa0ad6b765419f21e4cfa490ec7514a9fae4af986adef168a69477ba528671" "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" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" @@ -8762,6 +8789,7 @@ dependencies = [ "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-macros 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5795a71419535c6dcecc9b6ca95bdd3c2d6142f7e8343d7beb9923f129aa87e" "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" @@ -8815,13 +8843,13 @@ dependencies = [ "checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" "checksum want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" "checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" -"checksum wasm-bindgen 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)" = "701bc20794a7f9e8dcd85984a848f951ef6c5083322b6dd17fe880c99390f7cd" -"checksum wasm-bindgen-backend 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)" = "426315280d373e1a828e1c322507d51aa82e03c2fb1d654720b9e2f2368d291d" -"checksum wasm-bindgen-futures 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1de54efe80cb87a8fa1f715d60ab47a5eac6b1447dd68665300773f498c229b1" -"checksum wasm-bindgen-macro 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)" = "d9a8a46373db32c892de910ccca302ecdaf8262abab746324a8a4dac352fc11f" -"checksum wasm-bindgen-macro-support 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)" = "45d1c6c2259c0f4ef3d61ea0976ea075b6f8185497c4a5457793740c2cda6430" -"checksum wasm-bindgen-shared 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)" = "dd8e108ae395aae8017b091c4766101f08c635a5074e6631e0085e8a839e5810" -"checksum wasm-bindgen-webidl 0.2.57 (registry+https://github.com/rust-lang/crates.io-index)" = "7a38859ace1c29c8ed75cd74940d4c96b980837179355de542a2eab3b435bb5c" +"checksum wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c" +"checksum wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "11cdb95816290b525b32587d76419facd99662a07e59d3cdb560488a819d9a45" +"checksum wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8bbdd49e3e28b40dec6a9ba8d17798245ce32b019513a845369c641b275135d9" +"checksum wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "574094772ce6921576fb6f2e3f7497b8a76273b6db092be18fc48a082de09dc3" +"checksum wasm-bindgen-macro-support 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" +"checksum wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e7e61fc929f4c0dddb748b102ebf9f632e2b8d739f2016542b4de2965a9601" +"checksum wasm-bindgen-webidl 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "ef012a0d93fc0432df126a8eaf547b2dce25a8ce9212e1d3cbeef5c11157975d" "checksum wasm-gc-api 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c32691b6c7e6c14e7f8fd55361a9088b507aa49620fcd06c09b3a1082186b9" "checksum wasm-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "324c5e65a08699c9c4334ba136597ab22b85dccd4b65dd1e36ccf8f723a95b54" "checksum wasmi 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bf617d864d25af3587aa745529f7aaa541066c876d57e050c0d0c85c61c92aff" @@ -8831,7 +8859,7 @@ dependencies = [ "checksum wasmtime-environ 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a3947662a0b8e05b1418465e64f16de9114f9fec18cc3f56e0ed5aa7737b89d0" "checksum wasmtime-jit 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ed7922689461a7b5bd0d9c7350cac526c8a520a23b3ffd7f5b446ac51dfc51f" "checksum wasmtime-runtime 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "781d6bb8b346efaa3dc39746386957cd79b8d841e8652ed9b02d77bcf64fb514" -"checksum web-sys 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)" = "ba09295448c0b93bc87d2769614d371a924749e5e6c87e4c1df8b2416b49b775" +"checksum web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf97caf6aa8c2b1dac90faf0db529d9d63c93846cca4911856f78a83cebf53b" "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" diff --git a/Cargo.toml b/Cargo.toml index fb15de2ebe..5dd85091cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ members = [ "client/cli", "client/consensus/aura", "client/consensus/babe", + "client/consensus/manual-seal", "client/consensus/pow", "client/consensus/slots", "client/consensus/uncles", diff --git a/bin/node/cli/src/browser.rs b/bin/node/cli/src/browser.rs index 9747a583c7..b41bbe6281 100644 --- a/bin/node/cli/src/browser.rs +++ b/bin/node/cli/src/browser.rs @@ -43,7 +43,7 @@ async fn start_inner(wasm_ext: Transport) -> Result(args: I, exit: E, version: sc_cli::VersionInfo) -> error::Re |exit, _cli_args, _custom_args, mut config: Config<_, _>| { info!("{}", version.name); info!(" version {}", config.full_version()); - info!(" by Parity Technologies, 2017-2019"); + info!(" by Parity Technologies, 2017-2020"); info!("Chain specification: {}", config.chain_spec.name()); info!("Node name: {}", config.name); info!("Roles: {}", display_role(&config)); diff --git a/client/consensus/manual-seal/Cargo.toml b/client/consensus/manual-seal/Cargo.toml new file mode 100644 index 0000000000..83d7535dae --- /dev/null +++ b/client/consensus/manual-seal/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "sc-consensus-manual-seal" +version = "0.8.0" +authors = ["Parity Technologies "] +description = "Manual sealing engine for Substrate" +edition = "2018" + +[dependencies] +derive_more = "0.99.2" +futures = "0.3.1" +jsonrpc-core = "14.0.5" +jsonrpc-core-client = "14.0.5" +jsonrpc-derive = "14.0.5" +log = "0.4.8" +parking_lot = "0.10" +serde = { version = "1.0", features=["derive"] } + +sc-client = { path = "../../../client" } +sc-client-api = { path = "../../../client/api" } +sc-transaction-pool = { path = "../../transaction-pool", features = ["test-helpers"] } +sp-blockchain = { path = "../../../primitives/blockchain" } +sp-consensus = { package = "sp-consensus", path = "../../../primitives/consensus/common" } +sp-inherents = { path = "../../../primitives/inherents" } +sp-runtime = { path = "../../../primitives/runtime" } +sp-transaction-pool = { path = "../../../primitives/transaction-pool" } + +[dev-dependencies] +sc-basic-authorship = { path = "../../basic-authorship" } +substrate-test-runtime-client = { path = "../../../test-utils/runtime/client" } +tokio = { version = "0.2", features = ["rt-core", "macros"] } +env_logger = "0.7.0" +tempfile = "3.1.0" diff --git a/client/consensus/manual-seal/src/error.rs b/client/consensus/manual-seal/src/error.rs new file mode 100644 index 0000000000..d6ee9f1767 --- /dev/null +++ b/client/consensus/manual-seal/src/error.rs @@ -0,0 +1,98 @@ +// Copyright 2020 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 manual sealing engine: the engine listens for rpc calls to seal blocks and create forks. +//! This is suitable for a testing environment. +use sp_consensus::{Error as ConsensusError, ImportResult}; +use sp_blockchain::Error as BlockchainError; +use sp_inherents::Error as InherentsError; +use futures::channel::{oneshot, mpsc::SendError}; + +/// Error code for rpc +mod codes { + pub const SERVER_SHUTTING_DOWN: i64 = 10_000; + pub const BLOCK_IMPORT_FAILED: i64 = 11_000; + pub const EMPTY_TRANSACTION_POOL: i64 = 12_000; + pub const BLOCK_NOT_FOUND: i64 = 13_000; + pub const CONSENSUS_ERROR: i64 = 14_000; + pub const INHERENTS_ERROR: i64 = 15_000; + pub const BLOCKCHAIN_ERROR: i64 = 16_000; + pub const UNKNOWN_ERROR: i64 = 20_000; +} + +/// errors encountered by background block authorship task +#[derive(Debug, derive_more::Display, derive_more::From)] +pub enum Error { + /// An error occurred while importing the block + #[display(fmt = "Block import failed: {:?}", _0)] + BlockImportError(ImportResult), + /// Transaction pool is empty, cannot create a block + #[display(fmt = "Transaction pool is empty, set create_empty to true,\ + if you want to create empty blocks")] + EmptyTransactionPool, + /// encountered during creation of Proposer. + #[display(fmt = "Consensus Error: {}", _0)] + ConsensusError(ConsensusError), + /// Failed to create Inherents data + #[display(fmt = "Inherents Error: {}", _0)] + InherentError(InherentsError), + /// error encountered during finalization + #[display(fmt = "Finalization Error: {}", _0)] + BlockchainError(BlockchainError), + /// Supplied parent_hash doesn't exist in chain + #[display(fmt = "Supplied parent_hash: {} doesn't exist in chain", _0)] + #[from(ignore)] + BlockNotFound(String), + /// Some string error + #[display(fmt = "{}", _0)] + #[from(ignore)] + StringError(String), + ///send error + #[display(fmt = "Consensus process is terminating")] + Canceled(oneshot::Canceled), + ///send error + #[display(fmt = "Consensus process is terminating")] + SendError(SendError), + /// Some other error. + #[display(fmt="Other error: {}", _0)] + Other(Box), +} + +impl Error { + fn to_code(&self) -> i64 { + use Error::*; + match self { + BlockImportError(_) => codes::BLOCK_IMPORT_FAILED, + BlockNotFound(_) => codes::BLOCK_NOT_FOUND, + EmptyTransactionPool => codes::EMPTY_TRANSACTION_POOL, + ConsensusError(_) => codes::CONSENSUS_ERROR, + InherentError(_) => codes::INHERENTS_ERROR, + BlockchainError(_) => codes::BLOCKCHAIN_ERROR, + SendError(_) | Canceled(_) => codes::SERVER_SHUTTING_DOWN, + _ => codes::UNKNOWN_ERROR + } + } +} + +impl std::convert::From for jsonrpc_core::Error { + fn from(error: Error) -> Self { + jsonrpc_core::Error { + code: jsonrpc_core::ErrorCode::ServerError(error.to_code()), + message: format!("{}", error), + data: None + } + } +} diff --git a/client/consensus/manual-seal/src/finalize_block.rs b/client/consensus/manual-seal/src/finalize_block.rs new file mode 100644 index 0000000000..419159709f --- /dev/null +++ b/client/consensus/manual-seal/src/finalize_block.rs @@ -0,0 +1,64 @@ +// 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 . + +//! Block finalization utilities + +use crate::rpc; +use sp_runtime::{ + Justification, + traits::Block as BlockT, + generic::BlockId, +}; +use std::sync::Arc; +use sc_client_api::backend::Backend as ClientBackend; + +/// params for block finalization. +pub struct FinalizeBlockParams { + /// hash of the block + pub hash: ::Hash, + /// sender to report errors/success to the rpc. + pub sender: rpc::Sender<()>, + /// finalization justification + pub justification: Option, + /// client backend + pub backend: Arc, +} + +/// finalizes a block in the backend with the given params. +pub async fn finalize_block(params: FinalizeBlockParams) + where + B: BlockT, + CB: ClientBackend, +{ + let FinalizeBlockParams { + hash, + mut sender, + justification, + backend: back_end, + .. + } = params; + + match back_end.finalize_block(BlockId::Hash(hash), justification) { + Err(e) => { + log::warn!("Failed to finalize block {:?}", e); + rpc::send_result(&mut sender, Err(e.into())) + } + Ok(()) => { + log::info!("Successfully finalized block: {}", hash); + rpc::send_result(&mut sender, Ok(())) + } + } +} \ No newline at end of file diff --git a/client/consensus/manual-seal/src/lib.rs b/client/consensus/manual-seal/src/lib.rs new file mode 100644 index 0000000000..3bd85b9380 --- /dev/null +++ b/client/consensus/manual-seal/src/lib.rs @@ -0,0 +1,467 @@ +// Copyright 2020 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 manual sealing engine: the engine listens for rpc calls to seal blocks and create forks. +//! This is suitable for a testing environment. + +use sp_consensus::{ + self, BlockImport, Environment, Proposer, BlockCheckParams, + ForkChoiceStrategy, BlockImportParams, BlockOrigin, + ImportResult, SelectChain, + import_queue::{ + BasicQueue, + CacheKeyId, + Verifier, + BoxBlockImport, + }, +}; +use sp_inherents::InherentDataProviders; +use sp_runtime::{traits::Block as BlockT, Justification}; +use sc_client_api::backend::Backend as ClientBackend; +use futures::prelude::*; +use sc_transaction_pool::txpool; +use std::collections::HashMap; +use std::sync::Arc; + +pub mod rpc; +mod error; +mod finalize_block; +mod seal_new_block; +use finalize_block::{finalize_block, FinalizeBlockParams}; +use seal_new_block::{seal_new_block, SealBlockParams}; +pub use error::Error; +pub use rpc::{EngineCommand, CreatedBlock}; + +/// The synchronous block-import worker of the engine. +pub struct ManualSealBlockImport { + inner: I, +} + +impl From for ManualSealBlockImport { + fn from(i: I) -> Self { + ManualSealBlockImport { inner: i } + } +} + +impl BlockImport for ManualSealBlockImport + where + B: BlockT, + I: BlockImport, +{ + type Error = I::Error; + type Transaction = (); + + fn check_block(&mut self, block: BlockCheckParams) -> Result + { + self.inner.check_block(block) + } + + fn import_block( + &mut self, + block: BlockImportParams, + cache: HashMap>, + ) -> Result { + self.inner.import_block(block, cache) + } +} + +/// The verifier for the manual seal engine; instantly finalizes. +struct ManualSealVerifier; + +impl Verifier for ManualSealVerifier { + fn verify( + &mut self, + origin: BlockOrigin, + header: B::Header, + justification: Option, + body: Option>, + ) -> Result<(BlockImportParams, Option)>>), String> { + let import_params = BlockImportParams { + origin, + header, + justification, + post_digests: Vec::new(), + body, + storage_changes: None, + finalized: true, + auxiliary: Vec::new(), + intermediates: HashMap::new(), + fork_choice: Some(ForkChoiceStrategy::LongestChain), + allow_missing_state: false, + import_existing: false, + }; + + Ok((import_params, None)) + } +} + +/// Instantiate the import queue for the manual seal consensus engine. +pub fn import_queue(block_import: BoxBlockImport) -> BasicQueue +{ + BasicQueue::new( + ManualSealVerifier, + block_import, + None, + None, + ) +} + +/// Creates the background authorship task for the manual seal engine. +pub async fn run_manual_seal( + mut block_import: BoxBlockImport, + mut env: E, + backend: Arc, + pool: Arc>, + mut seal_block_channel: S, + select_chain: C, + inherent_data_providers: InherentDataProviders, +) + where + B: BlockT + 'static, + CB: ClientBackend + 'static, + E: Environment + 'static, + E::Error: std::fmt::Display, + >::Error: std::fmt::Display, + A: txpool::ChainApi::Hash> + 'static, + S: Stream::Hash>> + Unpin + 'static, + C: SelectChain + 'static, +{ + while let Some(command) = seal_block_channel.next().await { + match command { + EngineCommand::SealNewBlock { + create_empty, + finalize, + parent_hash, + sender, + } => { + seal_new_block( + SealBlockParams { + sender, + parent_hash, + finalize, + create_empty, + env: &mut env, + select_chain: &select_chain, + block_import: &mut block_import, + inherent_data_provider: &inherent_data_providers, + pool: pool.clone(), + backend: backend.clone(), + } + ).await; + } + EngineCommand::FinalizeBlock { hash, sender, justification } => { + finalize_block( + FinalizeBlockParams { + hash, + sender, + justification, + backend: backend.clone(), + } + ).await + } + } + } +} + +/// runs the background authorship task for the instant seal engine. +/// instant-seal creates a new block for every transaction imported into +/// the transaction pool. +pub async fn run_instant_seal( + block_import: BoxBlockImport, + env: E, + backend: Arc, + pool: Arc>, + select_chain: C, + inherent_data_providers: InherentDataProviders, +) + where + A: txpool::ChainApi::Hash> + 'static, + B: BlockT + 'static, + CB: ClientBackend + 'static, + E: Environment + 'static, + E::Error: std::fmt::Display, + >::Error: std::fmt::Display, + C: SelectChain + 'static +{ + // instant-seal creates blocks as soon as transactions are imported + // into the transaction pool. + let seal_block_channel = pool.import_notification_stream() + .map(|_| { + EngineCommand::SealNewBlock { + create_empty: false, + finalize: false, + parent_hash: None, + sender: None, + } + }); + + run_manual_seal( + block_import, + env, + backend, + pool, + seal_block_channel, + select_chain, + inherent_data_providers, + ).await +} + +#[cfg(test)] +mod tests { + use super::*; + use substrate_test_runtime_client::{ + DefaultTestClientBuilderExt, + TestClientBuilderExt, + AccountKeyring::*, + TestClientBuilder, + }; + use sc_transaction_pool::{ + BasicPool, + txpool::Options, + testing::*, + }; + use sp_transaction_pool::TransactionPool; + use sp_runtime::generic::BlockId; + use sp_blockchain::HeaderBackend; + use sp_consensus::ImportedAux; + use sc_client::LongestChain; + use sp_inherents::InherentDataProviders; + use sc_basic_authorship::ProposerFactory; + + fn api() -> TestApi { + let mut api = TestApi::default(); + api.nonce_offset = 0; + + api + } + + #[tokio::test] + async fn instant_seal() { + let builder = TestClientBuilder::new(); + let backend = builder.backend(); + let client = Arc::new(builder.build()); + let select_chain = LongestChain::new(backend.clone()); + let inherent_data_providers = InherentDataProviders::new(); + let pool = Arc::new(BasicPool::new(Options::default(), api())); + let env = ProposerFactory { + transaction_pool: pool.clone(), + client: client.clone(), + }; + // this test checks that blocks are created as soon as transactions are imported into the pool. + let (sender, receiver) = futures::channel::oneshot::channel(); + let mut sender = Arc::new(Some(sender)); + let stream = pool.pool().import_notification_stream() + .map(move |_| { + // we're only going to submit one tx so this fn will only be called once. + let mut_sender = Arc::get_mut(&mut sender).unwrap(); + let sender = std::mem::replace(mut_sender, None); + EngineCommand::SealNewBlock { + create_empty: false, + finalize: true, + parent_hash: None, + sender + } + }); + let future = run_manual_seal( + Box::new(client.clone()), + env, + backend.clone(), + pool.pool().clone(), + stream, + select_chain, + inherent_data_providers, + ); + std::thread::spawn(|| { + let mut rt = tokio::runtime::Runtime::new().unwrap(); + // spawn the background authorship task + rt.block_on(future); + }); + // submit a transaction to pool. + let result = pool.submit_one(&BlockId::Number(0), uxt(Alice, 0)).await; + // assert that it was successfully imported + assert!(result.is_ok()); + // assert that the background task returns ok + let created_block = receiver.await.unwrap().unwrap(); + assert_eq!( + created_block, + CreatedBlock { + hash: created_block.hash.clone(), + aux: ImportedAux { + header_only: false, + clear_justification_requests: false, + needs_justification: false, + bad_justification: false, + needs_finality_proof: false, + is_new_best: true, + } + } + ); + // assert that there's a new block in the db. + assert!(backend.blockchain().header(BlockId::Number(1)).unwrap().is_some()) + } + + #[tokio::test] + async fn manual_seal_and_finalization() { + let builder = TestClientBuilder::new(); + let backend = builder.backend(); + let client = Arc::new(builder.build()); + let select_chain = LongestChain::new(backend.clone()); + let inherent_data_providers = InherentDataProviders::new(); + let pool = Arc::new(BasicPool::new(Options::default(), api())); + let env = ProposerFactory { + transaction_pool: pool.clone(), + client: client.clone(), + }; + // this test checks that blocks are created as soon as an engine command is sent over the stream. + let (mut sink, stream) = futures::channel::mpsc::channel(1024); + let future = run_manual_seal( + Box::new(client.clone()), + env, + backend.clone(), + pool.pool().clone(), + stream, + select_chain, + inherent_data_providers, + ); + std::thread::spawn(|| { + let mut rt = tokio::runtime::Runtime::new().unwrap(); + // spawn the background authorship task + rt.block_on(future); + }); + // submit a transaction to pool. + let result = pool.submit_one(&BlockId::Number(0), uxt(Alice, 0)).await; + // assert that it was successfully imported + assert!(result.is_ok()); + let (tx, rx) = futures::channel::oneshot::channel(); + sink.send(EngineCommand::SealNewBlock { + parent_hash: None, + sender: Some(tx), + create_empty: false, + finalize: false, + }).await.unwrap(); + let created_block = rx.await.unwrap().unwrap(); + + // assert that the background task returns ok + assert_eq!( + created_block, + CreatedBlock { + hash: created_block.hash.clone(), + aux: ImportedAux { + header_only: false, + clear_justification_requests: false, + needs_justification: false, + bad_justification: false, + needs_finality_proof: false, + is_new_best: true, + } + } + ); + // assert that there's a new block in the db. + let header = backend.blockchain().header(BlockId::Number(1)).unwrap().unwrap(); + let (tx, rx) = futures::channel::oneshot::channel(); + sink.send(EngineCommand::FinalizeBlock { + sender: Some(tx), + hash: header.hash(), + justification: None + }).await.unwrap(); + // assert that the background task returns ok + assert_eq!(rx.await.unwrap().unwrap(), ()); + } + + #[tokio::test] + async fn manual_seal_fork_blocks() { + let builder = TestClientBuilder::new(); + let backend = builder.backend(); + let client = Arc::new(builder.build()); + let select_chain = LongestChain::new(backend.clone()); + let inherent_data_providers = InherentDataProviders::new(); + let pool = Arc::new(BasicPool::new(Options::default(), api())); + let env = ProposerFactory { + transaction_pool: pool.clone(), + client: client.clone(), + }; + // this test checks that blocks are created as soon as an engine command is sent over the stream. + let (mut sink, stream) = futures::channel::mpsc::channel(1024); + let future = run_manual_seal( + Box::new(client.clone()), + env, + backend.clone(), + pool.pool().clone(), + stream, + select_chain, + inherent_data_providers, + ); + std::thread::spawn(|| { + let mut rt = tokio::runtime::Runtime::new().unwrap(); + // spawn the background authorship task + rt.block_on(future); + }); + // submit a transaction to pool. + let result = pool.submit_one(&BlockId::Number(0), uxt(Alice, 0)).await; + // assert that it was successfully imported + assert!(result.is_ok()); + + let (tx, rx) = futures::channel::oneshot::channel(); + sink.send(EngineCommand::SealNewBlock { + parent_hash: None, + sender: Some(tx), + create_empty: false, + finalize: false, + }).await.unwrap(); + let created_block = rx.await.unwrap().unwrap(); + + // assert that the background task returns ok + assert_eq!( + created_block, + CreatedBlock { + hash: created_block.hash.clone(), + aux: ImportedAux { + header_only: false, + clear_justification_requests: false, + needs_justification: false, + bad_justification: false, + needs_finality_proof: false, + is_new_best: true + } + } + ); + // assert that there's a new block in the db. + assert!(backend.blockchain().header(BlockId::Number(0)).unwrap().is_some()); + assert!(pool.submit_one(&BlockId::Number(1), uxt(Alice, 1)).await.is_ok()); + + let (tx1, rx1) = futures::channel::oneshot::channel(); + assert!(sink.send(EngineCommand::SealNewBlock { + parent_hash: Some(created_block.hash.clone()), + sender: Some(tx1), + create_empty: false, + finalize: false, + }).await.is_ok()); + assert!(rx1.await.unwrap().is_ok()); + assert!(backend.blockchain().header(BlockId::Number(1)).unwrap().is_some()); + + assert!(pool.submit_one(&BlockId::Number(2), uxt(Alice, 2)).await.is_ok()); + let (tx2, rx2) = futures::channel::oneshot::channel(); + assert!(sink.send(EngineCommand::SealNewBlock { + parent_hash: Some(created_block.hash), + sender: Some(tx2), + create_empty: false, + finalize: false, + }).await.is_ok()); + let imported = rx2.await.unwrap().unwrap(); + // assert that fork block is in the db + assert!(backend.blockchain().header(BlockId::Hash(imported.hash)).unwrap().is_some()) + } +} diff --git a/client/consensus/manual-seal/src/rpc.rs b/client/consensus/manual-seal/src/rpc.rs new file mode 100644 index 0000000000..f3f0fe4a12 --- /dev/null +++ b/client/consensus/manual-seal/src/rpc.rs @@ -0,0 +1,163 @@ +// 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 interface for the ManualSeal Engine. +use sp_consensus::ImportedAux; +use jsonrpc_core::Error; +use jsonrpc_derive::rpc; +use futures::{ + channel::{mpsc, oneshot}, + TryFutureExt, + FutureExt, + SinkExt +}; +use serde::{Deserialize, Serialize}; +use sp_runtime::Justification; +pub use self::gen_client::Client as ManualSealClient; + +/// Future's type for jsonrpc +type FutureResult = Box + Send>; +/// sender passed to the authorship task to report errors or successes. +pub type Sender = Option>>; + +/// Message sent to the background authorship task, usually by RPC. +pub enum EngineCommand { + /// Tells the engine to propose a new block + /// + /// if create_empty == true, it will create empty blocks if there are no transactions + /// in the transaction pool. + /// + /// if finalize == true, the block will be instantly finalized. + SealNewBlock { + /// if true, empty blocks(without extrinsics) will be created. + /// otherwise, will return Error::EmptyTransactionPool. + create_empty: bool, + /// instantly finalize this block? + finalize: bool, + /// specify the parent hash of the about-to-created block + parent_hash: Option, + /// sender to report errors/success to the rpc. + sender: Sender>, + }, + /// Tells the engine to finalize the block with the supplied hash + FinalizeBlock { + /// hash of the block + hash: Hash, + /// sender to report errors/success to the rpc. + sender: Sender<()>, + /// finalization justification + justification: Option, + } +} + +/// RPC trait that provides methods for interacting with the manual-seal authorship task over rpc. +#[rpc] +pub trait ManualSealApi { + /// Instructs the manual-seal authorship task to create a new block + #[rpc(name = "engine_createBlock")] + fn create_block( + &self, + create_empty: bool, + finalize: bool, + parent_hash: Option + ) -> FutureResult>; + + /// Instructs the manual-seal authorship task to finalize a block + #[rpc(name = "engine_finalizeBlock")] + fn finalize_block( + &self, + hash: Hash, + justification: Option + ) -> FutureResult; +} + +/// A struct that implements the [`ManualSealApi`]. +pub struct ManualSeal { + import_block_channel: mpsc::Sender>, +} + +/// return type of `engine_createBlock` +#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)] +pub struct CreatedBlock { + /// hash of the created block. + pub hash: Hash, + /// some extra details about the import operation + pub aux: ImportedAux +} + +impl ManualSeal { + /// Create new `ManualSeal` with the given reference to the client. + pub fn new(import_block_channel: mpsc::Sender>) -> Self { + Self { import_block_channel } + } +} + +impl ManualSealApi for ManualSeal { + fn create_block( + &self, + create_empty: bool, + finalize: bool, + parent_hash: Option + ) -> FutureResult> { + let mut sink = self.import_block_channel.clone(); + let future = async move { + let (sender, receiver) = oneshot::channel(); + let command = EngineCommand::SealNewBlock { + create_empty, + finalize, + parent_hash, + sender: Some(sender), + }; + sink.send(command).await?; + receiver.await? + }.boxed(); + + Box::new(future.map_err(Error::from).compat()) + } + + fn finalize_block(&self, hash: Hash, justification: Option) -> FutureResult { + let mut sink = self.import_block_channel.clone(); + let future = async move { + let (sender, receiver) = oneshot::channel(); + sink.send( + EngineCommand::FinalizeBlock { hash, sender: Some(sender), justification } + ).await?; + + receiver.await?.map(|_| true) + }; + + Box::new(future.boxed().map_err(Error::from).compat()) + } +} + +/// report any errors or successes encountered by the authorship task back +/// to the rpc +pub fn send_result( + sender: &mut Sender, + result: std::result::Result +) { + if let Some(sender) = sender.take() { + if let Err(err) = sender.send(result) { + log::warn!("Server is shutting down: {:?}", err) + } + } else { + // instant seal doesn't report errors over rpc, simply log them. + match result { + Ok(r) => log::info!("Instant Seal success: {:?}", r), + Err(e) => log::error!("Instant Seal encountered an error: {}", e) + } + } +} diff --git a/client/consensus/manual-seal/src/seal_new_block.rs b/client/consensus/manual-seal/src/seal_new_block.rs new file mode 100644 index 0000000000..53dc82d353 --- /dev/null +++ b/client/consensus/manual-seal/src/seal_new_block.rs @@ -0,0 +1,148 @@ +// 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 . + +//! Block sealing utilities + +use crate::{Error, rpc}; +use std::sync::Arc; +use sp_runtime::{ + traits::{Block as BlockT, Header as HeaderT}, + generic::BlockId, +}; +use futures::prelude::*; +use sc_transaction_pool::txpool; +use rpc::CreatedBlock; + +use sp_consensus::{ + self, BlockImport, Environment, Proposer, + ForkChoiceStrategy, BlockImportParams, BlockOrigin, + ImportResult, SelectChain, + import_queue::BoxBlockImport, +}; +use sp_blockchain::HeaderBackend; +use sc_client_api::backend::Backend as ClientBackend; +use std::collections::HashMap; +use std::time::Duration; +use sp_inherents::InherentDataProviders; + +/// max duration for creating a proposal in secs +const MAX_PROPOSAL_DURATION: u64 = 10; + +/// params for sealing a new block +pub struct SealBlockParams<'a, B: BlockT, C, CB, E, T, P: txpool::ChainApi> { + /// if true, empty blocks(without extrinsics) will be created. + /// otherwise, will return Error::EmptyTransactionPool. + pub create_empty: bool, + /// instantly finalize this block? + pub finalize: bool, + /// specify the parent hash of the about-to-created block + pub parent_hash: Option<::Hash>, + /// sender to report errors/success to the rpc. + pub sender: rpc::Sender::Hash>>, + /// transaction pool + pub pool: Arc>, + /// client backend + pub backend: Arc, + /// Environment trait object for creating a proposer + pub env: &'a mut E, + /// SelectChain object + pub select_chain: &'a C, + /// block import object + pub block_import: &'a mut BoxBlockImport, + /// inherent data provider + pub inherent_data_provider: &'a InherentDataProviders, +} + +/// seals a new block with the given params +pub async fn seal_new_block( + SealBlockParams { + create_empty, + finalize, + pool, + parent_hash, + backend: back_end, + select_chain, + block_import, + env, + inherent_data_provider, + mut sender, + .. + }: SealBlockParams<'_, B, SC, CB, E, T, P> +) + where + B: BlockT, + CB: ClientBackend, + E: Environment, + >::Error: std::fmt::Display, + >::Error: std::fmt::Display, + P: txpool::ChainApi::Hash>, + SC: SelectChain, +{ + let future = async { + if pool.status().ready == 0 && !create_empty { + return Err(Error::EmptyTransactionPool) + } + + // get the header to build this new block on. + // use the parent_hash supplied via `EngineCommand` + // or fetch the best_block. + let header = match parent_hash { + Some(hash) => { + match back_end.blockchain().header(BlockId::Hash(hash))? { + Some(header) => header, + None => return Err(Error::BlockNotFound(format!("{}", hash))), + } + } + None => select_chain.best_chain()? + }; + + let mut proposer = env.init(&header) + .map_err(|err| Error::StringError(format!("{}", err))).await?; + let id = inherent_data_provider.create_inherent_data()?; + let inherents_len = id.len(); + let proposal = proposer.propose(id, Default::default(), Duration::from_secs(MAX_PROPOSAL_DURATION), false.into()) + .map_err(|err| Error::StringError(format!("{}", err))).await?; + + if proposal.block.extrinsics().len() == inherents_len && !create_empty { + return Err(Error::EmptyTransactionPool) + } + + let (header, body) = proposal.block.deconstruct(); + let params = BlockImportParams { + origin: BlockOrigin::Own, + header: header.clone(), + justification: None, + post_digests: Vec::new(), + body: Some(body), + finalized: finalize, + storage_changes: None, + auxiliary: Vec::new(), + intermediates: HashMap::new(), + fork_choice: Some(ForkChoiceStrategy::LongestChain), + allow_missing_state: false, + import_existing: false, + }; + + match block_import.import_block(params, HashMap::new())? { + ImportResult::Imported(aux) => { + Ok(CreatedBlock { hash: ::Header::hash(&header), aux }) + }, + other => Err(other.into()), + } + }; + + rpc::send_result(&mut sender, future.await) +} diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index 7018263071..c3cd8c9838 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -10,14 +10,17 @@ derive_more = "0.99.2" futures = { version = "0.3.1", features = ["compat"] } log = "0.4.8" parking_lot = "0.9.0" -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" } +sp-core = { path = "../../primitives/core" } +sp-api = { path = "../../primitives/api" } +sp-runtime = { path = "../../primitives/runtime" } +sc-transaction-graph = { path = "./graph" } +sp-transaction-pool = { path = "../../primitives/transaction-pool" } +sc-client-api = { path = "../api" } +sp-blockchain = { path = "../../primitives/blockchain" } +substrate-test-runtime-client = { path = "../../test-utils/runtime/client" } [dev-dependencies] sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } -substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" } + +[features] +test-helpers = [] diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index b085dba279..2771471ad9 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -24,6 +24,8 @@ pub mod error; #[cfg(test)] mod tests; +#[cfg(any(feature = "test-helpers", test))] +pub mod testing; pub use sc_transaction_graph as txpool; pub use crate::api::{FullChainApi, LightChainApi}; diff --git a/client/transaction-pool/src/testing.rs b/client/transaction-pool/src/testing.rs new file mode 100644 index 0000000000..f4fecbe1d6 --- /dev/null +++ b/client/transaction-pool/src/testing.rs @@ -0,0 +1,185 @@ +// Copyright 2018-2020 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 . + +//! Utilities for testing transaction pool +use super::*; +use codec::Encode; +use sp_runtime::{ + generic::{BlockId}, + traits::{Hash as HashT, BlakeTwo256}, + transaction_validity::{TransactionValidity, ValidTransaction, TransactionValidityError, InvalidTransaction}, +}; +use std::collections::HashSet; +use crate::BasicPool; +use parking_lot::RwLock; +use sc_transaction_graph::{self, ExHash, Pool}; +use substrate_test_runtime_client::{ + runtime::{AccountId, Block, BlockNumber, Extrinsic, Hash, Header, Index, Transfer}, + AccountKeyring, +}; + +/// `ChainApi` for test environments +pub struct TestApi { + /// transaction modifier + pub modifier: RwLock>, + /// cache of block number to extrinsics + pub chain_block_by_number: RwLock>>, + /// cache of block number to header + pub chain_headers_by_number: RwLock>, + /// cache of invalid hashes + pub invalid_hashes: RwLock>>, + /// validation requests + pub validation_requests: RwLock>, + /// used for calculating nonce for extrinsics + pub nonce_offset: u64, +} + +impl TestApi { + /// create an instance of `TestApi` + pub fn default() -> Self { + TestApi { + modifier: RwLock::new(Box::new(|_| {})), + chain_block_by_number: RwLock::new(HashMap::new()), + invalid_hashes: RwLock::new(HashSet::new()), + chain_headers_by_number: RwLock::new(HashMap::new()), + validation_requests: RwLock::new(Default::default()), + nonce_offset: 209, + } + } + + /// add a block to `TestApi` + pub fn push_block(&self, block_number: BlockNumber, xts: Vec) { + self.chain_block_by_number.write().insert(block_number, xts); + self.chain_headers_by_number.write().insert(block_number, Header { + number: block_number, + digest: Default::default(), + extrinsics_root: Default::default(), + parent_hash: Default::default(), + state_root: Default::default(), + }); + } +} + +impl sc_transaction_graph::ChainApi for TestApi { + type Block = Block; + type Hash = Hash; + type Error = error::Error; + type ValidationFuture = futures::future::Ready>; + type BodyFuture = futures::future::Ready>>>; + + fn validate_transaction( + &self, + at: &BlockId, + uxt: sc_transaction_graph::ExtrinsicFor, + ) -> Self::ValidationFuture { + + self.validation_requests.write().push(uxt.clone()); + + let expected = index(at, self.nonce_offset); + let requires = if expected == uxt.transfer().nonce { + vec![] + } else { + vec![vec![uxt.transfer().nonce as u8 - 1]] + }; + let provides = vec![vec![uxt.transfer().nonce as u8]]; + + if self.invalid_hashes.read().contains(&self.hash_and_length(&uxt).0) { + return futures::future::ready(Ok( + Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(0))) + )) + } + + let mut validity = ValidTransaction { + priority: 1, + requires, + provides, + longevity: 64, + propagate: true, + }; + + (self.modifier.read())(&mut validity); + + futures::future::ready(Ok(Ok(validity))) + } + + 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>> { + Ok(match at { + BlockId::Hash(x) => Some(x.clone()), + _ => Some(Default::default()), + }) + } + + fn hash_and_length( + &self, + ex: &sc_transaction_graph::ExtrinsicFor, + ) -> (Self::Hash, usize) { + let encoded = ex.encode(); + (BlakeTwo256::hash(&encoded), encoded.len()) + } + + fn block_body(&self, id: &BlockId) -> Self::BodyFuture { + futures::future::ready(Ok(if let BlockId::Number(num) = id { + self.chain_block_by_number.read().get(num).cloned() + } else { + None + })) + } +} + +/// get an instance of `BasicPool` with default options and `TestApi` +/// as the `ChainApi` +pub fn maintained_pool() -> BasicPool { + BasicPool::new(Default::default(), TestApi::default()) +} + +/// generate nonce to be used with testing TestApi +pub fn index(at: &BlockId, offset: u64) -> u64 { + offset + number_of(at) +} + +fn number_of(at: &BlockId) -> u64 { + match at { + BlockId::Number(n) => *n as u64, + _ => 0, + } +} + +/// generates a transfer extrinsic, given a keyring and a nonce. +pub fn uxt(who: AccountKeyring, nonce: Index) -> Extrinsic { + let transfer = Transfer { + from: who.into(), + to: AccountId::default(), + nonce, + amount: 1, + }; + let signature = transfer.using_encoded(|e| who.sign(e)); + Extrinsic::Transfer(transfer, signature.into()) +} + +/// creates a transaction pool with the TestApi ChainApi +pub fn pool() -> Pool { + Pool::new(Default::default(), Arc::new(TestApi::default())) +} diff --git a/client/transaction-pool/src/tests.rs b/client/transaction-pool/src/tests.rs index 778536b7b9..b06e335faf 100644 --- a/client/transaction-pool/src/tests.rs +++ b/client/transaction-pool/src/tests.rs @@ -16,163 +16,19 @@ use super::*; -use crate::{BasicPool, MaintainedTransactionPool}; -use codec::Encode; use futures::executor::block_on; -use parking_lot::RwLock; -use sc_transaction_graph::{self, ExHash, Pool}; +use txpool::{self, Pool}; +use substrate_test_runtime_client::{runtime::Index, AccountKeyring::*}; use sp_runtime::{ - generic::{self, BlockId}, - traits::{BlakeTwo256, Hash as HashT}, - transaction_validity::{TransactionValidity, ValidTransaction, TransactionValidityError, InvalidTransaction}, + generic::BlockId, + transaction_validity::ValidTransaction, }; -use std::collections::HashSet; -use substrate_test_runtime_client::{ - runtime::{AccountId, Block, BlockNumber, Extrinsic, Hash, Header, Index, Transfer}, - AccountKeyring::{self, *}, -}; - -struct TestApi { - pub modifier: RwLock>, - pub chain_block_by_number: RwLock>>, - pub chain_headers_by_number: RwLock>, - pub invalid_hashes: RwLock>>, - pub validation_requests: RwLock>, -} - -impl TestApi { - fn default() -> Self { - TestApi { - modifier: RwLock::new(Box::new(|_| {})), - chain_block_by_number: RwLock::new(HashMap::new()), - invalid_hashes: RwLock::new(HashSet::new()), - chain_headers_by_number: RwLock::new(HashMap::new()), - validation_requests: RwLock::new(Default::default()), - } - } - - fn push_block(&self, block_number: BlockNumber, xts: Vec) { - self.chain_block_by_number.write().insert(block_number, xts); - self.chain_headers_by_number.write().insert(block_number, Header { - number: block_number, - digest: Default::default(), - extrinsics_root: Default::default(), - parent_hash: Default::default(), - state_root: Default::default(), - }); - } -} - -impl sc_transaction_graph::ChainApi for TestApi { - type Block = Block; - type Hash = Hash; - type Error = error::Error; - type ValidationFuture = futures::future::Ready>; - type BodyFuture = futures::future::Ready>>>; - - fn validate_transaction( - &self, - at: &BlockId, - uxt: sc_transaction_graph::ExtrinsicFor, - ) -> Self::ValidationFuture { - - self.validation_requests.write().push(uxt.clone()); - - let expected = index(at); - let requires = if expected == uxt.transfer().nonce { - vec![] - } else { - vec![vec![uxt.transfer().nonce as u8 - 1]] - }; - let provides = vec![vec![uxt.transfer().nonce as u8]]; - - if self.invalid_hashes.read().contains(&self.hash_and_length(&uxt).0) { - return futures::future::ready(Ok( - Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(0))) - )) - } - - let mut validity = ValidTransaction { - priority: 1, - requires, - provides, - longevity: 64, - propagate: true, - }; - - (self.modifier.read())(&mut validity); - - futures::future::ready(Ok(Ok(validity))) - } - - 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>> { - Ok(match at { - generic::BlockId::Hash(x) => Some(x.clone()), - _ => Some(Default::default()), - }) - } - - fn hash_and_length( - &self, - ex: &sc_transaction_graph::ExtrinsicFor, - ) -> (Self::Hash, usize) { - let encoded = ex.encode(); - (BlakeTwo256::hash(&encoded), encoded.len()) - } - - fn block_body(&self, id: &BlockId) -> Self::BodyFuture { - futures::future::ready(Ok(if let BlockId::Number(num) = id { - self.chain_block_by_number.read().get(num).cloned() - } else { - None - })) - } -} - -fn index(at: &BlockId) -> u64 { - 209 + number_of(at) -} - -fn number_of(at: &BlockId) -> u64 { - match at { - generic::BlockId::Number(n) => *n as u64, - _ => 0, - } -} - -fn uxt(who: AccountKeyring, nonce: Index) -> Extrinsic { - let transfer = Transfer { - from: who.into(), - to: AccountId::default(), - nonce, - amount: 1, - }; - let signature = transfer.using_encoded(|e| who.sign(e)); - Extrinsic::Transfer(transfer, signature.into()) -} - -fn pool() -> Pool { - Pool::new(Default::default(), TestApi::default().into()) -} - -fn maintained_pool() -> BasicPool { - BasicPool::new(Default::default(), TestApi::default()) -} +use testing::*; #[test] fn submission_should_work() { let pool = pool(); - assert_eq!(209, index(&BlockId::number(0))); + assert_eq!(209, index(&BlockId::number(0), 209)); block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index 3ae79caa43..8735416028 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -19,6 +19,7 @@ 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" +serde = { version = "1.0", features = ["derive"] } [dev-dependencies] sp-test-primitives = { version = "2.0.0", path = "../../test-primitives" } diff --git a/primitives/consensus/common/src/block_import.rs b/primitives/consensus/common/src/block_import.rs index 71315b63ef..af1b61a9fe 100644 --- a/primitives/consensus/common/src/block_import.rs +++ b/primitives/consensus/common/src/block_import.rs @@ -16,10 +16,9 @@ //! Block import helpers. -use sp_runtime::{ - Justification, - traits::{Block as BlockT, DigestItemFor, Header as HeaderT, NumberFor, HasherFor}, -}; +use sp_runtime::traits::{Block as BlockT, DigestItemFor, Header as HeaderT, NumberFor, HasherFor}; +use sp_runtime::Justification; +use serde::{Serialize, Deserialize}; use std::borrow::Cow; use std::collections::HashMap; use std::sync::Arc; @@ -42,7 +41,7 @@ pub enum ImportResult { } /// Auxiliary data associated with an imported block result. -#[derive(Debug, Default, PartialEq, Eq)] +#[derive(Debug, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct ImportedAux { /// Only the header has been imported. Block body verification was skipped. pub header_only: bool, diff --git a/primitives/inherents/src/lib.rs b/primitives/inherents/src/lib.rs index f79d8357a5..f1b8db982d 100644 --- a/primitives/inherents/src/lib.rs +++ b/primitives/inherents/src/lib.rs @@ -147,6 +147,11 @@ impl InherentData { None => Ok(None) } } + + /// Get the number of inherents in this instance + pub fn len(&self) -> usize { + self.data.len() + } } /// The result of checking inherents. -- GitLab From 9a9f52a05d9520aeee627a6c942564e807fda6a2 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Mon, 27 Jan 2020 04:22:04 -0800 Subject: [PATCH 020/180] Transaction queue tests update (#4734) * shuffle tests * update tests * inc_nonce -> increment_nonce --- client/consensus/manual-seal/src/lib.rs | 9 +- client/transaction-pool/src/lib.rs | 5 +- .../src/{testing.rs => testing/api.rs} | 163 +++++++++++------- client/transaction-pool/src/testing/mod.rs | 23 +++ .../src/{tests.rs => testing/pool.rs} | 97 +++++++---- 5 files changed, 196 insertions(+), 101 deletions(-) rename client/transaction-pool/src/{testing.rs => testing/api.rs} (50%) create mode 100644 client/transaction-pool/src/testing/mod.rs rename client/transaction-pool/src/{tests.rs => testing/pool.rs} (68%) diff --git a/client/consensus/manual-seal/src/lib.rs b/client/consensus/manual-seal/src/lib.rs index 3bd85b9380..7262a62d12 100644 --- a/client/consensus/manual-seal/src/lib.rs +++ b/client/consensus/manual-seal/src/lib.rs @@ -231,7 +231,7 @@ mod tests { use sc_transaction_pool::{ BasicPool, txpool::Options, - testing::*, + testing::api::*, }; use sp_transaction_pool::TransactionPool; use sp_runtime::generic::BlockId; @@ -242,10 +242,7 @@ mod tests { use sc_basic_authorship::ProposerFactory; fn api() -> TestApi { - let mut api = TestApi::default(); - api.nonce_offset = 0; - - api + TestApi::empty() } #[tokio::test] @@ -422,6 +419,7 @@ mod tests { finalize: false, }).await.unwrap(); let created_block = rx.await.unwrap().unwrap(); + pool.api().increment_nonce(Alice.into()); // assert that the background task returns ok assert_eq!( @@ -451,6 +449,7 @@ mod tests { }).await.is_ok()); assert!(rx1.await.unwrap().is_ok()); assert!(backend.blockchain().header(BlockId::Number(1)).unwrap().is_some()); + pool.api().increment_nonce(Alice.into()); assert!(pool.submit_one(&BlockId::Number(2), uxt(Alice, 2)).await.is_ok()); let (tx2, rx2) = futures::channel::oneshot::channel(); diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index 2771471ad9..b97294abe1 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -22,8 +22,6 @@ mod api; pub mod error; -#[cfg(test)] -mod tests; #[cfg(any(feature = "test-helpers", test))] pub mod testing; @@ -114,7 +112,8 @@ impl BasicPool &self.pool } - #[cfg(test)] + /// Get reference to the inner chain api, for tests only. + #[cfg(any(feature = "test-helpers", test))] pub fn api(&self) -> &Arc { &self.api } diff --git a/client/transaction-pool/src/testing.rs b/client/transaction-pool/src/testing/api.rs similarity index 50% rename from client/transaction-pool/src/testing.rs rename to client/transaction-pool/src/testing/api.rs index f4fecbe1d6..c8e4b62883 100644 --- a/client/transaction-pool/src/testing.rs +++ b/client/transaction-pool/src/testing/api.rs @@ -1,4 +1,4 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. +// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. // Substrate is free software: you can redistribute it and/or modify @@ -14,56 +14,74 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Utilities for testing transaction pool -use super::*; +//! Test ChainApi + +use crate::*; use codec::Encode; +use parking_lot::RwLock; use sp_runtime::{ - generic::{BlockId}, - traits::{Hash as HashT, BlakeTwo256}, + generic::{self, BlockId}, + traits::{BlakeTwo256, Hash as HashT}, transaction_validity::{TransactionValidity, ValidTransaction, TransactionValidityError, InvalidTransaction}, }; use std::collections::HashSet; -use crate::BasicPool; -use parking_lot::RwLock; -use sc_transaction_graph::{self, ExHash, Pool}; use substrate_test_runtime_client::{ - runtime::{AccountId, Block, BlockNumber, Extrinsic, Hash, Header, Index, Transfer}, - AccountKeyring, + runtime::{Index, AccountId, Block, BlockNumber, Extrinsic, Hash, Header, Transfer}, + AccountKeyring::{self, *}, }; -/// `ChainApi` for test environments +#[derive(Default)] +struct ChainState { + pub block_by_number: HashMap>, + pub block_by_hash: HashMap>, + pub header_by_number: HashMap, + pub nonces: HashMap, + pub invalid_hashes: HashSet, +} + +/// Test Api for transaction pool. pub struct TestApi { - /// transaction modifier - pub modifier: RwLock>, - /// cache of block number to extrinsics - pub chain_block_by_number: RwLock>>, - /// cache of block number to header - pub chain_headers_by_number: RwLock>, - /// cache of invalid hashes - pub invalid_hashes: RwLock>>, - /// validation requests - pub validation_requests: RwLock>, - /// used for calculating nonce for extrinsics - pub nonce_offset: u64, + valid_modifier: RwLock>, + chain: RwLock, + validation_requests: RwLock>, } impl TestApi { - /// create an instance of `TestApi` - pub fn default() -> Self { - TestApi { - modifier: RwLock::new(Box::new(|_| {})), - chain_block_by_number: RwLock::new(HashMap::new()), - invalid_hashes: RwLock::new(HashSet::new()), - chain_headers_by_number: RwLock::new(HashMap::new()), + + /// Test Api with Alice nonce set initially. + pub fn with_alice_nonce(nonce: u64) -> Self { + let api = TestApi { + valid_modifier: RwLock::new(Box::new(|_| {})), + chain: Default::default(), validation_requests: RwLock::new(Default::default()), - nonce_offset: 209, - } + }; + + api.chain.write().nonces.insert(Alice.into(), nonce); + + api } - /// add a block to `TestApi` + /// Default Test Api + pub fn empty() -> Self { + let api = TestApi { + valid_modifier: RwLock::new(Box::new(|_| {})), + chain: Default::default(), + validation_requests: RwLock::new(Default::default()), + }; + + api + } + + /// Set hook on modify valid result of transaction. + pub fn set_valid_modifier(&self, modifier: Box) { + *self.valid_modifier.write() = modifier; + } + + /// Push block as a part of canonical chain under given number. pub fn push_block(&self, block_number: BlockNumber, xts: Vec) { - self.chain_block_by_number.write().insert(block_number, xts); - self.chain_headers_by_number.write().insert(block_number, Header { + let mut chain = self.chain.write(); + chain.block_by_number.insert(block_number, xts); + chain.header_by_number.insert(block_number, Header { number: block_number, digest: Default::default(), extrinsics_root: Default::default(), @@ -71,6 +89,40 @@ impl TestApi { state_root: Default::default(), }); } + + /// Push a block without a number. + /// + /// As a part of non-canonical chain. + pub fn push_fork_block(&self, block_hash: Hash, xts: Vec) { + let mut chain = self.chain.write(); + chain.block_by_hash.insert(block_hash, xts); + } + + fn hash_and_length_inner(ex: &Extrinsic) -> (Hash, usize) { + let encoded = ex.encode(); + (BlakeTwo256::hash(&encoded), encoded.len()) + } + + /// Mark some transaction is invalid. + /// + /// Next time transaction pool will try to validate this + /// extrinsic, api will return invalid result. + pub fn add_invalid(&self, xts: &Extrinsic) { + self.chain.write().invalid_hashes.insert( + Self::hash_and_length_inner(xts).0 + ); + } + + /// Query validation requests received. + pub fn validation_requests(&self) -> Vec { + self.validation_requests.read().clone() + } + + /// Increment nonce in the inner state. + pub fn increment_nonce(&self, account: AccountId) { + let mut chain = self.chain.write(); + chain.nonces.entry(account).and_modify(|n| *n += 1).or_insert(1); + } } impl sc_transaction_graph::ChainApi for TestApi { @@ -82,21 +134,20 @@ impl sc_transaction_graph::ChainApi for TestApi { fn validate_transaction( &self, - at: &BlockId, + _at: &BlockId, uxt: sc_transaction_graph::ExtrinsicFor, ) -> Self::ValidationFuture { - self.validation_requests.write().push(uxt.clone()); - let expected = index(at, self.nonce_offset); - let requires = if expected == uxt.transfer().nonce { + let chain_nonce = self.chain.read().nonces.get(&uxt.transfer().from).cloned().unwrap_or(0); + let requires = if chain_nonce == uxt.transfer().nonce { vec![] } else { - vec![vec![uxt.transfer().nonce as u8 - 1]] + vec![vec![chain_nonce as u8]] }; let provides = vec![vec![uxt.transfer().nonce as u8]]; - if self.invalid_hashes.read().contains(&self.hash_and_length(&uxt).0) { + if self.chain.read().invalid_hashes.contains(&self.hash_and_length(&uxt).0) { return futures::future::ready(Ok( Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(0))) )) @@ -110,7 +161,7 @@ impl sc_transaction_graph::ChainApi for TestApi { propagate: true, }; - (self.modifier.read())(&mut validity); + (self.valid_modifier.read())(&mut validity); futures::future::ready(Ok(Ok(validity))) } @@ -127,7 +178,7 @@ impl sc_transaction_graph::ChainApi for TestApi { at: &BlockId, ) -> error::Result>> { Ok(match at { - BlockId::Hash(x) => Some(x.clone()), + generic::BlockId::Hash(x) => Some(x.clone()), _ => Some(Default::default()), }) } @@ -136,38 +187,28 @@ impl sc_transaction_graph::ChainApi for TestApi { &self, ex: &sc_transaction_graph::ExtrinsicFor, ) -> (Self::Hash, usize) { - let encoded = ex.encode(); - (BlakeTwo256::hash(&encoded), encoded.len()) + Self::hash_and_length_inner(ex) } fn block_body(&self, id: &BlockId) -> Self::BodyFuture { futures::future::ready(Ok(if let BlockId::Number(num) = id { - self.chain_block_by_number.read().get(num).cloned() + self.chain.read().block_by_number.get(num).cloned() } else { None })) } } -/// get an instance of `BasicPool` with default options and `TestApi` -/// as the `ChainApi` -pub fn maintained_pool() -> BasicPool { - BasicPool::new(Default::default(), TestApi::default()) -} - -/// generate nonce to be used with testing TestApi -pub fn index(at: &BlockId, offset: u64) -> u64 { - offset + number_of(at) -} - fn number_of(at: &BlockId) -> u64 { match at { - BlockId::Number(n) => *n as u64, + generic::BlockId::Number(n) => *n as u64, _ => 0, } } -/// generates a transfer extrinsic, given a keyring and a nonce. +/// Generate transfer extrinsic with a given nonce. +/// +/// Part of the test api. pub fn uxt(who: AccountKeyring, nonce: Index) -> Extrinsic { let transfer = Transfer { from: who.into(), @@ -179,7 +220,3 @@ pub fn uxt(who: AccountKeyring, nonce: Index) -> Extrinsic { Extrinsic::Transfer(transfer, signature.into()) } -/// creates a transaction pool with the TestApi ChainApi -pub fn pool() -> Pool { - Pool::new(Default::default(), Arc::new(TestApi::default())) -} diff --git a/client/transaction-pool/src/testing/mod.rs b/client/transaction-pool/src/testing/mod.rs new file mode 100644 index 0000000000..c216a17ee6 --- /dev/null +++ b/client/transaction-pool/src/testing/mod.rs @@ -0,0 +1,23 @@ +// Copyright 2020 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 . + +//! Tests for top-level transaction pool api + +#[cfg(any(feature = "test-helpers", test))] +pub mod api; + +#[cfg(test)] +mod pool; \ No newline at end of file diff --git a/client/transaction-pool/src/tests.rs b/client/transaction-pool/src/testing/pool.rs similarity index 68% rename from client/transaction-pool/src/tests.rs rename to client/transaction-pool/src/testing/pool.rs index b06e335faf..30a48fbec6 100644 --- a/client/transaction-pool/src/tests.rs +++ b/client/transaction-pool/src/testing/pool.rs @@ -1,34 +1,28 @@ -// Copyright 2018-2020 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 super::*; +use crate::*; +use sc_transaction_graph::{self, Pool}; use futures::executor::block_on; -use txpool::{self, Pool}; -use substrate_test_runtime_client::{runtime::Index, AccountKeyring::*}; use sp_runtime::{ generic::BlockId, transaction_validity::ValidTransaction, }; -use testing::*; +use substrate_test_runtime_client::{ + runtime::{Block, Hash, Index}, + AccountKeyring::*, +}; +use crate::testing::api::{TestApi, uxt}; + +fn pool() -> Pool { + Pool::new(Default::default(), TestApi::with_alice_nonce(209).into()) +} + +fn maintained_pool() -> BasicPool { + BasicPool::new(Default::default(), TestApi::with_alice_nonce(209)) +} #[test] fn submission_should_work() { let pool = pool(); - assert_eq!(209, index(&BlockId::number(0), 209)); block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); @@ -70,13 +64,19 @@ fn late_nonce_should_be_queued() { #[test] fn prune_tags_should_work() { let pool = pool(); - block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); + let hash209 = block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).unwrap(); let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209, 210]); - block_on(pool.prune_tags(&BlockId::number(1), vec![vec![209]], vec![])).unwrap(); + block_on( + pool.prune_tags( + &BlockId::number(1), + vec![vec![209]], + vec![hash209], + ) + ).expect("Prune tags"); let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![210]); @@ -100,22 +100,24 @@ fn should_ban_invalid_transactions() { #[test] fn should_correctly_prune_transactions_providing_more_than_one_tag() { - let api = TestApi::default(); - *api.modifier.write() = Box::new(|v: &mut ValidTransaction| { + let api = Arc::new(TestApi::with_alice_nonce(209)); + api.set_valid_modifier(Box::new(|v: &mut ValidTransaction| { v.provides.push(vec![155]); - }); - let pool = Pool::new(Default::default(), Arc::new(api)); + })); + let pool = Pool::new(Default::default(), api.clone()); let xt = uxt(Alice, 209); block_on(pool.submit_one(&BlockId::number(0), xt.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 1); // remove the transaction that just got imported. + api.increment_nonce(Alice.into()); block_on(pool.prune_tags(&BlockId::number(1), vec![vec![209]], vec![])).expect("1. Pruned"); assert_eq!(pool.status().ready, 0); // it's re-imported to future assert_eq!(pool.status().future, 1); // so now let's insert another transaction that also provides the 155 + api.increment_nonce(Alice.into()); let xt = uxt(Alice, 211); block_on(pool.submit_one(&BlockId::number(2), xt.clone())).expect("2. Imported"); assert_eq!(pool.status().ready, 1); @@ -124,6 +126,7 @@ fn should_correctly_prune_transactions_providing_more_than_one_tag() { assert_eq!(pending, vec![211]); // prune it and make sure the pool is empty + api.increment_nonce(Alice.into()); block_on(pool.prune_tags(&BlockId::number(3), vec![vec![155]], vec![])).expect("2. Pruned"); assert_eq!(pool.status().ready, 0); assert_eq!(pool.status().future, 2); @@ -144,7 +147,6 @@ fn should_prune_old_during_maintenance() { assert_eq!(pool.status().ready, 0); } - #[test] fn should_revalidate_during_maintenance() { let xt1 = uxt(Alice, 209); @@ -154,12 +156,47 @@ fn should_revalidate_during_maintenance() { block_on(pool.submit_one(&BlockId::number(0), xt1.clone())).expect("1. Imported"); block_on(pool.submit_one(&BlockId::number(0), xt2.clone())).expect("2. Imported"); assert_eq!(pool.status().ready, 2); - assert_eq!(pool.api.validation_requests.read().len(), 2); + assert_eq!(pool.api.validation_requests().len(), 2); pool.api.push_block(1, vec![xt1.clone()]); block_on(pool.maintain(&BlockId::number(1), &[])); assert_eq!(pool.status().ready, 1); // test that pool revalidated transaction that left ready and not included in the block - assert_eq!(pool.api.validation_requests.read().len(), 3); + assert_eq!(pool.api.validation_requests().len(), 3); +} + +#[test] +fn should_resubmit_from_retracted_during_maintaince() { + let xt = uxt(Alice, 209); + let retracted_hash = Hash::random(); + + let pool = maintained_pool(); + + block_on(pool.submit_one(&BlockId::number(0), xt.clone())).expect("1. Imported"); + assert_eq!(pool.status().ready, 1); + + pool.api.push_block(1, vec![]); + pool.api.push_fork_block(retracted_hash, vec![xt.clone()]); + + block_on(pool.maintain(&BlockId::number(1), &[retracted_hash])); + assert_eq!(pool.status().ready, 1); +} + +#[test] +fn should_not_retain_invalid_hashes_from_retracted() { + let xt = uxt(Alice, 209); + let retracted_hash = Hash::random(); + + let pool = maintained_pool(); + + block_on(pool.submit_one(&BlockId::number(0), xt.clone())).expect("1. Imported"); + assert_eq!(pool.status().ready, 1); + + pool.api.push_block(1, vec![]); + pool.api.push_fork_block(retracted_hash, vec![xt.clone()]); + pool.api.add_invalid(&xt); + + block_on(pool.maintain(&BlockId::number(1), &[retracted_hash])); + assert_eq!(pool.status().ready, 0); } -- GitLab From e46f77b1fb1ec43aa635b6c71ce62a9a370a4a24 Mon Sep 17 00:00:00 2001 From: Joshy Orndorff Date: Mon, 27 Jan 2020 11:14:10 -0500 Subject: [PATCH 021/180] Remove references to frame_consensus from docs (#4582) * Simply remove references to frame_consensus * More thorough re-write * Update frame/session/src/lib.rs Co-Authored-By: thiolliere * on_initialize is not dispatchable * Attempt to fix test. * Actually fix test. * Actually ran passing test. * Update frame/session/src/lib.rs Co-Authored-By: thiolliere Co-authored-by: thiolliere --- frame/aura/src/lib.rs | 2 -- frame/session/src/lib.rs | 78 +++++++++++++++------------------------- frame/sudo/src/lib.rs | 1 - 3 files changed, 29 insertions(+), 52 deletions(-) diff --git a/frame/aura/src/lib.rs b/frame/aura/src/lib.rs index 1a711f314a..e2aafde9ef 100644 --- a/frame/aura/src/lib.rs +++ b/frame/aura/src/lib.rs @@ -33,8 +33,6 @@ //! //! - [Timestamp](../pallet_timestamp/index.html): The Timestamp module is used in Aura to track //! consensus rounds (via `slots`). -//! - [Consensus](../frame_consensus/index.html): The Consensus module does not relate directly to Aura, -//! but serves to manage offline reporting by implementing `ProvideInherent` in a similar way. //! //! ## References //! diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index 098b533077..f98e334cbb 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -30,92 +30,72 @@ //! //! - **Session:** A session is a period of time that has a constant set of validators. Validators can only join //! or exit the validator set at a session change. It is measured in block numbers. The block where a session is -//! ended is determined by the `ShouldSessionEnd` trait. When the session is ending, a new validator set +//! ended is determined by the `ShouldEndSession` trait. When the session is ending, a new validator set //! can be chosen by `OnSessionEnding` implementations. //! - **Session key:** A session key is actually several keys kept together that provide the various signing //! functions required by network authorities/validators in pursuit of their duties. //! - **Validator ID:** Every account has an associated validator ID. For some simple staking systems, this //! may just be the same as the account ID. For staking systems using a stash/controller model, //! the validator ID would be the stash account ID of the controller. -//! - **Session key configuration process:** A session key is set using `set_key` for use in the -//! next session. It is stored in `NextKeyFor`, a mapping between the caller's `ValidatorId` and the session -//! keys provided. `set_key` allows users to set their session key prior to being selected as validator. +//! - **Session key configuration process:** Session keys are set using `set_keys` for use not in +//! the next session, but the session after next. They are stored in `NextKeys`, a mapping between +//! the caller's `ValidatorId` and the session keys provided. `set_keys` allows users to set their +//! session key prior to being selected as validator. //! It is a public call since it uses `ensure_signed`, which checks that the origin is a signed account. -//! As such, the account ID of the origin stored in in `NextKeyFor` may not necessarily be associated with +//! As such, the account ID of the origin stored in `NextKeys` may not necessarily be associated with //! a block author or a validator. The session keys of accounts are removed once their account balance is zero. -//! - **Validator set session key configuration process:** Each session we iterate through the current -//! set of validator account IDs to check if a session key was created for it in the previous session -//! using `set_key`. If it was then we call `set_authority` from the [Consensus module](../frame_consensus/index.html) -//! and pass it a set of session keys (each associated with an account ID) as the session keys for the new -//! validator set. Lastly, if the session key of the current authority does not match any session keys stored under -//! its validator index in the `AuthorityStorageVec` mapping, then we update the mapping with its session -//! key and update the saved list of original authorities if necessary -//! (see https://github.com/paritytech/substrate/issues/1290). Note: Authorities are stored in the Consensus module. -//! They are represented by a validator account ID index from the Session module and allocated with a session -//! key for the length of the session. -//! - **Session length change process:** At the start of the next session we allocate a session index and record the -//! timestamp when the session started. If a `NextSessionLength` was recorded in the previous session, we record -//! it as the new session length. Additionally, if the new session length differs from the length of the -//! next session then we record a `LastLengthChange`. +//! - **Session length:** This pallet does not assume anything about the length of each session. +//! Rather, it relies on an implementation of `ShouldEndSession` to dictate a new session's start. +//! This pallet provides the `PeriodicSessions` struct for simple periodic sessions. //! - **Session rotation configuration:** Configure as either a 'normal' (rewardable session where rewards are //! applied) or 'exceptional' (slashable) session rotation. -//! - **Session rotation process:** The session is changed at the end of the final block of the current session -//! using the `on_finalize` method. It may be called by either an origin or internally from another runtime -//! module at the end of each block. +//! - **Session rotation process:** At the beginning of each block, the `on_initialize` function +//! queries the provided implementation of `ShouldEndSession`. If the session is to end the newly +//! activated validator IDs and session keys are taken from storage and passed to the +//! `SessionHandler`. The validator set supplied by `SessionManager::new_session` and the corresponding session +//! keys, which may have been registered via `set_keys` during the previous session, are written +//! to storage where they will wait one session before being passed to the `SessionHandler` +//! themselves. //! //! ### Goals //! -//! The Session module in Substrate is designed to make the following possible: +//! The Session pallet is designed to make the following possible: //! -//! - Set session keys of the validator set for the next session. -//! - Set the length of a session. +//! - Set session keys of the validator set for upcoming sessions. +//! - Control the length of sessions. //! - Configure and switch between either normal or exceptional session rotations. //! //! ## Interface //! //! ### Dispatchable Functions //! -//! - `set_key` - Set a validator's session key for the next session. -//! - `set_length` - Set a new session length to be applied upon the next session change. -//! - `force_new_session` - Force a new session that should be considered either a normal (rewardable) -//! or exceptional rotation. -//! - `on_finalize` - Called when a block is finalized. Will rotate session if it is the last -//! block of the current session. +//! - `set_keys` - Set a validator's session keys for upcoming sessions. //! //! ### Public Functions //! -//! - `validator_count` - Get the current number of validators. -//! - `last_length_change` - Get the block number when the session length last changed. -//! - `apply_force_new_session` - Force a new session. Can be called by other runtime modules. -//! - `set_validators` - Set the current set of validators. Can only be called by the Staking module. -//! - `check_rotate_session` - Rotate the session and apply rewards if necessary. Called after the Staking -//! module updates the authorities to the new validator set. -//! - `rotate_session` - Change to the next session. Register the new authority set. Update session keys. -//! Enact session length change if applicable. -//! - `ideal_session_duration` - Get the time of an ideal session. -//! - `blocks_remaining` - Get the number of blocks remaining in the current session, -//! excluding the current block. +//! - `rotate_session` - Change to the next session. Register the new authority set. Queue changes +//! for next session rotation. +//! - `disable_index` - Disable a validator by index. +//! - `disable` - Disable a validator by Validator ID //! //! ## Usage //! //! ### Example from the SRML //! -//! The [Staking module](../pallet_staking/index.html) uses the Session module to get the validator set. +//! The [Staking pallet](../pallet_staking/index.html) uses the Session pallet to get the validator set. //! //! ``` //! use pallet_session as session; -//! # fn not_executed() { //! -//! let validators = >::validators(); -//! # } +//! fn validators() -> Vec<::ValidatorId> { +//! >::validators() +//! } //! # fn main(){} //! ``` //! //! ## Related Modules //! -//! - [Consensus](../frame_consensus/index.html) //! - [Staking](../pallet_staking/index.html) -//! - [Timestamp](../pallet_timestamp/index.html) #![cfg_attr(not(feature = "std"), no_std)] @@ -478,7 +458,7 @@ decl_module! { fn deposit_event() = default; - /// Sets the session key(s) of the function caller to `key`. + /// Sets the session key(s) of the function caller to `keys`. /// Allows an account to set its session key prior to becoming a validator. /// This doesn't take effect until the next session. /// diff --git a/frame/sudo/src/lib.rs b/frame/sudo/src/lib.rs index e49596b4bd..ea436e2629 100644 --- a/frame/sudo/src/lib.rs +++ b/frame/sudo/src/lib.rs @@ -77,7 +77,6 @@ //! //! ## Related Modules //! -//! * [Consensus](../frame_consensus/index.html) //! * [Democracy](../pallet_democracy/index.html) //! //! [`Call`]: ./enum.Call.html -- GitLab From d2d7ab900d8a55661cb86aa1cc222a5964f021e1 Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Mon, 27 Jan 2020 17:40:57 +0100 Subject: [PATCH 022/180] pallet-contracts: Refactor and comment `rent` module. (#4733) * Refactor and comment `rent` module. * impl_version bump * Add doc for Exempt * Simplify code. * Update bin/node/runtime/src/lib.rs Co-Authored-By: thiolliere * Update frame/contracts/src/exec.rs Co-Authored-By: Hero Bird Co-authored-by: thiolliere Co-authored-by: Hero Bird --- bin/node/runtime/src/lib.rs | 2 +- frame/contracts/src/exec.rs | 6 +- frame/contracts/src/lib.rs | 2 +- frame/contracts/src/rent.rs | 289 +++++++++++++++++++++++------------- 4 files changed, 192 insertions(+), 107 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 23cd7405dd..7e1082ef54 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -81,7 +81,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 205, - impl_version: 205, + impl_version: 206, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index ceaccd35cb..cfbefa2a72 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -356,10 +356,10 @@ where }); } - // Assumption: pay_rent doesn't collide with overlay because - // pay_rent will be done on first call and dest contract and balance + // Assumption: `collect_rent` doesn't collide with overlay because + // `collect_rent` will be done on first call and destination contract and balance // cannot be changed before the first call - let contract_info = rent::pay_rent::(&dest); + let contract_info = rent::collect_rent::(&dest); // Calls to dead contracts always fail. if let Some(ContractInfo::Tombstone(_)) = contract_info { diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index d16462d8bf..1460ca3cf1 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -669,7 +669,7 @@ decl_module! { }; // If poking the contract has lead to eviction of the contract, give out the rewards. - if rent::try_evict::(&dest, handicap) == rent::RentOutcome::Evicted { + if rent::snitch_contract_should_be_evicted::(&dest, handicap) { T::Currency::deposit_into_existing(&rewarded, T::SurchargeReward::get())?; } } diff --git a/frame/contracts/src/rent.rs b/frame/contracts/src/rent.rs index 508511da4c..46f915e642 100644 --- a/frame/contracts/src/rent.rs +++ b/frame/contracts/src/rent.rs @@ -14,64 +14,91 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use crate::{Module, RawEvent, BalanceOf, ContractInfo, ContractInfoOf, TombstoneContractInfo, - Trait, AliveContractInfo}; -use sp_runtime::traits::{Bounded, CheckedDiv, CheckedMul, Saturating, Zero, - SaturatedConversion}; -use frame_support::traits::{Currency, ExistenceRequirement, Get, WithdrawReason, OnUnbalanced}; -use frame_support::StorageMap; +use crate::{ + AliveContractInfo, BalanceOf, ContractInfo, ContractInfoOf, Module, RawEvent, + TombstoneContractInfo, Trait, +}; use frame_support::storage::child; +use frame_support::traits::{Currency, ExistenceRequirement, Get, OnUnbalanced, WithdrawReason}; +use frame_support::StorageMap; +use sp_runtime::traits::{Bounded, CheckedDiv, CheckedMul, SaturatedConversion, Saturating, Zero}; -#[derive(PartialEq, Eq, Copy, Clone)] -#[must_use] -pub enum RentOutcome { - /// Exempted from rent iff: - /// * rent is offset completely by the `rent_deposit_offset`, - /// * or rent has already been paid for this block number, - /// * or account doesn't have a contract, - /// * or account has a tombstone. - Exempted, - /// Evicted iff: - /// * rent exceed rent allowance, - /// * or can't withdraw the rent, - /// * or go below subsistence threshold. - Evicted, - /// The outstanding dues were paid or were able to be paid. - Ok, +/// The amount to charge. +/// +/// This amount respects the contract's rent allowance and the subsistence deposit. +/// Because of that, charging the amount cannot remove the contract. +struct OutstandingAmount { + amount: BalanceOf, } -/// Evict and optionally pay dues (or check account can pay them otherwise) at the current -/// block number (modulo `handicap`, read on). -/// -/// `pay_rent` gives an ability to pay or skip paying rent. -/// `handicap` gives a way to check or pay the rent up to a moment in the past instead -/// of current block. +impl OutstandingAmount { + /// Create the new outstanding amount. + /// + /// The amount should be always withdrawable and it should not kill the account. + fn new(amount: BalanceOf) -> Self { + Self { amount } + } + + /// Returns the amount this instance wraps. + fn peek(&self) -> BalanceOf { + self.amount + } + + /// Withdraws the outstanding amount from the given account. + fn withdraw(self, account: &T::AccountId) { + if let Ok(imbalance) = T::Currency::withdraw( + account, + self.amount, + WithdrawReason::Fee.into(), + ExistenceRequirement::KeepAlive, + ) { + // This should never fail. However, let's err on the safe side. + T::RentPayment::on_unbalanced(imbalance); + } + } +} + +enum Verdict { + /// The contract is exempted from paying rent. + /// + /// For example, it already paid its rent in the current block, or it has enough deposit for not + /// paying rent at all. + Exempt, + /// Funds dropped below the subsistence deposit. + /// + /// Remove the contract along with it's storage. + Kill, + /// The contract cannot afford payment within its rent budget so it gets evicted. However, + /// because its balance is greater than the subsistence threshold it leaves a tombstone. + Evict { + amount: Option>, + }, + /// Everything is OK, we just only take some charge. + Charge { + amount: OutstandingAmount, + }, +} + +/// Consider the case for rent payment of the given account and returns a `Verdict`. /// -/// NOTE: This function acts eagerly, all modification are committed into the storage. -fn try_evict_or_and_pay_rent( +/// The `current_block_number` must be equal to the current block number. Use `handicap` do +/// change the reference block number. (See `snitch_contract_should_be_evicted` for more details). +fn consider_case( account: &T::AccountId, + current_block_number: T::BlockNumber, handicap: T::BlockNumber, - pay_rent: bool, -) -> (RentOutcome, Option>) { - let contract_info = >::get(account); - let contract = match contract_info { - None | Some(ContractInfo::Tombstone(_)) => return (RentOutcome::Exempted, contract_info), - Some(ContractInfo::Alive(contract)) => contract, - }; - - let current_block_number = >::block_number(); - + contract: &AliveContractInfo, +) -> Verdict { // How much block has passed since the last deduction for the contract. let blocks_passed = { // Calculate an effective block number, i.e. after adjusting for handicap. let effective_block_number = current_block_number.saturating_sub(handicap); - let n = effective_block_number.saturating_sub(contract.deduct_block); - if n.is_zero() { - // Rent has already been paid - return (RentOutcome::Exempted, Some(ContractInfo::Alive(contract))); - } - n + effective_block_number.saturating_sub(contract.deduct_block) }; + if blocks_passed.is_zero() { + // Rent has already been paid + return Verdict::Exempt; + } let balance = T::Currency::free_balance(account); @@ -92,7 +119,7 @@ fn try_evict_or_and_pay_rent( if fee_per_block.is_zero() { // The rent deposit offset reduced the fee to 0. This means that the contract // gets the rent for free. - return (RentOutcome::Exempted, Some(ContractInfo::Alive(contract))); + return Verdict::Exempt; } // The minimal amount of funds required for a contract not to be evicted. @@ -100,10 +127,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); - child::kill_storage(&contract.trie_id, contract.child_trie_unique_id()); - >::deposit_event(RawEvent::Evicted(account.clone(), false)); - return (RentOutcome::Evicted, None); + return Verdict::Kill; } let dues = fee_per_block @@ -127,75 +151,136 @@ fn try_evict_or_and_pay_rent( ) .is_ok(); - if can_withdraw_rent && (insufficient_rent || pay_rent) { - // Collect dues. - let imbalance = T::Currency::withdraw( - account, - dues_limited, - WithdrawReason::Fee.into(), - ExistenceRequirement::KeepAlive, - ) - .expect( - "Withdraw has been checked above; - dues_limited < rent_budget < balance - subsistence < balance - existential_deposit; - qed", - ); - - T::RentPayment::on_unbalanced(imbalance); - } - if insufficient_rent || !can_withdraw_rent { // The contract cannot afford the rent payment and has a balance above the subsistence // threshold, so it leaves a tombstone. + let amount = if can_withdraw_rent { + Some(OutstandingAmount::new(dues_limited)) + } else { + None + }; + return Verdict::Evict { amount }; + } - // Note: this operation is heavy. - let child_storage_root = child::child_root( - &contract.trie_id, - ); + return Verdict::Charge { + // We choose to use `dues_limited` here instead of `dues` just to err on the safer side. + amount: OutstandingAmount::new(dues_limited), + }; +} - let tombstone = >::new( - &child_storage_root[..], - contract.code_hash, - ); - let tombstone_info = ContractInfo::Tombstone(tombstone); - >::insert(account, &tombstone_info); +/// Enacts the given verdict and returns the updated `ContractInfo`. +/// +/// `alive_contract_info` should be from the same address as `account`. +fn enact_verdict( + account: &T::AccountId, + alive_contract_info: AliveContractInfo, + current_block_number: T::BlockNumber, + verdict: Verdict, +) -> Option> { + match verdict { + Verdict::Exempt => return Some(ContractInfo::Alive(alive_contract_info)), + Verdict::Kill => { + >::remove(account); + child::kill_storage( + &alive_contract_info.trie_id, + alive_contract_info.child_trie_unique_id(), + ); + >::deposit_event(RawEvent::Evicted(account.clone(), false)); + None + } + Verdict::Evict { amount } => { + if let Some(amount) = amount { + amount.withdraw(account); + } - child::kill_storage(&contract.trie_id, contract.child_trie_unique_id()); + // Note: this operation is heavy. + let child_storage_root = child::child_root(&alive_contract_info.trie_id); - >::deposit_event(RawEvent::Evicted(account.clone(), true)); + let tombstone = >::new( + &child_storage_root[..], + alive_contract_info.code_hash, + ); + let tombstone_info = ContractInfo::Tombstone(tombstone); + >::insert(account, &tombstone_info); - return (RentOutcome::Evicted, Some(tombstone_info)); - } + child::kill_storage( + &alive_contract_info.trie_id, + alive_contract_info.child_trie_unique_id(), + ); - if pay_rent { - let contract_info = ContractInfo::Alive(AliveContractInfo:: { - rent_allowance: contract.rent_allowance - dues, // rent_allowance is not exceeded - deduct_block: current_block_number, - ..contract - }); - - >::insert(account, &contract_info); + >::deposit_event(RawEvent::Evicted(account.clone(), true)); + Some(tombstone_info) + } + Verdict::Charge { amount } => { + let contract_info = ContractInfo::Alive(AliveContractInfo:: { + rent_allowance: alive_contract_info.rent_allowance - amount.peek(), + deduct_block: current_block_number, + ..alive_contract_info + }); + >::insert(account, &contract_info); - return (RentOutcome::Ok, Some(contract_info)); + amount.withdraw(account); + Some(contract_info) + } } - - (RentOutcome::Ok, Some(ContractInfo::Alive(contract))) } /// Make account paying the rent for the current block number /// -/// NOTE: This function acts eagerly. -pub fn pay_rent(account: &T::AccountId) -> Option> { - try_evict_or_and_pay_rent::(account, Zero::zero(), true).1 +/// NOTE this function performs eviction eagerly. All changes are read and written directly to +/// storage. +pub fn collect_rent(account: &T::AccountId) -> Option> { + let contract_info = >::get(account); + let alive_contract_info = match contract_info { + None | Some(ContractInfo::Tombstone(_)) => return contract_info, + Some(ContractInfo::Alive(contract)) => contract, + }; + + let current_block_number = >::block_number(); + let verdict = consider_case::( + account, + current_block_number, + Zero::zero(), + &alive_contract_info, + ); + enact_verdict(account, alive_contract_info, current_block_number, verdict) } -/// Evict the account if it should be evicted at the given block number. +/// Process a snitch that a contract under the given address should be evicted. +/// +/// Enact the eviction right away if the contract should be evicted and return true. +/// Otherwise, **do nothing** and return false. /// -/// `handicap` gives a way to check or pay the rent up to a moment in the past instead +/// The `handicap` parameter gives a way to check the rent to a moment in the past instead /// of current block. E.g. if the contract is going to be evicted at the current block, -/// `handicap=1` can defer the eviction for 1 block. +/// `handicap = 1` can defer the eviction for 1 block. This is useful to handicap certain snitchers +/// relative to others. /// -/// NOTE: This function acts eagerly. -pub fn try_evict(account: &T::AccountId, handicap: T::BlockNumber) -> RentOutcome { - try_evict_or_and_pay_rent::(account, handicap, false).0 +/// NOTE this function performs eviction eagerly. All changes are read and written directly to +/// storage. +pub fn snitch_contract_should_be_evicted( + account: &T::AccountId, + handicap: T::BlockNumber, +) -> bool { + let contract_info = >::get(account); + let alive_contract_info = match contract_info { + None | Some(ContractInfo::Tombstone(_)) => return false, + Some(ContractInfo::Alive(contract)) => contract, + }; + let current_block_number = >::block_number(); + let verdict = consider_case::( + account, + current_block_number, + handicap, + &alive_contract_info, + ); + + // Enact the verdict only if the contract gets removed. + match verdict { + Verdict::Kill | Verdict::Evict { .. } => { + enact_verdict(account, alive_contract_info, current_block_number, verdict); + true + } + _ => false, + } } -- GitLab From 6027e31d23f6e9b5b06c661a74f266e018bd57d0 Mon Sep 17 00:00:00 2001 From: gabriel klawitter Date: Mon, 27 Jan 2020 18:22:52 +0100 Subject: [PATCH 023/180] ci: fix runtime version check (#4741) --- .maintain/gitlab/check_runtime.sh | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/.maintain/gitlab/check_runtime.sh b/.maintain/gitlab/check_runtime.sh index f989904cb5..102c634dd9 100755 --- a/.maintain/gitlab/check_runtime.sh +++ b/.maintain/gitlab/check_runtime.sh @@ -9,11 +9,12 @@ set -e # fail on any error -# give some context -git log --graph --oneline --decorate=short -n 10 VERSIONS_FILE="bin/node/runtime/src/lib.rs" +boldprint () { printf "|\n| \033[1m${@}\033[0m\n|\n" ; } +boldcat () { printf "|\n"; while read l; do printf "| \033[1m${l}\033[0m\n"; done; printf "|\n" ; } + github_label () { echo echo "# run github-api job for labeling it ${1}" @@ -26,21 +27,19 @@ github_label () { } +boldprint "latest 10 commits of ${CI_COMMIT_REF_NAME}" +git log --graph --oneline --decorate=short -n 10 +boldprint "make sure the master branch is available in shallow clones" git fetch --depth=${GIT_DEPTH:-100} origin master -# check if master is part of this checkout -if ! git log -n 1 origin/master -then - echo "unable to check for runtime changes: checkout does not contain origin/master branch" - exit 3 -fi -# check if the wasm sources changed +boldprint "check if the wasm sources changed" if ! git diff --name-only origin/master...${CI_COMMIT_SHA} \ - | grep -q -e '^bin/node/src/runtime' -e '^frame/' -e '^primitives/sr-' | grep -v -e '^primitives/sr-arithmetic/fuzzer' + | grep -v -e '^primitives/sr-arithmetic/fuzzer' \ + | grep -q -e '^bin/node/src/runtime' -e '^frame/' -e '^primitives/sr-' then - cat <<-EOT + boldcat <<-EOT no changes to the runtime source code detected @@ -61,13 +60,13 @@ sub_spec_version="$(git diff origin/master...${CI_COMMIT_SHA} ${VERSIONS_FILE} \ | sed -n -r "s/^\-[[:space:]]+spec_version: +([0-9]+),$/\1/p")" -# see if the version and the binary blob changed + if [ "${add_spec_version}" != "${sub_spec_version}" ] then github_label "B2-breaksapi" - cat <<-EOT + boldcat <<-EOT changes to the runtime sources and changes in the spec version. @@ -89,7 +88,7 @@ else # see if the impl version changed if [ "${add_impl_version}" != "${sub_impl_version}" ] then - cat <<-EOT + boldcat <<-EOT changes to the runtime sources and changes in the impl version. @@ -100,7 +99,7 @@ else fi - cat <<-EOT + boldcat <<-EOT wasm source files changed but not the spec/impl version and the runtime binary blob. If changes made do not alter logic, just bump 'impl_version'. @@ -114,8 +113,6 @@ else versions file: ${VERSIONS_FILE} EOT - - # drop through into pushing `gotissues` and exit 1... fi # dropped through. there's something wrong; exit 1. -- GitLab From d2bb42d314bbdcc48c0cf01cb59f7ab10294ebad Mon Sep 17 00:00:00 2001 From: thiolliere Date: Mon, 27 Jan 2020 18:23:10 +0100 Subject: [PATCH 024/180] Remove default hasher (#4739) * remove default hasher from decl_storage! * fix decl_storage declarations --- frame/assets/src/lib.rs | 4 +- frame/babe/src/lib.rs | 2 +- frame/balances/src/lib.rs | 12 +++-- frame/collective/src/lib.rs | 6 ++- frame/contracts/src/lib.rs | 6 +-- frame/democracy/src/lib.rs | 25 ++++++---- frame/elections-phragmen/src/lib.rs | 4 +- frame/elections/src/lib.rs | 13 ++++-- frame/evm/src/lib.rs | 6 +-- frame/example/src/lib.rs | 6 +-- frame/generic-asset/src/lib.rs | 14 ++++-- frame/grandpa/src/lib.rs | 2 +- frame/identity/src/lib.rs | 9 ++-- frame/im-online/src/lib.rs | 6 ++- frame/indices/src/lib.rs | 2 +- frame/nicks/src/lib.rs | 2 +- frame/offences/src/lib.rs | 8 ++-- frame/recovery/src/lib.rs | 6 ++- frame/scored-pool/src/lib.rs | 2 +- frame/session/src/historical.rs | 7 ++- frame/society/src/lib.rs | 11 +++-- frame/staking/src/lib.rs | 30 +++++++----- frame/support/procedural/src/lib.rs | 17 ++++--- frame/support/procedural/src/storage/parse.rs | 18 ++++---- frame/support/src/lib.rs | 13 ++++-- frame/support/src/storage/generator/mod.rs | 2 +- frame/support/test/tests/decl_storage.rs | 46 ++++++++++--------- frame/support/test/tests/final_keys.rs | 16 +++---- frame/support/test/tests/genesisconfig.rs | 2 +- frame/support/test/tests/instance.rs | 10 ++-- frame/support/test/tests/issue2219.rs | 8 ++-- frame/system/src/lib.rs | 9 ++-- frame/treasury/src/lib.rs | 2 +- test-utils/runtime/src/system.rs | 2 +- utils/frame/rpc/support/src/lib.rs | 6 +-- 35 files changed, 193 insertions(+), 141 deletions(-) diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index f77eb663db..8a62fa9d82 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -228,11 +228,11 @@ decl_error! { decl_storage! { trait Store for Module as Assets { /// The number of units of assets held by any given account. - Balances: map (T::AssetId, T::AccountId) => T::Balance; + Balances: map hasher(blake2_256) (T::AssetId, T::AccountId) => T::Balance; /// The next asset identifier up for grabs. NextAssetId get(fn next_asset_id): T::AssetId; /// The total unit supply of an asset. - TotalSupply: map T::AssetId => T::Balance; + TotalSupply: map hasher(blake2_256) T::AssetId => T::Balance; } } diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index f249ca9e29..ab1822712f 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -145,7 +145,7 @@ decl_storage! { /// We reset all segments and return to `0` at the beginning of every /// epoch. SegmentIndex build(|_| 0): u32; - UnderConstruction: map u32 => Vec<[u8; 32 /* VRF_OUTPUT_LENGTH */]>; + UnderConstruction: map hasher(blake2_256) u32 => Vec<[u8; 32 /* VRF_OUTPUT_LENGTH */]>; /// Temporary value (cleared at block finalization) which is `Some` /// if per-block initialization has already been called for current block. diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index b488b96701..77d28e89e9 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -374,7 +374,9 @@ decl_storage! { }) }) }).collect::>() - }): map T::AccountId => Option>; + }): + map hasher(blake2_256) T::AccountId + => Option>; /// The 'free' balance of a given account. /// @@ -389,7 +391,7 @@ decl_storage! { /// collapsed to zero if it ever becomes less than `ExistentialDeposit`. pub FreeBalance get(fn free_balance) build(|config: &GenesisConfig| config.balances.clone()): - map T::AccountId => T::Balance; + map hasher(blake2_256) T::AccountId => T::Balance; /// The amount of the balance of a given account that is externally reserved; this can still get /// slashed, but gets slashed last of all. @@ -402,10 +404,12 @@ decl_storage! { /// /// `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; + pub ReservedBalance get(fn reserved_balance): + map hasher(blake2_256) T::AccountId => T::Balance; /// Any liquidity locks on some account balances. - pub Locks get(fn locks): map T::AccountId => Vec>; + pub Locks get(fn locks): + map hasher(blake2_256) T::AccountId => Vec>; } add_extra_genesis { config(balances): Vec<(T::AccountId, T::Balance)>; diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index 0d1032cca4..8d811b8dec 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -87,9 +87,11 @@ decl_storage! { /// The hashes of the active proposals. pub Proposals get(fn proposals): Vec; /// Actual proposal for a given hash, if it's current. - pub ProposalOf get(fn proposal_of): map T::Hash => Option<>::Proposal>; + pub ProposalOf get(fn proposal_of): + map hasher(blake2_256) T::Hash => Option<>::Proposal>; /// Votes on a given proposal, if it is ongoing. - pub Voting get(fn voting): map T::Hash => Option>; + pub Voting get(fn voting): + map hasher(blake2_256) T::Hash => Option>; /// Proposals so far. pub ProposalCount get(fn proposal_count): u32; /// The current members of the collective. This is stored sorted (just by value). diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index 1460ca3cf1..6324b3fabc 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -942,13 +942,13 @@ decl_storage! { /// Current cost schedule for contracts. CurrentSchedule get(fn current_schedule) config(): Schedule = Schedule::default(); /// A mapping from an original code hash to the original code, untouched by instrumentation. - pub PristineCode: map CodeHash => Option>; + pub PristineCode: map hasher(blake2_256) CodeHash => Option>; /// A mapping between an original code hash and instrumented wasm code, ready for execution. - pub CodeStorage: map CodeHash => Option; + pub CodeStorage: map hasher(blake2_256) CodeHash => Option; /// The subtrie counter. pub AccountCounter: u64 = 0; /// The code associated with a given account. - pub ContractInfoOf: map T::AccountId => Option>; + pub ContractInfoOf: map hasher(blake2_256) T::AccountId => Option>; /// The price of one unit of gas. GasPrice get(fn gas_price) config(): BalanceOf = 1.into(); } diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index d7790be8f7..682ce59f25 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -268,9 +268,12 @@ decl_storage! { 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)>; + pub Preimages: + map hasher(blake2_256) 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)>; + pub DepositOf get(fn deposit_of): + map hasher(blake2_256) 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; @@ -279,25 +282,28 @@ decl_storage! { 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>; + map hasher(blake2_256) 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; + pub VotersFor get(fn voters_for): + map hasher(blake2_256) ReferendumIndex => Vec; /// Get the vote in a given referendum of a particular voter. The result is meaningful only /// if `voters_for` includes the voter when called with the referendum (you'll get the /// default `Vote` value otherwise). If you don't want to check `voters_for`, then you can /// also check for simple existence with `VoteOf::exists` first. - pub VoteOf get(fn vote_of): map (ReferendumIndex, T::AccountId) => Vote; + pub VoteOf get(fn vote_of): map hasher(blake2_256) (ReferendumIndex, T::AccountId) => Vote; /// Who is able to vote for whom. Value is the fund-holding account, key is the /// vote-transaction-sending account. - pub Proxy get(fn proxy): map T::AccountId => Option; + pub Proxy get(fn proxy): map hasher(blake2_256) T::AccountId => Option; /// Get the account (and lock periods) to which another account is delegating vote. - pub Delegations get(fn delegations): linked_map T::AccountId => (T::AccountId, Conviction); + pub Delegations get(fn delegations): + linked_map hasher(blake2_256) T::AccountId => (T::AccountId, Conviction); /// True if the last referendum tabled was submitted externally. False if it was a public /// proposal. @@ -311,10 +317,11 @@ decl_storage! { /// 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. - pub Blacklist get(fn blacklist): map T::Hash => Option<(T::BlockNumber, Vec)>; + pub Blacklist get(fn blacklist): + map hasher(blake2_256) T::Hash => Option<(T::BlockNumber, Vec)>; /// Record of all proposals that have been subject to emergency cancellation. - pub Cancellations: map T::Hash => bool; + pub Cancellations: map hasher(blake2_256) T::Hash => bool; } } diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 1d9573cbbf..e022b24f01 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -157,9 +157,9 @@ decl_storage! { pub ElectionRounds get(fn election_rounds): u32 = Zero::zero(); /// Votes of a particular voter, with the round index of the votes. - pub VotesOf get(fn votes_of): linked_map T::AccountId => Vec; + pub VotesOf get(fn votes_of): linked_map hasher(blake2_256) T::AccountId => Vec; /// Locked stake of a voter. - pub StakeOf get(fn stake_of): map T::AccountId => BalanceOf; + pub StakeOf get(fn stake_of): map hasher(blake2_256) T::AccountId => BalanceOf; /// The present candidate list. Sorted based on account-id. A current member or a runner can /// never enter this vector and is always implicitly assumed to be a candidate. diff --git a/frame/elections/src/lib.rs b/frame/elections/src/lib.rs index e722c4db80..504aa5d8a0 100644 --- a/frame/elections/src/lib.rs +++ b/frame/elections/src/lib.rs @@ -235,14 +235,17 @@ decl_storage! { // bit-wise manner. In order to get a human-readable representation (`Vec`), use // [`all_approvals_of`]. Furthermore, each vector of scalars is chunked with the cap of // `APPROVAL_SET_SIZE`. - pub ApprovalsOf get(fn approvals_of): map (T::AccountId, SetIndex) => Vec; + pub ApprovalsOf get(fn approvals_of): + map hasher(blake2_256) (T::AccountId, SetIndex) => Vec; /// The vote index and list slot that the candidate `who` was registered or `None` if they /// are not currently registered. - pub RegisterInfoOf get(fn candidate_reg_info): map T::AccountId => Option<(VoteIndex, u32)>; + pub RegisterInfoOf get(fn candidate_reg_info): + map hasher(blake2_256) T::AccountId => Option<(VoteIndex, u32)>; /// Basic information about a voter. - pub VoterInfoOf get(fn voter_info): map T::AccountId => Option>>; + pub VoterInfoOf get(fn voter_info): + map hasher(blake2_256) T::AccountId => Option>>; /// The present voter list (chunked and capped at [`VOTER_SET_SIZE`]). - pub Voters get(fn voters): map SetIndex => Vec>; + pub Voters get(fn voters): map hasher(blake2_256) SetIndex => Vec>; /// the next free set to store a voter in. This will keep growing. pub NextVoterSet get(fn next_nonfull_voter_set): SetIndex = 0; /// Current number of Voters. @@ -263,7 +266,7 @@ decl_storage! { /// Who is able to vote for whom. Value is the fund-holding account, key is the /// vote-transaction-sending account. - pub Proxy get(fn proxy): map T::AccountId => Option; + pub Proxy get(fn proxy): map hasher(blake2_256) T::AccountId => Option; } } diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index 8d50412724..9c79274b4a 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -163,9 +163,9 @@ pub trait Trait: frame_system::Trait + pallet_timestamp::Trait { decl_storage! { trait Store for Module as Example { - Accounts get(fn accounts) config(): map H160 => Account; - AccountCodes: map H160 => Vec; - AccountStorages: double_map H160, H256 => H256; + Accounts get(fn accounts) config(): map hasher(blake2_256) H160 => Account; + AccountCodes: map hasher(blake2_256) H160 => Vec; + AccountStorages: double_map hasher(blake2_256) H160, hasher(blake2_256) H256 => H256; } } diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index 80569a1b57..ab85de8ea9 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -329,7 +329,7 @@ decl_storage! { // `pub? Name get(fn getter_name)? [config()|config(myname)] [build(|_| {...})] : (= )?;` // where `` is either: // - `Type` (a basic value item); or - // - `map KeyType => ValueType` (a map item). + // - `map hasher(HasherKind) KeyType => ValueType` (a map item). // // Note that there are two optional modifiers for the storage type declaration. // - `Foo: Option`: @@ -339,7 +339,7 @@ decl_storage! { // - `Foo::put(1); Foo::get()` returns `1`; // - `Foo::kill(); Foo::get()` returns `0` (u32::default()). // e.g. Foo: u32; - // e.g. pub Bar get(fn bar): map T::AccountId => Vec<(T::Balance, u64)>; + // e.g. pub Bar get(fn bar): map hasher(blake2_256) T::AccountId => Vec<(T::Balance, u64)>; // // For basic value items, you'll get a type which implements // `frame_support::StorageValue`. For map items, you'll get a type which @@ -351,7 +351,7 @@ decl_storage! { Dummy get(fn dummy) config(): Option; // A map that has enumerable entries. - Bar get(fn bar) config(): linked_map T::AccountId => T::Balance; + Bar get(fn bar) config(): linked_map hasher(blake2_256) T::AccountId => T::Balance; // this one uses the default, we'll demonstrate the usage of 'mutate' API. Foo get(fn foo) config(): T::Balance; diff --git a/frame/generic-asset/src/lib.rs b/frame/generic-asset/src/lib.rs index 3b509a683d..ca6812da8e 100644 --- a/frame/generic-asset/src/lib.rs +++ b/frame/generic-asset/src/lib.rs @@ -454,22 +454,26 @@ decl_storage! { pub TotalIssuance get(fn total_issuance) build(|config: &GenesisConfig| { let issuance = config.initial_balance * (config.endowed_accounts.len() as u32).into(); config.assets.iter().map(|id| (id.clone(), issuance)).collect::>() - }): map T::AssetId => T::Balance; + }): map hasher(blake2_256) T::AssetId => T::Balance; /// The free balance of a given asset under an account. - pub FreeBalance: double_map T::AssetId, hasher(twox_128) T::AccountId => T::Balance; + pub FreeBalance: + double_map hasher(blake2_256) T::AssetId, hasher(twox_128) T::AccountId => T::Balance; /// The reserved balance of a given asset under an account. - pub ReservedBalance: double_map T::AssetId, hasher(twox_128) T::AccountId => T::Balance; + pub ReservedBalance: + double_map hasher(blake2_256) T::AssetId, hasher(twox_128) T::AccountId => T::Balance; /// Next available ID for user-created asset. pub NextAssetId get(fn next_asset_id) config(): T::AssetId; /// Permission options for a given asset. - pub Permissions get(fn get_permission): map T::AssetId => PermissionVersions; + pub Permissions get(fn get_permission): + map hasher(blake2_256) T::AssetId => PermissionVersions; /// Any liquidity locks on some account balances. - pub Locks get(fn locks): map T::AccountId => Vec>; + pub Locks get(fn locks): + map hasher(blake2_256) T::AccountId => Vec>; /// The identity of the asset which is the one that is designated for the chain's staking system. pub StakingAssetId get(fn staking_asset_id) config(): T::AssetId; diff --git a/frame/grandpa/src/lib.rs b/frame/grandpa/src/lib.rs index f2ef16dc0e..71440f7aac 100644 --- a/frame/grandpa/src/lib.rs +++ b/frame/grandpa/src/lib.rs @@ -175,7 +175,7 @@ decl_storage! { CurrentSetId get(fn current_set_id) build(|_| fg_primitives::SetId::default()): SetId; /// A mapping from grandpa set ID to the index of the *most recent* session for which its members were responsible. - SetIdSession get(fn session_for_set): map SetId => Option; + SetIdSession get(fn session_for_set): map hasher(blake2_256) SetId => Option; } add_extra_genesis { config(authorities): AuthorityList; diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index b23407406b..0bcc33b217 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -377,16 +377,19 @@ pub struct RegistrarInfo< 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>>; + pub IdentityOf get(fn identity): + map hasher(blake2_256) 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)>; + pub SuperOf get(fn super_of): + map hasher(blake2_256) 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); + pub SubsOf get(fn subs): + map hasher(blake2_256) 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). diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index 065ca7e3bf..ab1c6d7fd3 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -233,12 +233,14 @@ decl_storage! { /// For each session index, we keep a mapping of `AuthIndex` /// to `offchain::OpaqueNetworkState`. - ReceivedHeartbeats get(fn received_heartbeats): double_map SessionIndex, AuthIndex + ReceivedHeartbeats get(fn received_heartbeats): + double_map hasher(blake2_256) SessionIndex, hasher(blake2_256) AuthIndex => Option>; /// For each session index, we keep a mapping of `T::ValidatorId` to the /// number of blocks authored by the given authority. - AuthoredBlocks get(fn authored_blocks): double_map SessionIndex, T::ValidatorId => u32; + AuthoredBlocks get(fn authored_blocks): + double_map hasher(blake2_256) SessionIndex, hasher(blake2_256) T::ValidatorId => u32; } add_extra_genesis { config(keys): Vec; diff --git a/frame/indices/src/lib.rs b/frame/indices/src/lib.rs index 8d7e37d5df..e6a2a7c144 100644 --- a/frame/indices/src/lib.rs +++ b/frame/indices/src/lib.rs @@ -108,7 +108,7 @@ decl_storage! { ].to_owned(), )) .collect::>() - }): map T::AccountIndex => Vec; + }): map hasher(blake2_256) T::AccountIndex => Vec; } add_extra_genesis { config(ids): Vec; diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index 1d33d12ae4..79365ff713 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -78,7 +78,7 @@ pub trait Trait: frame_system::Trait { decl_storage! { trait Store for Module as Sudo { /// The lookup table for names. - NameOf: map T::AccountId => Option<(Vec, BalanceOf)>; + NameOf: map hasher(blake2_256) T::AccountId => Option<(Vec, BalanceOf)>; } } diff --git a/frame/offences/src/lib.rs b/frame/offences/src/lib.rs index 310c018d76..2b625873f0 100644 --- a/frame/offences/src/lib.rs +++ b/frame/offences/src/lib.rs @@ -54,10 +54,12 @@ pub trait Trait: frame_system::Trait { decl_storage! { trait Store for Module as Offences { /// The primary structure that holds all offence records keyed by report identifiers. - Reports get(fn reports): map ReportIdOf => Option>; + Reports get(fn reports): map hasher(blake2_256) ReportIdOf => Option>; /// A vector of reports of the same kind that happened at the same time slot. - ConcurrentReportsIndex: double_map Kind, OpaqueTimeSlot => Vec>; + ConcurrentReportsIndex: + double_map hasher(blake2_256) Kind, hasher(blake2_256) OpaqueTimeSlot + => Vec>; /// Enumerates all reports of a kind along with the time they happened. /// @@ -65,7 +67,7 @@ decl_storage! { /// /// Note that the actual type of this mapping is `Vec`, this is because values of /// different types are not supported at the moment so we are doing the manual serialization. - ReportsByKindIndex: map Kind => Vec; // (O::TimeSlot, ReportIdOf) + ReportsByKindIndex: map hasher(blake2_256) Kind => Vec; // (O::TimeSlot, ReportIdOf) } } diff --git a/frame/recovery/src/lib.rs b/frame/recovery/src/lib.rs index f63f216fc7..0309fec12a 100644 --- a/frame/recovery/src/lib.rs +++ b/frame/recovery/src/lib.rs @@ -242,7 +242,8 @@ decl_storage! { trait Store for Module as Recovery { /// The set of recoverable accounts and their recovery configuration. pub Recoverable get(fn recovery_config): - map T::AccountId => Option, T::AccountId>>; + map hasher(blake2_256) T::AccountId + => Option, T::AccountId>>; /// Active recovery attempts. /// /// First account is the account to be recovered, and the second account @@ -253,7 +254,8 @@ decl_storage! { /// The final list of recovered accounts. /// /// Map from the recovered account to the user who can access it. - pub Recovered get(fn recovered_account): map T::AccountId => Option; + pub Recovered get(fn recovered_account): + map hasher(blake2_256) T::AccountId => Option; } } diff --git a/frame/scored-pool/src/lib.rs b/frame/scored-pool/src/lib.rs index a8fc69971a..2a73c4bb68 100644 --- a/frame/scored-pool/src/lib.rs +++ b/frame/scored-pool/src/lib.rs @@ -165,7 +165,7 @@ decl_storage! { /// check if a candidate is already in the pool, without having to /// iterate over the entire pool (the `Pool` is not sorted by /// `T::AccountId`, but by `T::Score` instead). - CandidateExists get(fn candidate_exists): map T::AccountId => bool; + CandidateExists get(fn candidate_exists): map hasher(blake2_256) T::AccountId => bool; /// The current membership, stored as an ordered Vec. Members get(fn members): Vec; diff --git a/frame/session/src/historical.rs b/frame/session/src/historical.rs index e67a2ae1b0..76175cd6be 100644 --- a/frame/session/src/historical.rs +++ b/frame/session/src/historical.rs @@ -55,11 +55,14 @@ pub trait Trait: super::Trait { decl_storage! { trait Store for Module as Session { /// Mapping from historical session indices to session-data root hash and validator count. - HistoricalSessions get(fn historical_root): map SessionIndex => Option<(T::Hash, ValidatorCount)>; + HistoricalSessions get(fn historical_root): + map hasher(blake2_256) SessionIndex => Option<(T::Hash, ValidatorCount)>; /// The range of historical sessions we store. [first, last) StoredRange: Option<(SessionIndex, SessionIndex)>; /// Deprecated. - CachedObsolete: map SessionIndex => Option>; + CachedObsolete: + map hasher(blake2_256) SessionIndex + => Option>; } } diff --git a/frame/society/src/lib.rs b/frame/society/src/lib.rs index f4e5904ea4..e45ac30bce 100644 --- a/frame/society/src/lib.rs +++ b/frame/society/src/lib.rs @@ -414,7 +414,8 @@ decl_storage! { /// The set of suspended candidates. pub SuspendedCandidates get(suspended_candidate): - map T::AccountId => Option<(BalanceOf, BidKind>)>; + map hasher(blake2_256) T::AccountId + => Option<(BalanceOf, BidKind>)>; /// Amount of our account balance that is specifically for the next round's bid(s). pub Pot get(fn pot) config(): BalanceOf; @@ -431,19 +432,19 @@ decl_storage! { }): Vec; /// The set of suspended members. - pub SuspendedMembers get(fn suspended_member): map T::AccountId => bool; + pub SuspendedMembers get(fn suspended_member): map hasher(blake2_256) T::AccountId => bool; /// The current bids, stored ordered by the value of the bid. Bids: Vec>>; /// Members currently vouching or banned from vouching again - Vouching get(fn vouching): map T::AccountId => Option; + Vouching get(fn vouching): map hasher(blake2_256) T::AccountId => Option; /// Pending payouts; ordered by block number, with the amount that should be paid out. - Payouts: map T::AccountId => Vec<(T::BlockNumber, BalanceOf)>; + Payouts: map hasher(blake2_256) T::AccountId => Vec<(T::BlockNumber, BalanceOf)>; /// The ongoing number of losing votes cast by the member. - Strikes: map T::AccountId => StrikeCount; + Strikes: map hasher(blake2_256) T::AccountId => StrikeCount; /// Double map from Candidate -> Voter -> (Maybe) Vote. Votes: double_map diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 7f1ad37b32..21ac24bc68 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -671,28 +671,32 @@ decl_storage! { pub Invulnerables get(fn invulnerables) config(): Vec; /// Map from all locked "stash" accounts to the controller account. - pub Bonded get(fn bonded): map T::AccountId => Option; + pub Bonded get(fn bonded): map hasher(blake2_256) T::AccountId => Option; /// Map from all (unlocked) "controller" accounts to the info regarding the staking. pub Ledger get(fn ledger): - map T::AccountId => Option>>; + map hasher(blake2_256) T::AccountId + => Option>>; /// Where the reward payment should be made. Keyed by stash. - pub Payee get(fn payee): map T::AccountId => RewardDestination; + pub Payee get(fn payee): map hasher(blake2_256) 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 hasher(blake2_256) T::AccountId => ValidatorPrefs; /// The map from nominator stash key to the set of stash keys of all validators to nominate. /// /// 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 get(fn nominators): + linked_map hasher(blake2_256) 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. /// /// This is keyed by the stash account. - pub Stakers get(fn stakers): map T::AccountId => Exposure>; + pub Stakers get(fn stakers): + map hasher(blake2_256) T::AccountId => Exposure>; /// The currently elected validator set keyed by stash account ID. pub CurrentElected get(fn current_elected): Vec; @@ -729,7 +733,8 @@ decl_storage! { pub CanceledSlashPayout get(fn canceled_payout) config(): BalanceOf; /// All unapplied slashes that are queued for later. - pub UnappliedSlashes: map EraIndex => Vec>>; + pub UnappliedSlashes: + map hasher(blake2_256) EraIndex => Vec>>; /// A mapping from still-bonded eras to the first session index of that era. BondedEras: Vec<(EraIndex, SessionIndex)>; @@ -737,19 +742,22 @@ decl_storage! { /// All slashing events on validators, mapped by era to the highest slash proportion /// and slash value of the era. ValidatorSlashInEra: - double_map EraIndex, hasher(twox_128) T::AccountId => Option<(Perbill, BalanceOf)>; + double_map hasher(blake2_256) EraIndex, hasher(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, hasher(twox_128) T::AccountId => Option>; + double_map hasher(blake2_256) EraIndex, hasher(twox_128) T::AccountId + => Option>; /// Slashing spans for stash accounts. - SlashingSpans: map T::AccountId => Option; + SlashingSpans: map hasher(blake2_256) 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>; + map hasher(blake2_256) (T::AccountId, slashing::SpanIndex) + => slashing::SpanRecord>; /// The earliest era for which we have a pending, unapplied slash. EarliestUnappliedSlash: Option; diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index 7c27bc2a04..b4376915a2 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -35,8 +35,8 @@ use proc_macro::TokenStream; /// decl_storage! { /// trait Store for Module as Example { /// Foo get(fn foo) config(): u32=12; -/// Bar: map u32 => u32; -/// pub Zed build(|config| vec![(0, 0)]): linked_map u32 => u32; +/// Bar: map hasher(blake2_256) u32 => u32; +/// pub Zed build(|config| vec![(0, 0)]): linked_map hasher(blake2_256) u32 => u32; /// } /// } /// ``` @@ -74,7 +74,7 @@ use proc_macro::TokenStream; /// `$hash` representing a choice of hashing algorithms available in the /// [`Hashable`](../frame_support/trait.Hashable.html) trait. /// -/// `hasher($hash)` is optional and its default is `blake2_256`. One should use another hasher +/// `blake2_256` and `blake2_128_concat` are strong hasher. One should use another hasher /// with care, see generator documentation. /// /// The generator is implemented with: @@ -95,7 +95,7 @@ use proc_macro::TokenStream; /// `$hash` representing a choice of hashing algorithms available in the /// [`Hashable`](../frame_support/trait.Hashable.html) trait. /// -/// `hasher($hash)` is optional and its default is `blake2_256`. One should use another hasher +/// `blake2_256` and `blake2_128_concat` are strong hasher. One should use another hasher /// with care, see generator documentation. /// /// All key formatting logic can be accessed in a type-agnostic format via the @@ -126,13 +126,12 @@ use proc_macro::TokenStream; /// [`Hashable`](../frame_support/trait.Hashable.html) trait. They must be choosen with care, see /// generator documentation. /// -/// `hasher($hash1)` and `hasher($hash2) are optional and default to `blake2_256`. -/// One should use another hasher with care, see generator documentation. -/// -/// If the first key is untrusted, a cryptographic `hasher` such as `blake2_256` must be used. +/// If the first key is untrusted, a cryptographic `hasher` such as `blake2_256` or +/// `blake2_128_concat` must be used. /// Otherwise, other values of all storage items can be compromised. /// -/// If the second key is untrusted, a cryptographic `hasher` such as `blake2_256` must be used. +/// If the second key is untrusted, a cryptographic `hasher` such as `blake2_256` or +/// `blake2_128_concat` must be used. /// Otherwise, other items in storage with the same first key can be compromised. /// /// The generator is implemented with: diff --git a/frame/support/procedural/src/storage/parse.rs b/frame/support/procedural/src/storage/parse.rs index 04af85a312..b503c2b81c 100644 --- a/frame/support/procedural/src/storage/parse.rs +++ b/frame/support/procedural/src/storage/parse.rs @@ -461,29 +461,31 @@ fn parse_storage_line_defs( })?; } + let span = line.storage_type.span(); + let no_hasher_error = || syn::Error::new( + span, + "Default hasher has been removed, use explicit hasher(blake2_256) instead." + ); + let storage_type = match line.storage_type { DeclStorageType::Map(map) => super::StorageLineTypeDef::Map( super::MapDef { - hasher: map.hasher.inner.map(Into::into) - .unwrap_or(super::HasherKind::Blake2_256), + hasher: map.hasher.inner.ok_or_else(no_hasher_error)?.into(), key: map.key, value: map.value, } ), DeclStorageType::LinkedMap(map) => super::StorageLineTypeDef::LinkedMap( super::MapDef { - hasher: map.hasher.inner.map(Into::into) - .unwrap_or(super::HasherKind::Blake2_256), + hasher: map.hasher.inner.ok_or_else(no_hasher_error)?.into(), key: map.key, value: map.value, } ), DeclStorageType::DoubleMap(map) => super::StorageLineTypeDef::DoubleMap( super::DoubleMapDef { - hasher1: map.hasher1.inner.map(Into::into) - .unwrap_or(super::HasherKind::Blake2_256), - hasher2: map.hasher2.inner.map(Into::into) - .unwrap_or(super::HasherKind::Blake2_256), + hasher1: map.hasher1.inner.ok_or_else(no_hasher_error)?.into(), + hasher2: map.hasher2.inner.ok_or_else(no_hasher_error)?.into(), key1: map.key1, key2: map.key2, value: map.value, diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index ebfc7bbe97..e601544b01 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -253,20 +253,23 @@ mod tests { trait Store for Module as Example { pub Data get(fn data) build(|_| vec![(15u32, 42u64)]): linked_map hasher(twox_64_concat) u32 => u64; - pub OptionLinkedMap: linked_map u32 => Option; + pub OptionLinkedMap: linked_map hasher(blake2_256) u32 => Option; pub GenericData get(fn generic_data): linked_map hasher(twox_128) T::BlockNumber => T::BlockNumber; pub GenericData2 get(fn generic_data2): - linked_map T::BlockNumber => Option; + linked_map hasher(blake2_256) T::BlockNumber => Option; pub GetterNoFnKeyword get(no_fn): Option; pub DataDM config(test_config) build(|_| vec![(15u32, 16u32, 42u64)]): double_map hasher(twox_64_concat) u32, hasher(blake2_256) u32 => u64; pub GenericDataDM: - double_map T::BlockNumber, hasher(twox_128) T::BlockNumber => T::BlockNumber; + double_map hasher(blake2_256) T::BlockNumber, hasher(twox_128) T::BlockNumber + => T::BlockNumber; pub GenericData2DM: - double_map T::BlockNumber, hasher(twox_256) T::BlockNumber => Option; - pub AppendableDM: double_map u32, T::BlockNumber => Vec; + double_map hasher(blake2_256) T::BlockNumber, hasher(twox_256) T::BlockNumber + => Option; + pub AppendableDM: + double_map hasher(blake2_256) u32, hasher(blake2_256) T::BlockNumber => Vec; } } diff --git a/frame/support/src/storage/generator/mod.rs b/frame/support/src/storage/generator/mod.rs index 476c6d4472..2bee76babd 100644 --- a/frame/support/src/storage/generator/mod.rs +++ b/frame/support/src/storage/generator/mod.rs @@ -65,7 +65,7 @@ mod tests { crate::decl_storage! { trait Store for Module as Runtime { Value get(fn value) config(): (u64, u64); - NumberMap: linked_map NumberNumber => u64; + NumberMap: linked_map hasher(blake2_256) NumberNumber => u64; } } diff --git a/frame/support/test/tests/decl_storage.rs b/frame/support/test/tests/decl_storage.rs index 15a0807fa5..f5e3892d5f 100644 --- a/frame/support/test/tests/decl_storage.rs +++ b/frame/support/test/tests/decl_storage.rs @@ -59,23 +59,27 @@ mod tests { 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; - MAPU32MYDEF : map u32 => Option; - pub PUBMAPU32MYDEF : map u32 => Option; + MAPU32 : map hasher(blake2_256) u32 => Option; + pub PUBMAPU32 : map hasher(blake2_256) u32 => Option; + MAPU32MYDEF : map hasher(blake2_256) u32 => Option; + pub PUBMAPU32MYDEF : map hasher(blake2_256) u32 => Option; // map getters: pub / $default - GETMAPU32 get(fn map_u32_getter): map u32 => String; - pub PUBGETMAPU32 get(fn pub_map_u32_getter): map u32 => String; + GETMAPU32 get(fn map_u32_getter): map hasher(blake2_256) u32 => String; + pub PUBGETMAPU32 get(fn pub_map_u32_getter): map hasher(blake2_256) u32 => String; - GETMAPU32MYDEF get(fn map_u32_getter_mydef): map u32 => String = "map".into(); - pub PUBGETMAPU32MYDEF get(fn pub_map_u32_getter_mydef): map u32 => String = "pubmap".into(); + GETMAPU32MYDEF get(fn map_u32_getter_mydef): + map hasher(blake2_256) u32 => String = "map".into(); + pub PUBGETMAPU32MYDEF get(fn pub_map_u32_getter_mydef): + map hasher(blake2_256) u32 => String = "pubmap".into(); // linked map - LINKEDMAPU32 : linked_map u32 => Option; - pub PUBLINKEDMAPU32MYDEF : linked_map u32 => Option; - GETLINKEDMAPU32 get(fn linked_map_u32_getter): linked_map u32 => String; - pub PUBGETLINKEDMAPU32MYDEF get(fn pub_linked_map_u32_getter_mydef): linked_map u32 => String = "pubmap".into(); + LINKEDMAPU32 : linked_map hasher(blake2_256) u32 => Option; + pub PUBLINKEDMAPU32MYDEF : linked_map hasher(blake2_256) u32 => Option; + GETLINKEDMAPU32 get(fn linked_map_u32_getter): + linked_map hasher(blake2_256) u32 => String; + pub PUBGETLINKEDMAPU32MYDEF get(fn pub_linked_map_u32_getter_mydef): + linked_map hasher(blake2_256) u32 => String = "pubmap".into(); COMPLEXTYPE1: ::std::vec::Vec<::Origin>; COMPLEXTYPE2: (Vec)>>, u32); @@ -558,17 +562,17 @@ mod test_append_and_len { JustVecWithDefault: Vec = vec![6, 9]; OptionVec: Option>; - MapVec: map u32 => Vec; - MapVecWithDefault: map u32 => Vec = vec![6, 9]; - OptionMapVec: map u32 => Option>; + MapVec: map hasher(blake2_256) u32 => Vec; + MapVecWithDefault: map hasher(blake2_256) u32 => Vec = vec![6, 9]; + OptionMapVec: map hasher(blake2_256) u32 => Option>; - DoubleMapVec: double_map u32, u32 => Vec; - DoubleMapVecWithDefault: double_map u32, u32 => Vec = vec![6, 9]; - OptionDoubleMapVec: double_map u32, u32 => Option>; + DoubleMapVec: double_map hasher(blake2_256) u32, hasher(blake2_256) u32 => Vec; + DoubleMapVecWithDefault: double_map hasher(blake2_256) u32, hasher(blake2_256) u32 => Vec = vec![6, 9]; + OptionDoubleMapVec: double_map hasher(blake2_256) u32, hasher(blake2_256) u32 => Option>; - LinkedMapVec: linked_map u32 => Vec; - LinkedMapVecWithDefault: linked_map u32 => Vec = vec![6, 9]; - OptionLinkedMapVec: linked_map u32 => Option>; + LinkedMapVec: linked_map hasher(blake2_256) u32 => Vec; + LinkedMapVecWithDefault: linked_map hasher(blake2_256) u32 => Vec = vec![6, 9]; + OptionLinkedMapVec: linked_map hasher(blake2_256) u32 => Option>; } } diff --git a/frame/support/test/tests/final_keys.rs b/frame/support/test/tests/final_keys.rs index 9f1b379e25..15ee65b627 100644 --- a/frame/support/test/tests/final_keys.rs +++ b/frame/support/test/tests/final_keys.rs @@ -35,18 +35,18 @@ mod no_instance { trait Store for Module as FinalKeysNone { pub Value config(value): u32; - pub Map: map u32 => u32; + pub Map: map hasher(blake2_256) u32 => u32; pub Map2: map hasher(twox_128) u32 => u32; - pub LinkedMap: linked_map u32 => u32; + pub LinkedMap: linked_map hasher(blake2_256) u32 => u32; pub LinkedMap2: linked_map hasher(twox_128) u32 => u32; - pub DoubleMap: double_map u32, u32 => u32; + pub DoubleMap: double_map hasher(blake2_256) u32, hasher(blake2_256) u32 => u32; pub DoubleMap2: double_map hasher(twox_128) u32, hasher(blake2_128) u32 => u32; pub TestGenericValue get(fn test_generic_value) config(): Option; pub TestGenericDoubleMap get(fn foo2) config(test_generic_double_map): - double_map u32, T::BlockNumber => Option; + double_map hasher(blake2_256) u32, hasher(blake2_256) T::BlockNumber => Option; } } } @@ -65,18 +65,18 @@ mod instance { { pub Value config(value): u32; - pub Map: map u32 => u32; + pub Map: map hasher(blake2_256) u32 => u32; pub Map2: map hasher(twox_128) u32 => u32; - pub LinkedMap: linked_map u32 => u32; + pub LinkedMap: linked_map hasher(blake2_256) u32 => u32; pub LinkedMap2: linked_map hasher(twox_128) u32 => u32; - pub DoubleMap: double_map u32, u32 => u32; + pub DoubleMap: double_map hasher(blake2_256) u32, hasher(blake2_256) u32 => u32; pub DoubleMap2: double_map hasher(twox_128) u32, hasher(blake2_128) u32 => u32; pub TestGenericValue get(fn test_generic_value) config(): Option; pub TestGenericDoubleMap get(fn foo2) config(test_generic_double_map): - double_map u32, T::BlockNumber => Option; + double_map hasher(blake2_256) u32, hasher(blake2_256) T::BlockNumber => Option; } add_extra_genesis { // See `decl_storage` limitation. diff --git a/frame/support/test/tests/genesisconfig.rs b/frame/support/test/tests/genesisconfig.rs index dee7aefe0a..12af18aac9 100644 --- a/frame/support/test/tests/genesisconfig.rs +++ b/frame/support/test/tests/genesisconfig.rs @@ -25,7 +25,7 @@ frame_support::decl_module! { frame_support::decl_storage! { trait Store for Module as Example { - pub AppendableDM config(t): double_map u32, T::BlockNumber => Vec; + pub AppendableDM config(t): double_map hasher(blake2_256) u32, hasher(blake2_256) T::BlockNumber => Vec; } } diff --git a/frame/support/test/tests/instance.rs b/frame/support/test/tests/instance.rs index 879ef4fa68..2c761ca43e 100644 --- a/frame/support/test/tests/instance.rs +++ b/frame/support/test/tests/instance.rs @@ -67,8 +67,8 @@ mod module1 { T::BlockNumber: From + std::fmt::Display { pub Value config(value): T::GenericType; - pub Map: map u32 => u64; - pub LinkedMap: linked_map u32 => u64; + pub Map: map hasher(blake2_256) u32 => u64; + pub LinkedMap: linked_map hasher(blake2_256) u32 => u64; } add_extra_genesis { @@ -136,9 +136,9 @@ mod module2 { 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; - pub LinkedMap config(linked_map): linked_map u64 => Vec; - pub DoubleMap config(double_map): double_map u64, u64 => u64; + pub Map config(map): map hasher(blake2_256) u64 => u64; + pub LinkedMap config(linked_map): linked_map hasher(blake2_256) u64 => Vec; + pub DoubleMap config(double_map): double_map hasher(blake2_256) u64, hasher(blake2_256) u64 => u64; } } diff --git a/frame/support/test/tests/issue2219.rs b/frame/support/test/tests/issue2219.rs index f3ce4dac80..c0a253f22b 100644 --- a/frame/support/test/tests/issue2219.rs +++ b/frame/support/test/tests/issue2219.rs @@ -109,7 +109,7 @@ mod module { } else { vec![] } - }): map Role => Option>; + }): map hasher(blake2_256) Role => Option>; /// the roles members can enter into pub AvailableRoles get(fn available_roles) build(|config: &GenesisConfig| { @@ -124,10 +124,12 @@ mod module { pub ActorAccountIds get(fn actor_account_ids) : Vec; /// actor accounts associated with a role - pub AccountIdsByRole get(fn account_ids_by_role) : map Role => Vec; + pub AccountIdsByRole get(fn account_ids_by_role): + map hasher(blake2_256) Role => Vec; /// tokens locked until given block number - pub Bondage get(fn bondage) : map T::AccountId => T::BlockNumber; + pub Bondage get(fn bondage): + map hasher(blake2_256) T::AccountId => T::BlockNumber; /// First step before enter a role is registering intent with a new account/key. /// This is done by sending a role_entry_request() from the new account. diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index ac51ef70e3..752ab9cc91 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -436,7 +436,7 @@ type EventIndex = u32; decl_storage! { trait Store for Module as System { /// Extrinsics nonce for accounts. - pub AccountNonce get(fn account_nonce): map T::AccountId => T::Index; + pub AccountNonce get(fn account_nonce): map hasher(blake2_256) T::AccountId => T::Index; /// Total extrinsics count for the current block. ExtrinsicCount: Option; /// Total weight for all extrinsics put together, for the current block. @@ -444,9 +444,10 @@ decl_storage! { /// Total length (in bytes) for all extrinsics put together, for the current block. AllExtrinsicsLen: Option; /// Map of block numbers to block hashes. - pub BlockHash get(fn block_hash) build(|_| vec![(T::BlockNumber::zero(), hash69())]): map T::BlockNumber => T::Hash; + pub BlockHash get(fn block_hash) build(|_| vec![(T::BlockNumber::zero(), hash69())]): + map hasher(blake2_256) T::BlockNumber => T::Hash; /// Extrinsics data for the current block (maps an extrinsic's index to its data). - ExtrinsicData get(fn extrinsic_data): map u32 => Vec; + ExtrinsicData get(fn extrinsic_data): map hasher(blake2_256) u32 => Vec; /// The current block number being processed. Set by `execute_block`. Number get(fn block_number) build(|_| 1.into()): T::BlockNumber; /// Hash of the previous block. @@ -475,7 +476,7 @@ decl_storage! { /// The value has the type `(T::BlockNumber, EventIndex)` because if we used only just /// the `EventIndex` then in case if the topic has the same contents on the next block /// no notification will be triggered thus the event might be lost. - EventTopics get(fn event_topics): map T::Hash => Vec<(T::BlockNumber, EventIndex)>; + EventTopics get(fn event_topics): map hasher(blake2_256) T::Hash => Vec<(T::BlockNumber, EventIndex)>; } add_extra_genesis { config(changes_trie_config): Option; diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index 1800d0ad04..8d1c25ad66 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -200,7 +200,7 @@ decl_storage! { ProposalCount get(fn proposal_count): ProposalIndex; /// Proposals that have been made. - Proposals get(fn proposals): map ProposalIndex => Option>>; + Proposals get(fn proposals): map hasher(blake2_256) ProposalIndex => Option>>; /// Proposal indices that have been approved but not yet awarded. Approvals get(fn approvals): Vec; diff --git a/test-utils/runtime/src/system.rs b/test-utils/runtime/src/system.rs index 4d12ab8437..d0a38c7c77 100644 --- a/test-utils/runtime/src/system.rs +++ b/test-utils/runtime/src/system.rs @@ -46,7 +46,7 @@ decl_module! { decl_storage! { trait Store for Module as TestRuntime { - ExtrinsicData: map u32 => Vec; + ExtrinsicData: map hasher(blake2_256) u32 => Vec; // The current block number being processed. Set by `execute_block`. Number get(fn number): Option; ParentHash get(fn parent_hash): Hash; diff --git a/utils/frame/rpc/support/src/lib.rs b/utils/frame/rpc/support/src/lib.rs index 1e29c4e91b..a9982945e7 100644 --- a/utils/frame/rpc/support/src/lib.rs +++ b/utils/frame/rpc/support/src/lib.rs @@ -65,9 +65,9 @@ use sc_rpc_api::state::StateClient; /// decl_storage! { /// trait Store for Module as TestRuntime { /// pub LastActionId: u64; -/// pub Voxels: map Loc => Block; -/// pub Actions: linked_map u64 => Loc; -/// pub Prefab: double_map u128, (i8, i8, i8) => Block; +/// pub Voxels: map hasher(blake2_256) Loc => Block; +/// pub Actions: linked_map hasher(blake2_256) u64 => Loc; +/// pub Prefab: double_map hasher(blake2_256) u128, hasher(blake2_256) (i8, i8, i8) => Block; /// } /// } /// -- GitLab From 70575db721d581eef782d77cc654a35bb8cd6673 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Mon, 27 Jan 2020 09:26:42 -0800 Subject: [PATCH 025/180] Fix quadratic iterations over transaction pool (#4736) * transaction pool changes * service & network changes * address review * reduce future pool --- client/network/src/protocol.rs | 30 +++++++++++++++---- client/network/src/service.rs | 25 ++++++++++++---- client/network/test/src/lib.rs | 2 ++ client/service/src/builder.rs | 4 +-- client/service/src/lib.rs | 6 +++- .../transaction-pool/graph/src/base_pool.rs | 11 +++++-- client/transaction-pool/graph/src/future.rs | 2 +- client/transaction-pool/graph/src/pool.rs | 19 +++++++----- client/transaction-pool/graph/src/ready.rs | 9 ++++-- .../graph/src/validated_pool.rs | 15 ++++++---- client/transaction-pool/src/lib.rs | 6 +++- primitives/transaction-pool/src/pool.rs | 10 ++++--- 12 files changed, 102 insertions(+), 37 deletions(-) diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 7a9fc7ecfb..2df8f6597c 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -1135,18 +1135,26 @@ impl, H: ExHashT> Protocol { } } - /// Call when we must propagate ready extrinsics to peers. - pub fn propagate_extrinsics( + /// Propagate one extrinsic. + pub fn propagate_extrinsic( &mut self, + hash: &H, ) { - debug!(target: "sync", "Propagating extrinsics"); - + debug!(target: "sync", "Propagating extrinsic [{:?}]", hash); // Accept transactions only when fully synced if self.sync.status().state != SyncState::Idle { return; } + if let Some(extrinsic) = self.transaction_pool.transaction(hash) { + let propagated_to = self.do_propagate_extrinsics(&[(hash.clone(), extrinsic)]); + self.transaction_pool.on_broadcasted(propagated_to); + } + } - let extrinsics = self.transaction_pool.transactions(); + fn do_propagate_extrinsics( + &mut self, + extrinsics: &[(H, B::Extrinsic)], + ) -> HashMap> { let mut propagated_to = HashMap::new(); for (who, peer) in self.context_data.peers.iter_mut() { // never send extrinsics to the light node @@ -1177,6 +1185,18 @@ impl, H: ExHashT> Protocol { } } + propagated_to + } + + /// Call when we must propagate ready extrinsics to peers. + pub fn propagate_extrinsics(&mut self) { + debug!(target: "sync", "Propagating extrinsics"); + // Accept transactions only when fully synced + if self.sync.status().state != SyncState::Idle { + return; + } + let extrinsics = self.transaction_pool.transactions(); + let propagated_to = self.do_propagate_extrinsics(&extrinsics); self.transaction_pool.on_broadcasted(propagated_to); } diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 9c9a87bb67..c6b6168126 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -77,6 +77,8 @@ pub trait TransactionPool: Send + Sync { ); /// Notify the pool about transactions broadcast. fn on_broadcasted(&self, propagations: HashMap>); + /// Get transaction by hash. + fn transaction(&self, hash: &H) -> Option; } /// A cloneable handle for reporting cost/benefits of peers. @@ -115,7 +117,7 @@ pub struct NetworkService, H: E /// nodes it should be connected to or not. peerset: PeersetHandle, /// Channel that sends messages to the actual worker. - to_worker: mpsc::UnboundedSender>, + to_worker: mpsc::UnboundedSender>, /// Marker to pin the `H` generic. Serves no purpose except to not break backwards /// compatibility. _marker: PhantomData, @@ -477,14 +479,22 @@ impl, H: ExHashT> NetworkServic }); } - /// You must call this when new transactons are imported by the transaction pool. + /// You may call this when new transactons are imported by the transaction pool. /// - /// The latest transactions will be fetched from the `TransactionPool` that was passed at - /// initialization as part of the configuration. + /// All transactions will be fetched from the `TransactionPool` that was passed at + /// initialization as part of the configuration and propagated to peers. pub fn trigger_repropagate(&self) { let _ = self.to_worker.unbounded_send(ServiceToWorkerMsg::PropagateExtrinsics); } + /// You must call when new transaction is imported by the transaction pool. + /// + /// This transaction will be fetched from the `TransactionPool` that was passed at + /// initialization as part of the configuration and propagated to peers. + pub fn propagate_extrinsic(&self, hash: H) { + let _ = self.to_worker.unbounded_send(ServiceToWorkerMsg::PropagateExtrinsic(hash)); + } + /// Make sure an important block is propagated to peers. /// /// In chain-based consensus, we often need to make sure non-best forks are @@ -665,7 +675,8 @@ impl NetworkStateInfo for NetworkService /// Messages sent from the `NetworkService` to the `NetworkWorker`. /// /// Each entry corresponds to a method of `NetworkService`. -enum ServiceToWorkerMsg> { +enum ServiceToWorkerMsg> { + PropagateExtrinsic(H), PropagateExtrinsics, RequestJustification(B::Hash, NumberFor), AnnounceBlock(B::Hash, Vec), @@ -704,7 +715,7 @@ pub struct NetworkWorker, H: Ex /// The import queue that was passed as initialization. import_queue: Box>, /// Messages from the `NetworkService` and that must be processed. - from_worker: mpsc::UnboundedReceiver>, + 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. @@ -747,6 +758,8 @@ impl, H: ExHashT> Future for Ne this.network_service.user_protocol_mut().announce_block(hash, data), ServiceToWorkerMsg::RequestJustification(hash, number) => this.network_service.user_protocol_mut().request_justification(&hash, number), + ServiceToWorkerMsg::PropagateExtrinsic(hash) => + this.network_service.user_protocol_mut().propagate_extrinsic(&hash), ServiceToWorkerMsg::PropagateExtrinsics => this.network_service.user_protocol_mut().propagate_extrinsics(), ServiceToWorkerMsg::GetValue(key) => diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 2369ba4f22..874c4d19f9 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -391,6 +391,8 @@ impl TransactionPool for EmptyTransactionPool { ) {} fn on_broadcasted(&self, _: HashMap>) {} + + fn transaction(&self, h: &Hash) -> Option { None } } pub trait SpecializationFactory { diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index caf97438ad..202597e787 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -906,9 +906,9 @@ ServiceBuilder< let network = Arc::downgrade(&network); let transaction_pool_ = transaction_pool.clone(); let events = transaction_pool.import_notification_stream() - .for_each(move |_| { + .for_each(move |hash| { if let Some(network) = network.upgrade() { - network.trigger_repropagate(); + network.propagate_extrinsic(hash); } let status = transaction_pool_.status(); telemetry!(SUBSTRATE_INFO; "txpool.import"; diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 57e1462f64..c7069ac6e5 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -608,7 +608,7 @@ where H: std::hash::Hash + Eq + sp_runtime::traits::Member + sp_runtime::traits::MaybeSerialize, E: 'static + IntoPoolError + From, { - fn transactions(&self) -> Vec<(H, ::Extrinsic)> { + fn transactions(&self) -> Vec<(H, B::Extrinsic)> { transactions_to_propagate(&*self.pool) } @@ -660,6 +660,10 @@ where fn on_broadcasted(&self, propagations: HashMap>) { self.pool.on_broadcasted(propagations) } + + fn transaction(&self, hash: &H) -> Option { + self.pool.ready_transaction(hash).map(|tx| tx.data().clone()) + } } #[cfg(test)] diff --git a/client/transaction-pool/graph/src/base_pool.rs b/client/transaction-pool/graph/src/base_pool.rs index 1da731b71e..7b7900c3e9 100644 --- a/client/transaction-pool/graph/src/base_pool.rs +++ b/client/transaction-pool/graph/src/base_pool.rs @@ -374,9 +374,9 @@ impl BasePool Vec>>> { - let ready = self.ready.by_hash(hashes); - let future = self.future.by_hash(hashes); + pub fn by_hashes(&self, hashes: &[Hash]) -> Vec>>> { + let ready = self.ready.by_hashes(hashes); + let future = self.future.by_hashes(hashes); ready .into_iter() @@ -385,6 +385,11 @@ impl BasePool Option>> { + self.ready.by_hash(hash) + } + /// Makes sure that the transactions in the queues stay within provided limits. /// /// Removes and returns worst transactions from the queues and all transactions that depend on them. diff --git a/client/transaction-pool/graph/src/future.rs b/client/transaction-pool/graph/src/future.rs index d106c65d45..0de50c1a65 100644 --- a/client/transaction-pool/graph/src/future.rs +++ b/client/transaction-pool/graph/src/future.rs @@ -160,7 +160,7 @@ impl FutureTransactions { } /// Returns a list of known transactions - pub fn by_hash(&self, hashes: &[Hash]) -> Vec>>> { + pub fn by_hashes(&self, hashes: &[Hash]) -> Vec>>> { hashes.iter().map(|h| self.waiting.get(h).map(|x| x.transaction.clone())).collect() } diff --git a/client/transaction-pool/graph/src/pool.rs b/client/transaction-pool/graph/src/pool.rs index d0f14ad40a..815b5871ea 100644 --- a/client/transaction-pool/graph/src/pool.rs +++ b/client/transaction-pool/graph/src/pool.rs @@ -38,7 +38,7 @@ use sp_transaction_pool::{error, PoolStatus}; use crate::validated_pool::{ValidatedPool, ValidatedTransaction}; /// Modification notification event stream type; -pub type EventStream = mpsc::UnboundedReceiver<()>; +pub type EventStream = mpsc::UnboundedReceiver; /// Extrinsic hash type for a pool. pub type ExHash = ::Hash; @@ -105,11 +105,11 @@ impl Default for Options { fn default() -> Self { Options { ready: base::Limit { - count: 512, - total_bytes: 10 * 1024 * 1024, + count: 8192, + total_bytes: 20 * 1024 * 1024, }, future: base::Limit { - count: 128, + count: 512, total_bytes: 1 * 1024 * 1024, }, reject_future_transactions: false, @@ -331,7 +331,7 @@ impl 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 { + pub fn import_notification_stream(&self) -> EventStream> { self.validated_pool.import_notification_stream() } @@ -437,6 +437,11 @@ impl Pool { (hash, validity) } + + /// Get ready transaction by hash, if it present in the pool. + pub fn ready_transaction(&self, hash: &ExHash) -> Option> { + self.validated_pool.ready_by_hash(hash) + } } impl Clone for Pool { @@ -638,8 +643,8 @@ mod tests { // then let mut it = futures::executor::block_on_stream(stream); - assert_eq!(it.next(), Some(())); - assert_eq!(it.next(), Some(())); + assert_eq!(it.next(), Some(32)); + assert_eq!(it.next(), Some(33)); assert_eq!(it.next(), None); } diff --git a/client/transaction-pool/graph/src/ready.rs b/client/transaction-pool/graph/src/ready.rs index cdb0076e5a..ec8d66e6b9 100644 --- a/client/transaction-pool/graph/src/ready.rs +++ b/client/transaction-pool/graph/src/ready.rs @@ -230,8 +230,13 @@ impl ReadyTransactions { self.ready.read().contains_key(hash) } - /// Retrieve transaction by hash - pub fn by_hash(&self, hashes: &[Hash]) -> Vec>>> { + /// Retrive transaction by hash + pub fn by_hash(&self, hash: &Hash) -> Option>> { + self.by_hashes(&[hash.clone()]).into_iter().next().unwrap_or(None) + } + + /// Retrieve transactions by hash + pub fn by_hashes(&self, hashes: &[Hash]) -> Vec>>> { let ready = self.ready.read(); hashes.iter().map(|hash| { ready.get(hash).map(|x| x.transaction.transaction.clone()) diff --git a/client/transaction-pool/graph/src/validated_pool.rs b/client/transaction-pool/graph/src/validated_pool.rs index 34f34d5806..44e51a7a61 100644 --- a/client/transaction-pool/graph/src/validated_pool.rs +++ b/client/transaction-pool/graph/src/validated_pool.rs @@ -70,7 +70,7 @@ pub(crate) struct ValidatedPool { ExHash, ExtrinsicFor, >>, - import_notification_sinks: Mutex>>, + import_notification_sinks: Mutex>>>, rotator: PoolRotator>, } @@ -125,8 +125,8 @@ impl ValidatedPool { ValidatedTransaction::Valid(tx) => { let imported = self.pool.write().import(tx)?; - if let base::Imported::Ready { .. } = imported { - self.import_notification_sinks.lock().retain(|sink| sink.unbounded_send(()).is_ok()); + if let base::Imported::Ready { ref hash, .. } = imported { + self.import_notification_sinks.lock().retain(|sink| sink.unbounded_send(hash.clone()).is_ok()); } let mut listener = self.listener.write(); @@ -320,7 +320,7 @@ impl ValidatedPool { /// For each extrinsic, returns tags that it provides (if known), or None (if it is unknown). pub fn extrinsics_tags(&self, hashes: &[ExHash]) -> Vec>> { - self.pool.read().by_hash(&hashes) + self.pool.read().by_hashes(&hashes) .into_iter() .map(|existing_in_pool| existing_in_pool .map(|transaction| transaction.provides.iter().cloned() @@ -328,6 +328,11 @@ impl ValidatedPool { .collect() } + /// Get ready transaction by hash + pub fn ready_by_hash(&self, hash: &ExHash) -> Option> { + self.pool.read().ready_by_hash(hash) + } + /// Prunes ready transactions that provide given list of tags. pub fn prune_tags( &self, @@ -444,7 +449,7 @@ impl ValidatedPool { } /// Return an event stream of transactions imported to the pool. - pub fn import_notification_stream(&self) -> EventStream { + pub fn import_notification_stream(&self) -> EventStream> { let (sink, stream) = mpsc::unbounded(); self.import_notification_sinks.lock().push(sink); stream diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index b97294abe1..5f116dfd02 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -180,7 +180,7 @@ impl TransactionPool for BasicPool Box::new(self.pool.ready()) } - fn import_notification_stream(&self) -> ImportNotificationStream { + fn import_notification_stream(&self) -> ImportNotificationStream> { self.pool.import_notification_stream() } @@ -191,6 +191,10 @@ impl TransactionPool for BasicPool fn on_broadcasted(&self, propagations: HashMap, Vec>) { self.pool.on_broadcasted(propagations) } + + fn ready_transaction(&self, hash: &TxHash) -> Option> { + self.pool.ready_transaction(hash) + } } #[cfg_attr(test, derive(Debug))] diff --git a/primitives/transaction-pool/src/pool.rs b/primitives/transaction-pool/src/pool.rs index 92a0c4b5c3..2a71773996 100644 --- a/primitives/transaction-pool/src/pool.rs +++ b/primitives/transaction-pool/src/pool.rs @@ -113,7 +113,7 @@ pub enum TransactionStatus { pub type TransactionStatusStream = dyn Stream> + Send + Unpin; /// The import notification event stream. -pub type ImportNotificationStream = mpsc::UnboundedReceiver<()>; +pub type ImportNotificationStream = mpsc::UnboundedReceiver; /// Transaction hash type for a pool. pub type TxHash

=

::Hash; @@ -167,7 +167,7 @@ pub trait TransactionPool: Send + Sync { /// Error type. type Error: From + crate::error::IntoPoolError; - // Networking + // *** RPC /// Returns a future that imports a bunch of unverified transactions to the pool. fn submit_at( @@ -183,7 +183,6 @@ pub trait TransactionPool: Send + Sync { xt: TransactionFor, ) -> PoolFuture, Self::Error>; - // *** RPC /// Returns a future that import a single transaction and starts to watch their progress in the pool. fn submit_and_watch( &self, @@ -205,7 +204,7 @@ pub trait TransactionPool: Send + Sync { // *** logging / RPC / networking /// Return an event stream of transactions imported to the pool. - fn import_notification_stream(&self) -> ImportNotificationStream; + fn import_notification_stream(&self) -> ImportNotificationStream>; // *** networking /// Notify the pool about transactions broadcast. @@ -213,6 +212,9 @@ pub trait TransactionPool: Send + Sync { /// Returns transaction hash fn hash_of(&self, xt: &TransactionFor) -> TxHash; + + /// Return specific ready transaction by hash, if there is one. + fn ready_transaction(&self, hash: &TxHash) -> Option>; } /// Trait for transaction pool maintenance. -- GitLab From 6408967f70ff10b06b0e54017859052bd71d4258 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Mon, 27 Jan 2020 18:27:36 +0100 Subject: [PATCH 026/180] Upgrade to libp2p 0.15 (#4732) * Fixes for libp2p 0.15 * More work * Update libp2p * Update to libp2p 0.15 --- Cargo.lock | 498 ++++++++++-------- client/authority-discovery/Cargo.toml | 2 +- client/network-gossip/Cargo.toml | 2 +- client/network/Cargo.toml | 2 +- client/network/src/config.rs | 5 + client/network/src/discovery.rs | 2 +- .../src/protocol/legacy_proto/handler.rs | 18 +- .../src/protocol/legacy_proto/upgrade.rs | 8 +- client/network/src/service.rs | 10 +- client/network/test/Cargo.toml | 2 +- client/network/test/src/lib.rs | 4 +- client/peerset/Cargo.toml | 2 +- client/service/src/builder.rs | 8 + client/telemetry/Cargo.toml | 2 +- primitives/consensus/common/Cargo.toml | 2 +- utils/browser/Cargo.toml | 2 +- 16 files changed, 332 insertions(+), 237 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b2bf3f6265..4124e32263 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -370,10 +370,10 @@ dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-web 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (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)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sc-chain-spec 2.0.0", "sc-network 0.8.0", "sc-service 0.8.0", @@ -447,7 +447,7 @@ dependencies = [ [[package]] name = "bytes" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -510,7 +510,7 @@ version = "2.0.0" 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)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sc-keystore 2.0.0", "sp-core 2.0.0", "structopt 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -608,7 +608,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -650,7 +650,7 @@ dependencies = [ "cranelift-entity 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.1.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.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -684,7 +684,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cranelift-codegen 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1025,8 +1025,8 @@ 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 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)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1241,7 +1241,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)", "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)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1251,6 +1251,11 @@ name = "fixedbitset" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "fixedbitset" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "flate2" version = "1.0.13" @@ -1602,7 +1607,7 @@ name = "futures_codec" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (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)", @@ -1729,7 +1734,7 @@ 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)", "grafana-data-source 0.8.0", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1754,7 +1759,7 @@ name = "h2" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (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)", @@ -1875,7 +1880,7 @@ name = "http" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (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)", ] @@ -1896,7 +1901,7 @@ name = "http-body" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1965,7 +1970,7 @@ name = "hyper" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (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)", @@ -2268,7 +2273,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "parity-bytes 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2296,7 +2301,7 @@ dependencies = [ "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.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2349,48 +2354,48 @@ dependencies = [ [[package]] name = "libp2p" -version = "0.14.0-alpha.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (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)", - "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core-derive 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-deflate 0.6.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-dns 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-floodsub 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-identify 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-kad 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-mdns 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-mplex 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-noise 0.12.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-ping 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-plaintext 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-secio 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.4.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-tcp 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-uds 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-wasm-ext 0.7.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-websocket 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-yamux 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core-derive 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-deflate 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-dns 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-floodsub 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-gossipsub 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-identify 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-kad 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-mdns 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-mplex 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-noise 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-ping 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-plaintext 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-secio 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-swarm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-tcp 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-uds 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-wasm-ext 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-websocket 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-yamux 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-core" -version = "0.14.0-alpha.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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.5.3 (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.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)", @@ -2400,15 +2405,16 @@ dependencies = [ "multistream-select 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multiaddr 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", "rw-stream-sink 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.3.0 (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)", @@ -2417,7 +2423,7 @@ dependencies = [ [[package]] name = "libp2p-core-derive" -version = "0.14.0-alpha.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2426,79 +2432,101 @@ dependencies = [ [[package]] name = "libp2p-deflate" -version = "0.6.0-alpha.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-dns" -version = "0.14.0-alpha.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-floodsub" -version = "0.14.0-alpha.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "cuckoofilter 0.3.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)", - "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.4.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "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)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-swarm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "libp2p-identify" -version = "0.14.0-alpha.1" +name = "libp2p-gossipsub" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (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)", "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.4.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-swarm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lru 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "libp2p-identify" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-swarm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "libp2p-kad" -version = "0.14.0-alpha.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (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)", "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.4.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-swarm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "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)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "uint 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2507,7 +2535,7 @@ dependencies = [ [[package]] name = "libp2p-mdns" -version = "0.14.0-alpha.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "async-std 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2516,45 +2544,44 @@ dependencies = [ "either 1.5.3 (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)", - "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.4.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-swarm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.1.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.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-mplex" -version = "0.14.0-alpha.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (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)", "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-noise" -version = "0.12.0-alpha.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "curve25519-dalek 1.2.3 (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)", - "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "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)", + "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2563,31 +2590,30 @@ dependencies = [ [[package]] name = "libp2p-ping" -version = "0.14.0-alpha.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.4.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-swarm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (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.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-plaintext" -version = "0.14.0-alpha.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rw-stream-sink 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2595,7 +2621,7 @@ dependencies = [ [[package]] name = "libp2p-secio" -version = "0.14.0-alpha.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2604,18 +2630,19 @@ dependencies = [ "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "quicksink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", "rw-stream-sink 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2623,50 +2650,50 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.4.0-alpha.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.1.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.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-tcp" -version = "0.14.0-alpha.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "async-std 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (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)", "get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "ipnet 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-uds" -version = "0.14.0-alpha.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "async-std 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libp2p-wasm-ext" -version = "0.7.0-alpha.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2674,14 +2701,14 @@ dependencies = [ [[package]] name = "libp2p-websocket" -version = "0.14.0-alpha.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "async-tls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "quicksink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2694,13 +2721,13 @@ dependencies = [ [[package]] name = "libp2p-yamux" -version = "0.14.0-alpha.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "yamux 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2725,8 +2752,8 @@ dependencies = [ "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "hmac-drbg 0.2.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)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.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)", ] @@ -2950,15 +2977,20 @@ name = "multimap" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "multimap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "multistream-select" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (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.10 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.1.0 (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.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3035,7 +3067,7 @@ dependencies = [ "pallet-timestamp 2.0.0", "pallet-transaction-payment 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sc-authority-discovery 0.8.0", "sc-basic-authorship 0.8.0", "sc-chain-spec 2.0.0", @@ -4132,7 +4164,7 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4143,10 +4175,10 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4198,7 +4230,7 @@ dependencies = [ "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem-derive 0.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)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4288,7 +4320,7 @@ dependencies = [ "cloudabi 0.0.3 (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)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4349,6 +4381,15 @@ dependencies = [ "fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "petgraph" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fixedbitset 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)", +] + [[package]] name = "pin-project" version = "0.4.6" @@ -4493,7 +4534,7 @@ name = "prost" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "prost-derive 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4514,6 +4555,23 @@ dependencies = [ "which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "prost-build" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.5.4 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "multimap 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "petgraph 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "which 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "prost-derive" version = "0.5.0" @@ -4548,9 +4606,13 @@ dependencies = [ ] [[package]] -name = "protobuf" -version = "2.8.1" +name = "prost-types" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "pwasm-utils" @@ -4574,7 +4636,7 @@ 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.10 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4645,7 +4707,7 @@ dependencies = [ [[package]] name = "rand" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5018,13 +5080,13 @@ 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)", "futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-build 0.5.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)", + "rand 0.7.3 (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", @@ -5291,7 +5353,7 @@ dependencies = [ "parity-scale-codec 1.1.2 (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)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sc-block-builder 0.8.0", "sc-client 0.8.0", "sc-client-api 2.0.0", @@ -5504,7 +5566,7 @@ dependencies = [ "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sc-client 0.8.0", "sc-client-api 2.0.0", "sc-keystore 2.0.0", @@ -5537,7 +5599,7 @@ 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)", + "rand 0.7.3 (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", @@ -5550,7 +5612,7 @@ name = "sc-network" version = "0.8.0" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (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)", @@ -5560,7 +5622,7 @@ dependencies = [ "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)", "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.15.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)", "linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5568,7 +5630,7 @@ dependencies = [ "parity-scale-codec 1.1.2 (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)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "sc-block-builder 0.8.0", "sc-client 0.8.0", @@ -5602,7 +5664,7 @@ 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.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (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)", @@ -5618,10 +5680,10 @@ 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.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (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)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sc-block-builder 0.8.0", "sc-client 0.8.0", "sc-client-api 2.0.0", @@ -5653,7 +5715,7 @@ dependencies = [ "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.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)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sc-client-api 2.0.0", "sc-client-db 0.8.0", "sc-keystore 2.0.0", @@ -5674,9 +5736,9 @@ name = "sc-peerset" version = "2.0.0" dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5850,14 +5912,14 @@ dependencies = [ name = "sc-telemetry" version = "2.0.0" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (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.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (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)", @@ -5940,7 +6002,7 @@ dependencies = [ "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)", + "sha2 0.8.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)", ] @@ -6079,7 +6141,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "sha2" -version = "0.8.0" +version = "0.8.1" 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)", @@ -6169,7 +6231,7 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -6190,15 +6252,15 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "futures 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)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6293,7 +6355,7 @@ dependencies = [ "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (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)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-debug-derive 2.0.0", "sp-std 2.0.0", @@ -6353,7 +6415,7 @@ 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)", "futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6428,13 +6490,13 @@ dependencies = [ "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)", + "rand 0.7.3 (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.1.0 (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.104 (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)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "sp-debug-derive 2.0.0", "sp-externalities 0.8.0", "sp-runtime-interface 2.0.0", @@ -6545,7 +6607,7 @@ dependencies = [ name = "sp-phragmen" version = "2.0.0" dependencies = [ - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-io 2.0.0", "sp-runtime 2.0.0", @@ -6570,7 +6632,7 @@ dependencies = [ "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (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)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (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", @@ -6684,7 +6746,7 @@ dependencies = [ "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.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)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-externalities 0.8.0", "sp-panic-handler 2.0.0", @@ -6882,7 +6944,7 @@ dependencies = [ "pallet-balances 2.0.0", "pallet-transaction-payment 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "sc-rpc 2.0.0", @@ -6900,7 +6962,7 @@ 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)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7138,7 +7200,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)", "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)", + "rand 0.7.3 (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)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7227,7 +7289,7 @@ dependencies = [ "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "pbkdf2 0.3.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)", + "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7283,7 +7345,7 @@ name = "tokio" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (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)", "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7504,7 +7566,7 @@ name = "tokio-util" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (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.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7584,7 +7646,7 @@ dependencies = [ "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7637,7 +7699,7 @@ name = "twox-hash" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7690,7 +7752,7 @@ name = "unicode-normalization" 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)", + "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7723,7 +7785,7 @@ name = "unsigned-varint" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -8008,7 +8070,7 @@ dependencies = [ "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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.1 (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.9 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -8151,6 +8213,14 @@ dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "which" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi" version = "0.2.8" @@ -8208,7 +8278,7 @@ dependencies = [ "log 0.4.10 (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)", + "rand 0.7.3 (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)", "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -8243,12 +8313,12 @@ name = "yamux" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (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.10 (registry+https://github.com/rust-lang/crates.io-index)", "nohash-hasher 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -8355,7 +8425,7 @@ 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.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10004c15deb332055f7a4a208190aed362cf9a7c2f6ab70a305fba50e1105f38" +"checksum bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" "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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "46e3374c604fb39d1a2f35ed5e4a4e30e60d01fab49446e08f1b3e9a90aef202" @@ -8440,6 +8510,7 @@ dependencies = [ "checksum finality-grandpa 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "52c48f8a628193ba18639b2f727c32132d75f167a4b32f44b252ea8b937f154c" "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 fixedbitset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" "checksum flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" @@ -8539,26 +8610,27 @@ dependencies = [ "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" "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.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0c85f850649e7533db125207d86bc2180faf7a962ea07686011031b71cbb3540" -"checksum libp2p-core 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "187ac3f588a74d48f163a8899fddafef4dc9796cad7b73ae754d9e928cebbbe7" -"checksum libp2p-core-derive 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b674da01855701636371b3d5f0e6b38bf5a74d283de705c1f66fab9980da8943" -"checksum libp2p-deflate 0.6.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2f83cefe9f01a4a7012c1285e20fca4f193c46526a350679465150035afc5a97" -"checksum libp2p-dns 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "67d5a6d0905479ee4c6bcfaeab597d506f3447e5eb09b84aff1ed5e6d834b221" -"checksum libp2p-floodsub 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "462f310a152433a94d4e9766aa8366e4770084f67b9a17289a9667a7b0780714" -"checksum libp2p-identify 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8269e7b673cf0fbce1cbfedf61708e860aeb4b2ad3ca2df54586f1e810b9fbc9" -"checksum libp2p-kad 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90fdc0027f76b50b0822f489f5b8a83664b71c6087e67e8e9e53e6c255b069b3" -"checksum libp2p-mdns 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be0b7cdeb0ad2c009099eaed258ef18b308c1e3f56d8f57668a868305f1c4caa" -"checksum libp2p-mplex 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "54c2ca42c7511fddc566af2259b81749d36011fefab1e99d9bf77bdc6210a5bd" -"checksum libp2p-noise 0.12.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8ff485bebd3181fc7f0c8ca7d11dde6231c132bbfb5d26c0e3a568e1a58b450" -"checksum libp2p-ping 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9061919a24a74760610c860e67cdb44ae4fd3cffe34c3b3a916f21ec68d9d50a" -"checksum libp2p-plaintext 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e9bf4b832590e0bf7efc09ff91c2d4cda0737f29b44356ef0cc3aecc08ed54a" -"checksum libp2p-secio 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2aa7599c5413cbc3de7138d64b932a26e86f8897ef3722f18840ed12ad54ea43" -"checksum libp2p-swarm 0.4.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ea29f98b08c7a5113a787bce1a44d33fca6cf9f680f99812b50555e50baf408" -"checksum libp2p-tcp 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a4e0d1f322101d81c26782e76c523043f96fe53fa41962fd2c2193a709985186" -"checksum libp2p-uds 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d5620aca9d9f85158b934be33a25a6310f1ca6a038392498eb7f35d35063aee9" -"checksum libp2p-wasm-ext 0.7.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2dfe80dd0d2cb6412b57fffeb3db2dc36f7ea23566ed94011e0e07ff948f9624" -"checksum libp2p-websocket 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ac2a4974254a91f5291ef8493e6377380473334ba166ea0487e898364931dd61" -"checksum libp2p-yamux 0.14.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ef3277eaffc7c3a0ad0c115dcbe3cbeb0e3a953a18b959d05081835fc2cf2ff9" +"checksum libp2p 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f84847789ab24b3fc5971a68656ac85886df640986d9ce3264c0327694eae471" +"checksum libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dbafb2706b8082233f66dc13e196f9cf9b4c229f2cd7c96b2b16617ad6ee330b" +"checksum libp2p-core-derive 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6c320266be0a7760e23484d635acdb83844b2d74d3612d93b41c393c9bcf004e" +"checksum libp2p-deflate 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be32697b42d040b325c3737f827ea04ede569ec956b7807700dd8d89d8210f9" +"checksum libp2p-dns 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f11c979b882f25d85726b15637d5bbc722dfa1be576605c54e99b8cf56906be3" +"checksum libp2p-floodsub 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4bdf6fba9272ad47dde94bade89540fdb16e24ae9ff7fb714c1c80a035165f28" +"checksum libp2p-gossipsub 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e6ecd058bf769d27ebec530544b081e08b0a1088e3186da8cc58d59915784d0" +"checksum libp2p-identify 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d1a6261b804111c2dbf53f8ca03f66edc5ad1c29b78a61cf0cc5354052e28e9" +"checksum libp2p-kad 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c6ea6fece0d99599afb1b2082ca8937944cdd6b0946a88d54cb3ae7a38d1253" +"checksum libp2p-mdns 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "074312353355df310affa105ec71b16fd7e52f5c6ae61d3dcbb3e79e8fdc9e5f" +"checksum libp2p-mplex 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "89d0b44dfdef80cc2be4b42d127de1c793905eca2459415a5c57d6b4fbd8ec30" +"checksum libp2p-noise 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0845e8208d814cd41c26c90a6a2f2b720c31b588209cecc49a44c881a09f417f" +"checksum libp2p-ping 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ecced2949ae93b6ff29565303ecd1bef15c4e4efb689033ee744922561a36b" +"checksum libp2p-plaintext 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "195fda6b6a948a242fd30570e0e3418ae8e0a20055ea75d45458e1079a8efb05" +"checksum libp2p-secio 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ceef68ca377b264f84d64c88739a8fa118b5db1e8f18297351dff75314504a5f" +"checksum libp2p-swarm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "14ea00be81bc3985e36abad263ce2ad1b6aeb862aa743563eb70ad42880c05ae" +"checksum libp2p-tcp 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9e65ef381570df31cb047dfbc11483ab0fe7e6abbdcf2bdc2c60b5d11133d241" +"checksum libp2p-uds 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4f4f7989b35f33d4b9738aab2f031310eb20fec513cab44d12b1bc985a8074" +"checksum libp2p-wasm-ext 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0b4d457adb91a5e2212343218a554394cd8ced64a79fb8e36e7aed2a16d49495" +"checksum libp2p-websocket 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bba425f2af1fdb7dece88b9ae05ca9430dfb0b72b2c078e73ded6f1556084509" +"checksum libp2p-yamux 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ca25b3aac78a3c93c2a567622abd3cfc16f96f26ae1bf6134f0056203d62d86" "checksum librocksdb-sys 6.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0785e816e1e11e7599388a492c61ef80ddc2afc91e313e61662cce537809be" "checksum libsecp256k1 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "df6edf84fd62aad1c93932b39324eaeda3912c1d26bc18dfaee6293848e49a50" "checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" @@ -8587,6 +8659,7 @@ dependencies = [ "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 multimap 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a97fbd5d00e0e37bfb10f433af8f5aaf631e739368dc9fc28286ca81ca4948dc" "checksum multistream-select 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f938ffe420493e77c8b6cbcc3f282283f68fc889c5dcbc8e51668d5f3a01ad94" "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" @@ -8637,6 +8710,7 @@ dependencies = [ "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" "checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" +"checksum petgraph 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29c127eea4a29ec6c85d153c59dc1213f33ec74cead30fe4730aecc88cc1fd92" "checksum pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "94b90146c7216e4cb534069fb91366de4ea0ea353105ee45ed297e2d1619e469" "checksum pin-project-internal 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "44ca92f893f0656d3cba8158dd0f2b99b94de256a4a54e870bd6922fcc6c8355" "checksum pin-project-lite 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f0af6cbca0e6e3ce8692ee19fb8d734b641899e07b68eb73e9bbbd32f1703991" @@ -8656,10 +8730,11 @@ dependencies = [ "checksum prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96d14b1c185652833d24aaad41c5832b0be5616a590227c1fbff57c616754b23" "checksum prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212" "checksum prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb788126ea840817128183f8f603dce02cb7aea25c2a0b764359d8e20010702e" +"checksum prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "02b10678c913ecbd69350e8535c3aef91a8676c0773fc1d7b95cdd196d7f2f26" "checksum prost-derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e7dc378b94ac374644181a2247cebf59a6ec1c88b49ac77f3a94b86b79d0e11" "checksum prost-derive 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72" "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 prost-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1834f67c0697c001304b75be76f67add9c89742eda3a085ad8ee0bb38c3417aa" "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.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5ca504a2fdaa08d3517f442fbbba91ac24d1ec4c51ea68688a038765e3b2662" @@ -8669,7 +8744,7 @@ dependencies = [ "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.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 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" @@ -8730,7 +8805,7 @@ dependencies = [ "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 sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" "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" @@ -8740,7 +8815,7 @@ dependencies = [ "checksum slog-scope 4.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c44c89dd8b0ae4537d1ae318353eaf7840b4869c536e31c41e963d1ea523ee6" "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 smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4" "checksum snow 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "afb767eee7d257ba202f0b9b08673bc13b22281632ef45267b19f13100accd2f" "checksum soketto 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3caa0ad6b765419f21e4cfa490ec7514a9fae4af986adef168a69477ba528671" "checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" @@ -8867,6 +8942,7 @@ dependencies = [ "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 which 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5475d47078209a02e60614f7ba5e645ef3ed60f771920ac1906d7c1cc65024c8" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index 25c3f161d4..6e4570a540 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -14,7 +14,7 @@ codec = { package = "parity-scale-codec", default-features = false, version = "1 derive_more = "0.99.2" futures = "0.3.1" futures-timer = "2.0" -libp2p = { version = "0.14.0-alpha.1", default-features = false, features = ["secp256k1", "libp2p-websocket"] } +libp2p = { version = "0.15.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } log = "0.4.8" prost = "0.6.1" rand = "0.7.2" diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index 91c80e2213..82611bffc8 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -12,7 +12,7 @@ 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.14.0-alpha.1", default-features = false, features = ["libp2p-websocket"] } +libp2p = { version = "0.15.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/Cargo.toml b/client/network/Cargo.toml index f1d89f71b0..7930087595 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -22,7 +22,7 @@ linked_hash_set = "0.1.3" lru = "0.4.0" rustc-hex = "2.0.1" rand = "0.7.2" -libp2p = { version = "0.14.0-alpha.1", default-features = false, features = ["libp2p-websocket"] } +libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] } fork-tree = { version = "2.0.0", path = "../../utils/fork-tree" } sp-consensus = { version = "0.8", path = "../../primitives/consensus/common" } sc-client = { version = "0.8", path = "../" } diff --git a/client/network/src/config.rs b/client/network/src/config.rs index 6a2062ddbf..6cf2587fe4 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -32,6 +32,7 @@ use libp2p::identity::{Keypair, ed25519}; use libp2p::wasm_ext; use libp2p::{PeerId, Multiaddr, multiaddr}; use core::{fmt, iter}; +use std::{future::Future, pin::Pin}; use std::{error::Error, fs, io::{self, Write}, net::Ipv4Addr, path::{Path, PathBuf}, sync::Arc}; use zeroize::Zeroize; @@ -40,6 +41,10 @@ pub struct Params { /// Assigned roles for our node (full, light, ...). pub roles: Roles, + /// How to spawn background tasks. If you pass `None`, then a threads pool will be used by + /// default. + pub executor: Option + Send>>) + Send>>, + /// Network layer configuration. pub network_config: NetworkConfiguration, diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index 11f687616e..531e769cce 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -122,7 +122,7 @@ impl DiscoveryBehaviour { allow_private_ipv4, #[cfg(not(target_os = "unknown"))] mdns: if enable_mdns { - match Mdns::new().await { + match Mdns::new() { Ok(mdns) => Some(mdns).into(), Err(err) => { warn!(target: "sub-libp2p", "Failed to initialize mDNS: {:?}", err); diff --git a/client/network/src/protocol/legacy_proto/handler.rs b/client/network/src/protocol/legacy_proto/handler.rs index f042d1b889..fc3b64b968 100644 --- a/client/network/src/protocol/legacy_proto/handler.rs +++ b/client/network/src/protocol/legacy_proto/handler.rs @@ -18,7 +18,7 @@ use super::upgrade::{RegisteredProtocol, RegisteredProtocolEvent, RegisteredProt use bytes::BytesMut; use futures::prelude::*; use futures_timer::Delay; -use libp2p::core::{ConnectedPoint, PeerId, Endpoint}; +use libp2p::core::{ConnectedPoint, Negotiated, PeerId, Endpoint}; use libp2p::core::upgrade::{InboundUpgrade, OutboundUpgrade}; use libp2p::swarm::{ ProtocolsHandler, ProtocolsHandlerEvent, @@ -159,7 +159,7 @@ enum ProtocolState { /// Waiting for the behaviour to tell the handler whether it is enabled or disabled. Init { /// List of substreams opened by the remote but that haven't been processed yet. - substreams: SmallVec<[RegisteredProtocolSubstream; 6]>, + substreams: SmallVec<[RegisteredProtocolSubstream>; 6]>, /// Deadline after which the initialization is abnormally long. init_deadline: Delay, }, @@ -175,9 +175,9 @@ enum ProtocolState { /// If we are in this state, we have sent a `CustomProtocolOpen` message to the outside. Normal { /// The substreams where bidirectional communications happen. - substreams: SmallVec<[RegisteredProtocolSubstream; 4]>, + substreams: SmallVec<[RegisteredProtocolSubstream>; 4]>, /// Contains substreams which are being shut down. - shutdown: SmallVec<[RegisteredProtocolSubstream; 4]>, + shutdown: SmallVec<[RegisteredProtocolSubstream>; 4]>, }, /// We are disabled. Contains substreams that are being closed. @@ -185,7 +185,7 @@ enum ProtocolState { /// outside or we have never sent any `CustomProtocolOpen` in the first place. Disabled { /// List of substreams to shut down. - shutdown: SmallVec<[RegisteredProtocolSubstream; 6]>, + shutdown: SmallVec<[RegisteredProtocolSubstream>; 6]>, /// If true, we should reactivate the handler after all the substreams in `shutdown` have /// been closed. @@ -466,7 +466,7 @@ where /// Called by `inject_fully_negotiated_inbound` and `inject_fully_negotiated_outbound`. fn inject_fully_negotiated( &mut self, - mut substream: RegisteredProtocolSubstream + mut substream: RegisteredProtocolSubstream> ) { self.state = match mem::replace(&mut self.state, ProtocolState::Poisoned) { ProtocolState::Poisoned => { @@ -538,14 +538,14 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin { fn inject_fully_negotiated_inbound( &mut self, - proto: >::Output + proto: >>::Output ) { self.inject_fully_negotiated(proto); } fn inject_fully_negotiated_outbound( &mut self, - proto: >::Output, + proto: >>::Output, _: Self::OutboundOpenInfo ) { self.inject_fully_negotiated(proto); @@ -621,7 +621,7 @@ where /// Given a list of substreams, tries to shut them down. The substreams that have been successfully /// shut down are removed from the list. fn shutdown_list - (list: &mut SmallVec>>, + (list: &mut SmallVec>>>, cx: &mut Context) where TSubstream: AsyncRead + AsyncWrite + Unpin { 'outer: for n in (0..list.len()).rev() { diff --git a/client/network/src/protocol/legacy_proto/upgrade.rs b/client/network/src/protocol/legacy_proto/upgrade.rs index c021d5917f..311e0b04f9 100644 --- a/client/network/src/protocol/legacy_proto/upgrade.rs +++ b/client/network/src/protocol/legacy_proto/upgrade.rs @@ -18,7 +18,7 @@ use crate::config::ProtocolId; use bytes::BytesMut; use futures::prelude::*; use futures_codec::Framed; -use libp2p::core::{Negotiated, Endpoint, UpgradeInfo, InboundUpgrade, OutboundUpgrade, upgrade::ProtocolName}; +use libp2p::core::{Endpoint, UpgradeInfo, InboundUpgrade, OutboundUpgrade, upgrade::ProtocolName}; use std::{collections::VecDeque, io, pin::Pin, vec::IntoIter as VecIntoIter}; use std::task::{Context, Poll}; use unsigned_varint::codec::UviBytes; @@ -82,7 +82,7 @@ pub struct RegisteredProtocolSubstream { /// If true, we should call `poll_complete` on the inner sink. requires_poll_flush: bool, /// The underlying substream. - inner: stream::Fuse, UviBytes>>, + inner: stream::Fuse>>, /// Version of the protocol that was negotiated. protocol_version: u8, /// If true, we have sent a "remote is clogged" event recently and shouldn't send another one @@ -250,7 +250,7 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin, fn upgrade_inbound( self, - socket: Negotiated, + socket: TSubstream, info: Self::Info, ) -> Self::Future { let framed = { @@ -280,7 +280,7 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin, fn upgrade_outbound( self, - socket: Negotiated, + socket: TSubstream, info: Self::Info, ) -> Self::Future { let framed = Framed::new(socket, UviBytes::default()); diff --git a/client/network/src/service.rs b/client/network/src/service.rs index c6b6168126..e3eaf6c31d 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -36,7 +36,7 @@ use futures::{prelude::*, channel::mpsc}; use log::{warn, error, info, trace}; use libp2p::{PeerId, Multiaddr, kad::record}; use libp2p::core::{transport::boxed::Boxed, muxing::StreamMuxerBox}; -use libp2p::swarm::{NetworkBehaviour, SwarmEvent}; +use libp2p::swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent}; use parking_lot::Mutex; use sc_peerset::PeersetHandle; use sp_runtime::{traits::{Block as BlockT, NumberFor}, ConsensusEngineId}; @@ -213,7 +213,7 @@ impl, H: ExHashT> NetworkWorker )?; // Build the swarm. - let (mut swarm, bandwidth) = { + let (mut swarm, bandwidth): (Swarm::, _) = { let user_agent = format!( "{} ({})", params.network_config.client_version, @@ -241,7 +241,11 @@ impl, H: ExHashT> NetworkWorker }; transport::build_transport(local_identity, config_mem, config_wasm) }; - (Swarm::::new(transport, behaviour, local_peer_id.clone()), bandwidth) + let mut builder = SwarmBuilder::new(transport, behaviour, local_peer_id.clone()); + if let Some(spawner) = params.executor { + builder = builder.executor_fn(spawner); + } + (builder.build(), bandwidth) }; // Listen on multiaddresses. diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index 036607df92..19590c2651 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -14,7 +14,7 @@ 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.14.0-alpha.1", default-features = false, features = ["libp2p-websocket"] } +libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] } sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" } sc-client = { version = "0.8", path = "../../" } sc-client-api = { version = "2.0.0", path = "../../api" } diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 874c4d19f9..1e14ec7bb0 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -52,7 +52,7 @@ use sc_network::config::{NetworkConfiguration, TransportConfig, BoxFinalityProof use libp2p::PeerId; use parking_lot::Mutex; use sp_core::H256; -use sc_network::{Context, ProtocolConfig}; +use sc_network::ProtocolConfig; use sp_runtime::generic::{BlockId, OpaqueDigestItemId}; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; use sp_runtime::Justification; @@ -613,6 +613,7 @@ pub trait TestNetFactory: Sized { let network = NetworkWorker::new(sc_network::config::Params { roles: config.roles, + executor: None, network_config: NetworkConfiguration { listen_addresses: vec![listen_addr.clone()], transport: TransportConfig::MemoryOnly, @@ -688,6 +689,7 @@ pub trait TestNetFactory: Sized { let network = NetworkWorker::new(sc_network::config::Params { roles: config.roles, + executor: None, network_config: NetworkConfiguration { listen_addresses: vec![listen_addr.clone()], transport: TransportConfig::MemoryOnly, diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index 90f44418c7..85c988d048 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -9,7 +9,7 @@ edition = "2018" [dependencies] futures = "0.3.1" -libp2p = { version = "0.14.0-alpha.1", default-features = false } +libp2p = { version = "0.15.0", default-features = false } log = "0.4.8" serde_json = "1.0.41" diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 202597e787..9b27a5b270 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -837,6 +837,14 @@ ServiceBuilder< let network_params = sc_network::config::Params { roles: config.roles, + executor: { + let to_spawn_tx = to_spawn_tx.clone(); + Some(Box::new(move |fut| { + if let Err(e) = to_spawn_tx.unbounded_send(fut) { + error!("Failed to spawn libp2p background task: {:?}", e); + } + })) + }, network_config: config.network.clone(), chain: client.clone(), finality_proof_provider, diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index c536b7599b..dbcc486d17 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -10,7 +10,7 @@ bytes = "0.5" parking_lot = "0.9.0" futures = "0.3.1" futures-timer = "2.0.0" -libp2p = { version = "0.14.0-alpha.1", default-features = false, features = ["libp2p-websocket"] } +libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] } log = "0.4.8" pin-project = "0.4.6" rand = "0.7.2" diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index 8735416028..9321660871 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -7,7 +7,7 @@ edition = "2018" [dependencies] derive_more = "0.99.2" -libp2p = { version = "0.14.0-alpha.1", default-features = false } +libp2p = { version = "0.15.0", default-features = false } log = "0.4.8" sp-core = { path= "../../core" } sp-inherents = { version = "2.0.0", path = "../../inherents" } diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index cfceaa143c..15ad771b45 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -9,7 +9,7 @@ edition = "2018" futures = "0.3" futures01 = { package = "futures", version = "0.1.29" } log = "0.4.8" -libp2p = { version = "0.14.0-alpha.1", default-features = false } +libp2p = { version = "0.15.0", default-features = false } console_error_panic_hook = "0.1.6" console_log = "0.1.2" js-sys = "0.3.34" -- GitLab From 17aae385e16ae4ac9591db910d7b3258e44ec592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 28 Jan 2020 09:36:57 +0100 Subject: [PATCH 027/180] WASM runtime switch to import memory (#4737) * WASM runtime switch to import memory Up to now runtimes have exported their memory. To unify it with sandboxing, this pr switches runtimes to import memory as well. From a functional perspective, exporting/importing memory makes no difference to the runtime. To provide backwards compatibility, WASM exported memory is still supported. * Revert debug stuff * Revert some stuff --- Cargo.lock | 12 +- bin/node-template/runtime/build.rs | 15 +- bin/node/runtime/build.rs | 18 +- client/executor/runtime-test/build.rs | 18 +- client/executor/runtime-test/src/lib.rs | 40 +++ client/executor/src/integration_tests/mod.rs | 157 +++++----- .../executor/src/integration_tests/sandbox.rs | 56 ---- client/executor/wasmi/src/lib.rs | 118 ++++++-- client/executor/wasmtime/src/runtime.rs | 178 ++++++----- .../runtime-interface/test-wasm/build.rs | 18 +- test-utils/client/src/lib.rs | 1 - test-utils/runtime/build.rs | 21 +- test-utils/runtime/src/lib.rs | 100 ------- utils/wasm-builder-runner/Cargo.toml | 2 +- utils/wasm-builder-runner/src/lib.rs | 279 +++++++++++++++--- 15 files changed, 604 insertions(+), 429 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4124e32263..ecf929384a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3234,7 +3234,7 @@ dependencies = [ "sp-std 2.0.0", "sp-transaction-pool 2.0.0", "sp-version 2.0.0", - "substrate-wasm-builder-runner 1.0.4", + "substrate-wasm-builder-runner 1.0.5", ] [[package]] @@ -3295,7 +3295,7 @@ dependencies = [ "sp-std 2.0.0", "sp-transaction-pool 2.0.0", "sp-version 2.0.0", - "substrate-wasm-builder-runner 1.0.4", + "substrate-wasm-builder-runner 1.0.5", ] [[package]] @@ -5823,7 +5823,7 @@ dependencies = [ "sp-runtime 2.0.0", "sp-sandbox 0.8.0", "sp-std 2.0.0", - "substrate-wasm-builder-runner 1.0.4", + "substrate-wasm-builder-runner 1.0.5", ] [[package]] @@ -6693,7 +6693,7 @@ dependencies = [ "sp-io 2.0.0", "sp-runtime-interface 2.0.0", "sp-std 2.0.0", - "substrate-wasm-builder-runner 1.0.4", + "substrate-wasm-builder-runner 1.0.5", ] [[package]] @@ -7063,7 +7063,7 @@ dependencies = [ "sp-trie 2.0.0", "sp-version 2.0.0", "substrate-test-runtime-client 2.0.0", - "substrate-wasm-builder-runner 1.0.4", + "substrate-wasm-builder-runner 1.0.5", "trie-db 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7104,7 +7104,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder-runner" -version = "1.0.4" +version = "1.0.5" [[package]] name = "subtle" diff --git a/bin/node-template/runtime/build.rs b/bin/node-template/runtime/build.rs index 8bdf7584bb..39f7f56feb 100644 --- a/bin/node-template/runtime/build.rs +++ b/bin/node-template/runtime/build.rs @@ -1,11 +1,10 @@ -use wasm_builder_runner::{build_current_project_with_rustflags, WasmBuilderSource}; +use wasm_builder_runner::WasmBuilder; fn main() { - build_current_project_with_rustflags( - "wasm_binary.rs", - WasmBuilderSource::Crates("1.0.9"), - // This instructs LLD to export __heap_base as a global variable, which is used by the - // external memory allocator. - "-Clink-arg=--export=__heap_base", - ); + WasmBuilder::new() + .with_current_project() + .with_wasm_builder_from_crates("1.0.9") + .export_heap_base() + .import_memory() + .build() } diff --git a/bin/node/runtime/build.rs b/bin/node/runtime/build.rs index 9c81ea6f38..647b476814 100644 --- a/bin/node/runtime/build.rs +++ b/bin/node/runtime/build.rs @@ -14,17 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use wasm_builder_runner::{build_current_project_with_rustflags, WasmBuilderSource}; +use wasm_builder_runner::WasmBuilder; fn main() { - build_current_project_with_rustflags( - "wasm_binary.rs", - WasmBuilderSource::CratesOrPath { - path: "../../../utils/wasm-builder", - version: "1.0.9", - }, - // This instructs LLD to export __heap_base as a global variable, which is used by the - // external memory allocator. - "-Clink-arg=--export=__heap_base", - ); + WasmBuilder::new() + .with_current_project() + .with_wasm_builder_from_crates_or_path("1.0.9", "../../../utils/wasm-builder") + .export_heap_base() + .import_memory() + .build() } diff --git a/client/executor/runtime-test/build.rs b/client/executor/runtime-test/build.rs index 9c81ea6f38..647b476814 100644 --- a/client/executor/runtime-test/build.rs +++ b/client/executor/runtime-test/build.rs @@ -14,17 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use wasm_builder_runner::{build_current_project_with_rustflags, WasmBuilderSource}; +use wasm_builder_runner::WasmBuilder; fn main() { - build_current_project_with_rustflags( - "wasm_binary.rs", - WasmBuilderSource::CratesOrPath { - path: "../../../utils/wasm-builder", - version: "1.0.9", - }, - // This instructs LLD to export __heap_base as a global variable, which is used by the - // external memory allocator. - "-Clink-arg=--export=__heap_base", - ); + WasmBuilder::new() + .with_current_project() + .with_wasm_builder_from_crates_or_path("1.0.9", "../../../utils/wasm-builder") + .export_heap_base() + .import_memory() + .build() } diff --git a/client/executor/runtime-test/src/lib.rs b/client/executor/runtime-test/src/lib.rs index c0807197b4..f6d37abf94 100644 --- a/client/executor/runtime-test/src/lib.rs +++ b/client/executor/runtime-test/src/lib.rs @@ -26,6 +26,11 @@ extern "C" { fn yet_another_missing_external(); } +#[cfg(not(feature = "std"))] +/// Mutable static variables should be always observed to have +/// the initialized value at the start of a runtime call. +static mut MUTABLE_STATIC: u64 = 32; + sp_core::wasm_export_functions! { fn test_calling_missing_external() { unsafe { missing_external() } @@ -217,6 +222,41 @@ sp_core::wasm_export_functions! { fn test_sp_allocator_compiles() { sp_allocator::FreeingBumpHeapAllocator::new(0); } + + fn returns_mutable_static() -> u64 { + unsafe { + MUTABLE_STATIC += 1; + MUTABLE_STATIC + } + } + + fn allocates_huge_stack_array(trap: bool) -> Vec { + // Allocate a stack frame that is approx. 75% of the stack (assuming it is 1MB). + // This will just decrease (stacks in wasm32-u-u grow downwards) the stack + // pointer. This won't trap on the current compilers. + let mut data = [0u8; 1024 * 768]; + + // Then make sure we actually write something to it. + // + // If: + // 1. the stack area is placed at the beginning of the linear memory space, and + // 2. the stack pointer points to out-of-bounds area, and + // 3. a write is performed around the current stack pointer. + // + // then a trap should happen. + // + for (i, v) in data.iter_mut().enumerate() { + *v = i as u8; // deliberate truncation + } + + if trap { + // There is a small chance of this to be pulled up in theory. In practice + // the probability of that is rather low. + panic!() + } + + data.to_vec() + } } #[cfg(not(feature = "std"))] diff --git a/client/executor/src/integration_tests/mod.rs b/client/executor/src/integration_tests/mod.rs index 5b2fc5ca0c..ef8171e5ad 100644 --- a/client/executor/src/integration_tests/mod.rs +++ b/client/executor/src/integration_tests/mod.rs @@ -27,6 +27,7 @@ use sc_runtime_test::WASM_BINARY; use sp_state_machine::TestExternalities as CoreTestExternalities; use test_case::test_case; use sp_trie::{TrieConfiguration, trie_types::Layout}; +use sp_wasm_interface::HostFunctions as _; use crate::WasmExecutionMethod; @@ -38,16 +39,14 @@ fn call_in_wasm( call_data: &[u8], execution_method: WasmExecutionMethod, ext: &mut E, - code: &[u8], - heap_pages: u64, ) -> crate::error::Result> { crate::call_in_wasm::( function, call_data, execution_method, ext, - code, - heap_pages, + &WASM_BINARY[..], + 1024, true, ) } @@ -57,15 +56,12 @@ fn call_in_wasm( fn returning_should_work(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); let mut ext = ext.ext(); - let test_code = WASM_BINARY; let output = call_in_wasm( "test_empty_return", &[], wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(); assert_eq!(output, vec![0u8; 0]); } @@ -73,17 +69,14 @@ fn returning_should_work(wasm_method: WasmExecutionMethod) { #[test_case(WasmExecutionMethod::Interpreted)] #[cfg_attr(feature = "wasmtime", test_case(WasmExecutionMethod::Compiled))] fn call_not_existing_function(wasm_method: WasmExecutionMethod) { - let mut ext = TestExternalities::default(); - let mut ext = ext.ext(); - let test_code = WASM_BINARY; + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); match call_in_wasm( "test_calling_missing_external", &[], wasm_method, &mut ext, - &test_code[..], - 8, ) { Ok(_) => panic!("was expected an `Err`"), Err(e) => { @@ -107,15 +100,12 @@ fn call_not_existing_function(wasm_method: WasmExecutionMethod) { fn call_yet_another_not_existing_function(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); let mut ext = ext.ext(); - let test_code = WASM_BINARY; match call_in_wasm( "test_calling_yet_another_missing_external", &[], wasm_method, &mut ext, - &test_code[..], - 8, ) { Ok(_) => panic!("was expected an `Err`"), Err(e) => { @@ -139,15 +129,12 @@ fn call_yet_another_not_existing_function(wasm_method: WasmExecutionMethod) { fn panicking_should_work(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); let mut ext = ext.ext(); - let test_code = WASM_BINARY; let output = call_in_wasm( "test_panic", &[], wasm_method, &mut ext, - &test_code[..], - 8, ); assert!(output.is_err()); @@ -156,8 +143,6 @@ fn panicking_should_work(wasm_method: WasmExecutionMethod) { &[0], wasm_method, &mut ext, - &test_code[..], - 8, ); assert_eq!(Decode::decode(&mut &output.unwrap()[..]), Ok(Vec::::new())); @@ -166,8 +151,6 @@ fn panicking_should_work(wasm_method: WasmExecutionMethod) { &vec![2].encode(), wasm_method, &mut ext, - &test_code[..], - 8, ); assert!(output.is_err()); } @@ -180,15 +163,12 @@ fn storage_should_work(wasm_method: WasmExecutionMethod) { { let mut ext = ext.ext(); ext.set_storage(b"foo".to_vec(), b"bar".to_vec()); - let test_code = WASM_BINARY; let output = call_in_wasm( "test_data_in", &b"Hello world".to_vec().encode(), wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(); assert_eq!(output, b"all ok!".to_vec().encode()); @@ -216,7 +196,6 @@ fn clear_prefix_should_work(wasm_method: WasmExecutionMethod) { ext.set_storage(b"aba".to_vec(), b"3".to_vec()); ext.set_storage(b"abb".to_vec(), b"4".to_vec()); ext.set_storage(b"bbb".to_vec(), b"5".to_vec()); - let test_code = WASM_BINARY; // This will clear all entries which prefix is "ab". let output = call_in_wasm( @@ -224,8 +203,6 @@ fn clear_prefix_should_work(wasm_method: WasmExecutionMethod) { &b"ab".to_vec().encode(), wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(); assert_eq!(output, b"all ok!".to_vec().encode()); @@ -247,15 +224,12 @@ fn clear_prefix_should_work(wasm_method: WasmExecutionMethod) { fn blake2_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_blake2_256", &[0], wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), blake2_256(&b""[..]).to_vec().encode(), ); @@ -265,8 +239,6 @@ fn blake2_256_should_work(wasm_method: WasmExecutionMethod) { &b"Hello world!".to_vec().encode(), wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), blake2_256(&b"Hello world!"[..]).to_vec().encode(), ); @@ -277,15 +249,12 @@ fn blake2_256_should_work(wasm_method: WasmExecutionMethod) { fn blake2_128_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_blake2_128", &[0], wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), blake2_128(&b""[..]).to_vec().encode(), ); @@ -295,8 +264,6 @@ fn blake2_128_should_work(wasm_method: WasmExecutionMethod) { &b"Hello world!".to_vec().encode(), wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), blake2_128(&b"Hello world!"[..]).to_vec().encode(), ); @@ -307,15 +274,12 @@ fn blake2_128_should_work(wasm_method: WasmExecutionMethod) { 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") @@ -328,8 +292,6 @@ fn sha2_256_should_work(wasm_method: WasmExecutionMethod) { &b"Hello world!".to_vec().encode(), wasm_method, &mut ext, - &test_code[..], - 8, ) .unwrap(), hex!("c0535e4be2b79ffd93291305436bf889314e4a3faec05ecffcbb7df31ad9e51a") @@ -343,15 +305,12 @@ fn sha2_256_should_work(wasm_method: WasmExecutionMethod) { fn twox_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_twox_256", &[0], wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), hex!( "99e9d85137db46ef4bbea33613baafd56f963c64b1f3685a4eb4abd67ff6203a" @@ -363,8 +322,6 @@ fn twox_256_should_work(wasm_method: WasmExecutionMethod) { &b"Hello world!".to_vec().encode(), wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), hex!( "b27dfd7f223f177f2a13647b533599af0c07f68bda23d96d059da2b451a35a74" @@ -377,15 +334,12 @@ fn twox_256_should_work(wasm_method: WasmExecutionMethod) { fn twox_128_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_twox_128", &[0], wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), hex!("99e9d85137db46ef4bbea33613baafd5").to_vec().encode(), ); @@ -395,8 +349,6 @@ fn twox_128_should_work(wasm_method: WasmExecutionMethod) { &b"Hello world!".to_vec().encode(), wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), hex!("b27dfd7f223f177f2a13647b533599af").to_vec().encode(), ); @@ -407,7 +359,6 @@ fn twox_128_should_work(wasm_method: WasmExecutionMethod) { fn ed25519_verify_should_work(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); let mut ext = ext.ext(); - let test_code = WASM_BINARY; let key = ed25519::Pair::from_seed(&blake2_256(b"test")); let sig = key.sign(b"all ok!"); let mut calldata = vec![]; @@ -420,8 +371,6 @@ fn ed25519_verify_should_work(wasm_method: WasmExecutionMethod) { &calldata.encode(), wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), true.encode(), ); @@ -437,8 +386,6 @@ fn ed25519_verify_should_work(wasm_method: WasmExecutionMethod) { &calldata.encode(), wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), false.encode(), ); @@ -449,7 +396,6 @@ fn ed25519_verify_should_work(wasm_method: WasmExecutionMethod) { fn sr25519_verify_should_work(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); let mut ext = ext.ext(); - let test_code = WASM_BINARY; let key = sr25519::Pair::from_seed(&blake2_256(b"test")); let sig = key.sign(b"all ok!"); let mut calldata = vec![]; @@ -462,8 +408,6 @@ fn sr25519_verify_should_work(wasm_method: WasmExecutionMethod) { &calldata.encode(), wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), true.encode(), ); @@ -479,8 +423,6 @@ fn sr25519_verify_should_work(wasm_method: WasmExecutionMethod) { &calldata.encode(), wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), false.encode(), ); @@ -490,17 +432,13 @@ fn sr25519_verify_should_work(wasm_method: WasmExecutionMethod) { #[cfg_attr(feature = "wasmtime", test_case(WasmExecutionMethod::Compiled))] fn ordered_trie_root_should_work(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); - let mut ext = ext.ext(); let trie_input = vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()]; - let test_code = WASM_BINARY; assert_eq!( call_in_wasm( "test_ordered_trie_root", &[0], wasm_method, - &mut ext, - &test_code[..], - 8, + &mut ext.ext(), ).unwrap(), Layout::::ordered_trie_root(trie_input.iter()).as_bytes().encode(), ); @@ -514,16 +452,12 @@ fn offchain_local_storage_should_work(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); let (offchain, state) = testing::TestOffchainExt::new(); ext.register_extension(OffchainExt::new(offchain)); - let test_code = WASM_BINARY; - let mut ext = ext.ext(); assert_eq!( call_in_wasm( "test_offchain_local_storage", &[0], wasm_method, - &mut ext, - &test_code[..], - 8, + &mut ext.ext(), ).unwrap(), true.encode(), ); @@ -550,17 +484,84 @@ fn offchain_http_should_work(wasm_method: WasmExecutionMethod) { }, ); - let test_code = WASM_BINARY; - let mut ext = ext.ext(); assert_eq!( call_in_wasm( "test_offchain_http", &[0], wasm_method, - &mut ext, - &test_code[..], - 8, + &mut ext.ext(), ).unwrap(), true.encode(), ); } + +#[test_case(WasmExecutionMethod::Interpreted)] +#[cfg_attr(feature = "wasmtime", test_case(WasmExecutionMethod::Compiled))] +#[should_panic(expected = "Allocator ran out of space")] +fn should_trap_when_heap_exhausted(wasm_method: WasmExecutionMethod) { + let mut ext = TestExternalities::default(); + + crate::call_in_wasm::( + "test_exhaust_heap", + &[0], + wasm_method, + &mut ext.ext(), + &WASM_BINARY[..], + // `17` is the initial number of pages compiled into the binary. + 17, + true, + ).unwrap(); +} + +#[test_case(WasmExecutionMethod::Interpreted)] +#[cfg_attr(feature = "wasmtime", test_case(WasmExecutionMethod::Compiled))] +fn returns_mutable_static(wasm_method: WasmExecutionMethod) { + let mut instance = crate::wasm_runtime::create_wasm_runtime_with_code( + wasm_method, + 1024, + &WASM_BINARY[..], + HostFunctions::host_functions(), + true, + ).expect("Creates instance"); + + let res = instance.call("returns_mutable_static", &[0]).unwrap(); + assert_eq!(33, u64::decode(&mut &res[..]).unwrap()); + + // We expect that every invocation will need to return the initial + // value plus one. If the value increases more than that then it is + // a sign that the wasm runtime preserves the memory content. + let res = instance.call("returns_mutable_static", &[0]).unwrap(); + assert_eq!(33, u64::decode(&mut &res[..]).unwrap()); +} + +// If we didn't restore the wasm instance properly, on a trap the stack pointer would not be +// returned to its initial value and thus the stack space is going to be leaked. +// +// See https://github.com/paritytech/substrate/issues/2967 for details +#[test_case(WasmExecutionMethod::Interpreted)] +#[cfg_attr(feature = "wasmtime", test_case(WasmExecutionMethod::Compiled))] +fn restoration_of_globals(wasm_method: WasmExecutionMethod) { + // Allocate 32 pages (of 65536 bytes) which gives the runtime 2048KB of heap to operate on + // (plus some additional space unused from the initial pages requested by the wasm runtime + // module). + // + // The fixture performs 2 allocations of 768KB and this theoretically gives 1536KB, however, due + // to our allocator algorithm there are inefficiencies. + const REQUIRED_MEMORY_PAGES: u64 = 32; + + let mut instance = crate::wasm_runtime::create_wasm_runtime_with_code( + wasm_method, + REQUIRED_MEMORY_PAGES, + &WASM_BINARY[..], + HostFunctions::host_functions(), + true, + ).expect("Creates instance"); + + // On the first invocation we allocate approx. 768KB (75%) of stack and then trap. + let res = instance.call("allocates_huge_stack_array", &true.encode()); + assert!(res.is_err()); + + // On the second invocation we allocate yet another 768KB (75%) of stack + let res = instance.call("allocates_huge_stack_array", &false.encode()); + assert!(res.is_ok()); +} diff --git a/client/executor/src/integration_tests/sandbox.rs b/client/executor/src/integration_tests/sandbox.rs index 9a9b33608d..9458542e3a 100644 --- a/client/executor/src/integration_tests/sandbox.rs +++ b/client/executor/src/integration_tests/sandbox.rs @@ -18,7 +18,6 @@ use super::{TestExternalities, call_in_wasm}; use crate::WasmExecutionMethod; use codec::Encode; -use sc_runtime_test::WASM_BINARY; use test_case::test_case; use wabt; @@ -27,7 +26,6 @@ use wabt; fn sandbox_should_work(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); let mut ext = ext.ext(); - let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" (module @@ -56,8 +54,6 @@ fn sandbox_should_work(wasm_method: WasmExecutionMethod) { &code, wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), true.encode(), ); @@ -68,7 +64,6 @@ fn sandbox_should_work(wasm_method: WasmExecutionMethod) { fn sandbox_trap(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); let mut ext = ext.ext(); - let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" (module @@ -86,47 +81,16 @@ fn sandbox_trap(wasm_method: WasmExecutionMethod) { &code, wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), vec![0], ); } -#[test_case(WasmExecutionMethod::Interpreted)] -#[cfg_attr(feature = "wasmtime", test_case(WasmExecutionMethod::Compiled))] -#[should_panic(expected = "Allocator ran out of space")] -fn sandbox_should_trap_when_heap_exhausted(wasm_method: WasmExecutionMethod) { - let mut ext = TestExternalities::default(); - let mut ext = ext.ext(); - let test_code = WASM_BINARY; - - let code = wabt::wat2wasm(r#" - (module - (import "env" "assert" (func $assert (param i32))) - (func (export "call") - i32.const 0 - call $assert - ) - ) - "#).unwrap().encode(); - - call_in_wasm( - "test_exhaust_heap", - &code, - wasm_method, - &mut ext, - &test_code[..], - 8, - ).unwrap(); -} - #[test_case(WasmExecutionMethod::Interpreted)] #[cfg_attr(feature = "wasmtime", test_case(WasmExecutionMethod::Compiled))] fn start_called(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); let mut ext = ext.ext(); - let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" (module @@ -161,8 +125,6 @@ fn start_called(wasm_method: WasmExecutionMethod) { &code, wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), true.encode(), ); @@ -173,7 +135,6 @@ fn start_called(wasm_method: WasmExecutionMethod) { fn invoke_args(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); let mut ext = ext.ext(); - let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" (module @@ -204,8 +165,6 @@ fn invoke_args(wasm_method: WasmExecutionMethod) { &code, wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), true.encode(), ); @@ -216,7 +175,6 @@ fn invoke_args(wasm_method: WasmExecutionMethod) { fn return_val(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); let mut ext = ext.ext(); - let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" (module @@ -235,8 +193,6 @@ fn return_val(wasm_method: WasmExecutionMethod) { &code, wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), true.encode(), ); @@ -247,7 +203,6 @@ fn return_val(wasm_method: WasmExecutionMethod) { fn unlinkable_module(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); let mut ext = ext.ext(); - let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" (module @@ -264,8 +219,6 @@ fn unlinkable_module(wasm_method: WasmExecutionMethod) { &code, wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), 1u8.encode(), ); @@ -276,7 +229,6 @@ fn unlinkable_module(wasm_method: WasmExecutionMethod) { fn corrupted_module(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); let mut ext = ext.ext(); - let test_code = WASM_BINARY; // Corrupted wasm file let code = vec![0u8, 0, 0, 0, 1, 0, 0, 0].encode(); @@ -287,8 +239,6 @@ fn corrupted_module(wasm_method: WasmExecutionMethod) { &code, wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), 1u8.encode(), ); @@ -299,7 +249,6 @@ fn corrupted_module(wasm_method: WasmExecutionMethod) { fn start_fn_ok(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); let mut ext = ext.ext(); - let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" (module @@ -319,8 +268,6 @@ fn start_fn_ok(wasm_method: WasmExecutionMethod) { &code, wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), 0u8.encode(), ); @@ -331,7 +278,6 @@ fn start_fn_ok(wasm_method: WasmExecutionMethod) { fn start_fn_traps(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); let mut ext = ext.ext(); - let test_code = WASM_BINARY; let code = wabt::wat2wasm(r#" (module @@ -352,8 +298,6 @@ fn start_fn_traps(wasm_method: WasmExecutionMethod) { &code, wasm_method, &mut ext, - &test_code[..], - 8, ).unwrap(), 2u8.encode(), ); diff --git a/client/executor/wasmi/src/lib.rs b/client/executor/wasmi/src/lib.rs index cf8125e774..c4701fd827 100644 --- a/client/executor/wasmi/src/lib.rs +++ b/client/executor/wasmi/src/lib.rs @@ -24,7 +24,7 @@ use wasmi::{ }; use codec::{Encode, Decode}; use sp_core::sandbox as sandbox_primitives; -use log::{error, trace}; +use log::{error, trace, debug}; use parity_wasm::elements::{deserialize_buffer, DataSegment, Instruction, Module as RawModule}; use sp_wasm_interface::{ FunctionContext, Pointer, WordSize, Sandbox, MemoryId, Result as WResult, Function, @@ -271,18 +271,36 @@ impl<'a> Sandbox for FunctionExecutor<'a> { } } +/// Will be used on initialization of a module to resolve function and memory imports. struct Resolver<'a> { - host_functions: &'a[&'static dyn Function], + /// All the hot functions that we export for the WASM blob. + host_functions: &'a [&'static dyn Function], + /// Should we allow missing function imports? + /// + /// If `true`, we return a stub that will return an error when being called. allow_missing_func_imports: bool, + /// All the names of functions for that we did not provide a host function. missing_functions: RefCell>, + /// Will be used as initial and maximum size of the imported memory. + heap_pages: usize, + /// By default, runtimes should import memory and this is `Some(_)` after + /// reolving. However, to be backwards compatible, we also support memory + /// exported by the WASM blob (this will be `None` after resolving). + import_memory: RefCell>, } impl<'a> Resolver<'a> { - fn new(host_functions: &'a[&'static dyn Function], allow_missing_func_imports: bool) -> Resolver<'a> { + fn new( + host_functions: &'a[&'static dyn Function], + allow_missing_func_imports: bool, + heap_pages: usize, + ) -> Resolver<'a> { Resolver { host_functions, allow_missing_func_imports, missing_functions: RefCell::new(Vec::new()), + heap_pages, + import_memory: Default::default(), } } } @@ -323,6 +341,48 @@ impl<'a> wasmi::ModuleImportResolver for Resolver<'a> { )) } } + + fn resolve_memory( + &self, + field_name: &str, + memory_type: &wasmi::MemoryDescriptor, + ) -> Result { + if field_name == "memory" { + match &mut *self.import_memory.borrow_mut() { + Some(_) => Err(wasmi::Error::Instantiation( + "Memory can not be imported twice!".into(), + )), + memory_ref @ None => { + if memory_type + .maximum() + .map(|m| m.saturating_sub(memory_type.initial())) + .map(|m| self.heap_pages > m as usize) + .unwrap_or(false) + { + Err(wasmi::Error::Instantiation(format!( + "Heap pages ({}) is greater than imported memory maximum ({}).", + self.heap_pages, + memory_type + .maximum() + .map(|m| m.saturating_sub(memory_type.initial())) + .expect("Maximum is set, checked above; qed"), + ))) + } else { + let memory = MemoryInstance::alloc( + Pages(memory_type.initial() as usize + self.heap_pages), + Some(Pages(memory_type.initial() as usize + self.heap_pages)), + )?; + *memory_ref = Some(memory.clone()); + Ok(memory) + } + } + } + } else { + Err(wasmi::Error::Instantiation( + format!("Unknown memory reference with name: {}", field_name), + )) + } + } } impl<'a> wasmi::Externals for FunctionExecutor<'a> { @@ -378,15 +438,14 @@ fn get_heap_base(module: &ModuleRef) -> Result { /// Call a given method in the given wasm-module runtime. fn call_in_wasm_module( module_instance: &ModuleRef, + memory: &MemoryRef, method: &str, data: &[u8], host_functions: &[&'static dyn Function], allow_missing_func_imports: bool, missing_functions: &Vec, ) -> Result, Error> { - // extract a reference to a linear memory, optional reference to a table - // and then initialize FunctionExecutor. - let memory = get_mem_instance(module_instance)?; + // Initialize FunctionExecutor. let table: Option = module_instance .export_by_name("__indirect_function_table") .and_then(|e| e.as_table().cloned()); @@ -434,8 +493,8 @@ fn instantiate_module( module: &Module, host_functions: &[&'static dyn Function], allow_missing_func_imports: bool, -) -> Result<(ModuleRef, Vec), Error> { - let resolver = Resolver::new(host_functions, allow_missing_func_imports); +) -> Result<(ModuleRef, Vec, MemoryRef), Error> { + let resolver = Resolver::new(host_functions, allow_missing_func_imports, heap_pages); // start module instantiation. Don't run 'start' function yet. let intermediate_instance = ModuleInstance::new( module, @@ -445,15 +504,33 @@ fn instantiate_module( // Verify that the module has the heap base global variable. let _ = get_heap_base(intermediate_instance.not_started_instance())?; - // Extract a reference to a linear memory. - let memory = get_mem_instance(intermediate_instance.not_started_instance())?; - memory.grow(Pages(heap_pages)).map_err(|_| Error::Runtime)?; + + // Get the memory reference. Runtimes should import memory, but to be backwards + // compatible we also support exported memory. + let memory = match resolver.import_memory.into_inner() { + Some(memory) => memory, + None => { + debug!( + target: "wasm-executor", + "WASM blob does not imports memory, falling back to exported memory", + ); + + let memory = get_mem_instance(intermediate_instance.not_started_instance())?; + memory.grow(Pages(heap_pages)).map_err(|_| Error::Runtime)?; + + memory + } + }; if intermediate_instance.has_start() { // Runtime is not allowed to have the `start` function. Err(Error::RuntimeHasStartFn) } else { - Ok((intermediate_instance.assert_no_start(), resolver.missing_functions.into_inner())) + Ok(( + intermediate_instance.assert_no_start(), + resolver.missing_functions.into_inner(), + memory, + )) } } @@ -528,14 +605,7 @@ impl StateSnapshot { /// the preserved memory and globals. /// /// Returns `Err` if applying the snapshot is failed. - fn apply(&self, instance: &ModuleRef) -> Result<(), WasmError> { - let memory = instance - .export_by_name("memory") - .ok_or(WasmError::ApplySnapshotFailed)? - .as_memory() - .cloned() - .ok_or(WasmError::ApplySnapshotFailed)?; - + fn apply(&self, instance: &ModuleRef, memory: &MemoryRef) -> Result<(), WasmError> { // First, erase the memory and copy the data segments into it. memory .erase() @@ -569,6 +639,8 @@ impl StateSnapshot { pub struct WasmiRuntime { /// A wasm module instance. instance: ModuleRef, + /// The memory instance of used by the wasm module. + memory: MemoryRef, /// The snapshot of the instance's state taken just after the instantiation. state_snapshot: StateSnapshot, /// The host functions registered for this instance. @@ -594,7 +666,7 @@ impl WasmRuntime for WasmiRuntime { method: &str, data: &[u8], ) -> Result, Error> { - self.state_snapshot.apply(&self.instance) + self.state_snapshot.apply(&self.instance, &self.memory) .map_err(|e| { // Snapshot restoration failed. This is pretty unexpected since this can happen // if some invariant is broken or if the system is under extreme memory pressure @@ -604,6 +676,7 @@ impl WasmRuntime for WasmiRuntime { })?; call_in_wasm_module( &self.instance, + &self.memory, method, data, &self.host_functions, @@ -628,7 +701,7 @@ pub fn create_instance( let data_segments = extract_data_segments(&code)?; // Instantiate this module. - let (instance, missing_functions) = instantiate_module( + let (instance, missing_functions, memory) = instantiate_module( heap_pages as usize, &module, &host_functions, @@ -646,6 +719,7 @@ pub fn create_instance( Ok(WasmiRuntime { instance, + memory, state_snapshot, host_functions, allow_missing_func_imports, diff --git a/client/executor/wasmtime/src/runtime.rs b/client/executor/wasmtime/src/runtime.rs index 77a11ddc7d..abf860667f 100644 --- a/client/executor/wasmtime/src/runtime.rs +++ b/client/executor/wasmtime/src/runtime.rs @@ -32,42 +32,38 @@ use sc_executor_common::{ use sp_wasm_interface::{Pointer, WordSize, Function}; use sp_runtime_interface::unpack_ptr_and_len; -use std::cell::RefCell; -use std::collections::HashMap; -use std::convert::TryFrom; -use std::rc::Rc; +use std::{cell::RefCell, collections::HashMap, convert::TryFrom, rc::Rc}; use cranelift_codegen::ir; use cranelift_codegen::isa::TargetIsa; use cranelift_entity::{EntityRef, PrimaryMap}; use cranelift_frontend::FunctionBuilderContext; -use cranelift_wasm::DefinedFuncIndex; +use cranelift_wasm::{DefinedFuncIndex, MemoryIndex}; use wasmtime_environ::{Module, translate_signature}; use wasmtime_jit::{ ActionOutcome, CodeMemory, CompilationStrategy, CompiledModule, Compiler, Context, RuntimeValue, }; use wasmtime_runtime::{Export, Imports, InstanceHandle, VMFunctionBody}; +/// TODO: We should remove this in https://github.com/paritytech/substrate/pull/4686 +/// Currently there is no way to extract this with wasmtime. +const INITIAL_HEAP_PAGES: u32 = 17; + /// A `WasmRuntime` implementation using the Wasmtime JIT to compile the runtime module to native /// and execute the compiled code. pub struct WasmtimeRuntime { module: CompiledModule, context: Context, - max_heap_pages: Option, heap_pages: u32, /// The host functions registered for this instance. host_functions: Vec<&'static dyn Function>, + /// The index of the memory in the module. + memory_index: MemoryIndex, } impl WasmRuntime for WasmtimeRuntime { fn update_heap_pages(&mut self, heap_pages: u64) -> bool { - match heap_pages_valid(heap_pages, self.max_heap_pages) { - Some(heap_pages) => { - self.heap_pages = heap_pages; - true - } - None => false, - } + self.heap_pages as u64 == heap_pages } fn host_functions(&self) -> &[&'static dyn Function] { @@ -80,6 +76,7 @@ impl WasmRuntime for WasmtimeRuntime { &mut self.module, method, data, + self.memory_index, self.heap_pages, ) } @@ -93,31 +90,42 @@ pub fn create_instance( host_functions: Vec<&'static dyn Function>, allow_missing_func_imports: bool, ) -> std::result::Result { - let (compiled_module, context) = create_compiled_unit(code, &host_functions, allow_missing_func_imports)?; - - // Inspect the module for the min and max memory sizes. - let (min_memory_size, max_memory_size) = { - let module = compiled_module.module_ref(); - let memory_index = match module.exports.get("memory") { - Some(wasmtime_environ::Export::Memory(memory_index)) => *memory_index, - _ => return Err(WasmError::InvalidMemory), + let heap_pages = u32::try_from(heap_pages) + .map_err(|e| + WasmError::Other(format!("Heap pages can not be converted into `u32`: {:?}", e)) + )?; + + let (compiled_module, context, memory_index) = create_compiled_unit( + code, + &host_functions, + heap_pages, + allow_missing_func_imports, + )?; + + let module = compiled_module.module_ref(); + if !module.is_imported_memory(memory_index) { + // Inspect the module for the min and max memory sizes. + let (min_memory_size, max_memory_size) = { + let memory_plan = module.memory_plans + .get(memory_index) + .ok_or_else(|| WasmError::InvalidMemory)?; + (memory_plan.memory.minimum, memory_plan.memory.maximum) }; - let memory_plan = module.memory_plans.get(memory_index) - .expect("memory_index is retrieved from the module's exports map; qed"); - (memory_plan.memory.minimum, memory_plan.memory.maximum) - }; - // Check that heap_pages is within the allowed range. - let max_heap_pages = max_memory_size.map(|max| max.saturating_sub(min_memory_size)); - let heap_pages = heap_pages_valid(heap_pages, max_heap_pages) - .ok_or_else(|| WasmError::InvalidHeapPages)?; + // Check that heap_pages is within the allowed range. + let max_heap_pages = max_memory_size.map(|max| max.saturating_sub(min_memory_size)); + + if max_heap_pages.map(|m| heap_pages > m).unwrap_or(false) { + return Err(WasmError::InvalidHeapPages) + } + } Ok(WasmtimeRuntime { module: compiled_module, context, - max_heap_pages, heap_pages, host_functions, + memory_index, }) } @@ -209,8 +217,9 @@ fn scan_missing_functions( fn create_compiled_unit( code: &[u8], host_functions: &[&'static dyn Function], + heap_pages: u32, allow_missing_func_imports: bool, -) -> std::result::Result<(CompiledModule, Context), WasmError> { +) -> std::result::Result<(CompiledModule, Context, MemoryIndex), WasmError> { let compilation_strategy = CompilationStrategy::Cranelift; let compiler = new_compiler(compilation_strategy)?; @@ -231,16 +240,32 @@ fn create_compiled_unit( MissingFunctionStubs::new() }; - let env_missing_functions = missing_functions_stubs.stubs.remove("env").unwrap_or_else(|| Vec::new()); - context.name_instance( - "env".to_owned(), - instantiate_env_module(global_exports, compiler, host_functions, env_missing_functions)?, - ); + let env_missing_functions = missing_functions_stubs.stubs + .remove("env") + .unwrap_or_else(|| Vec::new()); + + let (module, memory_index) = instantiate_env_module( + global_exports, + compiler, + host_functions, + heap_pages, + env_missing_functions, + true, + )?; + + context.name_instance("env".to_owned(), module); for (module, missing_functions_stubs) in missing_functions_stubs.stubs { let compiler = new_compiler(compilation_strategy)?; let global_exports = context.get_global_exports(); - let instance = instantiate_env_module(global_exports, compiler, &[], missing_functions_stubs)?; + let instance = instantiate_env_module( + global_exports, + compiler, + &[], + heap_pages, + missing_functions_stubs, + false, + )?.0; context.name_instance(module, instance); } @@ -248,7 +273,7 @@ fn create_compiled_unit( let module = context.compile_module(&code) .map_err(|e| WasmError::Other(format!("module compile error: {}", e)))?; - Ok((module, context)) + Ok((module, context, memory_index.expect("Memory is added on request; qed"))) } /// Call a function inside a precompiled Wasm module. @@ -257,22 +282,21 @@ fn call_method( module: &mut CompiledModule, method: &str, data: &[u8], + memory_index: MemoryIndex, heap_pages: u32, ) -> Result> { + let is_imported_memory = module.module().is_imported_memory(memory_index); // Old exports get clobbered in `InstanceHandle::new` if we don't explicitly remove them first. // // The global exports mechanism is temporary in Wasmtime and expected to be removed. // https://github.com/CraneStation/wasmtime/issues/332 - clear_globals(&mut *context.get_global_exports().borrow_mut()); + clear_globals(&mut *context.get_global_exports().borrow_mut(), is_imported_memory); - let mut instance = module.instantiate() - .map_err(|e| Error::Other(e.to_string()))?; + let mut instance = module.instantiate().map_err(|e| Error::Other(e.to_string()))?; - // Ideally there would be a way to set the heap pages during instantiation rather than - // growing the memory after the fact. Currently this may require an additional mmap and copy. - // However, the wasmtime API doesn't support modifying the size of memory on instantiation - // at this time. - grow_memory(&mut instance, heap_pages)?; + if !is_imported_memory { + grow_memory(&mut instance, heap_pages)?; + } // Initialize the function executor state. let heap_base = get_heap_base(&instance)?; @@ -280,7 +304,7 @@ fn call_method( reset_env_state_and_take_trap(context, Some(executor_state))?; // Write the input data into guest memory. - let (data_ptr, data_len) = inject_input_data(context, &mut instance, data)?; + let (data_ptr, data_len) = inject_input_data(context, &mut instance, data, memory_index)?; let args = [RuntimeValue::I32(u32::from(data_ptr) as i32), RuntimeValue::I32(data_len as i32)]; // Invoke the function in the runtime. @@ -300,7 +324,7 @@ fn call_method( // Read the output data from guest memory. let mut output = vec![0; output_len as usize]; - let memory = get_memory_mut(&mut instance)?; + let memory = get_memory_mut(&mut instance, memory_index)?; read_memory_into(memory, Pointer::new(output_ptr), &mut output)?; Ok(output) } @@ -310,9 +334,10 @@ fn instantiate_env_module( global_exports: Rc>>>, compiler: Compiler, host_functions: &[&'static dyn Function], + heap_pages: u32, missing_functions_stubs: Vec, -) -> std::result::Result -{ + add_memory: bool, +) -> std::result::Result<(InstanceHandle, Option), WasmError> { let isa = target_isa()?; let pointer_type = isa.pointer_type(); let call_conv = isa.default_call_conv(); @@ -325,7 +350,7 @@ fn instantiate_env_module( for function in host_functions { let sig = translate_signature( cranelift_ir_signature(function.signature(), &call_conv), - pointer_type + pointer_type, ); let sig_id = module.signatures.push(sig.clone()); let func_id = module.functions.push(sig_id); @@ -365,6 +390,22 @@ fn instantiate_env_module( code_memory.publish(); + let memory_id = if add_memory { + let memory = cranelift_wasm::Memory { + minimum: heap_pages + INITIAL_HEAP_PAGES, + maximum: Some(heap_pages + INITIAL_HEAP_PAGES), + shared: false, + }; + let memory_plan = wasmtime_environ::MemoryPlan::for_memory(memory, &Default::default()); + + let memory_id = module.memory_plans.push(memory_plan); + module.exports.insert("memory".into(), wasmtime_environ::Export::Memory(memory_id)); + + Some(memory_id) + } else { + None + }; + let imports = Imports::none(); let data_initializers = Vec::new(); let signatures = PrimaryMap::new(); @@ -380,7 +421,10 @@ fn instantiate_env_module( None, Box::new(env_state), ); - result.map_err(|e| WasmError::Other(format!("cannot instantiate env: {}", e))) + + result + .map_err(|e| WasmError::Other(format!("cannot instantiate env: {}", e))) + .map(|r| (r, memory_id)) } /// Build a new TargetIsa for the host machine. @@ -396,8 +440,11 @@ fn new_compiler(strategy: CompilationStrategy) -> std::result::Result>) { - global_exports.remove("memory"); +fn clear_globals(global_exports: &mut HashMap>, is_imported_memory: bool) { + // When memory is imported, we can not delete the global export. + if !is_imported_memory { + global_exports.remove("memory"); + } global_exports.remove("__heap_base"); global_exports.remove("__indirect_function_table"); } @@ -441,13 +488,14 @@ fn inject_input_data( context: &mut Context, instance: &mut InstanceHandle, data: &[u8], + memory_index: MemoryIndex, ) -> Result<(Pointer, WordSize)> { let env_state = get_env_state(context)?; let executor_state = env_state.executor_state .as_mut() .ok_or_else(|| "cannot get \"env\" module executor state")?; - let memory = get_memory_mut(instance)?; + let memory = get_memory_mut(instance, memory_index)?; let data_len = data.len() as WordSize; let data_ptr = executor_state.heap().allocate(memory, data_len)?; @@ -455,12 +503,12 @@ fn inject_input_data( Ok((data_ptr, data_len)) } -fn get_memory_mut(instance: &mut InstanceHandle) -> Result<&mut [u8]> { - match instance.lookup("memory") { +fn get_memory_mut(instance: &mut InstanceHandle, memory_index: MemoryIndex) -> Result<&mut [u8]> { + match instance.lookup_by_declaration(&wasmtime_environ::Export::Memory(memory_index)) { // This is safe to wrap in an unsafe block as: // - The definition pointer is returned by a lookup on a valid instance and thus points to // a valid memory definition - Some(Export::Memory { definition, vmctx: _, memory: _ }) => unsafe { + Export::Memory { definition, vmctx: _, memory: _ } => unsafe { Ok(std::slice::from_raw_parts_mut( (*definition).base, (*definition).current_length, @@ -484,17 +532,3 @@ fn get_heap_base(instance: &InstanceHandle) -> Result { } } } - -/// Checks whether the heap_pages parameter is within the valid range and converts it to a u32. -/// Returns None if heaps_pages in not in range. -fn heap_pages_valid(heap_pages: u64, max_heap_pages: Option) - -> Option -{ - let heap_pages = u32::try_from(heap_pages).ok()?; - if let Some(max_heap_pages) = max_heap_pages { - if heap_pages > max_heap_pages { - return None; - } - } - Some(heap_pages) -} diff --git a/primitives/runtime-interface/test-wasm/build.rs b/primitives/runtime-interface/test-wasm/build.rs index 9c81ea6f38..647b476814 100644 --- a/primitives/runtime-interface/test-wasm/build.rs +++ b/primitives/runtime-interface/test-wasm/build.rs @@ -14,17 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use wasm_builder_runner::{build_current_project_with_rustflags, WasmBuilderSource}; +use wasm_builder_runner::WasmBuilder; fn main() { - build_current_project_with_rustflags( - "wasm_binary.rs", - WasmBuilderSource::CratesOrPath { - path: "../../../utils/wasm-builder", - version: "1.0.9", - }, - // This instructs LLD to export __heap_base as a global variable, which is used by the - // external memory allocator. - "-Clink-arg=--export=__heap_base", - ); + WasmBuilder::new() + .with_current_project() + .with_wasm_builder_from_crates_or_path("1.0.9", "../../../utils/wasm-builder") + .export_heap_base() + .import_memory() + .build() } diff --git a/test-utils/client/src/lib.rs b/test-utils/client/src/lib.rs index 76aa1acd8a..e95c5ad162 100644 --- a/test-utils/client/src/lib.rs +++ b/test-utils/client/src/lib.rs @@ -184,7 +184,6 @@ impl TestClientBuilder + 'static, Backend: sc_client_api::backend::Backend, { - let storage = { let mut storage = self.genesis_init.genesis_storage(); diff --git a/test-utils/runtime/build.rs b/test-utils/runtime/build.rs index 8a9ee642c4..1fd3d52b2f 100644 --- a/test-utils/runtime/build.rs +++ b/test-utils/runtime/build.rs @@ -14,22 +14,17 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use wasm_builder_runner::{build_current_project_with_rustflags, WasmBuilderSource}; +use wasm_builder_runner::WasmBuilder; fn main() { - build_current_project_with_rustflags( - "wasm_binary.rs", - WasmBuilderSource::CratesOrPath { - path: "../../utils/wasm-builder", - version: "1.0.9", - }, + WasmBuilder::new() + .with_current_project() + .with_wasm_builder_from_crates_or_path("1.0.9", "../../utils/wasm-builder") + .export_heap_base() // Note that we set the stack-size to 1MB explicitly even though it is set // to this value by default. This is because some of our tests (`restoration_of_globals`) // depend on the stack-size. - // - // The --export=__heap_base instructs LLD to export __heap_base as a global variable, which - // is used by the external memory allocator. - "-Clink-arg=-zstack-size=1048576 \ - -Clink-arg=--export=__heap_base", - ); + .append_to_rust_flags("-Clink-arg=-zstack-size=1048576") + .import_memory() + .build() } diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index b8e858c3a4..96387b1efc 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -255,8 +255,6 @@ cfg_if! { fn use_trie() -> u64; fn benchmark_indirect_call() -> u64; fn benchmark_direct_call() -> u64; - fn returns_mutable_static() -> u64; - fn allocates_huge_stack_array(trap: bool) -> Vec; fn vec_with_capacity(size: u32) -> Vec; /// Returns the initialized block number. fn get_block_number() -> u64; @@ -299,8 +297,6 @@ cfg_if! { fn use_trie() -> u64; fn benchmark_indirect_call() -> u64; fn benchmark_direct_call() -> u64; - fn returns_mutable_static() -> u64; - fn allocates_huge_stack_array(trap: bool) -> Vec; fn vec_with_capacity(size: u32) -> Vec; /// Returns the initialized block number. fn get_block_number() -> u64; @@ -448,11 +444,6 @@ impl_opaque_keys! { } } -#[cfg(not(feature = "std"))] -/// Mutable static variables should be always observed to have -/// the initialized value at the start of a runtime call. -static mut MUTABLE_STATIC: u64 = 32; - cfg_if! { if #[cfg(feature = "std")] { impl_runtime_apis! { @@ -558,14 +549,6 @@ cfg_if! { (0..1000).fold(0, |p, i| p + benchmark_add_one(i)) } - fn returns_mutable_static() -> u64 { - unimplemented!("is not expected to be invoked from non-wasm builds"); - } - - fn allocates_huge_stack_array(_trap: bool) -> Vec { - unimplemented!("is not expected to be invoked from non-wasm builds"); - } - fn vec_with_capacity(_size: u32) -> Vec { unimplemented!("is not expected to be invoked from non-wasm builds"); } @@ -753,41 +736,6 @@ cfg_if! { (0..10000).fold(0, |p, i| p + benchmark_add_one(i)) } - fn returns_mutable_static() -> u64 { - unsafe { - MUTABLE_STATIC += 1; - MUTABLE_STATIC - } - } - - fn allocates_huge_stack_array(trap: bool) -> Vec { - // Allocate a stack frame that is approx. 75% of the stack (assuming it is 1MB). - // This will just decrease (stacks in wasm32-u-u grow downwards) the stack - // pointer. This won't trap on the current compilers. - let mut data = [0u8; 1024 * 768]; - - // Then make sure we actually write something to it. - // - // If: - // 1. the stack area is placed at the beginning of the linear memory space, and - // 2. the stack pointer points to out-of-bounds area, and - // 3. a write is performed around the current stack pointer. - // - // then a trap should happen. - // - for (i, v) in data.iter_mut().enumerate() { - *v = i as u8; // deliberate truncation - } - - if trap { - // There is a small chance of this to be pulled up in theory. In practice - // the probability of that is rather low. - panic!() - } - - data.to_vec() - } - fn vec_with_capacity(size: u32) -> Vec { Vec::with_capacity(size as usize) } @@ -970,54 +918,6 @@ mod tests { use sp_state_machine::ExecutionStrategy; use codec::Encode; - #[test] - fn returns_mutable_static() { - let client = TestClientBuilder::new() - .set_execution_strategy(ExecutionStrategy::AlwaysWasm) - .build(); - let runtime_api = client.runtime_api(); - let block_id = BlockId::Number(client.chain_info().best_number); - - let ret = runtime_api.returns_mutable_static(&block_id).unwrap(); - assert_eq!(ret, 33); - - // We expect that every invocation will need to return the initial - // value plus one. If the value increases more than that then it is - // a sign that the wasm runtime preserves the memory content. - let ret = runtime_api.returns_mutable_static(&block_id).unwrap(); - assert_eq!(ret, 33); - } - - // If we didn't restore the wasm instance properly, on a trap the stack pointer would not be - // returned to its initial value and thus the stack space is going to be leaked. - // - // See https://github.com/paritytech/substrate/issues/2967 for details - #[test] - fn restoration_of_globals() { - // Allocate 32 pages (of 65536 bytes) which gives the runtime 2048KB of heap to operate on - // (plus some additional space unused from the initial pages requested by the wasm runtime - // module). - // - // The fixture performs 2 allocations of 768KB and this theoretically gives 1536KB, however, due - // to our allocator algorithm there are inefficiencies. - const REQUIRED_MEMORY_PAGES: u64 = 32; - - let client = TestClientBuilder::new() - .set_execution_strategy(ExecutionStrategy::AlwaysWasm) - .set_heap_pages(REQUIRED_MEMORY_PAGES) - .build(); - let runtime_api = client.runtime_api(); - let block_id = BlockId::Number(client.chain_info().best_number); - - // On the first invocation we allocate approx. 768KB (75%) of stack and then trap. - let ret = runtime_api.allocates_huge_stack_array(&block_id, true); - assert!(ret.is_err()); - - // On the second invocation we allocate yet another 768KB (75%) of stack - let ret = runtime_api.allocates_huge_stack_array(&block_id, false); - assert!(ret.is_ok()); - } - #[test] fn heap_pages_is_respected() { // This tests that the on-chain HEAP_PAGES parameter is respected. diff --git a/utils/wasm-builder-runner/Cargo.toml b/utils/wasm-builder-runner/Cargo.toml index ab8a539054..1380d64fb3 100644 --- a/utils/wasm-builder-runner/Cargo.toml +++ b/utils/wasm-builder-runner/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "substrate-wasm-builder-runner" -version = "1.0.4" +version = "1.0.5" authors = ["Parity Technologies "] description = "Runner for substrate-wasm-builder" edition = "2018" diff --git a/utils/wasm-builder-runner/src/lib.rs b/utils/wasm-builder-runner/src/lib.rs index 40016a0159..6366c1ce37 100644 --- a/utils/wasm-builder-runner/src/lib.rs +++ b/utils/wasm-builder-runner/src/lib.rs @@ -25,7 +25,10 @@ //! //! For more information see -use std::{env, process::{Command, self}, fs, path::{PathBuf, Path}}; +use std::{ + env, process::{Command, self}, fs, path::{PathBuf, Path}, hash::{Hash, Hasher}, + collections::hash_map::DefaultHasher, +}; /// Environment variable that tells us to skip building the WASM binary. const SKIP_BUILD_ENV: &str = "SKIP_WASM_BUILD"; @@ -47,6 +50,225 @@ fn replace_back_slashes(path: T) -> String { path.to_string().replace("\\", "/") } +/// Returns the manifest dir from the `CARGO_MANIFEST_DIR` env. +fn get_manifest_dir() -> PathBuf { + env::var("CARGO_MANIFEST_DIR") + .expect("`CARGO_MANIFEST_DIR` is always set for `build.rs` files; qed") + .into() +} + +/// First step of the [`WasmBuilder`] to select the project to build. +pub struct WasmBuilderSelectProject { + /// This parameter just exists to make it impossible to construct + /// this type outside of this crate. + _ignore: (), +} + +impl WasmBuilderSelectProject { + /// Use the current project as project for building the WASM binary. + /// + /// # Panics + /// + /// Panics if the `CARGO_MANIFEST_DIR` variable is not set. This variable + /// is always set by `Cargo` in `build.rs` files. + pub fn with_current_project(self) -> WasmBuilderSelectSource { + WasmBuilderSelectSource(get_manifest_dir().join("Cargo.toml")) + } + + /// Use the given `path` as project for building the WASM binary. + /// + /// Returns an error if the given `path` does not points to a `Cargo.toml`. + pub fn with_project( + self, + path: impl Into, + ) -> Result { + let path = path.into(); + + if path.ends_with("Cargo.toml") { + Ok(WasmBuilderSelectSource(path)) + } else { + Err("Project path must point to the `Cargo.toml` of the project") + } + } +} + +/// Second step of the [`WasmBuilder`] to set the source of the `wasm-builder`. +pub struct WasmBuilderSelectSource(PathBuf); + +impl WasmBuilderSelectSource { + /// Use the given `path` as source for `wasm-builder`. + /// + /// The `path` must be relative and point to the directory that contains the `Cargo.toml` for + /// `wasm-builder`. + pub fn with_wasm_builder_from_path(self, path: &'static str) -> WasmBuilder { + WasmBuilder { + source: WasmBuilderSource::Path(path), + rust_flags: Vec::new(), + file_name: None, + project_cargo_toml: self.0, + } + } + + /// Use the given `repo` and `rev` as source for `wasm-builder`. + pub fn with_wasm_builder_from_git(self, repo: &'static str, rev: &'static str) -> WasmBuilder { + WasmBuilder { + source: WasmBuilderSource::Git { repo, rev }, + rust_flags: Vec::new(), + file_name: None, + project_cargo_toml: self.0, + } + } + + /// Use the given `version` to fetch `wasm-builder` source from crates.io. + pub fn with_wasm_builder_from_crates(self, version: &'static str) -> WasmBuilder { + WasmBuilder { + source: WasmBuilderSource::Crates(version), + rust_flags: Vec::new(), + file_name: None, + project_cargo_toml: self.0, + } + } + + /// Use the given `version` to fetch `wasm-builder` source from crates.io or use + /// the given `path` as source. + /// + /// The `path` must be relative and point to the directory that contains the `Cargo.toml` for + /// `wasm-builder`. + pub fn with_wasm_builder_from_crates_or_path( + self, + version: &'static str, + path: &'static str, + ) -> WasmBuilder { + WasmBuilder { + source: WasmBuilderSource::CratesOrPath { version, path }, + rust_flags: Vec::new(), + file_name: None, + project_cargo_toml: self.0, + } + } + + /// Use the given `source` as source for `wasm-builder`. + pub fn with_wasm_builder_source(self, source: WasmBuilderSource) -> WasmBuilder { + WasmBuilder { + source, + rust_flags: Vec::new(), + file_name: None, + project_cargo_toml: self.0, + } + } +} + +/// The builder for building a wasm binary. +/// +/// The builder itself is seperated into multiple structs to make the setup type safe. +/// +/// Building a wasm binary: +/// +/// 1. Call [`WasmBuilder::new`] to create a new builder. +/// 2. Select the project to build using the methods of [`WasmBuilderSelectProject`]. +/// 3. Select the source of the `wasm-builder` crate using the methods of +/// [`WasmBuilderSelectSource`]. +/// 4. Set additional `RUST_FLAGS` or a different name for the file containing the WASM code +/// using methods of [`Self`]. +/// 5. Build the WASM binary using [`Self::build`]. +pub struct WasmBuilder { + /// Where should we pull the `wasm-builder` crate from. + source: WasmBuilderSource, + /// Flags that should be appended to `RUST_FLAGS` env variable. + rust_flags: Vec, + /// The name of the file that is being generated in `OUT_DIR`. + /// + /// Defaults to `wasm_binary.rs`. + file_name: Option, + /// The path to the `Cargo.toml` of the project that should be build + /// for wasm. + project_cargo_toml: PathBuf, +} + +impl WasmBuilder { + /// Create a new instance of the builder. + pub fn new() -> WasmBuilderSelectProject { + WasmBuilderSelectProject { + _ignore: (), + } + } + + /// Enable exporting `__heap_base` as global variable in the WASM binary. + /// + /// This adds `-Clink-arg=--export=__heap_base` to `RUST_FLAGS`. + pub fn export_heap_base(mut self) -> Self { + self.rust_flags.push("-Clink-arg=--export=__heap_base".into()); + self + } + + /// Set the name of the file that will be generated in `OUT_DIR`. + /// + /// This file needs to be included to get access to the build WASM binary. + /// + /// If this function is not called, `file_name` defaults to `wasm_binary.rs` + pub fn set_file_name(mut self, file_name: impl Into) -> Self { + self.file_name = Some(file_name.into()); + self + } + + /// Instruct the linker to import the memory into the WASM binary. + /// + /// This adds `-C link-arg=--import-memory` to `RUST_FLAGS`. + pub fn import_memory(mut self) -> Self { + self.rust_flags.push("-C link-arg=--import-memory".into()); + self + } + + /// Append the given `flag` to `RUST_FLAGS`. + /// + /// `flag` is appended as is, so it needs to be a valid flag. + pub fn append_to_rust_flags(mut self, flag: impl Into) -> Self { + self.rust_flags.push(flag.into()); + self + } + + /// Build the WASM binary. + pub fn build(self) { + if check_skip_build() { + // If we skip the build, we still want to make sure to be called when an env variable + // changes + generate_rerun_if_changed_instructions(); + return; + } + + let out_dir = PathBuf::from(env::var("OUT_DIR").expect("`OUT_DIR` is set by cargo!")); + let file_path = out_dir.join(self.file_name.unwrap_or_else(|| "wasm_binary.rs".into())); + + // Hash the path to the project cargo toml. + let mut hasher = DefaultHasher::new(); + self.project_cargo_toml.hash(&mut hasher); + + let project_name = env::var("CARGO_PKG_NAME").expect("`CARGO_PKG_NAME` is set by cargo!"); + // Make sure the `wasm-builder-runner` path is unique by concatenating the name of the + // project that is compiling the WASM binary with the hash of the path to the project that + // should be compiled as WASM binary. + let project_folder = get_workspace_root() + .join(format!("{}{}", project_name, hasher.finish())); + + if check_provide_dummy_wasm_binary() { + provide_dummy_wasm_binary(&file_path); + } else { + create_project( + &project_folder, + &file_path, + self.source, + &self.project_cargo_toml, + &self.rust_flags.into_iter().map(|f| format!("{} ", f)).collect::(), + ); + run_project(&project_folder); + } + + // As last step we need to generate our `rerun-if-changed` stuff. If a build fails, we don't + // want to spam the output! + generate_rerun_if_changed_instructions(); + } +} + /// The `wasm-builder` dependency source. pub enum WasmBuilderSource { /// The relative path to the source code from the current manifest dir. @@ -96,46 +318,21 @@ impl WasmBuilderSource { /// Build the currently built project as WASM binary and extend `RUSTFLAGS` with the given rustflags. /// /// For more information, see [`build_current_project`]. +#[deprecated( + since = "1.0.5", + note = "Please switch to [`WasmBuilder`]", +)] pub fn build_current_project_with_rustflags( file_name: &str, wasm_builder_source: WasmBuilderSource, - default_rustflags: &str, + default_rust_flags: &str, ) { - if check_skip_build() { - // If we skip the build, we still want to make sure to be called when an env variable changes - generate_rerun_if_changed_instructions(); - return; - } - - let manifest_dir = PathBuf::from( - env::var("CARGO_MANIFEST_DIR").expect( - "`CARGO_MANIFEST_DIR` is always set for `build.rs` files; qed" - ) - ); - - let cargo_toml_path = manifest_dir.join("Cargo.toml"); - let out_dir = PathBuf::from(env::var("OUT_DIR").expect("`OUT_DIR` is set by cargo!")); - let file_path = out_dir.join(file_name); - let project_name = env::var("CARGO_PKG_NAME").expect("`CARGO_PKG_NAME` is set by cargo!"); - let project_folder = get_workspace_root().join(project_name); - - if check_provide_dummy_wasm_binary() { - provide_dummy_wasm_binary(&file_path); - } else { - create_project( - &project_folder, - &file_path, - &manifest_dir, - wasm_builder_source, - &cargo_toml_path, - default_rustflags, - ); - run_project(&project_folder); - } - - // As last step we need to generate our `rerun-if-changed` stuff. If a build fails, we don't - // want to spam the output! - generate_rerun_if_changed_instructions(); + WasmBuilder::new() + .with_current_project() + .with_wasm_builder_source(wasm_builder_source) + .append_to_rust_flags(default_rust_flags) + .set_file_name(file_name) + .build() } /// Build the currently built project as WASM binary. @@ -145,7 +342,12 @@ pub fn build_current_project_with_rustflags( /// `file_name` - The name of the file being generated in the `OUT_DIR`. The file contains the /// constant `WASM_BINARY` which contains the build wasm binary. /// `wasm_builder_path` - Path to the wasm-builder project, relative to `CARGO_MANIFEST_DIR`. +#[deprecated( + since = "1.0.5", + note = "Please switch to [`WasmBuilder`]", +)] pub fn build_current_project(file_name: &str, wasm_builder_source: WasmBuilderSource) { + #[allow(deprecated)] build_current_project_with_rustflags(file_name, wasm_builder_source, ""); } @@ -171,7 +373,6 @@ fn get_workspace_root() -> PathBuf { fn create_project( project_folder: &Path, file_path: &Path, - manifest_dir: &Path, wasm_builder_source: WasmBuilderSource, cargo_toml_path: &Path, default_rustflags: &str, @@ -193,7 +394,7 @@ fn create_project( [workspace] "#, - wasm_builder_source = wasm_builder_source.to_cargo_source(manifest_dir), + wasm_builder_source = wasm_builder_source.to_cargo_source(&get_manifest_dir()), ) ).expect("WASM build runner `Cargo.toml` writing can not fail; qed"); -- GitLab From 8bb1811e31e000ec442a8f6ddc1d51ca51fa4e2f Mon Sep 17 00:00:00 2001 From: Toralf Wittner Date: Tue, 28 Jan 2020 13:00:37 +0100 Subject: [PATCH 028/180] Update yamux to version 0.4.1 (#4746) --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ecf929384a..6720e9c658 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2729,7 +2729,7 @@ dependencies = [ "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "yamux 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "yamux 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -8310,7 +8310,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "yamux" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -8954,7 +8954,7 @@ dependencies = [ "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ee1585dc1484373cbc1cee7aafda26634665cf449436fd6e24bfd1fad230538" "checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" -"checksum yamux 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "809f4388471d280173404e3d4f889e2d36004960a37d822ce5637fbef33a0ce4" +"checksum yamux 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f937668802a2e862a4fed05267e10b20c310bf771adc89687710706d55a9a65" "checksum zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" "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" -- GitLab From 680c355c659c938a4346a79cc81039aae68d2d4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 28 Jan 2020 16:18:09 +0100 Subject: [PATCH 029/180] Make sure destroy_state is called in case of errors. (#4745) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Make sure to destroy state in case of error. * Update client/src/call_executor.rs * Update client/src/call_executor.rs Co-authored-by: Bastian Köcher --- client/src/call_executor.rs | 68 ++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/client/src/call_executor.rs b/client/src/call_executor.rs index 6c685fc1b8..18ad5b113e 100644 --- a/client/src/call_executor.rs +++ b/client/src/call_executor.rs @@ -77,10 +77,14 @@ where extensions: Option, ) -> sp_blockchain::Result> { let mut changes = OverlayedChanges::default(); + let changes_trie = backend::changes_tries_state_at_block( + id, self.backend.changes_trie_storage() + )?; + // make sure to destroy state before exiting this function let state = self.backend.state_at(*id)?; let return_data = StateMachine::new( &state, - backend::changes_tries_state_at_block(id, self.backend.changes_trie_storage())?, + changes_trie, &mut changes, &self.executor, method, @@ -89,12 +93,12 @@ where ).execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>( strategy.get_manager(), None, - )?; + ); { let _lock = self.backend.get_import_lock().read(); self.backend.destroy_state(state)?; } - Ok(return_data.into_encoded()) + Ok(return_data?.into_encoded()) } fn contextual_call< @@ -131,37 +135,36 @@ where _ => {}, } - let mut state = self.backend.state_at(*at)?; let changes_trie_state = backend::changes_tries_state_at_block(at, self.backend.changes_trie_storage())?; - let mut storage_transaction_cache = storage_transaction_cache.map(|c| c.borrow_mut()); + // make sure to destroy state before exiting this function + let mut state = self.backend.state_at(*at)?; let result = match recorder { - Some(recorder) => { - let trie_state = state.as_trie_backend() - .ok_or_else(|| - Box::new(sp_state_machine::ExecutionError::UnableToGenerateProof) - as Box - )?; - - let backend = sp_state_machine::ProvingBackend::new_with_recorder( - trie_state, - recorder.clone(), - ); - - StateMachine::new( - &backend, - changes_trie_state, - &mut *changes.borrow_mut(), - &self.executor, - method, - call_data, - extensions.unwrap_or_default(), + Some(recorder) => state.as_trie_backend() + .ok_or_else(|| + Box::new(sp_state_machine::ExecutionError::UnableToGenerateProof) + as Box ) - // TODO: https://github.com/paritytech/substrate/issues/4455 - // .with_storage_transaction_cache(storage_transaction_cache.as_mut().map(|c| &mut **c)) - .execute_using_consensus_failure_handler(execution_manager, native_call) - } + .and_then(|trie_state| { + let backend = sp_state_machine::ProvingBackend::new_with_recorder( + trie_state, + recorder.clone(), + ); + + StateMachine::new( + &backend, + changes_trie_state, + &mut *changes.borrow_mut(), + &self.executor, + method, + call_data, + extensions.unwrap_or_default(), + ) + // TODO: https://github.com/paritytech/substrate/issues/4455 + // .with_storage_transaction_cache(storage_transaction_cache.as_mut().map(|c| &mut **c)) + .execute_using_consensus_failure_handler(execution_manager, native_call) + }), None => StateMachine::new( &state, changes_trie_state, @@ -173,18 +176,19 @@ where ) .with_storage_transaction_cache(storage_transaction_cache.as_mut().map(|c| &mut **c)) .execute_using_consensus_failure_handler(execution_manager, native_call) - }?; + }; { let _lock = self.backend.get_import_lock().read(); self.backend.destroy_state(state)?; } - Ok(result) + result.map_err(Into::into) } fn runtime_version(&self, id: &BlockId) -> sp_blockchain::Result { let mut overlay = OverlayedChanges::default(); - let state = self.backend.state_at(*id)?; let changes_trie_state = backend::changes_tries_state_at_block(id, self.backend.changes_trie_storage())?; + // make sure to destroy state before exiting this function + let state = self.backend.state_at(*id)?; let mut cache = StorageTransactionCache::::default(); let mut ext = Ext::new( &mut overlay, -- GitLab From dda91c28044b175b999c59e5b01725a9763b6942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 28 Jan 2020 19:33:23 +0100 Subject: [PATCH 030/180] Print extrinsic failed error always, not just on import (#4747) * Print extrinsic failed error always, not just on import Before we printed the error of a transaction only when importing a block, this pr changes it to print the error also at building the block. * Increment `impl_version` --- bin/node/runtime/src/lib.rs | 2 +- frame/executive/src/lib.rs | 3 +-- frame/system/src/lib.rs | 5 ++++- primitives/runtime/src/traits.rs | 6 ++++++ 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 7e1082ef54..57856dd2f1 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -81,7 +81,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 205, - impl_version: 206, + impl_version: 207, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 0507946ef5..96c79c1073 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -262,8 +262,7 @@ where fn apply_extrinsic_no_note(uxt: Block::Extrinsic) { let l = uxt.encode().len(); match Self::apply_extrinsic_with_len(uxt, l, None) { - Ok(Ok(())) => (), - Ok(Err(e)) => sp_runtime::print(e), + Ok(_) => (), Err(e) => { let err: &'static str = e.into(); panic!(err) }, } } diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 752ab9cc91..4e665fd385 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -852,7 +852,10 @@ impl Module { Self::deposit_event( match r { Ok(()) => Event::ExtrinsicSuccess(info), - Err(err) => Event::ExtrinsicFailed(err.clone(), info), + Err(err) => { + sp_runtime::print(err); + Event::ExtrinsicFailed(err.clone(), info) + }, } ); diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 7d889cae9b..3210b00c6b 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -1216,6 +1216,12 @@ pub trait Printable { fn print(&self); } +impl Printable for &T { + fn print(&self) { + (*self).print() + } +} + impl Printable for u8 { fn print(&self) { (*self as u64).print() -- GitLab From bd8eacc5b38349f52f5129736db060bc09c11f84 Mon Sep 17 00:00:00 2001 From: Joshy Orndorff Date: Tue, 28 Jan 2020 13:33:50 -0500 Subject: [PATCH 031/180] Add decl_error to template module (#4743) * Update template to use decl_error * Test for error on template * Comments * Reorder decl_* blocks: storage, event, error, module * Remove TODOs * Clarify comment on type Error = Error --- bin/node-template/runtime/src/template.rs | 88 +++++++++++++++++------ 1 file changed, 66 insertions(+), 22 deletions(-) diff --git a/bin/node-template/runtime/src/template.rs b/bin/node-template/runtime/src/template.rs index a64a4c3216..4ed8066578 100644 --- a/bin/node-template/runtime/src/template.rs +++ b/bin/node-template/runtime/src/template.rs @@ -8,18 +8,18 @@ /// For more guidance on Substrate modules, see the example module /// https://github.com/paritytech/substrate/blob/master/frame/example/src/lib.rs -use frame_support::{decl_module, decl_storage, decl_event, dispatch}; +use frame_support::{decl_module, decl_storage, decl_event, decl_error, dispatch}; use system::ensure_signed; -/// The module's configuration trait. +/// The pallet's configuration trait. pub trait Trait: system::Trait { - // TODO: Add other types and constants required configure this module. + // Add other types and constants required to configure this pallet. /// The overarching event type. type Event: From> + Into<::Event>; } -// This module's storage items. +// This pallet's storage items. decl_storage! { trait Store for Module as TemplateModule { // Just a dummy storage item. @@ -29,48 +29,81 @@ decl_storage! { } } -// The module's dispatchable functions. +// The pallet's events +decl_event!( + pub enum Event where AccountId = ::AccountId { + /// Just a dummy event. + /// Event `Something` is declared with a parameter of the type `u32` and `AccountId` + /// To emit this event, we call the deposit funtion, from our runtime funtions + SomethingStored(u32, AccountId), + } +); + +// The pallet's errors +decl_error! { + pub enum Error for Module { + /// Value was None + NoneValue, + /// Value reached maximum and cannot be incremented further + StorageOverflow, + } +} + +// The pallet's dispatchable functions. decl_module! { /// The module declaration. pub struct Module for enum Call where origin: T::Origin { + // Initializing errors + // this includes information about your errors in the node's metadata. + // it is needed only if you are using errors in your pallet + type Error = Error; + // Initializing events - // this is needed only if you are using events in your module + // this is needed only if you are using events in your pallet fn deposit_event() = default; - // 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 + /// 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) -> dispatch::DispatchResult { - // TODO: You only need this if you want to check it was signed. + // Check it was signed and get the signer. See also: ensure_root and ensure_none let who = ensure_signed(origin)?; - // TODO: Code to execute when something calls this. + // Code to execute when something calls this. // For example: the following line stores the passed in u32 in the storage Something::put(something); - // here we are raising the Something event + // Here we are raising the Something event Self::deposit_event(RawEvent::SomethingStored(something, who)); Ok(()) } + + /// Another dummy entry point. + /// takes no parameters, attempts to increment storage value, and possibly throws an error + pub fn cause_error(origin) -> dispatch::DispatchResult { + // Check it was signed and get the signer. See also: ensure_root and ensure_none + let _who = ensure_signed(origin)?; + + match Something::get() { + None => Err(Error::::NoneValue)?, + Some(old) => { + let new = old.checked_add(1).ok_or(Error::::StorageOverflow)?; + Something::put(new); + Ok(()) + }, + } + } } } -decl_event!( - pub enum Event where AccountId = ::AccountId { - // Just a dummy event. - // Event `Something` is declared with a parameter of the type `u32` and `AccountId` - // To emit this event, we call the deposit funtion, from our runtime funtions - SomethingStored(u32, AccountId), - } -); -/// tests for this module +/// Tests for this pallet #[cfg(test)] mod tests { use super::*; use sp_core::H256; - use frame_support::{impl_outer_origin, assert_ok, parameter_types, weights::Weight}; + use frame_support::{impl_outer_origin, assert_ok, assert_noop, parameter_types, weights::Weight}; use sp_runtime::{ traits::{BlakeTwo256, IdentityLookup}, testing::Header, Perbill, }; @@ -129,4 +162,15 @@ mod tests { assert_eq!(TemplateModule::something(), Some(42)); }); } + + #[test] + fn correct_error_for_none_value() { + new_test_ext().execute_with(|| { + // Ensure the correct error is thrown on None value + assert_noop!( + TemplateModule::cause_error(Origin::signed(1)), + Error::::NoneValue + ); + }); + } } -- GitLab From 97eab5239239c9d631c2db0fc05fde5df99f988d Mon Sep 17 00:00:00 2001 From: philipstanislaus <6912756+philipstanislaus@users.noreply.github.com> Date: Tue, 28 Jan 2020 20:30:39 +0100 Subject: [PATCH 032/180] Add SS58 network identifier for Centrifuge (#4748) * Add SS58 network identifier for Centrifuge * Bump version --- bin/node/runtime/src/lib.rs | 2 +- primitives/core/src/crypto.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 57856dd2f1..24cdbcfbb6 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -80,7 +80,7 @@ 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: 205, + spec_version: 207, impl_version: 207, apis: RUNTIME_API_VERSIONS, }; diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index 3cc6c50f76..86a579e499 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -442,6 +442,8 @@ ss58_address_format!( (16, "kulupu", "Kulupu mainnet, direct checksum, standard account (*25519).") EdgewareAccountDirect => (7, "edgeware", "Edgeware mainnet, direct checksum, standard account (*25519).") + CentrifugeAccountDirect => + (36, "centrifuge", "Centrifuge Chain mainnet, direct checksum, standard account (*25519).") ); /// Set the default "version" (actually, this is a bit of a misnomer and the version byte is -- GitLab From e29336bff9400f3522caf042b76bfdc64782f419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 28 Jan 2020 22:34:41 +0100 Subject: [PATCH 033/180] Display `has_api_with` results if invalid version of Offchain Workers is detected. (#4749) * Display error message when checking has_api. * Cargo.lock. --- Cargo.lock | 6 +++--- client/offchain/src/lib.rs | 8 +++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6720e9c658..ecf929384a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2729,7 +2729,7 @@ dependencies = [ "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "yamux 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "yamux 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -8310,7 +8310,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "yamux" -version = "0.4.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -8954,7 +8954,7 @@ dependencies = [ "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ee1585dc1484373cbc1cee7aafda26634665cf449436fd6e24bfd1fad230538" "checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" -"checksum yamux 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f937668802a2e862a4fed05267e10b20c310bf771adc89687710706d55a9a65" +"checksum yamux 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "809f4388471d280173404e3d4f889e2d36004960a37d822ce5637fbef33a0ce4" "checksum zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" "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" diff --git a/client/offchain/src/lib.rs b/client/offchain/src/lib.rs index 78760fb011..3cd3b2cba5 100644 --- a/client/offchain/src/lib.rs +++ b/client/offchain/src/lib.rs @@ -107,7 +107,11 @@ impl OffchainWorkers< let version = match (has_api_v1, has_api_v2) { (_, Ok(true)) => 2, (Ok(true), _) => 1, - _ => 0, + err => { + let help = "Consider turning off offchain workers if they are not part of your runtime."; + log::error!("Unsupported Offchain Worker API version: {:?}. {}.", err, help); + 0 + } }; debug!("Checking offchain workers at {:?}: version:{}", at, version); if version > 0 { @@ -140,8 +144,6 @@ impl OffchainWorkers< }); futures::future::Either::Left(runner.process()) } else { - let help = "Consider turning off offchain workers if they are not part of your runtime."; - log::error!("Unsupported Offchain Worker API version: {}. {}", version, help); futures::future::Either::Right(futures::future::ready(())) } } -- GitLab From 2241c6b03b567fdd77aea4aa47dac9fad4b5e66b Mon Sep 17 00:00:00 2001 From: Hoani Bryson Date: Wed, 29 Jan 2020 11:30:25 +1300 Subject: [PATCH 034/180] Remove unnecessary duplication in generic asset create (#4744) * Remove unneccessary duplication in generic asset create * Increment impl_version due to refactoring generic_asset --- bin/node/runtime/src/lib.rs | 2 +- frame/generic-asset/src/lib.rs | 16 +--------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 24cdbcfbb6..afd2631373 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -81,7 +81,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 207, - impl_version: 207, + impl_version: 208, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/generic-asset/src/lib.rs b/frame/generic-asset/src/lib.rs index ca6812da8e..8b7668dc12 100644 --- a/frame/generic-asset/src/lib.rs +++ b/frame/generic-asset/src/lib.rs @@ -362,21 +362,7 @@ decl_module! { /// Create a new kind of asset. fn create(origin, options: AssetOptions) -> DispatchResult { let origin = ensure_signed(origin)?; - let id = Self::next_asset_id(); - - let permissions: PermissionVersions = options.permissions.clone().into(); - - // The last available id serves as the overflow mark and won't be used. - let next_id = id.checked_add(&One::one()).ok_or_else(|| Error::::NoIdAvailable)?; - - >::put(next_id); - >::insert(id, &options.initial_issuance); - >::insert(&id, &origin, &options.initial_issuance); - >::insert(&id, permissions); - - Self::deposit_event(RawEvent::Created(id, origin, options)); - - Ok(()) + Self::create_asset(None, Some(origin), options) } /// Transfer some liquid free balance to another account. -- GitLab From acb1b9b3da10c73297b139fcb26cae4928b42879 Mon Sep 17 00:00:00 2001 From: Edwin Date: Wed, 29 Jan 2020 06:31:28 +0800 Subject: [PATCH 035/180] RPC api for offchain storage (#4694) * Rpc api for offchain storage * Replace Vec to Bytes, replace Mutex to RwLock * Remove pub * Modify copyright year --- Cargo.lock | 1 + client/rpc-api/src/lib.rs | 1 + client/rpc-api/src/offchain/error.rs | 51 +++++++++++++++++++++ client/rpc-api/src/offchain/mod.rs | 37 +++++++++++++++ client/rpc/Cargo.toml | 1 + client/rpc/src/lib.rs | 1 + client/rpc/src/offchain/mod.rs | 67 ++++++++++++++++++++++++++++ client/rpc/src/offchain/tests.rs | 36 +++++++++++++++ client/service/src/builder.rs | 31 +++++++++---- primitives/core/src/offchain/mod.rs | 1 + 10 files changed, 218 insertions(+), 9 deletions(-) create mode 100644 client/rpc-api/src/offchain/error.rs create mode 100644 client/rpc-api/src/offchain/mod.rs create mode 100644 client/rpc/src/offchain/mod.rs create mode 100644 client/rpc/src/offchain/tests.rs diff --git a/Cargo.lock b/Cargo.lock index ecf929384a..5d4b97a3c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5768,6 +5768,7 @@ dependencies = [ "sp-blockchain 2.0.0", "sp-core 2.0.0", "sp-io 2.0.0", + "sp-offchain 2.0.0", "sp-rpc 2.0.0", "sp-runtime 2.0.0", "sp-session 2.0.0", diff --git a/client/rpc-api/src/lib.rs b/client/rpc-api/src/lib.rs index c9306f2cdd..8ad2d94bfd 100644 --- a/client/rpc-api/src/lib.rs +++ b/client/rpc-api/src/lib.rs @@ -30,5 +30,6 @@ pub use helpers::Receiver; pub mod author; pub mod chain; +pub mod offchain; pub mod state; pub mod system; diff --git a/client/rpc-api/src/offchain/error.rs b/client/rpc-api/src/offchain/error.rs new file mode 100644 index 0000000000..c28a2a2f39 --- /dev/null +++ b/client/rpc-api/src/offchain/error.rs @@ -0,0 +1,51 @@ +// Copyright 2020 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 . + +//! Offchain RPC errors. + +use jsonrpc_core as rpc; + +/// Offchain RPC Result type. +pub type Result = std::result::Result; + +/// Offchain RPC errors. +#[derive(Debug, derive_more::Display, derive_more::From)] +pub enum Error { + /// Unavailable storage kind error. + #[display(fmt="This storage kind is not available yet.")] + UnavailableStorageKind, +} + +impl std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + None + } +} + +/// Base error code for all offchain errors. +const BASE_ERROR: i64 = 5000; + +impl From for rpc::Error { + fn from(e: Error) -> Self { + match e { + Error::UnavailableStorageKind => rpc::Error { + code: rpc::ErrorCode::ServerError(BASE_ERROR + 1), + message: "This storage kind is not available yet" .into(), + data: None, + }, + } + } +} diff --git a/client/rpc-api/src/offchain/mod.rs b/client/rpc-api/src/offchain/mod.rs new file mode 100644 index 0000000000..bbe466ff59 --- /dev/null +++ b/client/rpc-api/src/offchain/mod.rs @@ -0,0 +1,37 @@ +// Copyright 2020 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 offchain API. + +pub mod error; + +use jsonrpc_derive::rpc; +use self::error::Result; +use sp_core::{Bytes, offchain::StorageKind}; + +pub use self::gen_client::Client as OffchainClient; + +/// Substrate offchain RPC API +#[rpc] +pub trait OffchainApi { + /// Set offchain local storage under given key and prefix. + #[rpc(name = "offchain_localStorageSet")] + fn set_local_storage(&self, kind: StorageKind, key: Bytes, value: Bytes) -> Result<()>; + + /// Get offchain local storage under given key and prefix. + #[rpc(name = "offchain_localStorageGet")] + fn get_local_storage(&self, kind: StorageKind, key: Bytes) -> Result>; +} diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index 6530bff4ed..789ebf565c 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -18,6 +18,7 @@ rpc = { package = "jsonrpc-core", version = "14.0.3" } sp-version = { version = "2.0.0", path = "../../primitives/version" } serde_json = "1.0.41" sp-session = { version = "2.0.0", path = "../../primitives/session" } +sp-offchain = { version = "2.0.0", path = "../../primitives/offchain" } sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } sp-rpc = { version = "2.0.0", path = "../../primitives/rpc" } sp-state-machine = { version = "0.8", path = "../../primitives/state-machine" } diff --git a/client/rpc/src/lib.rs b/client/rpc/src/lib.rs index 3a226a6fb3..ea65785c20 100644 --- a/client/rpc/src/lib.rs +++ b/client/rpc/src/lib.rs @@ -28,5 +28,6 @@ pub use rpc::IoHandlerExtension as RpcExtension; pub mod author; pub mod chain; +pub mod offchain; pub mod state; pub mod system; diff --git a/client/rpc/src/offchain/mod.rs b/client/rpc/src/offchain/mod.rs new file mode 100644 index 0000000000..61984d4845 --- /dev/null +++ b/client/rpc/src/offchain/mod.rs @@ -0,0 +1,67 @@ +// Copyright 2020 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 offchain API. + +#[cfg(test)] +mod tests; + +/// Re-export the API for backward compatibility. +pub use sc_rpc_api::offchain::*; +use self::error::{Error, Result}; +use sp_core::{ + Bytes, + offchain::{OffchainStorage, StorageKind}, +}; +use parking_lot::RwLock; +use std::sync::Arc; + +/// Offchain API +#[derive(Debug)] +pub struct Offchain { + /// Offchain storage + storage: Arc>, +} + +impl Offchain { + /// Create new instance of Offchain API. + pub fn new(storage: T) -> Self { + Offchain { + storage: Arc::new(RwLock::new(storage)), + } + } +} + +impl OffchainApi for Offchain { + /// Set offchain local storage under given key and prefix. + fn set_local_storage(&self, kind: StorageKind, key: Bytes, value: Bytes) -> Result<()> { + let prefix = match kind { + StorageKind::PERSISTENT => sp_offchain::STORAGE_PREFIX, + StorageKind::LOCAL => return Err(Error::UnavailableStorageKind), + }; + self.storage.write().set(prefix, &*key, &*value); + Ok(()) + } + + /// Get offchain local storage under given key and prefix. + fn get_local_storage(&self, kind: StorageKind, key: Bytes) -> Result> { + let prefix = match kind { + StorageKind::PERSISTENT => sp_offchain::STORAGE_PREFIX, + StorageKind::LOCAL => return Err(Error::UnavailableStorageKind), + }; + Ok(self.storage.read().get(prefix, &*key).map(Into::into)) + } +} diff --git a/client/rpc/src/offchain/tests.rs b/client/rpc/src/offchain/tests.rs new file mode 100644 index 0000000000..ac1a6a4de3 --- /dev/null +++ b/client/rpc/src/offchain/tests.rs @@ -0,0 +1,36 @@ +// Copyright 2020 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 super::*; +use assert_matches::assert_matches; +use sp_core::{Bytes, offchain::storage::InMemOffchainStorage}; + +#[test] +fn local_storage_should_work() { + let storage = InMemOffchainStorage::default(); + let offchain = Offchain::new(storage); + let key = Bytes(b"offchain_storage".to_vec()); + let value = Bytes(b"offchain_value".to_vec()); + + assert_matches!( + offchain.set_local_storage(StorageKind::PERSISTENT, key.clone(), value.clone()), + Ok(()) + ); + assert_matches!( + offchain.get_local_storage(StorageKind::PERSISTENT, key), + Ok(Some(ref v)) if *v == value + ); +} diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 9b27a5b270..d3f1362bfc 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -863,7 +863,7 @@ ServiceBuilder< 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) { + let offchain_workers = match (config.offchain_worker, offchain_storage.clone()) { (true, Some(db)) => { Some(Arc::new(sc_offchain::OffchainWorkers::new(client.clone(), db))) }, @@ -1008,7 +1008,7 @@ ServiceBuilder< // RPC let (system_rpc_tx, system_rpc_rx) = mpsc::unbounded(); let gen_handler = || { - use sc_rpc::{chain, state, author, system}; + use sc_rpc::{chain, state, author, system, offchain}; let system_info = sc_rpc::system::SystemInfo { chain_name: config.chain_spec.name().into(), @@ -1054,13 +1054,26 @@ ServiceBuilder< ); let system = system::System::new(system_info, system_rpc_tx.clone()); - sc_rpc_server::rpc_handler(( - state::StateApi::to_delegate(state), - chain::ChainApi::to_delegate(chain), - author::AuthorApi::to_delegate(author), - system::SystemApi::to_delegate(system), - rpc_extensions.clone(), - )) + match offchain_storage.clone() { + Some(storage) => { + let offchain = sc_rpc::offchain::Offchain::new(storage); + sc_rpc_server::rpc_handler(( + state::StateApi::to_delegate(state), + chain::ChainApi::to_delegate(chain), + offchain::OffchainApi::to_delegate(offchain), + author::AuthorApi::to_delegate(author), + system::SystemApi::to_delegate(system), + rpc_extensions.clone(), + )) + }, + None => sc_rpc_server::rpc_handler(( + state::StateApi::to_delegate(state), + chain::ChainApi::to_delegate(chain), + author::AuthorApi::to_delegate(author), + system::SystemApi::to_delegate(system), + rpc_extensions.clone(), + )) + } }; let rpc_handlers = gen_handler(); let rpc = start_rpc_servers(&config, gen_handler)?; diff --git a/primitives/core/src/offchain/mod.rs b/primitives/core/src/offchain/mod.rs index e2e00c36e0..425957a21f 100644 --- a/primitives/core/src/offchain/mod.rs +++ b/primitives/core/src/offchain/mod.rs @@ -50,6 +50,7 @@ pub trait OffchainStorage: Clone + Send + Sync { /// A type of supported crypto. #[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, RuntimeDebug, PassByEnum)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] #[repr(C)] pub enum StorageKind { /// Persistent storage is non-revertible and not fork-aware. It means that any value -- GitLab From 8f4495886a98d4a867d3f3813a8bf4dc6bca3a3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 29 Jan 2020 09:52:54 +0100 Subject: [PATCH 036/180] Don't run dev light client as validator (#4757) A light client can not be a validator, so we should not set `authority == true` in dev mode. --- client/cli/src/lib.rs | 8 +++++--- client/cli/src/params.rs | 5 ++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index fc50259528..d9ea238ba0 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -998,9 +998,11 @@ where fill_config_keystore_password_and_path(&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 is_light = cli.light; + let is_authority = (cli.validator || cli.sentry || is_dev || cli.keyring.account.is_some()) + && !is_light; let role = - if cli.light { + if is_light { sc_service::Roles::LIGHT } else if is_authority { sc_service::Roles::AUTHORITY @@ -1056,7 +1058,7 @@ where config.dev_key_seed = cli.keyring.account .map(|a| format!("//{}", a)).or_else(|| { - if is_dev { + if is_dev && !is_light { Some("//Alice".into()) } else { None diff --git a/client/cli/src/params.rs b/client/cli/src/params.rs index 57b90c2e73..ccaf24454d 100644 --- a/client/cli/src/params.rs +++ b/client/cli/src/params.rs @@ -417,7 +417,10 @@ pub struct RunCmd { pub no_grandpa: bool, /// Experimental: Run in light client mode. - #[structopt(long = "light")] + #[structopt( + long = "light", + conflicts_with_all = &[ "validator" ] + )] pub light: bool, /// Listen to all RPC interfaces. -- GitLab From 38c5ed0af7740d55993e91bdc9001cc17446180f Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 29 Jan 2020 11:46:39 +0100 Subject: [PATCH 037/180] Add diagnostics to tasks (#4752) --- Cargo.lock | 21 +++++- bin/node-template/src/service.rs | 6 +- bin/node/cli/src/service.rs | 7 +- client/service/Cargo.toml | 1 + client/service/src/builder.rs | 62 ++++++++++++------ client/service/src/lib.rs | 64 ++++++++++++------- client/transaction-pool/Cargo.toml | 1 + client/transaction-pool/src/api.rs | 4 +- primitives/consensus/common/Cargo.toml | 1 + .../common/src/import_queue/basic_queue.rs | 2 +- 10 files changed, 117 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5d4b97a3c6..16100cee87 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1513,6 +1513,21 @@ dependencies = [ "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "futures-diagnose" +version = "1.0.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)", + "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.10 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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 = "futures-executor" version = "0.3.1" @@ -5835,6 +5850,7 @@ dependencies = [ "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)", + "futures-diagnose 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "grafana-data-source 0.8.0", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5969,6 +5985,7 @@ 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)", + "futures-diagnose 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6415,6 +6432,7 @@ 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)", + "futures-diagnose 1.0.0 (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.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7700,7 +7718,7 @@ name = "twox-hash" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -8528,6 +8546,7 @@ dependencies = [ "checksum futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "79564c427afefab1dfb3298535b21eda083ef7935b4f0ecbfcb121f0aec10866" "checksum futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "b35b6263fb1ef523c3056565fa67b1d16f0a8604ff12b11b08c25f28a734c60a" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" +"checksum futures-diagnose 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbb8371dd6ee87aa2aeaa8458a372fd82fe216032387b766255754c92dd7271" "checksum futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e274736563f686a837a0568b478bdabfeaec2dca794b5649b04e2fe1627c231" "checksum futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e676577d229e70952ab25f3945795ba5b16d63ca794ca9d2c860e5595d20b5ff" "checksum futures-macro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "52e7c56c15537adb4f76d0b7a76ad131cb4d2f4f32d3b0bcabcbe1c7c5e87764" diff --git a/bin/node-template/src/service.rs b/bin/node-template/src/service.rs index 8a5c660b23..a396a5301c 100644 --- a/bin/node-template/src/service.rs +++ b/bin/node-template/src/service.rs @@ -131,7 +131,7 @@ pub fn new_full(config: Configuration(config: Configuration { // start the lightweight GRANDPA observer - service.spawn_task(grandpa::run_grandpa_observer( + service.spawn_task("grandpa-observer", grandpa::run_grandpa_observer( grandpa_config, grandpa_link, service.network(), @@ -178,7 +178,7 @@ pub fn new_full(config: Configuration { grandpa::setup_disabled_grandpa( diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index 2aaca315b9..32f2d0001c 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -172,7 +172,7 @@ macro_rules! new_full { }; let babe = sc_consensus_babe::start_babe(babe_config)?; - service.spawn_essential_task(babe); + service.spawn_essential_task("babe-proposer", babe); let network = service.network(); let dht_event_stream = network.event_stream().filter_map(|e| async move { match e { @@ -187,7 +187,7 @@ macro_rules! new_full { dht_event_stream, ); - service.spawn_task(authority_discovery); + service.spawn_task("authority-discovery", authority_discovery); } // if the node isn't actively participating in consensus then it doesn't @@ -211,7 +211,7 @@ macro_rules! new_full { match (is_authority, disable_grandpa) { (false, false) => { // start the lightweight GRANDPA observer - service.spawn_task(grandpa::run_grandpa_observer( + service.spawn_task("grandpa-observer", grandpa::run_grandpa_observer( config, grandpa_link, service.network(), @@ -234,6 +234,7 @@ macro_rules! new_full { // the GRANDPA voter task is considered infallible, i.e. // if it fails we take down the service with it. service.spawn_essential_task( + "grandpa-voter", grandpa::run_grandpa_voter(grandpa_config)? ); }, diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 095136a11c..f5b3b71914 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -17,6 +17,7 @@ wasmtime = [ derive_more = "0.99.2" futures01 = { package = "futures", version = "0.1.29" } futures = "0.3.1" +futures-diagnose = "1.0" parking_lot = "0.9.0" lazy_static = "1.4.0" log = "0.4.8" diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index d3f1362bfc..548a0c6170 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -44,6 +44,7 @@ use sp_runtime::traits::{ use sp_api::ProvideRuntimeApi; use sc_executor::{NativeExecutor, NativeExecutionDispatch}; use std::{ + borrow::Cow, io::{Read, Write, Seek}, marker::PhantomData, sync::Arc, time::SystemTime, pin::Pin }; @@ -791,7 +792,7 @@ ServiceBuilder< // List of asynchronous tasks to spawn. We collect them, then spawn them all at once. let (to_spawn_tx, to_spawn_rx) = - mpsc::unbounded:: + Send>>>(); + mpsc::unbounded::<(Pin + Send>>, Cow<'static, str>)>(); // A side-channel for essential tasks to communicate shutdown. let (essential_failed_tx, essential_failed_rx) = mpsc::unbounded(); @@ -816,7 +817,7 @@ ServiceBuilder< imports_external_transactions: !config.roles.is_light(), pool: transaction_pool.clone(), client: client.clone(), - executor: Arc::new(SpawnTaskHandle { sender: to_spawn_tx.clone(), on_exit: exit.clone() }), + executor: SpawnTaskHandle { sender: to_spawn_tx.clone(), on_exit: exit.clone() }, }); let protocol_id = { @@ -840,7 +841,7 @@ ServiceBuilder< executor: { let to_spawn_tx = to_spawn_tx.clone(); Some(Box::new(move |fut| { - if let Err(e) = to_spawn_tx.unbounded_send(fut) { + if let Err(e) = to_spawn_tx.unbounded_send((fut, From::from("libp2p-node"))) { error!("Failed to spawn libp2p background task: {:?}", e); } })) @@ -891,7 +892,10 @@ ServiceBuilder< &BlockId::hash(notification.hash), ¬ification.retracted, ); - let _ = to_spawn_tx_.unbounded_send(Box::pin(future)); + let _ = to_spawn_tx_.unbounded_send(( + Box::pin(future), + From::from("txpool-maintain") + )); } let offchain = offchain.as_ref().and_then(|o| o.upgrade()); @@ -901,12 +905,18 @@ ServiceBuilder< network_state_info.clone(), is_validator ); - let _ = to_spawn_tx_.unbounded_send(Box::pin(future)); + let _ = to_spawn_tx_.unbounded_send(( + Box::pin(future), + From::from("offchain-on-block") + )); } ready(()) }); - let _ = to_spawn_tx.unbounded_send(Box::pin(select(events, exit.clone()).map(drop))); + let _ = to_spawn_tx.unbounded_send(( + Box::pin(select(events, exit.clone()).map(drop)), + From::from("txpool-and-offchain-notif") + )); } { @@ -926,7 +936,10 @@ ServiceBuilder< ready(()) }); - let _ = to_spawn_tx.unbounded_send(Box::pin(select(events, exit.clone()).map(drop))); + let _ = to_spawn_tx.unbounded_send(( + Box::pin(select(events, exit.clone()).map(drop)), + From::from("telemetry-on-block") + )); } // Periodically notify the telemetry. @@ -990,7 +1003,10 @@ ServiceBuilder< ready(()) }); - let _ = to_spawn_tx.unbounded_send(Box::pin(select(tel_task, exit.clone()).map(drop))); + let _ = to_spawn_tx.unbounded_send(( + Box::pin(select(tel_task, exit.clone()).map(drop)), + From::from("telemetry-periodic-send") + )); // Periodically send the network state to the telemetry. let (netstat_tx, netstat_rx) = mpsc::unbounded::<(NetworkStatus<_>, NetworkState)>(); @@ -1003,7 +1019,10 @@ ServiceBuilder< ); ready(()) }); - let _ = to_spawn_tx.unbounded_send(Box::pin(select(tel_task_2, exit.clone()).map(drop))); + let _ = to_spawn_tx.unbounded_send(( + Box::pin(select(tel_task_2, exit.clone()).map(drop)), + From::from("telemetry-periodic-network-state") + )); // RPC let (system_rpc_tx, system_rpc_rx) = mpsc::unbounded(); @@ -1079,14 +1098,17 @@ ServiceBuilder< let rpc = start_rpc_servers(&config, gen_handler)?; - let _ = to_spawn_tx.unbounded_send(Box::pin(select(build_network_future( - config.roles, - network_mut, - client.clone(), - network_status_sinks.clone(), - system_rpc_rx, - has_bootnodes, - ), exit.clone()).map(drop))); + let _ = to_spawn_tx.unbounded_send(( + Box::pin(select(build_network_future( + config.roles, + network_mut, + client.clone(), + network_status_sinks.clone(), + system_rpc_rx, + has_bootnodes, + ), exit.clone()).map(drop)), + From::from("network-worker") + )); let telemetry_connection_sinks: Arc>>> = Default::default(); @@ -1127,9 +1149,9 @@ ServiceBuilder< }); ready(()) }); - let _ = to_spawn_tx.unbounded_send(Box::pin(select( + let _ = to_spawn_tx.unbounded_send((Box::pin(select( future, exit.clone() - ).map(drop))); + ).map(drop)), From::from("telemetry-worker"))); telemetry }); @@ -1140,7 +1162,7 @@ ServiceBuilder< exit.clone() ).map(drop); - let _ = to_spawn_tx.unbounded_send(Box::pin(future)); + let _ = to_spawn_tx.unbounded_send((Box::pin(future), From::from("grafana-server"))); } // Instrumentation diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index c7069ac6e5..3bd8f6d290 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -27,7 +27,7 @@ pub mod error; mod builder; mod status_sinks; -use std::{io, pin::Pin}; +use std::{borrow::Cow, io, pin::Pin}; use std::marker::PhantomData; use std::net::SocketAddr; use std::collections::HashMap; @@ -42,7 +42,7 @@ use futures::{ future::select, channel::mpsc, compat::*, sink::SinkExt, - task::{Spawn, SpawnExt, FutureObj, SpawnError}, + task::{Spawn, FutureObj, SpawnError}, }; use sc_network::{ NetworkService, NetworkState, specialization::NetworkSpecialization, @@ -92,9 +92,9 @@ pub struct Service { /// 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>>>, + to_spawn_tx: mpsc::UnboundedSender<(Pin + Send>>, Cow<'static, str>)>, /// Receiver for futures that must be spawned as background tasks. - to_spawn_rx: mpsc::UnboundedReceiver + Send>>>, + to_spawn_rx: mpsc::UnboundedReceiver<(Pin + Send>>, Cow<'static, str>)>, /// How to spawn background tasks. tasks_executor: Box + Send>>) + Send>, rpc_handlers: sc_rpc_server::RpcHandler, @@ -112,15 +112,29 @@ pub type TaskExecutor = Arc; /// An handle for spawning tasks in the service. #[derive(Clone)] pub struct SpawnTaskHandle { - sender: mpsc::UnboundedSender + Send>>>, + sender: mpsc::UnboundedSender<(Pin + Send>>, Cow<'static, str>)>, on_exit: exit_future::Exit, } +impl SpawnTaskHandle { + /// Spawns the given task with the given name. + pub fn spawn(&self, name: impl Into>, task: impl Future + Send + 'static) { + let on_exit = self.on_exit.clone(); + let future = async move { + futures::pin_mut!(task); + let _ = select(on_exit, task).await; + }; + if self.sender.unbounded_send((Box::pin(future), name.into())).is_err() { + error!("Failed to send task to spawn over channel"); + } + } +} + impl Spawn for SpawnTaskHandle { fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> { let future = select(self.on_exit.clone(), future).map(drop); - self.sender.unbounded_send(Box::pin(future)) + self.sender.unbounded_send((Box::pin(future), From::from("unnamed"))) .map_err(|_| SpawnError::shutdown()) } } @@ -129,7 +143,7 @@ type Boxed01Future01 = Box + Send + impl futures01::future::Executor for SpawnTaskHandle { fn execute(&self, future: Boxed01Future01) -> Result<(), futures01::future::ExecuteError>{ - self.spawn(future.compat().map(drop)); + self.spawn("unnamed", future.compat().map(drop)); Ok(()) } } @@ -159,12 +173,12 @@ pub trait AbstractService: 'static + Future> + 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 + Unpin + 'static); + fn spawn_task(&self, name: impl Into>, task: impl Future + Send + 'static); /// Spawns a task in the background that runs the future passed as /// parameter. The given task is considered essential, i.e. if it errors we /// trigger a service exit. - fn spawn_essential_task(&self, task: impl Future + Send + Unpin + 'static); + fn spawn_essential_task(&self, name: impl Into>, task: impl Future + Send + 'static); /// Returns a handle for spawning tasks. fn spawn_task_handle(&self) -> SpawnTaskHandle; @@ -238,12 +252,16 @@ where self.keystore.clone() } - fn spawn_task(&self, task: impl Future + Send + Unpin + 'static) { - let task = select(self.on_exit(), task).map(drop); - let _ = self.to_spawn_tx.unbounded_send(Box::pin(task)); + fn spawn_task(&self, name: impl Into>, task: impl Future + Send + 'static) { + let on_exit = self.on_exit(); + let task = async move { + futures::pin_mut!(task); + let _ = select(on_exit, task).await; + }; + let _ = self.to_spawn_tx.unbounded_send((Box::pin(task), name.into())); } - fn spawn_essential_task(&self, task: impl Future + Send + Unpin + 'static) { + fn spawn_essential_task(&self, name: impl Into>, task: impl Future + Send + 'static) { let mut essential_failed = self.essential_failed_tx.clone(); let essential_task = std::panic::AssertUnwindSafe(task) .catch_unwind() @@ -251,9 +269,13 @@ where error!("Essential task failed. Shutting down service."); let _ = essential_failed.send(()); }); - let task = select(self.on_exit(), essential_task).map(drop); + let on_exit = self.on_exit(); + let task = async move { + futures::pin_mut!(essential_task); + let _ = select(on_exit, essential_task).await; + }; - let _ = self.to_spawn_tx.unbounded_send(Box::pin(task)); + let _ = self.to_spawn_tx.unbounded_send((Box::pin(task), name.into())); } fn spawn_task_handle(&self) -> SpawnTaskHandle { @@ -317,8 +339,8 @@ impl Future for } } - while let Poll::Ready(Some(task_to_spawn)) = Pin::new(&mut this.to_spawn_rx).poll_next(cx) { - (this.tasks_executor)(task_to_spawn); + while let Poll::Ready(Some((task_to_spawn, name))) = Pin::new(&mut this.to_spawn_rx).poll_next(cx) { + (this.tasks_executor)(Box::pin(futures_diagnose::diagnose(name, task_to_spawn))); } // The service future never ends. @@ -333,7 +355,7 @@ impl Spawn for &self, future: FutureObj<'static, ()> ) -> Result<(), SpawnError> { - self.to_spawn_tx.unbounded_send(Box::pin(future)) + self.to_spawn_tx.unbounded_send((Box::pin(future), From::from("unnamed"))) .map_err(|_| SpawnError::shutdown()) } } @@ -575,7 +597,7 @@ pub struct TransactionPoolAdapter { imports_external_transactions: bool, pool: Arc

, client: Arc, - executor: TaskExecutor, + executor: SpawnTaskHandle, } /// Get transactions for propagation. @@ -649,9 +671,7 @@ where } }); - if let Err(e) = self.executor.spawn(Box::new(import_future)) { - warn!("Error scheduling extrinsic import: {:?}", e); - } + self.executor.spawn("extrinsic-import", import_future); } Err(e) => debug!("Error decoding transaction {}", e), } diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index c3cd8c9838..855c7bd40d 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -8,6 +8,7 @@ edition = "2018" codec = { package = "parity-scale-codec", version = "1.0.0" } derive_more = "0.99.2" futures = { version = "0.3.1", features = ["compat"] } +futures-diagnose = "1.0" log = "0.4.8" parking_lot = "0.9.0" sp-core = { path = "../../primitives/core" } diff --git a/client/transaction-pool/src/api.rs b/client/transaction-pool/src/api.rs index 1bf6348214..bfc13c01fd 100644 --- a/client/transaction-pool/src/api.rs +++ b/client/transaction-pool/src/api.rs @@ -87,13 +87,13 @@ impl sc_transaction_graph::ChainApi for FullChainApi BasicQueue { let manual_poll; if let Some(pool) = &mut pool { - pool.spawn_ok(future); + pool.spawn_ok(futures_diagnose::diagnose("import-queue", future)); manual_poll = None; } else { manual_poll = Some(Box::pin(future) as Pin>); -- GitLab From 0f0cc75608e7302670fb560da4612c50179ef069 Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Wed, 29 Jan 2020 11:57:13 +0100 Subject: [PATCH 038/180] clarify licensing (#4755) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * adding license fields to all crates * Apply suggestions from code review Co-Authored-By: Bastian Köcher Co-authored-by: Bastian Köcher --- .maintain/node-template-release/Cargo.toml | 1 + Cargo.lock | 12 +----------- bin/node-template/Cargo.toml | 1 + bin/node-template/runtime/Cargo.toml | 1 + bin/node/cli/Cargo.toml | 1 + bin/node/executor/Cargo.toml | 1 + bin/node/primitives/Cargo.toml | 1 + bin/node/rpc-client/Cargo.toml | 1 + bin/node/rpc/Cargo.toml | 1 + bin/node/runtime/Cargo.toml | 2 ++ bin/node/testing/Cargo.toml | 1 + bin/node/transaction-factory/Cargo.toml | 1 + bin/utils/chain-spec-builder/Cargo.toml | 1 + bin/utils/subkey/Cargo.toml | 1 + client/Cargo.toml | 1 + client/api/Cargo.toml | 1 + client/authority-discovery/Cargo.toml | 1 + client/basic-authorship/Cargo.toml | 1 + client/block-builder/Cargo.toml | 1 + client/chain-spec/Cargo.toml | 1 + client/chain-spec/derive/Cargo.toml | 1 + client/cli/Cargo.toml | 1 + client/consensus/aura/Cargo.toml | 1 + client/consensus/babe/Cargo.toml | 1 + client/consensus/manual-seal/Cargo.toml | 1 + client/consensus/pow/Cargo.toml | 1 + client/consensus/slots/Cargo.toml | 1 + client/consensus/uncles/Cargo.toml | 1 + client/db/Cargo.toml | 3 ++- client/db/src/upgrade.rs | 6 +++--- client/executor/Cargo.toml | 1 + client/executor/common/Cargo.toml | 1 + client/executor/runtime-test/Cargo.toml | 1 + client/executor/wasmi/Cargo.toml | 1 + client/executor/wasmtime/Cargo.toml | 1 + client/finality-grandpa/Cargo.toml | 1 + client/keystore/Cargo.toml | 1 + client/rpc-api/Cargo.toml | 1 + client/rpc-servers/Cargo.toml | 1 + client/rpc/Cargo.toml | 1 + client/service/Cargo.toml | 1 + client/service/test/Cargo.toml | 1 + client/state-db/Cargo.toml | 1 + client/telemetry/Cargo.toml | 1 + client/transaction-pool/Cargo.toml | 1 + client/transaction-pool/graph/Cargo.toml | 1 + frame/assets/Cargo.toml | 1 + frame/aura/Cargo.toml | 1 + frame/authority-discovery/Cargo.toml | 1 + frame/authorship/Cargo.toml | 1 + frame/babe/Cargo.toml | 1 + frame/balances/Cargo.toml | 1 + frame/collective/Cargo.toml | 1 + frame/contracts/Cargo.toml | 1 + frame/contracts/rpc/Cargo.toml | 1 + frame/contracts/rpc/runtime-api/Cargo.toml | 1 + frame/democracy/Cargo.toml | 1 + frame/elections-phragmen/Cargo.toml | 1 + frame/elections/Cargo.toml | 1 + frame/evm/Cargo.toml | 1 + frame/example/Cargo.toml | 1 + frame/executive/Cargo.toml | 1 + frame/finality-tracker/Cargo.toml | 1 + frame/generic-asset/Cargo.toml | 1 + frame/grandpa/Cargo.toml | 1 + frame/identity/Cargo.toml | 1 + frame/im-online/Cargo.toml | 1 + frame/indices/Cargo.toml | 1 + frame/membership/Cargo.toml | 1 + frame/metadata/Cargo.toml | 1 + frame/nicks/Cargo.toml | 1 + frame/offences/Cargo.toml | 1 + frame/randomness-collective-flip/Cargo.toml | 1 + frame/recovery/Cargo.toml | 1 + frame/scored-pool/Cargo.toml | 1 + frame/session/Cargo.toml | 3 ++- frame/society/Cargo.toml | 1 + frame/staking/Cargo.toml | 1 + frame/staking/reward-curve/Cargo.toml | 1 + frame/sudo/Cargo.toml | 1 + frame/support/Cargo.toml | 1 + frame/support/procedural/Cargo.toml | 1 + frame/support/procedural/tools/Cargo.toml | 1 + frame/support/procedural/tools/derive/Cargo.toml | 1 + frame/support/test/Cargo.toml | 1 + frame/system/Cargo.toml | 1 + frame/system/rpc/runtime-api/Cargo.toml | 1 + frame/timestamp/Cargo.toml | 1 + frame/transaction-payment/Cargo.toml | 1 + frame/transaction-payment/rpc/Cargo.toml | 1 + frame/transaction-payment/rpc/runtime-api/Cargo.toml | 1 + frame/treasury/Cargo.toml | 1 + frame/utility/Cargo.toml | 1 + primitives/allocator/Cargo.toml | 1 + primitives/api/Cargo.toml | 1 + primitives/api/proc-macro/Cargo.toml | 1 + primitives/api/test/Cargo.toml | 1 + primitives/application-crypto/Cargo.toml | 1 + primitives/application-crypto/test/Cargo.toml | 1 + primitives/arithmetic/Cargo.toml | 1 + primitives/arithmetic/fuzzer/Cargo.toml | 1 + primitives/authority-discovery/Cargo.toml | 1 + primitives/authorship/Cargo.toml | 1 + primitives/block-builder/Cargo.toml | 1 + primitives/blockchain/Cargo.toml | 1 + primitives/consensus/aura/Cargo.toml | 1 + primitives/consensus/babe/Cargo.toml | 1 + primitives/consensus/common/Cargo.toml | 1 + primitives/consensus/pow/Cargo.toml | 1 + primitives/core/Cargo.toml | 1 + primitives/debug-derive/Cargo.toml | 1 + primitives/finality-grandpa/Cargo.toml | 1 + primitives/finality-tracker/Cargo.toml | 1 + primitives/inherents/Cargo.toml | 1 + primitives/io/Cargo.toml | 1 + primitives/keyring/Cargo.toml | 1 + primitives/panic-handler/Cargo.toml | 1 + primitives/phragmen/Cargo.toml | 1 + primitives/rpc/Cargo.toml | 1 + primitives/runtime-interface/Cargo.toml | 1 + primitives/runtime-interface/proc-macro/Cargo.toml | 1 + primitives/runtime-interface/test-wasm/Cargo.toml | 1 + primitives/runtime-interface/test/Cargo.toml | 1 + primitives/runtime/Cargo.toml | 1 + primitives/sandbox/Cargo.toml | 1 + primitives/serializer/Cargo.toml | 1 + primitives/session/Cargo.toml | 1 + primitives/staking/Cargo.toml | 1 + primitives/state-machine/Cargo.toml | 1 + primitives/std/Cargo.toml | 1 + primitives/storage/Cargo.toml | 1 + primitives/test-primitives/Cargo.toml | 1 + primitives/timestamp/Cargo.toml | 1 + primitives/transaction-pool/Cargo.toml | 1 + primitives/version/Cargo.toml | 1 + primitives/wasm-interface/Cargo.toml | 1 + test-utils/Cargo.toml | 1 + test-utils/client/Cargo.toml | 1 + test-utils/runtime/Cargo.toml | 1 + test-utils/runtime/client/Cargo.toml | 1 + utils/browser/Cargo.toml | 1 + utils/build-script-utils/Cargo.toml | 1 + utils/fork-tree/Cargo.toml | 1 + utils/frame/rpc/support/Cargo.toml | 1 + utils/frame/rpc/system/Cargo.toml | 1 + 145 files changed, 150 insertions(+), 16 deletions(-) diff --git a/.maintain/node-template-release/Cargo.toml b/.maintain/node-template-release/Cargo.toml index 8a43435b20..606def19bb 100644 --- a/.maintain/node-template-release/Cargo.toml +++ b/.maintain/node-template-release/Cargo.toml @@ -3,6 +3,7 @@ name = "node-template-release" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] toml = "0.4" diff --git a/Cargo.lock b/Cargo.lock index 16100cee87..88b73133f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5308,7 +5308,7 @@ dependencies = [ "sp-state-machine 0.8.0", "sp-trie 2.0.0", "substrate-test-runtime-client 2.0.0", - "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7203,15 +7203,6 @@ 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" @@ -8861,7 +8852,6 @@ dependencies = [ "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" diff --git a/bin/node-template/Cargo.toml b/bin/node-template/Cargo.toml index cf3d7509f4..9ad91a973c 100644 --- a/bin/node-template/Cargo.toml +++ b/bin/node-template/Cargo.toml @@ -4,6 +4,7 @@ version = "2.0.0" authors = ["Anonymous"] build = "build.rs" edition = "2018" +license = "Unlicense" [[bin]] name = "node-template" diff --git a/bin/node-template/runtime/Cargo.toml b/bin/node-template/runtime/Cargo.toml index e048d8baf7..299e78996a 100644 --- a/bin/node-template/runtime/Cargo.toml +++ b/bin/node-template/runtime/Cargo.toml @@ -3,6 +3,7 @@ name = "node-template-runtime" version = "2.0.0" authors = ["Anonymous"] edition = "2018" +license = "Unlicense" [dependencies] aura = { version = "2.0.0", default-features = false, package = "pallet-aura", path = "../../../frame/aura" } diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index c81cf38a9c..585c3f57d6 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -5,6 +5,7 @@ authors = ["Parity Technologies "] description = "Substrate node implementation in Rust." build = "build.rs" edition = "2018" +license = "GPL-3.0" default-run = "substrate" [badges] diff --git a/bin/node/executor/Cargo.toml b/bin/node/executor/Cargo.toml index 6e624e09d2..0d68b70522 100644 --- a/bin/node/executor/Cargo.toml +++ b/bin/node/executor/Cargo.toml @@ -4,6 +4,7 @@ version = "2.0.0" authors = ["Parity Technologies "] description = "Substrate node implementation in Rust." edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0" } diff --git a/bin/node/primitives/Cargo.toml b/bin/node/primitives/Cargo.toml index 1ecfd76792..5fc6ce8f10 100644 --- a/bin/node/primitives/Cargo.toml +++ b/bin/node/primitives/Cargo.toml @@ -3,6 +3,7 @@ name = "node-primitives" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-core = { version = "2.0.0", default-features = false, path = "../../../primitives/core" } diff --git a/bin/node/rpc-client/Cargo.toml b/bin/node/rpc-client/Cargo.toml index 5ef9d1e99d..0d8106dcee 100644 --- a/bin/node/rpc-client/Cargo.toml +++ b/bin/node/rpc-client/Cargo.toml @@ -3,6 +3,7 @@ name = "node-rpc-client" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] env_logger = "0.7.0" diff --git a/bin/node/rpc/Cargo.toml b/bin/node/rpc/Cargo.toml index 174b287516..289d20ea01 100644 --- a/bin/node/rpc/Cargo.toml +++ b/bin/node/rpc/Cargo.toml @@ -3,6 +3,7 @@ name = "node-rpc" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sc-client = { version = "0.8", path = "../../../client/" } diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 27b1e9382f..35f01e32cb 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -4,8 +4,10 @@ version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" +license = "GPL-3.0" [dependencies] + # third-party dependencies codec = { package = "parity-scale-codec", version = "1.0.6", default-features = false, features = ["derive"] } integer-sqrt = { version = "0.1.2" } diff --git a/bin/node/testing/Cargo.toml b/bin/node/testing/Cargo.toml index 37e85452d5..051460e839 100644 --- a/bin/node/testing/Cargo.toml +++ b/bin/node/testing/Cargo.toml @@ -4,6 +4,7 @@ version = "2.0.0" authors = ["Parity Technologies "] description = "Test utilities for Substrate node." edition = "2018" +license = "GPL-3.0" [dependencies] pallet-balances = { version = "2.0.0", path = "../../../frame/balances" } diff --git a/bin/node/transaction-factory/Cargo.toml b/bin/node/transaction-factory/Cargo.toml index f32a3c23e0..cd40e2f0d9 100644 --- a/bin/node/transaction-factory/Cargo.toml +++ b/bin/node/transaction-factory/Cargo.toml @@ -3,6 +3,7 @@ name = "node-transaction-factory" version = "0.8.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-block-builder = { version = "2.0.0", path = "../../../primitives/block-builder" } diff --git a/bin/utils/chain-spec-builder/Cargo.toml b/bin/utils/chain-spec-builder/Cargo.toml index c8d79afbce..b4707a5eb4 100644 --- a/bin/utils/chain-spec-builder/Cargo.toml +++ b/bin/utils/chain-spec-builder/Cargo.toml @@ -4,6 +4,7 @@ version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" +license = "GPL-3.0" [dependencies] ansi_term = "0.12.1" diff --git a/bin/utils/subkey/Cargo.toml b/bin/utils/subkey/Cargo.toml index b4398d9f8b..9b7db6699f 100644 --- a/bin/utils/subkey/Cargo.toml +++ b/bin/utils/subkey/Cargo.toml @@ -3,6 +3,7 @@ name = "subkey" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] futures = "0.1.29" diff --git a/client/Cargo.toml b/client/Cargo.toml index 7413fc23f9..6437d699d1 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-client" version = "0.8.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sc-block-builder = { version = "0.8", path = "block-builder" } diff --git a/client/api/Cargo.toml b/client/api/Cargo.toml index 651ee1434f..ac47537e79 100644 --- a/client/api/Cargo.toml +++ b/client/api/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-client-api" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index 6e4570a540..0c267cbcc6 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -4,6 +4,7 @@ version = "0.8.0" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" +license = "GPL-3.0" [build-dependencies] prost-build = "0.5.0" diff --git a/client/basic-authorship/Cargo.toml b/client/basic-authorship/Cargo.toml index 8fa0b9f5cc..68bd4d87f2 100644 --- a/client/basic-authorship/Cargo.toml +++ b/client/basic-authorship/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-basic-authorship" version = "0.8.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] log = "0.4.8" diff --git a/client/block-builder/Cargo.toml b/client/block-builder/Cargo.toml index 29531c4288..383a931b2f 100644 --- a/client/block-builder/Cargo.toml +++ b/client/block-builder/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-block-builder" version = "0.8.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-state-machine = { version = "0.8", path = "../../primitives/state-machine" } diff --git a/client/chain-spec/Cargo.toml b/client/chain-spec/Cargo.toml index fee166df32..222914145e 100644 --- a/client/chain-spec/Cargo.toml +++ b/client/chain-spec/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-chain-spec" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sc-chain-spec-derive = { version = "2.0.0", path = "./derive" } diff --git a/client/chain-spec/derive/Cargo.toml b/client/chain-spec/derive/Cargo.toml index 1086440664..566948883b 100644 --- a/client/chain-spec/derive/Cargo.toml +++ b/client/chain-spec/derive/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-chain-spec-derive" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [lib] proc-macro = true diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index b46e3992b2..020ae164ef 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -4,6 +4,7 @@ version = "0.8.0" authors = ["Parity Technologies "] description = "Substrate CLI interface." edition = "2018" +license = "GPL-3.0" [dependencies] clap = "2.33.0" diff --git a/client/consensus/aura/Cargo.toml b/client/consensus/aura/Cargo.toml index 3d4c5a9157..4f15a11302 100644 --- a/client/consensus/aura/Cargo.toml +++ b/client/consensus/aura/Cargo.toml @@ -4,6 +4,7 @@ version = "0.8.0" authors = ["Parity Technologies "] description = "Aura consensus algorithm for substrate" edition = "2018" +license = "GPL-3.0" [dependencies] sp-application-crypto = { version = "2.0.0", path = "../../../primitives/application-crypto" } diff --git a/client/consensus/babe/Cargo.toml b/client/consensus/babe/Cargo.toml index 55b0e0cf20..124304093f 100644 --- a/client/consensus/babe/Cargo.toml +++ b/client/consensus/babe/Cargo.toml @@ -4,6 +4,7 @@ version = "0.8.0" authors = ["Parity Technologies "] description = "BABE consensus algorithm for substrate" edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } diff --git a/client/consensus/manual-seal/Cargo.toml b/client/consensus/manual-seal/Cargo.toml index 83d7535dae..821b314501 100644 --- a/client/consensus/manual-seal/Cargo.toml +++ b/client/consensus/manual-seal/Cargo.toml @@ -4,6 +4,7 @@ version = "0.8.0" authors = ["Parity Technologies "] description = "Manual sealing engine for Substrate" edition = "2018" +license = "GPL-3.0" [dependencies] derive_more = "0.99.2" diff --git a/client/consensus/pow/Cargo.toml b/client/consensus/pow/Cargo.toml index bf0efa6c08..b31d9406e1 100644 --- a/client/consensus/pow/Cargo.toml +++ b/client/consensus/pow/Cargo.toml @@ -4,6 +4,7 @@ version = "0.8.0" authors = ["Parity Technologies "] description = "PoW consensus algorithm for substrate" edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } diff --git a/client/consensus/slots/Cargo.toml b/client/consensus/slots/Cargo.toml index 89ee14b8fa..d9b55bb07d 100644 --- a/client/consensus/slots/Cargo.toml +++ b/client/consensus/slots/Cargo.toml @@ -5,6 +5,7 @@ authors = ["Parity Technologies "] description = "Generic slots-based utilities for consensus" edition = "2018" build = "build.rs" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0" } diff --git a/client/consensus/uncles/Cargo.toml b/client/consensus/uncles/Cargo.toml index 54789c5794..f336564c4e 100644 --- a/client/consensus/uncles/Cargo.toml +++ b/client/consensus/uncles/Cargo.toml @@ -4,6 +4,7 @@ version = "0.8.0" authors = ["Parity Technologies "] description = "Generic uncle inclusion utilities for consensus" edition = "2018" +license = "GPL-3.0" [dependencies] sc-client-api = { version = "2.0.0", path = "../../api" } diff --git a/client/db/Cargo.toml b/client/db/Cargo.toml index dcc7df29ca..ae6445c8d3 100644 --- a/client/db/Cargo.toml +++ b/client/db/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-client-db" version = "0.8.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] parking_lot = "0.9.0" @@ -32,7 +33,7 @@ substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/ru env_logger = "0.7.0" quickcheck = "0.9" kvdb-rocksdb = "0.4" -tempdir = "0.3" +tempfile = "3" [features] default = [] diff --git a/client/db/src/upgrade.rs b/client/db/src/upgrade.rs index ab2d4bbf79..69230e7851 100644 --- a/client/db/src/upgrade.rs +++ b/client/db/src/upgrade.rs @@ -172,14 +172,14 @@ mod tests { #[test] fn downgrade_never_happens() { - let db_dir = tempdir::TempDir::new("").unwrap(); + let db_dir = tempfile::TempDir::new().unwrap(); create_db(db_dir.path(), Some(CURRENT_VERSION + 1)); assert!(open_database(db_dir.path()).is_err()); } #[test] fn open_empty_database_works() { - let db_dir = tempdir::TempDir::new("").unwrap(); + let db_dir = tempfile::TempDir::new().unwrap(); open_database(db_dir.path()).unwrap(); open_database(db_dir.path()).unwrap(); assert_eq!(current_version(db_dir.path()).unwrap(), CURRENT_VERSION); @@ -188,7 +188,7 @@ mod tests { #[test] fn upgrade_from_0_to_1_works() { for version_from_file in &[None, Some(0)] { - let db_dir = tempdir::TempDir::new("").unwrap(); + let db_dir = tempfile::TempDir::new().unwrap(); let db_path = db_dir.path(); create_db(db_path, *version_from_file); open_database(db_path).unwrap(); diff --git a/client/executor/Cargo.toml b/client/executor/Cargo.toml index aa8c46999d..21fd00ba90 100644 --- a/client/executor/Cargo.toml +++ b/client/executor/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-executor" version = "0.8.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] derive_more = "0.99.2" diff --git a/client/executor/common/Cargo.toml b/client/executor/common/Cargo.toml index d3282e4dff..e10afe3448 100644 --- a/client/executor/common/Cargo.toml +++ b/client/executor/common/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-executor-common" version = "0.8.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] log = "0.4.8" diff --git a/client/executor/runtime-test/Cargo.toml b/client/executor/runtime-test/Cargo.toml index 80dda384a0..3cb0c03a87 100644 --- a/client/executor/runtime-test/Cargo.toml +++ b/client/executor/runtime-test/Cargo.toml @@ -4,6 +4,7 @@ version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" +license = "GPL-3.0" [dependencies] sp-std = { version = "2.0.0", default-features = false, path = "../../../primitives/std" } diff --git a/client/executor/wasmi/Cargo.toml b/client/executor/wasmi/Cargo.toml index 6e67c73e56..9e968fdc68 100644 --- a/client/executor/wasmi/Cargo.toml +++ b/client/executor/wasmi/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-executor-wasmi" version = "0.8.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] log = "0.4.8" diff --git a/client/executor/wasmtime/Cargo.toml b/client/executor/wasmtime/Cargo.toml index a8f30a54b3..30d3a5dc87 100644 --- a/client/executor/wasmtime/Cargo.toml +++ b/client/executor/wasmtime/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-executor-wasmtime" version = "0.8.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] log = "0.4.8" diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index a26b2e7a41..e1fe3f0361 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-finality-grandpa" version = "0.8.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] fork-tree = { version = "2.0.0", path = "../../utils/fork-tree" } diff --git a/client/keystore/Cargo.toml b/client/keystore/Cargo.toml index cdc69349fb..b4dde77e7d 100644 --- a/client/keystore/Cargo.toml +++ b/client/keystore/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-keystore" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] derive_more = "0.99.2" diff --git a/client/rpc-api/Cargo.toml b/client/rpc-api/Cargo.toml index 7f1a12f80e..1f52f41508 100644 --- a/client/rpc-api/Cargo.toml +++ b/client/rpc-api/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-rpc-api" version = "0.8.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0" } diff --git a/client/rpc-servers/Cargo.toml b/client/rpc-servers/Cargo.toml index e540274e25..6b0d3f4ada 100644 --- a/client/rpc-servers/Cargo.toml +++ b/client/rpc-servers/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-rpc-server" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] jsonrpc-core = "14.0.3" diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index 789ebf565c..a8cbc5c536 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-rpc" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sc-rpc-api = { version = "0.8", path = "../rpc-api" } diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index f5b3b71914..36213993e3 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-service" version = "0.8.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [features] default = ["rocksdb"] diff --git a/client/service/test/Cargo.toml b/client/service/test/Cargo.toml index 01ccf71a4b..c9dbe97464 100644 --- a/client/service/test/Cargo.toml +++ b/client/service/test/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-service-test" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] tempfile = "3.1.0" diff --git a/client/state-db/Cargo.toml b/client/state-db/Cargo.toml index 9e162c5cb9..3d3eca9d5e 100644 --- a/client/state-db/Cargo.toml +++ b/client/state-db/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-state-db" version = "0.8.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] parking_lot = "0.9.0" diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index dbcc486d17..5127712e12 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -4,6 +4,7 @@ version = "2.0.0" authors = ["Parity Technologies "] description = "Telemetry utils" edition = "2018" +license = "GPL-3.0" [dependencies] bytes = "0.5" diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index 855c7bd40d..0bdf5efaa6 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-transaction-pool" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0" } diff --git a/client/transaction-pool/graph/Cargo.toml b/client/transaction-pool/graph/Cargo.toml index c5897e84fe..3b0adf5cb1 100644 --- a/client/transaction-pool/graph/Cargo.toml +++ b/client/transaction-pool/graph/Cargo.toml @@ -3,6 +3,7 @@ name = "sc-transaction-graph" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] derive_more = "0.99.2" diff --git a/frame/assets/Cargo.toml b/frame/assets/Cargo.toml index f371f21e1a..cd6b41c4c7 100644 --- a/frame/assets/Cargo.toml +++ b/frame/assets/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-assets" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true } diff --git a/frame/aura/Cargo.toml b/frame/aura/Cargo.toml index 2675445832..8eb91016ff 100644 --- a/frame/aura/Cargo.toml +++ b/frame/aura/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-aura" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-application-crypto = { version = "2.0.0", default-features = false, path = "../../primitives/application-crypto" } diff --git a/frame/authority-discovery/Cargo.toml b/frame/authority-discovery/Cargo.toml index 3760d863d7..d8c72683ca 100644 --- a/frame/authority-discovery/Cargo.toml +++ b/frame/authority-discovery/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-authority-discovery" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-authority-discovery = { version = "2.0.0", default-features = false, path = "../../primitives/authority-discovery" } diff --git a/frame/authorship/Cargo.toml b/frame/authorship/Cargo.toml index 298da65a2b..124d66c1bc 100644 --- a/frame/authorship/Cargo.toml +++ b/frame/authorship/Cargo.toml @@ -4,6 +4,7 @@ version = "2.0.0" description = "Block and Uncle Author tracking for the SRML" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } diff --git a/frame/babe/Cargo.toml b/frame/babe/Cargo.toml index 30dbda4e53..590c1fe5bd 100644 --- a/frame/babe/Cargo.toml +++ b/frame/babe/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-babe" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] hex-literal = "0.2.1" diff --git a/frame/balances/Cargo.toml b/frame/balances/Cargo.toml index f9522b5379..f2e24dbae4 100644 --- a/frame/balances/Cargo.toml +++ b/frame/balances/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-balances" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true } diff --git a/frame/collective/Cargo.toml b/frame/collective/Cargo.toml index a2150b82dd..8f7ffa7653 100644 --- a/frame/collective/Cargo.toml +++ b/frame/collective/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-collective" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true } diff --git a/frame/contracts/Cargo.toml b/frame/contracts/Cargo.toml index d583809f0b..fa4c915cc8 100644 --- a/frame/contracts/Cargo.toml +++ b/frame/contracts/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-contracts" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } diff --git a/frame/contracts/rpc/Cargo.toml b/frame/contracts/rpc/Cargo.toml index 61eb55368e..7767a762f4 100644 --- a/frame/contracts/rpc/Cargo.toml +++ b/frame/contracts/rpc/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-contracts-rpc" version = "0.8.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0" } diff --git a/frame/contracts/rpc/runtime-api/Cargo.toml b/frame/contracts/rpc/runtime-api/Cargo.toml index e0cbd73f80..0f228bc99d 100644 --- a/frame/contracts/rpc/runtime-api/Cargo.toml +++ b/frame/contracts/rpc/runtime-api/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-contracts-rpc-runtime-api" version = "0.8.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-api = { version = "2.0.0", default-features = false, path = "../../../../primitives/api" } diff --git a/frame/democracy/Cargo.toml b/frame/democracy/Cargo.toml index 02145e8589..12d5dfc158 100644 --- a/frame/democracy/Cargo.toml +++ b/frame/democracy/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-democracy" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } diff --git a/frame/elections-phragmen/Cargo.toml b/frame/elections-phragmen/Cargo.toml index 9d0c3ed61c..f3cfc800f0 100644 --- a/frame/elections-phragmen/Cargo.toml +++ b/frame/elections-phragmen/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-elections-phragmen" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } diff --git a/frame/elections/Cargo.toml b/frame/elections/Cargo.toml index 495151018e..b7c98a65e1 100644 --- a/frame/elections/Cargo.toml +++ b/frame/elections/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-elections" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true } diff --git a/frame/evm/Cargo.toml b/frame/evm/Cargo.toml index 933b450ee4..b45bf6e31e 100644 --- a/frame/evm/Cargo.toml +++ b/frame/evm/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-evm" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } diff --git a/frame/example/Cargo.toml b/frame/example/Cargo.toml index fd80d8b8df..0d37940fc7 100644 --- a/frame/example/Cargo.toml +++ b/frame/example/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-example" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true } diff --git a/frame/executive/Cargo.toml b/frame/executive/Cargo.toml index b2b30edd1c..514fb68d6d 100644 --- a/frame/executive/Cargo.toml +++ b/frame/executive/Cargo.toml @@ -3,6 +3,7 @@ name = "frame-executive" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } diff --git a/frame/finality-tracker/Cargo.toml b/frame/finality-tracker/Cargo.toml index 22e1380e65..7c87df4e54 100644 --- a/frame/finality-tracker/Cargo.toml +++ b/frame/finality-tracker/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-finality-tracker" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", default-features = false, features = ["derive"] } diff --git a/frame/generic-asset/Cargo.toml b/frame/generic-asset/Cargo.toml index 87f4c9d1cf..cd236d7b7d 100644 --- a/frame/generic-asset/Cargo.toml +++ b/frame/generic-asset/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-generic-asset" version = "2.0.0" authors = ["Centrality Developers "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true } diff --git a/frame/grandpa/Cargo.toml b/frame/grandpa/Cargo.toml index ab5b34c91f..e67e64dd5f 100644 --- a/frame/grandpa/Cargo.toml +++ b/frame/grandpa/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-grandpa" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } diff --git a/frame/identity/Cargo.toml b/frame/identity/Cargo.toml index 7962c2a1c6..59e8f721c8 100644 --- a/frame/identity/Cargo.toml +++ b/frame/identity/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-identity" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true } diff --git a/frame/im-online/Cargo.toml b/frame/im-online/Cargo.toml index 5045509c77..46bff2dc35 100644 --- a/frame/im-online/Cargo.toml +++ b/frame/im-online/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-im-online" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-application-crypto = { version = "2.0.0", default-features = false, path = "../../primitives/application-crypto" } diff --git a/frame/indices/Cargo.toml b/frame/indices/Cargo.toml index bd83761ff1..839f668819 100644 --- a/frame/indices/Cargo.toml +++ b/frame/indices/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-indices" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true } diff --git a/frame/membership/Cargo.toml b/frame/membership/Cargo.toml index cc45cfb94c..719718505e 100644 --- a/frame/membership/Cargo.toml +++ b/frame/membership/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-membership" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true } diff --git a/frame/metadata/Cargo.toml b/frame/metadata/Cargo.toml index bcb90d2368..9cb6752926 100644 --- a/frame/metadata/Cargo.toml +++ b/frame/metadata/Cargo.toml @@ -3,6 +3,7 @@ name = "frame-metadata" version = "10.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } diff --git a/frame/nicks/Cargo.toml b/frame/nicks/Cargo.toml index 0dce684f0d..7c05080d49 100644 --- a/frame/nicks/Cargo.toml +++ b/frame/nicks/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-nicks" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true } diff --git a/frame/offences/Cargo.toml b/frame/offences/Cargo.toml index 36d057f4e9..f5486f35ff 100644 --- a/frame/offences/Cargo.toml +++ b/frame/offences/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-offences" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] pallet-balances = { version = "2.0.0", default-features = false, path = "../balances" } diff --git a/frame/randomness-collective-flip/Cargo.toml b/frame/randomness-collective-flip/Cargo.toml index 9e25ba4c57..56ff12d2df 100644 --- a/frame/randomness-collective-flip/Cargo.toml +++ b/frame/randomness-collective-flip/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-randomness-collective-flip" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] safe-mix = { version = "1.0", default-features = false } diff --git a/frame/recovery/Cargo.toml b/frame/recovery/Cargo.toml index 9f2f50ab06..645b1f2e98 100644 --- a/frame/recovery/Cargo.toml +++ b/frame/recovery/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-recovery" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true } diff --git a/frame/scored-pool/Cargo.toml b/frame/scored-pool/Cargo.toml index 0b4c2768df..c0935cd88b 100644 --- a/frame/scored-pool/Cargo.toml +++ b/frame/scored-pool/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-scored-pool" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } diff --git a/frame/session/Cargo.toml b/frame/session/Cargo.toml index aa9aaa1f44..06981240b1 100644 --- a/frame/session/Cargo.toml +++ b/frame/session/Cargo.toml @@ -2,7 +2,8 @@ name = "pallet-session" version = "2.0.0" authors = ["Parity Technologies "] -edition = "2018" +edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true } diff --git a/frame/society/Cargo.toml b/frame/society/Cargo.toml index 94000e898d..ac140c9714 100644 --- a/frame/society/Cargo.toml +++ b/frame/society/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-society" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true } diff --git a/frame/staking/Cargo.toml b/frame/staking/Cargo.toml index 52584cf47f..a38cc0416b 100644 --- a/frame/staking/Cargo.toml +++ b/frame/staking/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-staking" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true } diff --git a/frame/staking/reward-curve/Cargo.toml b/frame/staking/reward-curve/Cargo.toml index 0353476a95..0753400596 100644 --- a/frame/staking/reward-curve/Cargo.toml +++ b/frame/staking/reward-curve/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-staking-reward-curve" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [lib] proc-macro = true diff --git a/frame/sudo/Cargo.toml b/frame/sudo/Cargo.toml index c97d04f9c7..ac91129c57 100644 --- a/frame/sudo/Cargo.toml +++ b/frame/sudo/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-sudo" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true } diff --git a/frame/support/Cargo.toml b/frame/support/Cargo.toml index d8460ef7e8..77aa3aa168 100644 --- a/frame/support/Cargo.toml +++ b/frame/support/Cargo.toml @@ -3,6 +3,7 @@ name = "frame-support" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] log = "0.4" diff --git a/frame/support/procedural/Cargo.toml b/frame/support/procedural/Cargo.toml index 321002e08b..06a84750b5 100644 --- a/frame/support/procedural/Cargo.toml +++ b/frame/support/procedural/Cargo.toml @@ -3,6 +3,7 @@ name = "frame-support-procedural" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [lib] proc-macro = true diff --git a/frame/support/procedural/tools/Cargo.toml b/frame/support/procedural/tools/Cargo.toml index a9b8f6d4bf..4a1301e712 100644 --- a/frame/support/procedural/tools/Cargo.toml +++ b/frame/support/procedural/tools/Cargo.toml @@ -3,6 +3,7 @@ name = "frame-support-procedural-tools" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] frame-support-procedural-tools-derive = { version = "2.0.0", path = "./derive" } diff --git a/frame/support/procedural/tools/derive/Cargo.toml b/frame/support/procedural/tools/derive/Cargo.toml index 49aea10807..e65a7e0e5f 100644 --- a/frame/support/procedural/tools/derive/Cargo.toml +++ b/frame/support/procedural/tools/derive/Cargo.toml @@ -3,6 +3,7 @@ name = "frame-support-procedural-tools-derive" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [lib] proc-macro = true diff --git a/frame/support/test/Cargo.toml b/frame/support/test/Cargo.toml index 0c73dcd65e..71d3893426 100644 --- a/frame/support/test/Cargo.toml +++ b/frame/support/test/Cargo.toml @@ -3,6 +3,7 @@ name = "frame-support-test" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", default-features = false, features = ["derive"] } diff --git a/frame/system/Cargo.toml b/frame/system/Cargo.toml index 098c320f45..631d8eecb4 100644 --- a/frame/system/Cargo.toml +++ b/frame/system/Cargo.toml @@ -3,6 +3,7 @@ name = "frame-system" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } diff --git a/frame/system/rpc/runtime-api/Cargo.toml b/frame/system/rpc/runtime-api/Cargo.toml index f9beb848aa..6244032376 100644 --- a/frame/system/rpc/runtime-api/Cargo.toml +++ b/frame/system/rpc/runtime-api/Cargo.toml @@ -3,6 +3,7 @@ name = "frame-system-rpc-runtime-api" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-api = { version = "2.0.0", default-features = false, path = "../../../../primitives/api" } diff --git a/frame/timestamp/Cargo.toml b/frame/timestamp/Cargo.toml index 354a4740b7..f2d6f40582 100644 --- a/frame/timestamp/Cargo.toml +++ b/frame/timestamp/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-timestamp" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true } diff --git a/frame/transaction-payment/Cargo.toml b/frame/transaction-payment/Cargo.toml index ceb1ba9ebb..ac3dbb2c2b 100644 --- a/frame/transaction-payment/Cargo.toml +++ b/frame/transaction-payment/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-transaction-payment" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } diff --git a/frame/transaction-payment/rpc/Cargo.toml b/frame/transaction-payment/rpc/Cargo.toml index b8d1c35492..5fb5f5e274 100644 --- a/frame/transaction-payment/rpc/Cargo.toml +++ b/frame/transaction-payment/rpc/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-transaction-payment-rpc" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0" } diff --git a/frame/transaction-payment/rpc/runtime-api/Cargo.toml b/frame/transaction-payment/rpc/runtime-api/Cargo.toml index 3cf28bf662..8ee16a90dc 100644 --- a/frame/transaction-payment/rpc/runtime-api/Cargo.toml +++ b/frame/transaction-payment/rpc/runtime-api/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-transaction-payment-rpc-runtime-api" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } diff --git a/frame/treasury/Cargo.toml b/frame/treasury/Cargo.toml index 9fd76ddd9c..10226f3572 100644 --- a/frame/treasury/Cargo.toml +++ b/frame/treasury/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-treasury" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } diff --git a/frame/utility/Cargo.toml b/frame/utility/Cargo.toml index afd7ae3d37..6d1187b0ee 100644 --- a/frame/utility/Cargo.toml +++ b/frame/utility/Cargo.toml @@ -3,6 +3,7 @@ name = "pallet-utility" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true } diff --git a/primitives/allocator/Cargo.toml b/primitives/allocator/Cargo.toml index 737fa91273..3cfc9a4de6 100644 --- a/primitives/allocator/Cargo.toml +++ b/primitives/allocator/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-allocator" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-std = { version = "2.0.0", path = "../std", default-features = false } diff --git a/primitives/api/Cargo.toml b/primitives/api/Cargo.toml index b9f736570a..f6966f9462 100644 --- a/primitives/api/Cargo.toml +++ b/primitives/api/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-api" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } diff --git a/primitives/api/proc-macro/Cargo.toml b/primitives/api/proc-macro/Cargo.toml index 122c889add..cb9f2e4599 100644 --- a/primitives/api/proc-macro/Cargo.toml +++ b/primitives/api/proc-macro/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-api-proc-macro" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [lib] proc-macro = true diff --git a/primitives/api/test/Cargo.toml b/primitives/api/test/Cargo.toml index 5892063bd1..c193c9dc5e 100644 --- a/primitives/api/test/Cargo.toml +++ b/primitives/api/test/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-api-test" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-api = { version = "2.0.0", path = "../" } diff --git a/primitives/application-crypto/Cargo.toml b/primitives/application-crypto/Cargo.toml index f6487ebc29..9377bcff8a 100644 --- a/primitives/application-crypto/Cargo.toml +++ b/primitives/application-crypto/Cargo.toml @@ -4,6 +4,7 @@ version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" description = "Provides facilities for generating application specific crypto wrapper types." +license = "GPL-3.0" [dependencies] sp-core = { version = "2.0.0", default-features = false, path = "../core" } diff --git a/primitives/application-crypto/test/Cargo.toml b/primitives/application-crypto/test/Cargo.toml index 1931e6f84b..de4412db2d 100644 --- a/primitives/application-crypto/test/Cargo.toml +++ b/primitives/application-crypto/test/Cargo.toml @@ -4,6 +4,7 @@ version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" description = "Integration tests for application-crypto" +license = "GPL-3.0" publish = false [dependencies] diff --git a/primitives/arithmetic/Cargo.toml b/primitives/arithmetic/Cargo.toml index 71be14862a..1b6d36ca37 100644 --- a/primitives/arithmetic/Cargo.toml +++ b/primitives/arithmetic/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-arithmetic" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } diff --git a/primitives/arithmetic/fuzzer/Cargo.toml b/primitives/arithmetic/fuzzer/Cargo.toml index e8568db370..56e789f3e4 100644 --- a/primitives/arithmetic/fuzzer/Cargo.toml +++ b/primitives/arithmetic/fuzzer/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-arithmetic-fuzzer" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-arithmetic = { version = "2.0.0", path = ".." } diff --git a/primitives/authority-discovery/Cargo.toml b/primitives/authority-discovery/Cargo.toml index 516ea413ac..44a7cad155 100644 --- a/primitives/authority-discovery/Cargo.toml +++ b/primitives/authority-discovery/Cargo.toml @@ -4,6 +4,7 @@ version = "2.0.0" authors = ["Parity Technologies "] description = "Authority discovery primitives" edition = "2018" +license = "GPL-3.0" [dependencies] sp-application-crypto = { version = "2.0.0", default-features = false, path = "../application-crypto" } diff --git a/primitives/authorship/Cargo.toml b/primitives/authorship/Cargo.toml index d8ddbb7a92..7dc5fcfc95 100644 --- a/primitives/authorship/Cargo.toml +++ b/primitives/authorship/Cargo.toml @@ -4,6 +4,7 @@ version = "2.0.0" authors = ["Parity Technologies "] description = "Authorship primitives" edition = "2018" +license = "GPL-3.0" [dependencies] sp-inherents = { version = "2.0.0", default-features = false, path = "../inherents" } diff --git a/primitives/block-builder/Cargo.toml b/primitives/block-builder/Cargo.toml index 5bbe9ea123..1700209ec4 100644 --- a/primitives/block-builder/Cargo.toml +++ b/primitives/block-builder/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-block-builder" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-runtime = { version = "2.0.0", default-features = false, path = "../runtime" } diff --git a/primitives/blockchain/Cargo.toml b/primitives/blockchain/Cargo.toml index a3c442094d..cd8ee78394 100644 --- a/primitives/blockchain/Cargo.toml +++ b/primitives/blockchain/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-blockchain" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] log = "0.4.8" diff --git a/primitives/consensus/aura/Cargo.toml b/primitives/consensus/aura/Cargo.toml index 57958ed851..6e05bf4aac 100644 --- a/primitives/consensus/aura/Cargo.toml +++ b/primitives/consensus/aura/Cargo.toml @@ -4,6 +4,7 @@ version = "0.8.0" authors = ["Parity Technologies "] description = "Primitives for Aura consensus" edition = "2018" +license = "GPL-3.0" [dependencies] sp-application-crypto = { version = "2.0.0", default-features = false, path = "../../application-crypto" } diff --git a/primitives/consensus/babe/Cargo.toml b/primitives/consensus/babe/Cargo.toml index 11c186faa9..7f0277a720 100644 --- a/primitives/consensus/babe/Cargo.toml +++ b/primitives/consensus/babe/Cargo.toml @@ -4,6 +4,7 @@ version = "0.8.0" authors = ["Parity Technologies "] description = "Primitives for BABE consensus" edition = "2018" +license = "GPL-3.0" [dependencies] sp-application-crypto = { version = "2.0.0", default-features = false, path = "../../application-crypto" } diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index d60f170b83..3ac89ec70c 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -4,6 +4,7 @@ version = "0.8.0" authors = ["Parity Technologies "] description = "Common utilities for substrate consensus" edition = "2018" +license = "GPL-3.0" [dependencies] derive_more = "0.99.2" diff --git a/primitives/consensus/pow/Cargo.toml b/primitives/consensus/pow/Cargo.toml index 12e97890d7..8e964e0c18 100644 --- a/primitives/consensus/pow/Cargo.toml +++ b/primitives/consensus/pow/Cargo.toml @@ -4,6 +4,7 @@ version = "0.8.0" authors = ["Parity Technologies "] description = "Primitives for Aura consensus" edition = "2018" +license = "GPL-3.0" [dependencies] sp-api = { version = "2.0.0", default-features = false, path = "../../api" } diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index f7eec82e55..0cc7498184 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-core" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-std = { version = "2.0.0", default-features = false, path = "../std" } diff --git a/primitives/debug-derive/Cargo.toml b/primitives/debug-derive/Cargo.toml index 9c65cb34f5..9b12bfb205 100644 --- a/primitives/debug-derive/Cargo.toml +++ b/primitives/debug-derive/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-debug-derive" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [lib] proc-macro = true diff --git a/primitives/finality-grandpa/Cargo.toml b/primitives/finality-grandpa/Cargo.toml index c2856e524f..dfa6b572d8 100644 --- a/primitives/finality-grandpa/Cargo.toml +++ b/primitives/finality-grandpa/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-finality-grandpa" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] app-crypto = { version = "2.0.0", default-features = false, package = "sp-application-crypto", path = "../application-crypto" } diff --git a/primitives/finality-tracker/Cargo.toml b/primitives/finality-tracker/Cargo.toml index 3245803945..1b0e81da91 100644 --- a/primitives/finality-tracker/Cargo.toml +++ b/primitives/finality-tracker/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-finality-tracker" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } diff --git a/primitives/inherents/Cargo.toml b/primitives/inherents/Cargo.toml index 0dc465e288..18fa8412f3 100644 --- a/primitives/inherents/Cargo.toml +++ b/primitives/inherents/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-inherents" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] parking_lot = { version = "0.9.0", optional = true } diff --git a/primitives/io/Cargo.toml b/primitives/io/Cargo.toml index 2f03f230ef..7d831cdfeb 100644 --- a/primitives/io/Cargo.toml +++ b/primitives/io/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-io" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.6", default-features = false } diff --git a/primitives/keyring/Cargo.toml b/primitives/keyring/Cargo.toml index 61ebf89ad2..e2603a0262 100644 --- a/primitives/keyring/Cargo.toml +++ b/primitives/keyring/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-keyring" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-core = { version = "2.0.0", path = "../core" } diff --git a/primitives/panic-handler/Cargo.toml b/primitives/panic-handler/Cargo.toml index 19e34352cf..0fb6e3b173 100644 --- a/primitives/panic-handler/Cargo.toml +++ b/primitives/panic-handler/Cargo.toml @@ -4,6 +4,7 @@ version = "2.0.0" authors = ["Parity Technologies "] description = "Substrate panic handler." edition = "2018" +license = "GPL-3.0" [dependencies] backtrace = "0.3.38" diff --git a/primitives/phragmen/Cargo.toml b/primitives/phragmen/Cargo.toml index 92807376de..3bfff32d2a 100644 --- a/primitives/phragmen/Cargo.toml +++ b/primitives/phragmen/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-phragmen" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } diff --git a/primitives/rpc/Cargo.toml b/primitives/rpc/Cargo.toml index 33a854e6b7..448f8b8c9c 100644 --- a/primitives/rpc/Cargo.toml +++ b/primitives/rpc/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-rpc" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", features = ["derive"] } diff --git a/primitives/runtime-interface/Cargo.toml b/primitives/runtime-interface/Cargo.toml index 7ed2257556..30e9ae6bd6 100644 --- a/primitives/runtime-interface/Cargo.toml +++ b/primitives/runtime-interface/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-runtime-interface" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-wasm-interface = { version = "2.0.0", optional = true, path = "../wasm-interface" } diff --git a/primitives/runtime-interface/proc-macro/Cargo.toml b/primitives/runtime-interface/proc-macro/Cargo.toml index a5d12de0a6..b239fbcce3 100644 --- a/primitives/runtime-interface/proc-macro/Cargo.toml +++ b/primitives/runtime-interface/proc-macro/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-runtime-interface-proc-macro" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [lib] proc-macro = true diff --git a/primitives/runtime-interface/test-wasm/Cargo.toml b/primitives/runtime-interface/test-wasm/Cargo.toml index b3a400a12d..c38413aee7 100644 --- a/primitives/runtime-interface/test-wasm/Cargo.toml +++ b/primitives/runtime-interface/test-wasm/Cargo.toml @@ -4,6 +4,7 @@ version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" +license = "GPL-3.0" [dependencies] sp-runtime-interface = { version = "2.0.0", default-features = false, path = "../" } diff --git a/primitives/runtime-interface/test/Cargo.toml b/primitives/runtime-interface/test/Cargo.toml index f0a4c0edd4..d6d724da9d 100644 --- a/primitives/runtime-interface/test/Cargo.toml +++ b/primitives/runtime-interface/test/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-runtime-interface-test" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" publish = false [dependencies] diff --git a/primitives/runtime/Cargo.toml b/primitives/runtime/Cargo.toml index 2574fef4b9..7046975416 100644 --- a/primitives/runtime/Cargo.toml +++ b/primitives/runtime/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-runtime" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } diff --git a/primitives/sandbox/Cargo.toml b/primitives/sandbox/Cargo.toml index 5d161a6deb..071ac2ba7b 100755 --- a/primitives/sandbox/Cargo.toml +++ b/primitives/sandbox/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-sandbox" version = "0.8.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] wasmi = { version = "0.6.2", optional = true } diff --git a/primitives/serializer/Cargo.toml b/primitives/serializer/Cargo.toml index 39fdeb0e7e..b9e78d968c 100644 --- a/primitives/serializer/Cargo.toml +++ b/primitives/serializer/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-serializer" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] serde = "1.0.101" diff --git a/primitives/session/Cargo.toml b/primitives/session/Cargo.toml index 24475e9414..143ff87942 100644 --- a/primitives/session/Cargo.toml +++ b/primitives/session/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-session" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-api = { version = "2.0.0", default-features = false, path = "../api" } diff --git a/primitives/staking/Cargo.toml b/primitives/staking/Cargo.toml index 35725c72e3..97afa0d0a7 100644 --- a/primitives/staking/Cargo.toml +++ b/primitives/staking/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-staking" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } diff --git a/primitives/state-machine/Cargo.toml b/primitives/state-machine/Cargo.toml index d390471aca..a856146667 100644 --- a/primitives/state-machine/Cargo.toml +++ b/primitives/state-machine/Cargo.toml @@ -4,6 +4,7 @@ version = "0.8.0" authors = ["Parity Technologies "] description = "Substrate State Machine" edition = "2018" +license = "GPL-3.0" [dependencies] log = "0.4.8" diff --git a/primitives/std/Cargo.toml b/primitives/std/Cargo.toml index 7fdf7d1144..dd4b7e4511 100644 --- a/primitives/std/Cargo.toml +++ b/primitives/std/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-std" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [features] default = ["std"] diff --git a/primitives/storage/Cargo.toml b/primitives/storage/Cargo.toml index 384519cc1d..c9fda1816b 100644 --- a/primitives/storage/Cargo.toml +++ b/primitives/storage/Cargo.toml @@ -4,6 +4,7 @@ version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" description = "Storage related primitives" +license = "GPL-3.0" [dependencies] sp-std = { version = "2.0.0", default-features = false, path = "../std" } diff --git a/primitives/test-primitives/Cargo.toml b/primitives/test-primitives/Cargo.toml index 5c2f2dcc0a..ba19eb00f3 100644 --- a/primitives/test-primitives/Cargo.toml +++ b/primitives/test-primitives/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-test-primitives" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-application-crypto = { version = "2.0.0", default-features = false, path = "../application-crypto" } diff --git a/primitives/timestamp/Cargo.toml b/primitives/timestamp/Cargo.toml index ee86d6e3bc..fa146ebd6f 100644 --- a/primitives/timestamp/Cargo.toml +++ b/primitives/timestamp/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-timestamp" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sp-api = { version = "2.0.0", default-features = false, path = "../api" } diff --git a/primitives/transaction-pool/Cargo.toml b/primitives/transaction-pool/Cargo.toml index 3a3e15e611..18b254f2c0 100644 --- a/primitives/transaction-pool/Cargo.toml +++ b/primitives/transaction-pool/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-transaction-pool" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", optional = true } diff --git a/primitives/version/Cargo.toml b/primitives/version/Cargo.toml index 784051b56e..1219d9840c 100644 --- a/primitives/version/Cargo.toml +++ b/primitives/version/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-version" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] impl-serde = { version = "0.2.3", optional = true } diff --git a/primitives/wasm-interface/Cargo.toml b/primitives/wasm-interface/Cargo.toml index dc17a8afbe..b97e3040aa 100644 --- a/primitives/wasm-interface/Cargo.toml +++ b/primitives/wasm-interface/Cargo.toml @@ -3,6 +3,7 @@ name = "sp-wasm-interface" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] wasmi = { version = "0.6.2", optional = true } diff --git a/test-utils/Cargo.toml b/test-utils/Cargo.toml index ac4c995419..0a552973c9 100644 --- a/test-utils/Cargo.toml +++ b/test-utils/Cargo.toml @@ -3,3 +3,4 @@ name = "substrate-test-utils" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" diff --git a/test-utils/client/Cargo.toml b/test-utils/client/Cargo.toml index 8b1ebc39f4..2107f3bdd8 100644 --- a/test-utils/client/Cargo.toml +++ b/test-utils/client/Cargo.toml @@ -3,6 +3,7 @@ name = "substrate-test-client" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sc-client-api = { version = "2.0.0", path = "../../client/api" } diff --git a/test-utils/runtime/Cargo.toml b/test-utils/runtime/Cargo.toml index b827163a1b..e0d8aa77b7 100644 --- a/test-utils/runtime/Cargo.toml +++ b/test-utils/runtime/Cargo.toml @@ -4,6 +4,7 @@ version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" +license = "GPL-3.0" [dependencies] sp-application-crypto = { version = "2.0.0", default-features = false, path = "../../primitives/application-crypto" } diff --git a/test-utils/runtime/client/Cargo.toml b/test-utils/runtime/client/Cargo.toml index aa33f55012..643cde16b3 100644 --- a/test-utils/runtime/client/Cargo.toml +++ b/test-utils/runtime/client/Cargo.toml @@ -3,6 +3,7 @@ name = "substrate-test-runtime-client" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sc-block-builder = { version = "0.8", path = "../../../client/block-builder" } diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index 15ad771b45..36f21f192b 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -4,6 +4,7 @@ version = "0.8.0" authors = ["Parity Technologies "] description = "Utilities for creating a browser light-client." edition = "2018" +license = "GPL-3.0" [dependencies] futures = "0.3" diff --git a/utils/build-script-utils/Cargo.toml b/utils/build-script-utils/Cargo.toml index 36703ab838..8c94edd527 100644 --- a/utils/build-script-utils/Cargo.toml +++ b/utils/build-script-utils/Cargo.toml @@ -3,5 +3,6 @@ name = "substrate-build-script-utils" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] diff --git a/utils/fork-tree/Cargo.toml b/utils/fork-tree/Cargo.toml index fa37161dc2..0ac0fb6522 100644 --- a/utils/fork-tree/Cargo.toml +++ b/utils/fork-tree/Cargo.toml @@ -3,6 +3,7 @@ name = "fork-tree" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } diff --git a/utils/frame/rpc/support/Cargo.toml b/utils/frame/rpc/support/Cargo.toml index 19451743cd..3b4339496a 100644 --- a/utils/frame/rpc/support/Cargo.toml +++ b/utils/frame/rpc/support/Cargo.toml @@ -3,6 +3,7 @@ name = "substrate-frame-rpc-support" version = "2.0.0" authors = ["Parity Technologies ", "Andrew Dirksen "] edition = "2018" +license = "GPL-3.0" [dependencies] futures = { version = "0.3.0", features = ["compat"] } diff --git a/utils/frame/rpc/system/Cargo.toml b/utils/frame/rpc/system/Cargo.toml index 39f7735eed..818794f846 100644 --- a/utils/frame/rpc/system/Cargo.toml +++ b/utils/frame/rpc/system/Cargo.toml @@ -3,6 +3,7 @@ name = "substrate-frame-rpc-system" version = "2.0.0" authors = ["Parity Technologies "] edition = "2018" +license = "GPL-3.0" [dependencies] sc-client = { version = "0.8", path = "../../../../client/" } -- GitLab From aa2cf01249c356c664c27c175db5d1eb2f84fe70 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 29 Jan 2020 13:26:09 +0100 Subject: [PATCH 039/180] doc (#4761) --- frame/support/src/storage/generator/linked_map.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frame/support/src/storage/generator/linked_map.rs b/frame/support/src/storage/generator/linked_map.rs index 14bef77c9e..face87edf9 100644 --- a/frame/support/src/storage/generator/linked_map.rs +++ b/frame/support/src/storage/generator/linked_map.rs @@ -433,6 +433,8 @@ where } } + /// The translation happens in-place, new keys are inserted at the same time as old keys are + /// removed, thus new keys must not collide with still remaining old keys. fn translate(translate_key: TK, translate_val: TV) -> Result<(), Option> where K2: FullCodec + Clone, V2: Decode, TK: Fn(K2) -> K, TV: Fn(V2) -> V { -- GitLab From 5dfd4f24fee5e1117dc74f6b971a0d0a510844de Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Wed, 29 Jan 2020 13:27:23 +0100 Subject: [PATCH 040/180] Clean up indentation problems (#4762) --- client/api/src/light.rs | 12 ++-- client/consensus/aura/src/lib.rs | 2 +- client/executor/src/integration_tests/mod.rs | 2 +- client/rpc/src/state/state_light.rs | 2 +- client/service/src/builder.rs | 2 +- .../transaction-pool/graph/benches/basics.rs | 2 +- frame/contracts/src/wasm/prepare.rs | 2 +- primitives/arithmetic/benches/bench.rs | 6 +- primitives/core/benches/bench.rs | 6 +- primitives/phragmen/benches/phragmen.rs | 8 +-- primitives/runtime/src/generic/era.rs | 16 ++--- primitives/state-machine/src/stats.rs | 62 +++++++++---------- 12 files changed, 61 insertions(+), 61 deletions(-) diff --git a/client/api/src/light.rs b/client/api/src/light.rs index fc9b6dc6fd..c0bebc1740 100644 --- a/client/api/src/light.rs +++ b/client/api/src/light.rs @@ -21,10 +21,10 @@ use std::collections::{BTreeMap, HashMap}; use std::future::Future; use sp_runtime::{ - traits::{ - Block as BlockT, Header as HeaderT, NumberFor, - }, - generic::BlockId + traits::{ + Block as BlockT, Header as HeaderT, NumberFor, + }, + generic::BlockId }; use sp_core::ChangesTrieConfigurationRange; use sp_state_machine::StorageProof; @@ -307,8 +307,8 @@ pub trait RemoteBlockchain: Send + Sync { pub mod tests { use futures::future::Ready; use parking_lot::Mutex; - use sp_blockchain::Error as ClientError; - use sp_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/consensus/aura/src/lib.rs b/client/consensus/aura/src/lib.rs index 270bd19422..4b107d87d5 100644 --- a/client/consensus/aura/src/lib.rs +++ b/client/consensus/aura/src/lib.rs @@ -65,7 +65,7 @@ use sp_timestamp::{ use sc_telemetry::{telemetry, CONSENSUS_TRACE, CONSENSUS_DEBUG, CONSENSUS_INFO}; use sc_consensus_slots::{ - CheckedHeader, SlotWorker, SlotInfo, SlotCompatible, StorageChanges, check_equivocation, + CheckedHeader, SlotWorker, SlotInfo, SlotCompatible, StorageChanges, check_equivocation, }; use sc_keystore::KeyStorePtr; diff --git a/client/executor/src/integration_tests/mod.rs b/client/executor/src/integration_tests/mod.rs index ef8171e5ad..02a5897ea4 100644 --- a/client/executor/src/integration_tests/mod.rs +++ b/client/executor/src/integration_tests/mod.rs @@ -72,7 +72,7 @@ fn call_not_existing_function(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); let mut ext = ext.ext(); - match call_in_wasm( + match call_in_wasm( "test_calling_missing_external", &[], wasm_method, diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index 482eb0723f..cc3d1a4951 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -708,7 +708,7 @@ fn ignore_error(future: F) -> impl std::future::Future, number: u64) { fn benchmark_main(c: &mut Criterion) { - c.bench_function("sequential 50 tx", |b| { + c.bench_function("sequential 50 tx", |b| { b.iter(|| { bench_configured(Pool::new(Default::default(), TestApi::new_dependant().into()), 50); }); diff --git a/frame/contracts/src/wasm/prepare.rs b/frame/contracts/src/wasm/prepare.rs index 39e1fca79d..ba934f353e 100644 --- a/frame/contracts/src/wasm/prepare.rs +++ b/frame/contracts/src/wasm/prepare.rs @@ -76,7 +76,7 @@ impl<'a> ContractModule<'a> { /// Ensures that tables declared in the module are not too big. fn ensure_table_size_limit(&self, limit: u32) -> Result<(), &'static str> { - if let Some(table_section) = self.module.table_section() { + if let Some(table_section) = self.module.table_section() { // In Wasm MVP spec, there may be at most one table declared. Double check this // explicitly just in case the Wasm version changes. if table_section.entries().len() > 1 { diff --git a/primitives/arithmetic/benches/bench.rs b/primitives/arithmetic/benches/bench.rs index 1025e883ef..1dbcf260af 100644 --- a/primitives/arithmetic/benches/bench.rs +++ b/primitives/arithmetic/benches/bench.rs @@ -73,8 +73,8 @@ fn bench_division(c: &mut Criterion) { } criterion_group!{ - name = benches; - config = Criterion::default(); - targets = bench_addition, bench_subtraction, bench_multiplication, bench_division + name = benches; + config = Criterion::default(); + targets = bench_addition, bench_subtraction, bench_multiplication, bench_division } criterion_main!(benches); diff --git a/primitives/core/benches/bench.rs b/primitives/core/benches/bench.rs index 36728742d8..7096cd6c19 100644 --- a/primitives/core/benches/bench.rs +++ b/primitives/core/benches/bench.rs @@ -87,8 +87,8 @@ fn bench_ed25519(c: &mut Criterion) { } criterion_group!{ - name = benches; - config = Criterion::default().warm_up_time(Duration::from_millis(500)).without_plots(); - targets = bench_hash_128_fix_size, bench_hash_128_dyn_size, bench_ed25519 + name = benches; + config = Criterion::default().warm_up_time(Duration::from_millis(500)).without_plots(); + targets = bench_hash_128_fix_size, bench_hash_128_dyn_size, bench_ed25519 } criterion_main!(benches); diff --git a/primitives/phragmen/benches/phragmen.rs b/primitives/phragmen/benches/phragmen.rs index 7bebda564e..aa99e6f384 100644 --- a/primitives/phragmen/benches/phragmen.rs +++ b/primitives/phragmen/benches/phragmen.rs @@ -158,8 +158,8 @@ fn do_phragmen( macro_rules! phragmen_benches { ($($name:ident: $tup:expr,)*) => { $( - #[bench] - fn $name(b: &mut Bencher) { + #[bench] + fn $name(b: &mut Bencher) { let (v, n, t, e, eq_iter, eq_tol) = $tup; println!("----------------------"); println!( @@ -168,8 +168,8 @@ macro_rules! phragmen_benches { v, n, e, e * n, t, eq_iter, eq_tol, ); do_phragmen(b, v, n, t, e, eq_iter, eq_tol); - } - )* + } + )* } } diff --git a/primitives/runtime/src/generic/era.rs b/primitives/runtime/src/generic/era.rs index 238130db00..37b4b495fe 100644 --- a/primitives/runtime/src/generic/era.rs +++ b/primitives/runtime/src/generic/era.rs @@ -47,14 +47,14 @@ pub enum Era { } /* -E.g. with period == 4: -0 10 20 30 40 -0123456789012345678901234567890123456789012 - |...| - authored -/ \- expiry -phase = 1 -n = Q(current - phase, period) + phase -*/ + * E.g. with period == 4: + * 0 10 20 30 40 + * 0123456789012345678901234567890123456789012 + * |...| + * authored -/ \- expiry + * phase = 1 + * n = Q(current - phase, period) + phase + */ impl Era { /// Create a new era based on a period (which should be a power of two between 4 and 65536 inclusive) /// and a block number on which it should start (or, for long periods, be shortly after the start). diff --git a/primitives/state-machine/src/stats.rs b/primitives/state-machine/src/stats.rs index 38286be545..aa69b5be9d 100644 --- a/primitives/state-machine/src/stats.rs +++ b/primitives/state-machine/src/stats.rs @@ -21,42 +21,42 @@ use std::time::{Instant, Duration}; /// Measured count of operations and total bytes. #[derive(Clone, Debug, Default)] pub struct UsageUnit { - /// Number of operations. - pub ops: u64, - /// Number of bytes. - pub bytes: u64, + /// Number of operations. + pub ops: u64, + /// Number of bytes. + pub bytes: u64, } /// Usage statistics for state backend. #[derive(Clone, Debug)] pub struct UsageInfo { - /// Read statistics (total). - pub reads: UsageUnit, - /// Write statistics. - pub writes: UsageUnit, - /// Cache read statistics. - pub cache_reads: UsageUnit, - /// Memory used. - pub memory: usize, - - /// Moment at which current statistics has been started being collected. - pub started: Instant, - /// Timespan of the statistics. - pub span: Duration, + /// Read statistics (total). + pub reads: UsageUnit, + /// Write statistics. + pub writes: UsageUnit, + /// Cache read statistics. + pub cache_reads: UsageUnit, + /// Memory used. + pub memory: usize, + + /// Moment at which current statistics has been started being collected. + pub started: Instant, + /// Timespan of the statistics. + pub span: Duration, } impl UsageInfo { - /// Empty statistics. - /// - /// Means no data was collected. - pub fn empty() -> Self { - Self { - reads: UsageUnit::default(), - writes: UsageUnit::default(), - cache_reads: UsageUnit::default(), - memory: 0, - started: Instant::now(), - span: Default::default(), - } - } -} \ No newline at end of file + /// Empty statistics. + /// + /// Means no data was collected. + pub fn empty() -> Self { + Self { + reads: UsageUnit::default(), + writes: UsageUnit::default(), + cache_reads: UsageUnit::default(), + memory: 0, + started: Instant::now(), + span: Default::default(), + } + } +} -- GitLab From 89e079f48c32d05dde59509f058d0670613f37b5 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Wed, 29 Jan 2020 13:36:52 +0100 Subject: [PATCH 041/180] LinkedMap doesn't implement StoragePrefixedMap (#4760) * LinkedMap doesn't implement StoragePrefixedMap * fix test --- .../support/procedural/src/storage/storage_struct.rs | 12 ------------ frame/support/test/tests/final_keys.rs | 6 ------ 2 files changed, 18 deletions(-) diff --git a/frame/support/procedural/src/storage/storage_struct.rs b/frame/support/procedural/src/storage/storage_struct.rs index e44863b157..91bdf7bf87 100644 --- a/frame/support/procedural/src/storage/storage_struct.rs +++ b/frame/support/procedural/src/storage/storage_struct.rs @@ -167,18 +167,6 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre ); 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 { diff --git a/frame/support/test/tests/final_keys.rs b/frame/support/test/tests/final_keys.rs index 15ee65b627..e604038f4e 100644 --- a/frame/support/test/tests/final_keys.rs +++ b/frame/support/test/tests/final_keys.rs @@ -112,13 +112,11 @@ fn final_keys_no_instance() { 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 = [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 = [twox_128(b"FinalKeysNone"), twox_128(b"DoubleMap")].concat(); @@ -163,13 +161,11 @@ fn final_keys_default_instance() { 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 = [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 = [twox_128(b"FinalKeysSome"), twox_128(b"DoubleMap")].concat(); @@ -214,13 +210,11 @@ fn final_keys_instance_2() { 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 = [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 = [twox_128(b"Instance2FinalKeysSome"), twox_128(b"DoubleMap")].concat(); -- GitLab From 922b36c8eb6d971fbe2b72d69099a291a368ea25 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Wed, 29 Jan 2020 13:38:46 +0100 Subject: [PATCH 042/180] Revamp some of the weights (#4759) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove free transaction dos vectors. * Bump spec version * Indentation. * Update frame/support/src/weights.rs Co-authored-by: Bastian Köcher --- bin/node/runtime/src/lib.rs | 6 +++--- frame/executive/src/lib.rs | 2 +- frame/identity/src/lib.rs | 2 +- frame/nicks/src/lib.rs | 4 ++-- frame/staking/src/lib.rs | 14 +++++++------- frame/sudo/src/lib.rs | 2 +- frame/support/src/weights.rs | 15 +++++---------- frame/transaction-payment/src/lib.rs | 4 ++-- 8 files changed, 22 insertions(+), 27 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index afd2631373..bad1ea4174 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -77,11 +77,11 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { impl_name: create_runtime_str!("substrate-node"), authoring_version: 10, // Per convention: if the runtime behavior changes, increment spec_version - // and set impl_version to equal spec_version. If only runtime + // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 207, - impl_version: 208, + spec_version: 208, + impl_version: 0, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 96c79c1073..cafb9fad27 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -385,7 +385,7 @@ mod tests { fn some_root_operation(origin) { let _ = frame_system::ensure_root(origin); } - #[weight = SimpleDispatchInfo::FreeNormal] + #[weight = SimpleDispatchInfo::InsecureFreeNormal] fn some_unsigned_message(origin) { let _ = frame_system::ensure_none(origin); } diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index 0bcc33b217..631d77d0bf 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -842,7 +842,7 @@ decl_module! { /// - `S + 2` storage mutations. /// - One event. /// # - #[weight = SimpleDispatchInfo::FreeOperational] + #[weight = SimpleDispatchInfo::FixedNormal(100_000)] fn kill_identity(origin, target: ::Source) { T::ForceOrigin::try_origin(origin) .map(|_| ()) diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index 79365ff713..1067e9a5de 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -194,7 +194,7 @@ decl_module! { /// - One storage read/write. /// - One event. /// # - #[weight = SimpleDispatchInfo::FreeOperational] + #[weight = SimpleDispatchInfo::FixedNormal(70_000)] fn kill_name(origin, target: ::Source) { T::ForceOrigin::try_origin(origin) .map(|_| ()) @@ -222,7 +222,7 @@ decl_module! { /// - One storage read/write. /// - One event. /// # - #[weight = SimpleDispatchInfo::FreeOperational] + #[weight = SimpleDispatchInfo::FixedNormal(70_000)] fn force_name(origin, target: ::Source, name: Vec) { T::ForceOrigin::try_origin(origin) .map(|_| ()) diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 21ac24bc68..757f75bf0a 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -1150,7 +1150,7 @@ decl_module! { } /// The ideal number of validators. - #[weight = SimpleDispatchInfo::FreeOperational] + #[weight = SimpleDispatchInfo::FixedNormal(5_000)] fn set_validator_count(origin, #[compact] new: u32) { ensure_root(origin)?; ValidatorCount::put(new); @@ -1163,7 +1163,7 @@ decl_module! { /// # /// - No arguments. /// # - #[weight = SimpleDispatchInfo::FreeOperational] + #[weight = SimpleDispatchInfo::FixedNormal(5_000)] fn force_no_eras(origin) { ensure_root(origin)?; ForceEra::put(Forcing::ForceNone); @@ -1175,21 +1175,21 @@ decl_module! { /// # /// - No arguments. /// # - #[weight = SimpleDispatchInfo::FreeOperational] + #[weight = SimpleDispatchInfo::FixedNormal(5_000)] fn force_new_era(origin) { ensure_root(origin)?; ForceEra::put(Forcing::ForceNew); } /// Set the validators who cannot be slashed (if any). - #[weight = SimpleDispatchInfo::FreeOperational] + #[weight = SimpleDispatchInfo::FixedNormal(5_000)] fn set_invulnerables(origin, validators: Vec) { ensure_root(origin)?; >::put(validators); } /// Force a current staker to become completely unstaked, immediately. - #[weight = SimpleDispatchInfo::FreeOperational] + #[weight = SimpleDispatchInfo::FixedNormal(10_000)] fn force_unstake(origin, stash: T::AccountId) { ensure_root(origin)?; @@ -1204,7 +1204,7 @@ decl_module! { /// # /// - One storage write /// # - #[weight = SimpleDispatchInfo::FreeOperational] + #[weight = SimpleDispatchInfo::FixedNormal(5_000)] fn force_new_era_always(origin) { ensure_root(origin)?; ForceEra::put(Forcing::ForceAlways); @@ -1217,7 +1217,7 @@ decl_module! { /// # /// - One storage write. /// # - #[weight = SimpleDispatchInfo::FreeOperational] + #[weight = SimpleDispatchInfo::FixedNormal(1_000_000)] fn cancel_deferred_slash(origin, era: EraIndex, slash_indices: Vec) { T::SlashCancelOrigin::try_origin(origin) .map(|_| ()) diff --git a/frame/sudo/src/lib.rs b/frame/sudo/src/lib.rs index ea436e2629..e69840e158 100644 --- a/frame/sudo/src/lib.rs +++ b/frame/sudo/src/lib.rs @@ -119,7 +119,7 @@ decl_module! { /// - One DB write (event). /// - Unknown weight of derivative `proposal` execution. /// # - #[weight = SimpleDispatchInfo::FreeOperational] + #[weight = SimpleDispatchInfo::FixedNormal(50_000)] 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)?; diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index e44ab16458..34166c368c 100644 --- a/frame/support/src/weights.rs +++ b/frame/support/src/weights.rs @@ -127,11 +127,10 @@ impl From for DispatchClass { match tx { SimpleDispatchInfo::FixedOperational(_) => DispatchClass::Operational, SimpleDispatchInfo::MaxOperational => DispatchClass::Operational, - SimpleDispatchInfo::FreeOperational => DispatchClass::Operational, SimpleDispatchInfo::FixedNormal(_) => DispatchClass::Normal, SimpleDispatchInfo::MaxNormal => DispatchClass::Normal, - SimpleDispatchInfo::FreeNormal => DispatchClass::Normal, + SimpleDispatchInfo::InsecureFreeNormal => DispatchClass::Normal, } } } @@ -178,14 +177,12 @@ pub enum SimpleDispatchInfo { FixedNormal(Weight), /// A normal dispatch with the maximum weight. MaxNormal, - /// A normal dispatch with no weight. - FreeNormal, + /// A normal dispatch with no weight. Base and bytes fees still need to be paid. + InsecureFreeNormal, /// An operational dispatch with fixed weight. FixedOperational(Weight), /// An operational dispatch with the maximum weight. MaxOperational, - /// An operational dispatch with no weight. - FreeOperational, } impl WeighData for SimpleDispatchInfo { @@ -193,11 +190,10 @@ impl WeighData for SimpleDispatchInfo { match self { SimpleDispatchInfo::FixedNormal(w) => *w, SimpleDispatchInfo::MaxNormal => Bounded::max_value(), - SimpleDispatchInfo::FreeNormal => Bounded::min_value(), + SimpleDispatchInfo::InsecureFreeNormal => Bounded::min_value(), SimpleDispatchInfo::FixedOperational(w) => *w, SimpleDispatchInfo::MaxOperational => Bounded::max_value(), - SimpleDispatchInfo::FreeOperational => Bounded::min_value(), } } } @@ -213,11 +209,10 @@ impl PaysFee for SimpleDispatchInfo { match self { SimpleDispatchInfo::FixedNormal(_) => true, SimpleDispatchInfo::MaxNormal => true, - SimpleDispatchInfo::FreeNormal => true, + SimpleDispatchInfo::InsecureFreeNormal => true, SimpleDispatchInfo::FixedOperational(_) => true, SimpleDispatchInfo::MaxOperational => true, - SimpleDispatchInfo::FreeOperational => false, } } } diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 00dbf6bc66..370bd87b4c 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -477,7 +477,7 @@ mod tests { let len = 100; - // like a FreeOperational + // This is a completely free (and thus wholly insecure/DoS-ridden) transaction. let operational_transaction = DispatchInfo { weight: 0, class: DispatchClass::Operational, @@ -489,7 +489,7 @@ mod tests { .is_ok() ); - // like a FreeNormal + // like a InsecureFreeNormal let free_transaction = DispatchInfo { weight: 0, class: DispatchClass::Normal, -- GitLab From 4e8ced458ed91ab341c3c1efa0d3cf7ab85ec75b Mon Sep 17 00:00:00 2001 From: brenzi Date: Wed, 29 Jan 2020 15:30:25 +0100 Subject: [PATCH 043/180] adding a ss58 format for SubstraTEE (#4764) --- primitives/core/src/crypto.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index 86a579e499..5ad5e19813 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -444,6 +444,8 @@ ss58_address_format!( (7, "edgeware", "Edgeware mainnet, direct checksum, standard account (*25519).") CentrifugeAccountDirect => (36, "centrifuge", "Centrifuge Chain mainnet, direct checksum, standard account (*25519).") + SubstraTeeAccountDirect => + (44, "substratee", "Any SubstraTEE off-chain network private account, direct checksum, standard account (*25519).") ); /// Set the default "version" (actually, this is a bit of a misnomer and the version byte is -- GitLab From 49d47266216d6e22d134b7047e6e4e81a78f6d81 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 29 Jan 2020 15:32:45 +0100 Subject: [PATCH 044/180] Order network dependencies alphabetically (#4763) --- client/network-gossip/Cargo.toml | 6 +++--- client/network/Cargo.toml | 36 ++++++++++++++++---------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index 82611bffc8..ca86af7df4 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -8,11 +8,11 @@ edition = "2018" [dependencies] log = "0.4.8" -futures01 = { package = "futures", version = "0.1.29" } futures = { version = "0.3.1", features = ["compat"] } +futures01 = { package = "futures", version = "0.1.29" } futures-timer = "0.4.0" -lru = "0.1.2" libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] } -sc-network = { version = "0.8", path = "../network" } +lru = "0.1.2" parking_lot = "0.9.0" +sc-network = { version = "0.8", path = "../network" } sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index 7930087595..f20ce36a27 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -7,53 +7,53 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] +bitflags = "1.2.0" bytes = "0.5.0" +codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } derive_more = "0.99.2" either = "1.5.3" -log = "0.4.8" -parking_lot = "0.9.0" -bitflags = "1.2.0" +erased-serde = "0.3.9" fnv = "1.0.6" +fork-tree = { version = "2.0.0", path = "../../utils/fork-tree" } futures = "0.3.1" futures_codec = "0.3.3" futures-timer = "0.4.0" +libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] } linked-hash-map = "0.5.2" linked_hash_set = "0.1.3" +log = "0.4.8" lru = "0.4.0" -rustc-hex = "2.0.1" +parking_lot = "0.9.0" rand = "0.7.2" -libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] } -fork-tree = { version = "2.0.0", path = "../../utils/fork-tree" } -sp-consensus = { version = "0.8", path = "../../primitives/consensus/common" } +rustc-hex = "2.0.1" +sc-block-builder = { version = "0.8", path = "../block-builder" } sc-client = { version = "0.8", 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 = "0.8", path = "../block-builder" } -codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } 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.2.0" smallvec = "0.6.10" -unsigned-varint = { version = "0.3.0", features = ["codec"] } +sp-arithmetic = { version = "2.0.0", path = "../../primitives/arithmetic" } +sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } +sp-consensus = { version = "0.8", path = "../../primitives/consensus/common" } +sp-consensus-babe = { version = "0.8", path = "../../primitives/consensus/babe" } +sp-core = { version = "2.0.0", path = "../../primitives/core" } sp-keyring = { version = "2.0.0", optional = true, path = "../../primitives/keyring" } +sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } 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" +unsigned-varint = { version = "0.3.0", features = ["codec"] } void = "1.0.2" zeroize = "1.0.0" -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" -sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } quickcheck = "0.9.0" rand = "0.7.2" +sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } +sp-test-primitives = { version = "2.0.0", path = "../../primitives/test-primitives" } tempfile = "3.1.0" [features] -- GitLab From b02a97129286a8453ef78f58963b72c7ae47aef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Wed, 29 Jan 2020 16:24:40 +0100 Subject: [PATCH 045/180] Add `get_global` for `Sandbox` (#4756) * Add `get_global` for `Sandbox` This pr adds `get_global` to retrieve a `global` variable from an instantiated sandbox wasm blob. * Bump `spec_version` * Update primitives/wasm-interface/src/lib.rs Co-Authored-By: Sergei Pepyakin * `get_global` -> `get_global_val` Co-authored-by: Sergei Pepyakin Co-authored-by: Gavin Wood --- Cargo.lock | 9 +- bin/node/runtime/src/lib.rs | 2 +- client/executor/common/src/sandbox.rs | 17 +++- client/executor/runtime-test/src/lib.rs | 34 +++++-- client/executor/src/integration_tests/mod.rs | 4 +- .../executor/src/integration_tests/sandbox.rs | 23 +++++ client/executor/wasmi/src/lib.rs | 15 ++- .../wasmtime/src/function_executor.rs | 15 ++- frame/contracts/src/wasm/env_def/macros.rs | 20 ++-- frame/contracts/src/wasm/env_def/mod.rs | 30 +++--- frame/contracts/src/wasm/runtime.rs | 6 +- primitives/core/src/sandbox.rs | 93 ------------------- primitives/io/Cargo.toml | 2 + primitives/io/src/lib.rs | 8 ++ primitives/runtime-interface/Cargo.toml | 4 +- primitives/runtime-interface/src/impls.rs | 10 +- primitives/runtime/Cargo.toml | 2 +- primitives/sandbox/Cargo.toml | 2 + primitives/sandbox/src/lib.rs | 14 ++- primitives/sandbox/with_std.rs | 67 ++++++------- primitives/sandbox/without_std.rs | 14 ++- primitives/wasm-interface/Cargo.toml | 3 +- primitives/wasm-interface/src/lib.rs | 76 ++++++++++++++- 23 files changed, 275 insertions(+), 195 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 88b73133f9..0ad431f9d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4206,13 +4206,13 @@ dependencies = [ "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "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)", + "parity-scale-codec-derive 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parity-scale-codec-derive" -version = "1.1.0" +version = "1.1.1" 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)", @@ -6594,6 +6594,7 @@ dependencies = [ "sp-state-machine 0.8.0", "sp-std 2.0.0", "sp-trie 2.0.0", + "sp-wasm-interface 2.0.0", ] [[package]] @@ -6724,6 +6725,7 @@ dependencies = [ "sp-core 2.0.0", "sp-io 2.0.0", "sp-std 2.0.0", + "sp-wasm-interface 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)", ] @@ -6857,6 +6859,7 @@ name = "sp-wasm-interface" 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.2 (registry+https://github.com/rust-lang/crates.io-index)", "sp-std 2.0.0", "wasmi 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -8700,7 +8703,7 @@ dependencies = [ "checksum parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df3a17dc27848fd99e4f87eb0f8c9baba6ede0a6d555400c850ca45254ef4ce3" "checksum parity-multihash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70a4d7b05e51bff5ae2c29c7b8c3d889985bbd8f4e15b3542fcc1f6f9666d292" "checksum parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f747c06d9f3b2ad387ac881b9667298c81b1243aa9833f086e05996937c35507" -"checksum parity-scale-codec-derive 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "492ac3aa93d6caa5d20e4e3e0b75d08e2dcd9dd8a50d19529548b6fe11b3f295" +"checksum parity-scale-codec-derive 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34e513ff3e406f3ede6796dcdc83d0b32ffb86668cea1ccf7363118abeb00476" "checksum parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" "checksum parity-util-mem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8174d85e62c4d615fddd1ef67966bdc5757528891d0742f15b131ad04667b3f9" "checksum parity-util-mem 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "900dd84654b048e5bad420bb341658fc2c4d7fea628c22bcf4621733e54859b4" diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index bad1ea4174..0d4b094c79 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -81,7 +81,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 208, - impl_version: 0, + impl_version: 1, apis: RUNTIME_API_VERSIONS, }; diff --git a/client/executor/common/src/sandbox.rs b/client/executor/common/src/sandbox.rs index e48afd4891..89285a75fc 100644 --- a/client/executor/common/src/sandbox.rs +++ b/client/executor/common/src/sandbox.rs @@ -224,7 +224,8 @@ fn trap(msg: &'static str) -> Trap { } fn deserialize_result(serialized_result: &[u8]) -> std::result::Result, Trap> { - use self::sandbox_primitives::{HostError, ReturnValue}; + use self::sandbox_primitives::HostError; + use sp_wasm_interface::ReturnValue; let result_val = std::result::Result::::decode(&mut &serialized_result[..]) .map_err(|_| trap("Decoding Result failed!"))?; @@ -260,7 +261,7 @@ impl<'a, FE: SandboxCapabilities + 'a> Externals for GuestExternals<'a, FE> { let invoke_args_data: Vec = args.as_ref() .iter() .cloned() - .map(sandbox_primitives::TypedValue::from) + .map(sp_wasm_interface::Value::from) .collect::>() .encode(); @@ -362,6 +363,18 @@ impl SandboxInstance { }, ) } + + /// Get the value from a global with the given `name`. + /// + /// Returns `Some(_)` if the global could be found. + pub fn get_global_val(&self, name: &str) -> Option { + let global = self.instance + .export_by_name(name)? + .as_global()? + .get(); + + Some(global.into()) + } } /// Error occurred during instantiation of a sandboxed module. diff --git a/client/executor/runtime-test/src/lib.rs b/client/executor/runtime-test/src/lib.rs index f6d37abf94..b183398c02 100644 --- a/client/executor/runtime-test/src/lib.rs +++ b/client/executor/runtime-test/src/lib.rs @@ -17,6 +17,8 @@ use sp_io::{ use sp_runtime::{print, traits::{BlakeTwo256, Hash}}; #[cfg(not(feature = "std"))] use sp_core::{ed25519, sr25519}; +#[cfg(not(feature = "std"))] +use sp_sandbox::Value; extern "C" { #[allow(dead_code)] @@ -133,8 +135,8 @@ sp_core::wasm_export_functions! { execute_sandboxed( &code, &[ - sp_sandbox::TypedValue::I32(0x12345678), - sp_sandbox::TypedValue::I64(0x1234567887654321), + Value::I32(0x12345678), + Value::I64(0x1234567887654321), ], ).is_ok() } @@ -143,10 +145,10 @@ sp_core::wasm_export_functions! { let ok = match execute_sandboxed( &code, &[ - sp_sandbox::TypedValue::I32(0x1336), + Value::I32(0x1336), ] ) { - Ok(sp_sandbox::ReturnValue::Value(sp_sandbox::TypedValue::I32(0x1337))) => true, + Ok(sp_sandbox::ReturnValue::Value(Value::I32(0x1337))) => true, _ => false, }; @@ -165,6 +167,22 @@ sp_core::wasm_export_functions! { code } + + fn test_sandbox_get_global_val(code: Vec) -> i64 { + let env_builder = sp_sandbox::EnvironmentDefinitionBuilder::new(); + let instance = if let Ok(i) = sp_sandbox::Instance::new(&code, &env_builder, &mut ()) { + i + } else { + return 20; + }; + + match instance.get_global_val("test_global") { + Some(sp_sandbox::Value::I64(val)) => val, + None => 30, + val => 40, + } + } + fn test_offchain_local_storage() -> bool { let kind = sp_core::offchain::StorageKind::PERSISTENT; assert_eq!(sp_io::offchain::local_storage_get(kind, b"test"), None); @@ -262,7 +280,7 @@ sp_core::wasm_export_functions! { #[cfg(not(feature = "std"))] fn execute_sandboxed( code: &[u8], - args: &[sp_sandbox::TypedValue], + args: &[Value], ) -> Result { struct State { counter: u32, @@ -270,7 +288,7 @@ fn execute_sandboxed( fn env_assert( _e: &mut State, - args: &[sp_sandbox::TypedValue], + args: &[Value], ) -> Result { if args.len() != 1 { return Err(sp_sandbox::HostError); @@ -284,14 +302,14 @@ fn execute_sandboxed( } fn env_inc_counter( e: &mut State, - args: &[sp_sandbox::TypedValue], + args: &[Value], ) -> Result { if args.len() != 1 { return Err(sp_sandbox::HostError); } let inc_by = args[0].as_i32().ok_or_else(|| sp_sandbox::HostError)?; e.counter += inc_by as u32; - Ok(sp_sandbox::ReturnValue::Value(sp_sandbox::TypedValue::I32(e.counter as i32))) + Ok(sp_sandbox::ReturnValue::Value(Value::I32(e.counter as i32))) } let mut state = State { counter: 0 }; diff --git a/client/executor/src/integration_tests/mod.rs b/client/executor/src/integration_tests/mod.rs index 02a5897ea4..3f3d9f69e1 100644 --- a/client/executor/src/integration_tests/mod.rs +++ b/client/executor/src/integration_tests/mod.rs @@ -88,7 +88,7 @@ fn call_not_existing_function(wasm_method: WasmExecutionMethod) { #[cfg(feature = "wasmtime")] WasmExecutionMethod::Compiled => assert_eq!( &format!("{:?}", e), - "Other(\"call to undefined external function with index 67\")" + "Other(\"call to undefined external function with index 68\")" ), } } @@ -117,7 +117,7 @@ fn call_yet_another_not_existing_function(wasm_method: WasmExecutionMethod) { #[cfg(feature = "wasmtime")] WasmExecutionMethod::Compiled => assert_eq!( &format!("{:?}", e), - "Other(\"call to undefined external function with index 68\")" + "Other(\"call to undefined external function with index 69\")" ), } } diff --git a/client/executor/src/integration_tests/sandbox.rs b/client/executor/src/integration_tests/sandbox.rs index 9458542e3a..8e8b7896cf 100644 --- a/client/executor/src/integration_tests/sandbox.rs +++ b/client/executor/src/integration_tests/sandbox.rs @@ -302,3 +302,26 @@ fn start_fn_traps(wasm_method: WasmExecutionMethod) { 2u8.encode(), ); } + +#[test_case(WasmExecutionMethod::Interpreted)] +#[cfg_attr(feature = "wasmtime", test_case(WasmExecutionMethod::Compiled))] +fn get_global_val_works(wasm_method: WasmExecutionMethod) { + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); + + let code = wabt::wat2wasm(r#" + (module + (global (export "test_global") i64 (i64.const 500)) + ) + "#).unwrap().encode(); + + assert_eq!( + call_in_wasm( + "test_sandbox_get_global_val", + &code, + wasm_method, + &mut ext, + ).unwrap(), + 500i64.encode(), + ); +} diff --git a/client/executor/wasmi/src/lib.rs b/client/executor/wasmi/src/lib.rs index c4701fd827..1bcb1aab8a 100644 --- a/client/executor/wasmi/src/lib.rs +++ b/client/executor/wasmi/src/lib.rs @@ -213,7 +213,7 @@ impl<'a> Sandbox for FunctionExecutor<'a> { trace!(target: "sp-sandbox", "invoke, instance_idx={}", instance_id); // Deserialize arguments and convert them into wasmi types. - let args = Vec::::decode(&mut &args[..]) + let args = Vec::::decode(&mut &args[..]) .map_err(|_| "Can't decode serialized arguments for the invocation")? .into_iter() .map(Into::into) @@ -226,7 +226,7 @@ impl<'a> Sandbox for FunctionExecutor<'a> { Ok(None) => Ok(sandbox_primitives::ERR_OK), Ok(Some(val)) => { // Serialize return value and write it back into the memory. - sandbox_primitives::ReturnValue::Value(val.into()).using_encoded(|val| { + sp_wasm_interface::ReturnValue::Value(val.into()).using_encoded(|val| { if val.len() > return_val_len as usize { Err("Return value buffer is too small")?; } @@ -269,6 +269,17 @@ impl<'a> Sandbox for FunctionExecutor<'a> { Ok(instance_idx_or_err_code as u32) } + + fn get_global_val( + &self, + instance_idx: u32, + name: &str, + ) -> WResult> { + self.sandbox_store + .instance(instance_idx) + .map(|i| i.get_global_val(name)) + .map_err(|e| e.to_string()) + } } /// Will be used on initialization of a module to resolve function and memory imports. diff --git a/client/executor/wasmtime/src/function_executor.rs b/client/executor/wasmtime/src/function_executor.rs index bc665f18e4..7bbf5a456b 100644 --- a/client/executor/wasmtime/src/function_executor.rs +++ b/client/executor/wasmtime/src/function_executor.rs @@ -286,7 +286,7 @@ impl<'a> Sandbox for FunctionExecutor<'a> { trace!(target: "sp-sandbox", "invoke, instance_idx={}", instance_id); // Deserialize arguments and convert them into wasmi types. - let args = Vec::::decode(&mut &args[..]) + let args = Vec::::decode(&mut &args[..]) .map_err(|_| "Can't decode serialized arguments for the invocation")? .into_iter() .map(Into::into) @@ -299,7 +299,7 @@ impl<'a> Sandbox for FunctionExecutor<'a> { Ok(None) => Ok(sandbox_primitives::ERR_OK), Ok(Some(val)) => { // Serialize return value and write it back into the memory. - sandbox_primitives::ReturnValue::Value(val.into()).using_encoded(|val| { + sp_wasm_interface::ReturnValue::Value(val.into()).using_encoded(|val| { if val.len() > return_val_len as usize { Err("Return value buffer is too small")?; } @@ -337,6 +337,17 @@ impl<'a> Sandbox for FunctionExecutor<'a> { Ok(instance_idx_or_err_code as u32) } + + fn get_global_val( + &self, + instance_idx: u32, + name: &str, + ) -> WResult> { + self.sandbox_store + .instance(instance_idx) + .map(|i| i.get_global_val(name)) + .map_err(|e| e.to_string()) + } } // The storage for a Wasmtime invocation argument. diff --git a/frame/contracts/src/wasm/env_def/macros.rs b/frame/contracts/src/wasm/env_def/macros.rs index 89a147b2c6..335d35f1e7 100644 --- a/frame/contracts/src/wasm/env_def/macros.rs +++ b/frame/contracts/src/wasm/env_def/macros.rs @@ -126,7 +126,7 @@ 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: &[sp_sandbox::TypedValue], + args: &[sp_sandbox::Value], ) -> Result { #[allow(unused)] let mut args = args.iter(); @@ -196,7 +196,7 @@ mod tests { use parity_wasm::elements::FunctionType; use parity_wasm::elements::ValueType; use sp_runtime::traits::Zero; - use sp_sandbox::{self, ReturnValue, TypedValue}; + use sp_sandbox::{ReturnValue, Value}; use crate::wasm::tests::MockExt; use crate::wasm::Runtime; use crate::exec::Ext; @@ -206,7 +206,7 @@ mod tests { fn macro_unmarshall_then_body_then_marshall_value_or_trap() { fn test_value( _ctx: &mut u32, - args: &[sp_sandbox::TypedValue], + args: &[sp_sandbox::Value], ) -> Result { let mut args = args.iter(); unmarshall_then_body_then_marshall!( @@ -224,17 +224,17 @@ mod tests { let ctx = &mut 0; assert_eq!( - test_value(ctx, &[TypedValue::I32(15), TypedValue::I32(3)]).unwrap(), - ReturnValue::Value(TypedValue::I32(5)), + test_value(ctx, &[Value::I32(15), Value::I32(3)]).unwrap(), + ReturnValue::Value(Value::I32(5)), ); - assert!(test_value(ctx, &[TypedValue::I32(15), TypedValue::I32(0)]).is_err()); + assert!(test_value(ctx, &[Value::I32(15), Value::I32(0)]).is_err()); } #[test] fn macro_unmarshall_then_body_then_marshall_unit() { fn test_unit( ctx: &mut u32, - args: &[sp_sandbox::TypedValue], + args: &[sp_sandbox::Value], ) -> Result { let mut args = args.iter(); unmarshall_then_body_then_marshall!( @@ -248,7 +248,7 @@ mod tests { } let ctx = &mut 0; - let result = test_unit(ctx, &[TypedValue::I32(2), TypedValue::I32(3)]).unwrap(); + let result = test_unit(ctx, &[Value::I32(2), Value::I32(3)]).unwrap(); assert_eq!(result, ReturnValue::Unit); assert_eq!(*ctx, 5); } @@ -263,7 +263,7 @@ mod tests { Err(sp_sandbox::HostError) } }); - let _f: fn(&mut Runtime, &[sp_sandbox::TypedValue]) + let _f: fn(&mut Runtime, &[sp_sandbox::Value]) -> Result = ext_gas::; } @@ -282,7 +282,7 @@ mod tests { #[test] fn macro_unmarshall_then_body() { - let args = vec![TypedValue::I32(5), TypedValue::I32(3)]; + let args = vec![Value::I32(5), Value::I32(3)]; let mut args = args.iter(); let ctx: &mut u32 = &mut 0; diff --git a/frame/contracts/src/wasm/env_def/mod.rs b/frame/contracts/src/wasm/env_def/mod.rs index 004308da42..7b67f74ec9 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 sp_sandbox::{self, TypedValue}; +use sp_sandbox::Value; use parity_wasm::elements::{FunctionType, ValueType}; #[macro_use] @@ -26,28 +26,28 @@ pub(crate) mod macros; pub trait ConvertibleToWasm: Sized { const VALUE_TYPE: ValueType; type NativeType; - fn to_typed_value(self) -> TypedValue; - fn from_typed_value(_: TypedValue) -> Option; + fn to_typed_value(self) -> Value; + fn from_typed_value(_: Value) -> Option; } impl ConvertibleToWasm for i32 { type NativeType = i32; const VALUE_TYPE: ValueType = ValueType::I32; - fn to_typed_value(self) -> TypedValue { - TypedValue::I32(self) + fn to_typed_value(self) -> Value { + Value::I32(self) } - fn from_typed_value(v: TypedValue) -> Option { + fn from_typed_value(v: Value) -> Option { v.as_i32() } } impl ConvertibleToWasm for u32 { type NativeType = u32; const VALUE_TYPE: ValueType = ValueType::I32; - fn to_typed_value(self) -> TypedValue { - TypedValue::I32(self as i32) + fn to_typed_value(self) -> Value { + Value::I32(self as i32) } - fn from_typed_value(v: TypedValue) -> Option { + fn from_typed_value(v: Value) -> Option { match v { - TypedValue::I32(v) => Some(v as u32), + Value::I32(v) => Some(v as u32), _ => None, } } @@ -55,12 +55,12 @@ impl ConvertibleToWasm for u32 { impl ConvertibleToWasm for u64 { type NativeType = u64; const VALUE_TYPE: ValueType = ValueType::I64; - fn to_typed_value(self) -> TypedValue { - TypedValue::I64(self as i64) + fn to_typed_value(self) -> Value { + Value::I64(self as i64) } - fn from_typed_value(v: TypedValue) -> Option { + fn from_typed_value(v: Value) -> Option { match v { - TypedValue::I64(v) => Some(v as u64), + Value::I64(v) => Some(v as u64), _ => None, } } @@ -69,7 +69,7 @@ impl ConvertibleToWasm for u64 { pub(crate) type HostFunc = fn( &mut Runtime, - &[sp_sandbox::TypedValue] + &[sp_sandbox::Value] ) -> Result; pub(crate) trait FunctionImplProvider { diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index 07cb8cb524..66ae8a4996 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -23,9 +23,7 @@ use crate::exec::{ use crate::gas::{Gas, GasMeter, Token, GasMeterResult, approx_gas_for_balance}; use sp_sandbox; use frame_system; -use sp_std::prelude::*; -use sp_std::convert::TryInto; -use sp_std::mem; +use sp_std::{prelude::*, mem, convert::TryInto}; use codec::{Decode, Encode}; use sp_runtime::traits::{Bounded, SaturatedConversion}; @@ -89,7 +87,7 @@ pub(crate) fn to_execution_result( buffer.clear(); Ok(ExecReturnValue { status: STATUS_SUCCESS, data: buffer }) } - Ok(sp_sandbox::ReturnValue::Value(sp_sandbox::TypedValue::I32(exit_code))) => { + Ok(sp_sandbox::ReturnValue::Value(sp_sandbox::Value::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 }) diff --git a/primitives/core/src/sandbox.rs b/primitives/core/src/sandbox.rs index a0673c49db..73fbcfb572 100644 --- a/primitives/core/src/sandbox.rs +++ b/primitives/core/src/sandbox.rs @@ -24,99 +24,6 @@ use sp_std::vec::Vec; #[derive(crate::RuntimeDebug)] pub struct HostError; -/// Representation of a typed wasm value. -#[derive(Clone, Copy, PartialEq, Encode, Decode)] -#[derive(crate::RuntimeDebug)] -pub enum TypedValue { - /// Value of 32-bit signed or unsigned integer. - #[codec(index = "1")] - I32(i32), - - /// Value of 64-bit signed or unsigned integer. - #[codec(index = "2")] - I64(i64), - - /// Value of 32-bit IEEE 754-2008 floating point number represented as a bit pattern. - #[codec(index = "3")] - F32(i32), - - /// Value of 64-bit IEEE 754-2008 floating point number represented as a bit pattern. - #[codec(index = "4")] - F64(i64), -} - -impl TypedValue { - /// Returns `Some` if this value of type `I32`. - pub fn as_i32(&self) -> Option { - match *self { - TypedValue::I32(v) => Some(v), - _ => None, - } - } -} - -#[cfg(feature = "std")] -impl From<::wasmi::RuntimeValue> for TypedValue { - fn from(val: ::wasmi::RuntimeValue) -> TypedValue { - use ::wasmi::RuntimeValue; - match val { - RuntimeValue::I32(v) => TypedValue::I32(v), - RuntimeValue::I64(v) => TypedValue::I64(v), - RuntimeValue::F32(v) => TypedValue::F32(v.to_bits() as i32), - RuntimeValue::F64(v) => TypedValue::F64(v.to_bits() as i64), - } - } -} - -#[cfg(feature = "std")] -impl From for ::wasmi::RuntimeValue { - fn from(val: TypedValue) -> ::wasmi::RuntimeValue { - use ::wasmi::RuntimeValue; - use ::wasmi::nan_preserving_float::{F32, F64}; - match val { - TypedValue::I32(v) => RuntimeValue::I32(v), - TypedValue::I64(v) => RuntimeValue::I64(v), - TypedValue::F32(v_bits) => RuntimeValue::F32(F32::from_bits(v_bits as u32)), - TypedValue::F64(v_bits) => RuntimeValue::F64(F64::from_bits(v_bits as u64)), - } - } -} - -/// Typed value that can be returned from a function. -/// -/// Basically a `TypedValue` plus `Unit`, for functions which return nothing. -#[derive(Clone, Copy, PartialEq, Encode, Decode)] -#[derive(crate::RuntimeDebug)] -pub enum ReturnValue { - /// For returning nothing. - Unit, - /// For returning some concrete value. - Value(TypedValue), -} - -impl From for ReturnValue { - fn from(v: TypedValue) -> ReturnValue { - ReturnValue::Value(v) - } -} - -impl ReturnValue { - /// Maximum number of bytes `ReturnValue` might occupy when serialized with - /// `Codec`. - /// - /// Breakdown: - /// 1 byte for encoding unit/value variant - /// 1 byte for encoding value type - /// 8 bytes for encoding the biggest value types available in wasm: f64, i64. - pub const ENCODED_MAX_SIZE: usize = 10; -} - -#[test] -fn return_value_encoded_max_size() { - let encoded = ReturnValue::Value(TypedValue::I64(-1)).encode(); - assert_eq!(encoded.len(), ReturnValue::ENCODED_MAX_SIZE); -} - /// Describes an entity to define or import into the environment. #[derive(Clone, PartialEq, Eq, Encode, Decode)] #[derive(crate::RuntimeDebug)] diff --git a/primitives/io/Cargo.toml b/primitives/io/Cargo.toml index 7d831cdfeb..f494697b4b 100644 --- a/primitives/io/Cargo.toml +++ b/primitives/io/Cargo.toml @@ -12,6 +12,7 @@ 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.4", optional = true } sp-state-machine = { version = "0.8", optional = true, path = "../../primitives/state-machine" } +sp-wasm-interface = { version = "2.0.0", path = "../../primitives/wasm-interface", default-features = false } 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 = "0.8.0", optional = true, path = "../externalities" } @@ -29,6 +30,7 @@ std = [ "libsecp256k1", "sp-runtime-interface/std", "sp-externalities", + "sp-wasm-interface/std", "log", ] diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index 704477b1fb..dce67133d3 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -850,6 +850,14 @@ pub trait Sandbox { fn instance_teardown(&mut self, instance_idx: u32) { self.sandbox().instance_teardown(instance_idx).expect("Failed to teardown sandbox instance") } + + /// Get the value from a global with the given `name`. The sandbox is determined by the given + /// `instance_idx`. + /// + /// Returns `Some(_)` when the requested global variable could be found. + fn get_global_val(&mut self, instance_idx: u32, name: &str) -> Option { + self.sandbox().get_global_val(instance_idx, name).expect("Failed to get global from sandbox") + } } /// Allocator used by Substrate when executing the Wasm runtime. diff --git a/primitives/runtime-interface/Cargo.toml b/primitives/runtime-interface/Cargo.toml index 30e9ae6bd6..3f20de1288 100644 --- a/primitives/runtime-interface/Cargo.toml +++ b/primitives/runtime-interface/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "GPL-3.0" [dependencies] -sp-wasm-interface = { version = "2.0.0", optional = true, path = "../wasm-interface" } +sp-wasm-interface = { version = "2.0.0", path = "../wasm-interface", default-features = false } 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 = "0.8.0", optional = true, path = "../externalities" } @@ -25,7 +25,7 @@ trybuild = "1.0.17" [features] default = [ "std" ] std = [ - "sp-wasm-interface", + "sp-wasm-interface/std", "sp-std/std", "codec/std", "sp-externalities", diff --git a/primitives/runtime-interface/src/impls.rs b/primitives/runtime-interface/src/impls.rs index cde8e60eea..35bd96bd05 100644 --- a/primitives/runtime-interface/src/impls.rs +++ b/primitives/runtime-interface/src/impls.rs @@ -17,7 +17,7 @@ //! Provides implementations for the runtime interface traits. use crate::{ - RIType, Pointer, pass_by::{PassBy, Codec, Inner, PassByInner}, + RIType, Pointer, pass_by::{PassBy, Codec, Inner, PassByInner, Enum}, util::{unpack_ptr_and_len, pack_ptr_and_len}, }; #[cfg(feature = "std")] @@ -523,3 +523,11 @@ macro_rules! for_u128_i128 { for_u128_i128!(u128); for_u128_i128!(i128); + +impl PassBy for sp_wasm_interface::ValueType { + type PassBy = Enum; +} + +impl PassBy for sp_wasm_interface::Value { + type PassBy = Codec; +} diff --git a/primitives/runtime/Cargo.toml b/primitives/runtime/Cargo.toml index 7046975416..6f50a1a4d9 100644 --- a/primitives/runtime/Cargo.toml +++ b/primitives/runtime/Cargo.toml @@ -7,7 +7,7 @@ license = "GPL-3.0" [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.1.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.1.2", 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" } diff --git a/primitives/sandbox/Cargo.toml b/primitives/sandbox/Cargo.toml index 071ac2ba7b..c942e019fe 100755 --- a/primitives/sandbox/Cargo.toml +++ b/primitives/sandbox/Cargo.toml @@ -10,6 +10,7 @@ wasmi = { version = "0.6.2", optional = true } 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" } +sp-wasm-interface = { version = "2.0.0", default-features = false, path = "../wasm-interface" } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } [dev-dependencies] @@ -24,5 +25,6 @@ std = [ "sp-std/std", "codec/std", "sp-io/std", + "sp-wasm-interface/std", ] strict = [] diff --git a/primitives/sandbox/src/lib.rs b/primitives/sandbox/src/lib.rs index 2760a46b48..17712ad365 100755 --- a/primitives/sandbox/src/lib.rs +++ b/primitives/sandbox/src/lib.rs @@ -40,7 +40,8 @@ use sp_std::prelude::*; -pub use sp_core::sandbox::{TypedValue, ReturnValue, HostError}; +pub use sp_core::sandbox::HostError; +pub use sp_wasm_interface::{Value, ReturnValue}; mod imp { #[cfg(feature = "std")] @@ -75,7 +76,7 @@ impl From for HostError { /// supervisor in [`EnvironmentDefinitionBuilder`]. /// /// [`EnvironmentDefinitionBuilder`]: struct.EnvironmentDefinitionBuilder.html -pub type HostFuncType = fn(&mut T, &[TypedValue]) -> Result; +pub type HostFuncType = fn(&mut T, &[Value]) -> Result; /// Reference to a sandboxed linear memory, that /// will be used by the guest module. @@ -197,9 +198,16 @@ impl Instance { pub fn invoke( &mut self, name: &str, - args: &[TypedValue], + args: &[Value], state: &mut T, ) -> Result { self.inner.invoke(name, args, state) } + + /// Get the value from a global with the given `name`. + /// + /// Returns `Some(_)` if the global could be found. + pub fn get_global_val(&self, name: &str) -> Option { + self.inner.get_global_val(name) + } } diff --git a/primitives/sandbox/with_std.rs b/primitives/sandbox/with_std.rs index 5f20342a5a..cc3119003d 100755 --- a/primitives/sandbox/with_std.rs +++ b/primitives/sandbox/with_std.rs @@ -23,7 +23,7 @@ use wasmi::{ RuntimeArgs, RuntimeValue, Signature, TableDescriptor, TableRef, Trap, TrapKind }; use wasmi::memory_units::Pages; -use super::{Error, TypedValue, ReturnValue, HostFuncType, HostError}; +use super::{Error, Value, ReturnValue, HostFuncType, HostError}; #[derive(Clone)] pub struct Memory { @@ -88,27 +88,7 @@ impl fmt::Display for DummyHostError { } } -impl wasmi::HostError for DummyHostError { -} - -fn from_runtime_value(v: RuntimeValue) -> TypedValue { - match v { - RuntimeValue::I32(v) => TypedValue::I32(v), - RuntimeValue::I64(v) => TypedValue::I64(v), - RuntimeValue::F32(v) => TypedValue::F32(v.to_bits() as i32), - RuntimeValue::F64(v) => TypedValue::F64(v.to_bits() as i64), - } -} - -fn to_runtime_value(v: TypedValue) -> RuntimeValue { - use wasmi::nan_preserving_float::{F32, F64}; - match v { - TypedValue::I32(v) => RuntimeValue::I32(v as i32), - TypedValue::I64(v) => RuntimeValue::I64(v as i64), - TypedValue::F32(v_bits) => RuntimeValue::F32(F32::from_bits(v_bits as u32)), - TypedValue::F64(v_bits) => RuntimeValue::F64(F64::from_bits(v_bits as u64)), - } -} +impl wasmi::HostError for DummyHostError {} struct GuestExternals<'a, T: 'a> { state: &'a mut T, @@ -124,13 +104,13 @@ impl<'a, T> Externals for GuestExternals<'a, T> { let args = args.as_ref() .iter() .cloned() - .map(from_runtime_value) + .map(Into::into) .collect::>(); let result = (self.defined_host_functions.funcs[index])(self.state, &args); match result { Ok(value) => Ok(match value { - ReturnValue::Value(v) => Some(to_runtime_value(v)), + ReturnValue::Value(v) => Some(v.into()), ReturnValue::Unit => None, }), Err(HostError) => Err(TrapKind::Host(Box::new(DummyHostError)).into()), @@ -253,7 +233,7 @@ impl ImportResolver for EnvironmentDefinitionBuilder { pub struct Instance { instance: ModuleRef, defined_host_functions: DefinedHostFunctions, - _marker: ::std::marker::PhantomData, + _marker: std::marker::PhantomData, } impl Instance { @@ -281,14 +261,14 @@ impl Instance { Ok(Instance { instance, defined_host_functions, - _marker: ::std::marker::PhantomData::, + _marker: std::marker::PhantomData::, }) } pub fn invoke( &mut self, name: &str, - args: &[TypedValue], + args: &[Value], state: &mut T, ) -> Result { let args = args.iter().cloned().map(Into::into).collect::>(); @@ -306,20 +286,29 @@ impl Instance { Err(_err) => Err(Error::Execution), } } + + pub fn get_global_val(&self, name: &str) -> Option { + let global = self.instance + .export_by_name(name)? + .as_global()? + .get(); + + Some(global.into()) + } } #[cfg(test)] mod tests { use wabt; - use crate::{Error, TypedValue, ReturnValue, HostError, EnvironmentDefinitionBuilder, Instance}; + use crate::{Error, Value, ReturnValue, HostError, EnvironmentDefinitionBuilder, Instance}; use assert_matches::assert_matches; - fn execute_sandboxed(code: &[u8], args: &[TypedValue]) -> Result { + fn execute_sandboxed(code: &[u8], args: &[Value]) -> Result { struct State { counter: u32, } - fn env_assert(_e: &mut State, args: &[TypedValue]) -> Result { + fn env_assert(_e: &mut State, args: &[Value]) -> Result { if args.len() != 1 { return Err(HostError); } @@ -330,16 +319,16 @@ mod tests { Err(HostError) } } - fn env_inc_counter(e: &mut State, args: &[TypedValue]) -> Result { + fn env_inc_counter(e: &mut State, args: &[Value]) -> Result { if args.len() != 1 { return Err(HostError); } let inc_by = args[0].as_i32().ok_or_else(|| HostError)?; e.counter += inc_by as u32; - Ok(ReturnValue::Value(TypedValue::I32(e.counter as i32))) + Ok(ReturnValue::Value(Value::I32(e.counter as i32))) } /// Function that takes one argument of any type and returns that value. - fn env_polymorphic_id(_e: &mut State, args: &[TypedValue]) -> Result { + fn env_polymorphic_id(_e: &mut State, args: &[Value]) -> Result { if args.len() != 1 { return Err(HostError); } @@ -387,8 +376,8 @@ mod tests { let result = execute_sandboxed( &code, &[ - TypedValue::I32(0x12345678), - TypedValue::I64(0x1234567887654321), + Value::I32(0x12345678), + Value::I64(0x1234567887654321), ] ); assert!(result.is_ok()); @@ -410,10 +399,10 @@ mod tests { let return_val = execute_sandboxed( &code, &[ - TypedValue::I32(0x1336), + Value::I32(0x1336), ] ).unwrap(); - assert_eq!(return_val, ReturnValue::Value(TypedValue::I32(0x1337))); + assert_eq!(return_val, ReturnValue::Value(Value::I32(0x1337))); } #[test] @@ -453,8 +442,8 @@ mod tests { #[test] fn cant_return_unmatching_type() { - fn env_returns_i32(_e: &mut (), _args: &[TypedValue]) -> Result { - Ok(ReturnValue::Value(TypedValue::I32(42))) + fn env_returns_i32(_e: &mut (), _args: &[Value]) -> Result { + Ok(ReturnValue::Value(Value::I32(42))) } let mut env_builder = EnvironmentDefinitionBuilder::new(); diff --git a/primitives/sandbox/without_std.rs b/primitives/sandbox/without_std.rs index 901354aee3..c31c6fe349 100755 --- a/primitives/sandbox/without_std.rs +++ b/primitives/sandbox/without_std.rs @@ -18,7 +18,7 @@ use codec::{Decode, Encode}; 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 super::{Error, Value, ReturnValue, HostFuncType}; mod ffi { use sp_std::mem; @@ -183,7 +183,7 @@ extern "C" fn dispatch_thunk( slice::from_raw_parts(serialized_args_ptr, serialized_args_len) } }; - let args = Vec::::decode(&mut &serialized_args[..]).expect( + let args = Vec::::decode(&mut &serialized_args[..]).expect( "serialized args should be provided by the runtime; correctly serialized data should be deserializable; qed", @@ -244,11 +244,11 @@ impl Instance { pub fn invoke( &mut self, name: &str, - args: &[TypedValue], + args: &[Value], state: &mut T, ) -> Result { let serialized_args = args.to_vec().encode(); - let mut return_val = vec![0u8; sandbox_primitives::ReturnValue::ENCODED_MAX_SIZE]; + let mut return_val = vec![0u8; ReturnValue::ENCODED_MAX_SIZE]; let result = sandbox::invoke( self.instance_idx, @@ -261,7 +261,7 @@ impl Instance { match result { sandbox_primitives::ERR_OK => { - let return_val = sandbox_primitives::ReturnValue::decode(&mut &return_val[..]) + let return_val = ReturnValue::decode(&mut &return_val[..]) .map_err(|_| Error::Execution)?; Ok(return_val) } @@ -269,6 +269,10 @@ impl Instance { _ => unreachable!(), } } + + pub fn get_global_val(&self, name: &str) -> Option { + sandbox::get_global_val(self.instance_idx, name) + } } impl Drop for Instance { diff --git a/primitives/wasm-interface/Cargo.toml b/primitives/wasm-interface/Cargo.toml index b97e3040aa..bb9ea85872 100644 --- a/primitives/wasm-interface/Cargo.toml +++ b/primitives/wasm-interface/Cargo.toml @@ -9,7 +9,8 @@ license = "GPL-3.0" wasmi = { version = "0.6.2", optional = true } impl-trait-for-tuples = "0.1.2" sp-std = { version = "2.0.0", path = "../std", default-features = false } +codec = { package = "parity-scale-codec", version = "1.1.2", default-features = false, features = ["derive"] } [features] default = [ "std" ] -std = [ "wasmi", "sp-std/std" ] +std = [ "wasmi", "sp-std/std", "codec/std" ] diff --git a/primitives/wasm-interface/src/lib.rs b/primitives/wasm-interface/src/lib.rs index d6f9bbfbf0..7bb4469c77 100644 --- a/primitives/wasm-interface/src/lib.rs +++ b/primitives/wasm-interface/src/lib.rs @@ -44,8 +44,33 @@ pub enum ValueType { F64, } +impl From for u8 { + fn from(val: ValueType) -> u8 { + match val { + ValueType::I32 => 0, + ValueType::I64 => 1, + ValueType::F32 => 2, + ValueType::F64 => 3, + } + } +} + +impl sp_std::convert::TryFrom for ValueType { + type Error = (); + + fn try_from(val: u8) -> sp_std::result::Result { + match val { + 0 => Ok(Self::I32), + 1 => Ok(Self::I64), + 2 => Ok(Self::F32), + 3 => Ok(Self::F64), + _ => Err(()), + } + } +} + /// Values supported by Substrate on the boundary between host/Wasm. -#[derive(PartialEq, Debug, Clone, Copy)] +#[derive(PartialEq, Debug, Clone, Copy, codec::Encode, codec::Decode)] pub enum Value { /// A 32-bit integer. I32(i32), @@ -71,6 +96,14 @@ impl Value { Value::F64(_) => ValueType::F64, } } + + /// Return `Self` as `i32`. + pub fn as_i32(&self) -> Option { + match self { + Self::I32(val) => Some(*val), + _ => None, + } + } } /// Provides `Sealed` trait to prevent implementing trait `PointerType` outside of this crate. @@ -298,6 +331,12 @@ pub trait Sandbox { raw_env_def: &[u8], state: u32, ) -> Result; + + /// Get the value from a global with the given `name`. The sandbox is determined by the + /// given `instance_idx` instance. + /// + /// Returns `Some(_)` when the requested global variable could be found. + fn get_global_val(&self, instance_idx: u32, name: &str) -> Result>; } /// Something that provides implementations for host functions. @@ -409,9 +448,37 @@ impl ReadPrimitive for &mut dyn FunctionContext { } } +/// Typed value that can be returned from a function. +/// +/// Basically a `TypedValue` plus `Unit`, for functions which return nothing. +#[derive(Clone, Copy, PartialEq, codec::Encode, codec::Decode, Debug)] +pub enum ReturnValue { + /// For returning nothing. + Unit, + /// For returning some concrete value. + Value(Value), +} + +impl From for ReturnValue { + fn from(v: Value) -> ReturnValue { + ReturnValue::Value(v) + } +} + +impl ReturnValue { + /// Maximum number of bytes `ReturnValue` might occupy when serialized with `SCALE`. + /// + /// Breakdown: + /// 1 byte for encoding unit/value variant + /// 1 byte for encoding value type + /// 8 bytes for encoding the biggest value types available in wasm: f64, i64. + pub const ENCODED_MAX_SIZE: usize = 10; +} + #[cfg(test)] mod tests { use super::*; + use codec::Encode; #[test] fn pointer_offset_works() { @@ -425,4 +492,11 @@ mod tests { assert_eq!(ptr.offset(10).unwrap(), Pointer::new(80)); assert_eq!(ptr.offset(32).unwrap(), Pointer::new(256)); } + + + #[test] + fn return_value_encoded_max_size() { + let encoded = ReturnValue::Value(Value::I64(-1)).encode(); + assert_eq!(encoded.len(), ReturnValue::ENCODED_MAX_SIZE); + } } -- GitLab From 8e074bb17cb68a3df6093e0513e728519f1676d0 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Wed, 29 Jan 2020 17:57:51 +0100 Subject: [PATCH 046/180] RPC calls should execute with configured strategy (#4772) --- client/rpc/src/state/state_full.rs | 48 ++++++++++++++---------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index e42e6b722e..cd77e8b080 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -30,7 +30,7 @@ use sp_blockchain::{ Result as ClientResult, Error as ClientError, HeaderMetadata, CachedHeaderMetadata }; use sc_client::{ - Client, CallExecutor, BlockchainEvents, + Client, CallExecutor, BlockchainEvents }; use sp_core::{ Bytes, storage::{well_known_keys, StorageKey, StorageData, StorageChangeSet, ChildInfo}, @@ -213,15 +213,14 @@ impl FullState } } -impl StateBackend for FullState - where - Block: BlockT + 'static, - B: Backend + Send + Sync + 'static, - E: CallExecutor + Send + Sync + 'static + Clone, - RA: Send + Sync + 'static, - Client: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: - Metadata, +impl StateBackend for FullState where + Block: BlockT + 'static, + B: Backend + Send + Sync + 'static, + E: CallExecutor + Send + Sync + 'static + Clone, + RA: Send + Sync + 'static, + Client: ProvideRuntimeApi, + as ProvideRuntimeApi>::Api: + Metadata, { fn call( &self, @@ -229,21 +228,20 @@ impl StateBackend for FullState FutureResult { - Box::new(result( - self.block_or_best(block) - .and_then(|block| - self - .client - .executor() - .call( - &BlockId::Hash(block), - &method, - &*call_data, - ExecutionStrategy::NativeElseWasm, - None, - ) - .map(Into::into)) - .map_err(client_err))) + let r = self.block_or_best(block) + .and_then(|block| self + .client + .executor() + .call( + &BlockId::Hash(block), + &method, + &*call_data, + self.client.execution_extensions().strategies().other, + None, + ) + .map(Into::into) + ).map_err(client_err); + Box::new(result(r)) } fn storage_keys( -- GitLab From 2c9ce7296b19934b1ffd50150be2fdb2ddf81a4e Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Wed, 29 Jan 2020 18:41:51 +0100 Subject: [PATCH 047/180] Identity should bound additional fields (#4770) * Identity should bound additional fields * ump rutnime --- bin/node/runtime/src/lib.rs | 10 ++++++---- frame/identity/src/lib.rs | 34 ++++++++++++++++++++++++++-------- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 0d4b094c79..3f12957a05 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -80,8 +80,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 208, - impl_version: 1, + spec_version: 209, + impl_version: 0, apis: RUNTIME_API_VERSIONS, }; @@ -490,7 +490,8 @@ parameter_types! { pub const BasicDeposit: Balance = 10 * DOLLARS; // 258 bytes on-chain pub const FieldDeposit: Balance = 250 * CENTS; // 66 bytes on-chain pub const SubAccountDeposit: Balance = 2 * DOLLARS; // 53 bytes on-chain - pub const MaximumSubAccounts: u32 = 100; + pub const MaxSubAccounts: u32 = 100; + pub const MaxAdditionalFields: u32 = 100; } impl pallet_identity::Trait for Runtime { @@ -500,7 +501,8 @@ impl pallet_identity::Trait for Runtime { type BasicDeposit = BasicDeposit; type FieldDeposit = FieldDeposit; type SubAccountDeposit = SubAccountDeposit; - type MaximumSubAccounts = MaximumSubAccounts; + type MaxSubAccounts = MaxSubAccounts; + type MaxAdditionalFields = MaxAdditionalFields; type RegistrarOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; type ForceOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; } diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index 631d77d0bf..b16e87ff81 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -100,7 +100,11 @@ pub trait Trait: frame_system::Trait { type SubAccountDeposit: Get>; /// The maximum number of sub-accounts allowed per identified account. - type MaximumSubAccounts: Get; + type MaxSubAccounts: Get; + + /// Maximum number of additional fields that may be stored in an ID. Needed to bound the I/O + /// required to access an identity, but can be pretty high. + type MaxAdditionalFields: Get; /// What to do with slashed funds. type Slashed: OnUnbalanced>; @@ -443,7 +447,9 @@ decl_error! { InvalidIndex, /// The target is invalid. InvalidTarget, - } + /// Too many additional fields. + TooManyFields, +} } decl_module! { @@ -493,15 +499,17 @@ decl_module! { /// Emits `IdentitySet` if successful. /// /// # - /// - `O(X + R)` where `X` additional-field-count (deposit-bounded). + /// - `O(X + X' + R)` where `X` additional-field-count (deposit-bounded and code-bounded). /// - At most two balance operations. - /// - One storage mutation (codec `O(X + R)`). + /// - One storage mutation (codec-read `O(X' + R)`, codec-write `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 extra_fields = info.additional.len() as u32; + ensure!(extra_fields <= T::MaxAdditionalFields::get(), Error::::TooManyFields); + let fd = >::from(extra_fields) * T::FieldDeposit::get(); let mut id = match >::get(&sender) { Some(mut id) => { @@ -546,7 +554,7 @@ decl_module! { fn set_subs(origin, subs: Vec<(T::AccountId, Data)>) { let sender = ensure_signed(origin)?; ensure!(>::exists(&sender), Error::::NotFound); - ensure!(subs.len() <= T::MaximumSubAccounts::get() as usize, Error::::TooManySubAccounts); + ensure!(subs.len() <= T::MaxSubAccounts::get() as usize, Error::::TooManySubAccounts); let (old_deposit, old_ids) = >::get(&sender); let new_deposit = T::SubAccountDeposit::get() * >::from(subs.len() as u32); @@ -936,7 +944,8 @@ mod tests { pub const BasicDeposit: u64 = 10; pub const FieldDeposit: u64 = 10; pub const SubAccountDeposit: u64 = 10; - pub const MaximumSubAccounts: u32 = 2; + pub const MaxSubAccounts: u32 = 2; + pub const MaxAdditionalFields: u32 = 2; } ord_parameter_types! { pub const One: u64 = 1; @@ -949,7 +958,8 @@ mod tests { type BasicDeposit = BasicDeposit; type FieldDeposit = FieldDeposit; type SubAccountDeposit = SubAccountDeposit; - type MaximumSubAccounts = MaximumSubAccounts; + type MaxSubAccounts = MaxSubAccounts; + type MaxAdditionalFields = MaxAdditionalFields; type RegistrarOrigin = EnsureSignedBy; type ForceOrigin = EnsureSignedBy; } @@ -1012,6 +1022,14 @@ mod tests { 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 mut three_fields = ten(); + three_fields.additional.push(Default::default()); + three_fields.additional.push(Default::default()); + three_fields.additional.push(Default::default()); + assert_noop!( + Identity::set_identity(Origin::signed(10), three_fields), + Error::::TooManyFields + ); assert_ok!(Identity::set_identity(Origin::signed(10), ten())); assert_eq!(Identity::identity(10).unwrap().info, ten()); assert_eq!(Balances::free_balance(10), 90); -- GitLab From 7d58ceeb46aa13899da5a9d94eeee52555a948c9 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Wed, 29 Jan 2020 18:42:21 +0100 Subject: [PATCH 048/180] client/finality-grandpa/src/observer: Poll NetworkBridge (#4766) Patch d4fbb897c reintegrated the periodic neighbor packet worker, by moving its logic into a `Future` implementation on `NetworkBridge` which needs to be polled by its upper layer. Polling by the upper layer was implemented within the `Future` implementation of the `VoterWork` struct but not within the `Future` implementation of the `ObserverWork` struct. This patch adds polling of the `NetworkBridge` to the latter. --- client/finality-grandpa/src/observer.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/client/finality-grandpa/src/observer.rs b/client/finality-grandpa/src/observer.rs index 418bd570c0..ef85bede1c 100644 --- a/client/finality-grandpa/src/observer.rs +++ b/client/finality-grandpa/src/observer.rs @@ -336,10 +336,8 @@ where { type Output = Result<(), Error>; - fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { - let this = Pin::into_inner(self); - - match Future::poll(Pin::new(&mut this.observer), cx) { + fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { + match Future::poll(Pin::new(&mut self.observer), cx) { Poll::Pending => {} Poll::Ready(Ok(())) => { // observer commit stream doesn't conclude naturally; this could reasonably be an error. @@ -351,12 +349,12 @@ where } Poll::Ready(Err(CommandOrError::VoterCommand(command))) => { // some command issued internally - this.handle_voter_command(command)?; + self.handle_voter_command(command)?; cx.waker().wake_by_ref(); } } - match Stream::poll_next(Pin::new(&mut this.voter_commands_rx), cx) { + match Stream::poll_next(Pin::new(&mut self.voter_commands_rx), cx) { Poll::Pending => {} Poll::Ready(None) => { // the `voter_commands_rx` stream should never conclude since it's never closed. @@ -364,11 +362,11 @@ where } Poll::Ready(Some(command)) => { // some command issued externally - this.handle_voter_command(command)?; + self.handle_voter_command(command)?; cx.waker().wake_by_ref(); } } - Poll::Pending + Future::poll(Pin::new(&mut self.network), cx) } } -- GitLab From 2e1717225a5971f1f9e89f443657ee1c8d2e3d48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 29 Jan 2020 21:37:26 +0100 Subject: [PATCH 049/180] Fix warnings. (#4768) --- bin/node-template/src/cli.rs | 4 +++- bin/node-template/src/service.rs | 1 - bin/node/cli/src/cli.rs | 4 +++- client/finality-grandpa/src/lib.rs | 9 --------- client/network/test/src/lib.rs | 2 +- 5 files changed, 7 insertions(+), 13 deletions(-) diff --git a/bin/node-template/src/cli.rs b/bin/node-template/src/cli.rs index fcfd330816..8408f17379 100644 --- a/bin/node-template/src/cli.rs +++ b/bin/node-template/src/cli.rs @@ -90,7 +90,9 @@ where let _ = exit_send.send(()); - runtime.block_on(handle); + if let Err(e) = runtime.block_on(handle) { + log::error!("Error running node: {:?}", e); + } match service_res { Either::Left((res, _)) => res.map_err(error::Error::Service), diff --git a/bin/node-template/src/service.rs b/bin/node-template/src/service.rs index a396a5301c..bdaff5ad09 100644 --- a/bin/node-template/src/service.rs +++ b/bin/node-template/src/service.rs @@ -11,7 +11,6 @@ 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 futures::{FutureExt, compat::Future01CompatExt}; // Our native executor instance. native_executor_instance!( diff --git a/bin/node/cli/src/cli.rs b/bin/node/cli/src/cli.rs index 2c68789e38..2a3d60a794 100644 --- a/bin/node/cli/src/cli.rs +++ b/bin/node/cli/src/cli.rs @@ -200,7 +200,9 @@ where let _ = exit_send.send(()); - runtime.block_on(handle); + if let Err(e) = runtime.block_on(handle) { + log::error!("Error running node: {:?}", e); + } match service_res { Either::Left((res, _)) => res.map_err(error::Error::Service), diff --git a/client/finality-grandpa/src/lib.rs b/client/finality-grandpa/src/lib.rs index a86a97c0da..afca0ed48b 100644 --- a/client/finality-grandpa/src/lib.rs +++ b/client/finality-grandpa/src/lib.rs @@ -171,15 +171,6 @@ type CommunicationInH = finality_grandpa::voter::CommunicationIn< AuthorityId, >; -/// A global communication sink for commits. Not exposed publicly, used -/// internally to simplify types in the communication layer. -type CommunicationOut = finality_grandpa::voter::CommunicationOut< - ::Hash, - NumberFor, - AuthoritySignature, - AuthorityId, ->; - /// 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. diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 1e14ec7bb0..22e340a2a8 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -392,7 +392,7 @@ impl TransactionPool for EmptyTransactionPool { fn on_broadcasted(&self, _: HashMap>) {} - fn transaction(&self, h: &Hash) -> Option { None } + fn transaction(&self, _h: &Hash) -> Option { None } } pub trait SpecializationFactory { -- GitLab From 1ed1cc542110aaaee9cf0de87a7c256a1de407c6 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Thu, 30 Jan 2020 09:54:10 +0100 Subject: [PATCH 050/180] Remove --release from check_for_exit.sh (#4775) I don't see any good reason to build with --release to test this but this step takes 8-8:30 min on the CI and I suspect we would save some time by using the debug build instead. --- .maintain/check_for_exit.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.maintain/check_for_exit.sh b/.maintain/check_for_exit.sh index c5a54eb83b..edc2130e57 100755 --- a/.maintain/check_for_exit.sh +++ b/.maintain/check_for_exit.sh @@ -4,8 +4,8 @@ set -e -cargo build --release -./target/release/substrate --dev & +cargo build +./target/debug/substrate --dev & PID=$! # Let the chain running for 60 seconds -- GitLab From 26e37ff685819646633f5246419c03c02df81dff Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Thu, 30 Jan 2020 11:40:08 +0100 Subject: [PATCH 051/180] CLI API refactoring and improvement (#4692) It changes the way we extended the CLI functionalities of substrate to allow more flexibility. (If this was not clear, here is another version: it changes the `sc_cli` API to allow more flexibility). This touches a few important things: - the startup of the async task with tokei: This was in node and node-template and I moved it to substrate. The idea is to have 1 time the code that handles unix signals (SIGTERM and SIGINT) properly. It is however possible to make this more generic to wait for a future instead and provide only a helper for the basic handling of SIGTERM and SIGINT. - increased the version of structopt and tokei - no more use of structopt internal's API - less use of generics Related to #4643 and https://github.com/paritytech/cumulus/pull/42: the implementation of "into_configuration" and "get_config" are similar but with better flexibility so it is now possible in cumulus to have the command-line arguments only of the run command for polkadot if we want Related to https://github.com/paritytech/cumulus/issues/24 and https://github.com/paritytech/cumulus/issues/34 : it will now be possible to make a configuration struct for polkadot with some overrides of the default parameters much more easily. --- Cargo.lock | 1435 +++++++++++------------ bin/node-template/Cargo.toml | 5 +- bin/node-template/src/chain_spec.rs | 7 + bin/node-template/src/cli.rs | 126 +- bin/node-template/src/command.rs | 48 + bin/node-template/src/main.rs | 8 +- bin/node-template/src/service.rs | 4 +- bin/node/cli/Cargo.toml | 23 +- bin/node/cli/bin/main.rs | 26 +- bin/node/cli/build.rs | 69 +- bin/node/cli/src/browser.rs | 4 +- bin/node/cli/src/cli.rs | 159 +-- bin/node/cli/src/command.rs | 82 ++ bin/node/cli/src/lib.rs | 4 + bin/node/cli/src/service.rs | 6 +- bin/utils/chain-spec-builder/Cargo.toml | 2 +- client/cli/Cargo.toml | 5 +- client/cli/src/lib.rs | 1136 ++++-------------- client/cli/src/node_key.rs | 208 ++++ client/cli/src/params.rs | 526 ++++++--- client/cli/src/runtime.rs | 138 +++ client/service/src/builder.rs | 78 +- client/service/src/chain_ops.rs | 4 +- client/service/src/config.rs | 45 +- client/service/src/lib.rs | 12 +- client/service/test/src/lib.rs | 45 +- primitives/keyring/src/sr25519.rs | 27 + utils/browser/src/lib.rs | 9 +- 28 files changed, 2024 insertions(+), 2217 deletions(-) create mode 100644 bin/node-template/src/command.rs create mode 100644 bin/node/cli/src/command.rs create mode 100644 client/cli/src/node_key.rs create mode 100644 client/cli/src/runtime.rs diff --git a/Cargo.lock b/Cargo.lock index 0ad431f9d3..f28d341847 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,7 +6,7 @@ version = "0.11.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)", - "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -50,15 +50,15 @@ name = "ahash" version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "const-random 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "const-random 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "aho-corasick" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -79,7 +79,7 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -100,7 +100,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "arrayref" -version = "0.3.5" +version = "0.3.6" 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.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -140,10 +140,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "async-std" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "async-task 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-task 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "broadcaster 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -152,23 +152,24 @@ dependencies = [ "futures-io 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)", "kv-log-macro 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.0 (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)", - "pin-project-lite 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "once_cell 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "async-task" -version = "1.0.0" +version = "1.3.0" 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)", + "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)", ] [[package]] @@ -184,9 +185,10 @@ dependencies = [ [[package]] name = "atty" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "hermit-abi 0.1.6 (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)", ] @@ -196,9 +198,14 @@ name = "autocfg" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "autocfg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "backtrace" -version = "0.3.40" +version = "0.3.42" 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)", @@ -212,7 +219,7 @@ name = "backtrace-sys" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -265,11 +272,11 @@ dependencies = [ "env_logger 0.6.2 (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.10 (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)", + "regex 1.3.3 (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)", ] @@ -306,17 +313,17 @@ version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "blake2b_simd" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -371,7 +378,7 @@ dependencies = [ "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-web 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sc-chain-spec 2.0.0", @@ -393,11 +400,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bstr" -version = "0.2.8" +version = "0.2.10" 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)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.0 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -417,7 +424,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "byte-slice-cast" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -471,7 +478,7 @@ dependencies = [ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -484,11 +491,10 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.48" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jobserver 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -513,7 +519,7 @@ dependencies = [ "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sc-keystore 2.0.0", "sp-core 2.0.0", - "structopt 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -521,8 +527,8 @@ name = "chrono" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -543,7 +549,7 @@ version = "2.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "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)", @@ -556,7 +562,7 @@ name = "clear_on_drop" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -572,7 +578,7 @@ name = "cmake" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -589,31 +595,31 @@ name = "console_log" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "const-random" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "const-random-macro 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "const-random-macro 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "const-random-macro" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "constant_time_eq" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -648,11 +654,11 @@ dependencies = [ "cranelift-codegen-meta 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", "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.10 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.1.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.9 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -683,7 +689,7 @@ version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cranelift-codegen 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -706,9 +712,9 @@ dependencies = [ "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)", - "log 0.4.10 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "wasmparser 0.39.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -725,49 +731,49 @@ name = "criterion" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "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)", + "csv 1.1.3 (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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (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)", + "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (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)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "tinytemplate 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "criterion" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "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)", + "criterion-plot 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "csv 1.1.3 (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.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)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "oorandom 11.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "plotters 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (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)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "tinytemplate 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -782,7 +788,7 @@ dependencies = [ [[package]] name = "criterion-plot" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -829,9 +835,10 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.2.0" +version = "0.2.1" 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)", "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -870,12 +877,12 @@ dependencies = [ [[package]] name = "csv" -version = "1.1.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "bstr 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "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)", + "itoa 0.4.5 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -885,7 +892,7 @@ name = "csv-core" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -902,7 +909,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.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -914,15 +921,6 @@ dependencies = [ "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "ctrlc" -version = "3.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nix 0.14.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 = "cuckoofilter" version = "0.3.2" @@ -966,9 +964,9 @@ name = "derive_more" version = "0.99.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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1000,7 +998,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)", "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)", + "redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1010,7 +1008,7 @@ version = "0.8.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)", - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1047,9 +1045,9 @@ 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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1057,11 +1055,11 @@ name = "env_logger" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1069,11 +1067,11 @@ name = "env_logger" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1083,7 +1081,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "erased-serde" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1116,7 +1114,7 @@ dependencies = [ "evm-core 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "evm-gasometer 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", + "primitive-types 0.6.2 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1127,7 +1125,7 @@ name = "evm-core" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1137,7 +1135,7 @@ 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)", "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)", + "primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1146,7 +1144,7 @@ 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)", - "primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1163,14 +1161,14 @@ name = "faerie" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "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.10 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", + "goblin 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.1 (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.9 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1178,7 +1176,7 @@ name = "failure" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1187,9 +1185,9 @@ name = "failure_derive" version = "0.1.6" 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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1205,7 +1203,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "fdlimit" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1217,7 +1215,7 @@ version = "0.1.2" 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.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1227,8 +1225,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" 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.10 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.10 (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.11 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.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.6.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1236,7 +1234,7 @@ dependencies = [ [[package]] name = "fixed-hash" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1330,7 +1328,7 @@ dependencies = [ "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.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1343,7 +1341,7 @@ dependencies = [ "sp-runtime 2.0.0", "sp-state-machine 0.8.0", "sp-std 2.0.0", - "tracing 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1351,9 +1349,9 @@ 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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1362,18 +1360,18 @@ 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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1389,7 +1387,7 @@ dependencies = [ "sp-io 2.0.0", "sp-runtime 2.0.0", "sp-state-machine 0.8.0", - "trybuild 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "trybuild 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1510,7 +1508,7 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1521,11 +1519,11 @@ 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)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1536,7 +1534,7 @@ dependencies = [ "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures-task 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)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1550,9 +1548,9 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" 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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1597,7 +1595,7 @@ dependencies = [ "futures-macro 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-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1624,8 +1622,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (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)", + "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1671,12 +1669,12 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.1.13" +version = "0.1.14" 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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1688,7 +1686,7 @@ dependencies = [ "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "fallible-iterator 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)", + "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1707,19 +1705,19 @@ name = "globset" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", - "bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bstr 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "goblin" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "scroll 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1728,18 +1726,18 @@ dependencies = [ name = "grafana-data-source" version = "0.8.0" dependencies = [ - "async-std 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-std 1.4.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)", "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.10 (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.104 (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)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1762,8 +1760,8 @@ dependencies = [ "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.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.10 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.1 (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-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1780,10 +1778,10 @@ dependencies = [ "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.10 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.1 (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)", - "tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1833,7 +1831,7 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1887,7 +1885,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)", "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)", + "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1897,7 +1895,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.4 (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)", + "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1930,7 +1928,7 @@ name = "humantime" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1943,7 +1941,7 @@ dependencies = [ "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1964,8 +1962,8 @@ dependencies = [ "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)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.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)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1993,11 +1991,11 @@ dependencies = [ "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)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.5 (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.8 (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)", + "tokio 0.2.11 (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)", ] @@ -2013,7 +2011,7 @@ dependencies = [ "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-rustls 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-rustls 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", "webpki-roots 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2037,7 +2035,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.11 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2047,7 +2045,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.11 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2074,27 +2072,35 @@ dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "impl-serde" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "impl-trait-for-tuples" version = "0.1.3" 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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "indexmap" -version = "1.3.0" +version = "1.3.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)", + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "integer-sqrt" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2125,17 +2131,15 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "jobserver" -version = "0.1.17" +version = "0.1.19" 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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2157,9 +2161,9 @@ dependencies = [ "hyper-tls 0.3.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.10 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (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.24.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2171,10 +2175,10 @@ 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.10 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2191,9 +2195,9 @@ 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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2204,7 +2208,7 @@ dependencies = [ "hyper 0.12.35 (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.10 (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)", "unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2216,7 +2220,7 @@ version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2230,7 +2234,7 @@ dependencies = [ "globset 0.4.4 (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.10 (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)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2243,7 +2247,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "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.10 (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)", "ws 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2278,7 +2282,7 @@ name = "kv-log-macro" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2309,12 +2313,12 @@ dependencies = [ "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.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.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.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.4.1 (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)", + "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rocksdb 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2328,7 +2332,7 @@ dependencies = [ "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "send_wrapper 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2344,9 +2348,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "lazycell" @@ -2363,7 +2364,7 @@ name = "libloading" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2395,10 +2396,10 @@ dependencies = [ "libp2p-wasm-ext 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-websocket 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-yamux 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-multiaddr 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2416,20 +2417,20 @@ dependencies = [ "futures-timer 2.0.2 (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.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-multiaddr 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", - "rw-stream-sink 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rw-stream-sink 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.3.0 (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)", @@ -2442,7 +2443,7 @@ version = "0.15.0" 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.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2462,7 +2463,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2496,7 +2497,7 @@ dependencies = [ "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-swarm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2515,7 +2516,7 @@ dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-swarm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2535,7 +2536,7 @@ dependencies = [ "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-swarm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-multihash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2553,7 +2554,7 @@ name = "libp2p-mdns" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "async-std 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-std 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "dns-parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2561,7 +2562,7 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-swarm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2579,7 +2580,7 @@ dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2593,7 +2594,7 @@ dependencies = [ "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)", "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2611,7 +2612,7 @@ dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-swarm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.3 (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.2.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2626,10 +2627,10 @@ dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rw-stream-sink 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rw-stream-sink 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2646,15 +2647,15 @@ dependencies = [ "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "quicksink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", - "rw-stream-sink 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rw-stream-sink 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2670,7 +2671,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.1.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.2.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2681,13 +2682,13 @@ name = "libp2p-tcp" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "async-std 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-std 1.4.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)", "get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "ipnet 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2695,10 +2696,10 @@ name = "libp2p-uds" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "async-std 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-std 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2724,12 +2725,12 @@ dependencies = [ "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "quicksink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rw-stream-sink 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "soketto 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rw-stream-sink 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "soketto 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", "webpki-roots 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2741,10 +2742,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "yamux 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "yamux 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2753,7 +2754,7 @@ version = "6.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "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)", + "cc 1.0.50 (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)", ] @@ -2763,7 +2764,7 @@ name = "libsecp256k1" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "hmac-drbg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2778,7 +2779,7 @@ name = "libz-sys" version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (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.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2807,7 +2808,7 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2818,12 +2819,12 @@ name = "log" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "log" -version = "0.4.10" +version = "0.4.8" 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)", @@ -2858,8 +2859,8 @@ name = "malloc_size_of_derive" 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.11 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2875,7 +2876,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memchr" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2943,7 +2944,7 @@ dependencies = [ "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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2956,7 +2957,7 @@ 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.10 (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.21 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3004,7 +3005,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.4 (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.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.1.0 (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.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3025,7 +3026,7 @@ 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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.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.53 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3045,30 +3046,17 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "nix" -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.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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "node-cli" version = "2.0.0" dependencies = [ "browser-utils 0.8.0", - "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.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)", "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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", @@ -3113,10 +3101,9 @@ dependencies = [ "sp-runtime 2.0.0", "sp-timestamp 2.0.0", "sp-transaction-pool 2.0.0", - "structopt 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-build-script-utils 2.0.0", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3126,7 +3113,7 @@ dependencies = [ name = "node-executor" version = "2.0.0" dependencies = [ - "criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "criterion 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "frame-support 2.0.0", "frame-system 2.0.0", "node-primitives 2.0.0", @@ -3188,7 +3175,7 @@ dependencies = [ "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.5 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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", "sc-rpc 2.0.0", ] @@ -3201,7 +3188,7 @@ dependencies = [ "frame-support 2.0.0", "frame-system 2.0.0", "frame-system-rpc-runtime-api 2.0.0", - "integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "integer-sqrt 0.1.3 (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", @@ -3256,9 +3243,8 @@ dependencies = [ name = "node-template" version = "2.0.0" dependencies = [ - "ctrlc 3.1.3 (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.10 (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", "sc-basic-authorship 0.8.0", "sc-cli 0.8.0", @@ -3276,8 +3262,8 @@ dependencies = [ "sp-inherents 2.0.0", "sp-runtime 2.0.0", "sp-transaction-pool 2.0.0", + "structopt 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-build-script-utils 2.0.0", - "tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3347,7 +3333,7 @@ dependencies = [ name = "node-transaction-factory" version = "0.8.0" dependencies = [ - "log 0.4.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "sc-cli 0.8.0", "sc-client 0.8.0", @@ -3368,7 +3354,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "nohash-hasher" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -3376,54 +3362,54 @@ name = "nom" version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-bigint" -version = "0.2.3" +version = "0.2.6" 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.10 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-integer" -version = "0.1.41" +version = "0.1.42" 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.10 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-rational" -version = "0.2.2" +version = "0.2.3" 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-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.10 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num_cpus" -version = "1.11.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3451,7 +3437,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "once_cell" -version = "1.2.0" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "oorandom" +version = "11.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -3483,7 +3474,7 @@ 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.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (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.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3665,7 +3656,7 @@ dependencies = [ "pallet-contracts-rpc-runtime-api 0.8.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "sp-api 2.0.0", "sp-blockchain 2.0.0", "sp-core 2.0.0", @@ -3742,7 +3733,7 @@ dependencies = [ "pallet-balances 2.0.0", "pallet-timestamp 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.6.2 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4019,10 +4010,10 @@ name = "pallet-staking-reward-curve" 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)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4095,7 +4086,7 @@ dependencies = [ "frame-support 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "sp-api 2.0.0", "sp-runtime 2.0.0", "sp-std 2.0.0", @@ -4141,7 +4132,7 @@ name = "parity-multiaddr" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "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)", @@ -4155,10 +4146,10 @@ dependencies = [ [[package]] name = "parity-multiaddr" -version = "0.7.0" +version = "0.7.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)", + "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4167,7 +4158,7 @@ dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4178,7 +4169,7 @@ dependencies = [ "blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4192,7 +4183,7 @@ dependencies = [ "blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4205,7 +4196,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "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)", + "byte-slice-cast 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec-derive 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4216,9 +4207,9 @@ version = "1.1.1" 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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4254,8 +4245,8 @@ name = "parity-util-mem-derive" version = "0.1.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)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4286,7 +4277,7 @@ name = "parking_lot" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api 0.3.3 (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)", ] @@ -4296,7 +4287,7 @@ name = "parking_lot" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4354,9 +4345,9 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" 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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4402,30 +4393,30 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fixedbitset 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)", + "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pin-project" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "pin-project-internal 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-internal 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pin-project-internal" -version = "0.4.6" +version = "0.4.8" 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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pin-project-lite" -version = "0.1.1" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -4443,6 +4434,17 @@ name = "plain" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "plotters" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ppv-lite86" version = "0.2.6" @@ -4461,13 +4463,13 @@ dependencies = [ [[package]] name = "primitive-types" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "fixed-hash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fixed-hash 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "impl-codec 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "impl-rlp 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)", + "impl-serde 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "uint 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4476,30 +4478,30 @@ name = "proc-macro-crate" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "proc-macro-error" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro-error-attr 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-error-attr 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (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)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "proc-macro-error-attr" -version = "0.4.3" +version = "0.4.5" 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)", + "proc-macro2 1.0.8 (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)", - "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", + "rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", "syn-mid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4508,9 +4510,9 @@ name = "proc-macro-hack" version = "0.5.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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4528,7 +4530,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4561,7 +4563,7 @@ 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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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)", "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4578,7 +4580,7 @@ dependencies = [ "bytes 0.5.4 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "multimap 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "petgraph 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4604,11 +4606,11 @@ name = "prost-derive" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4635,22 +4637,22 @@ 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.10 (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.41.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "quick-error" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "quickcheck" -version = "0.9.0" +version = "0.9.2" 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.10 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4662,7 +4664,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "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)", - "pin-project-lite 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4678,7 +4680,7 @@ name = "quote" version = "1.0.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)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4725,7 +4727,7 @@ name = "rand" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.14 (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)", @@ -4768,7 +4770,7 @@ name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4819,15 +4821,6 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rand_os" -version = "0.2.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)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rand_pcg" version = "0.1.2" @@ -4854,44 +4847,36 @@ dependencies = [ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rand_xoshiro" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "raw-cpuid" 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.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (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 = "rayon" -version = "1.2.1" +version = "1.3.0" 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)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rayon-core" -version = "1.6.1" +version = "1.7.0" 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)", - "crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4909,24 +4894,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "redox_users" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "1.3.1" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4939,7 +4923,7 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.12" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -4966,7 +4950,7 @@ name = "ring" version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (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.66 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4994,7 +4978,7 @@ dependencies = [ [[package]] name = "rpassword" -version = "4.0.3" +version = "4.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5003,12 +4987,13 @@ dependencies = [ [[package]] name = "rust-argon2" -version = "0.5.1" +version = "0.7.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)", - "blake2b_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5035,7 +5020,7 @@ version = "0.16.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)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", "sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5043,20 +5028,21 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.0" +version = "1.0.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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rw-stream-sink" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5080,10 +5066,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "same-file" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5096,17 +5082,17 @@ 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)", "libp2p 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quickcheck 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quickcheck 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (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)", + "serde_json 1.0.45 (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", @@ -5120,7 +5106,7 @@ name = "sc-basic-authorship" version = "0.8.0" dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.2 (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 0.8.0", @@ -5163,7 +5149,7 @@ dependencies = [ "sc-network 0.8.0", "sc-telemetry 2.0.0", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-runtime 2.0.0", ] @@ -5173,9 +5159,9 @@ 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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5184,33 +5170,34 @@ version = "0.8.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)", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.10 (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)", + "fdlimit 0.1.2 (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.10 (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)", + "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rpassword 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sc-client-api 2.0.0", "sc-network 0.8.0", "sc-service 0.8.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)", + "serde_json 1.0.45 (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 0.8.0", - "structopt 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.3.8 (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)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5225,7 +5212,7 @@ dependencies = [ "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-memorydb 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.2 (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 0.8.0", @@ -5247,7 +5234,7 @@ dependencies = [ "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)", + "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5260,7 +5247,7 @@ dependencies = [ "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.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.2 (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 0.8.0", @@ -5291,11 +5278,11 @@ dependencies = [ "kvdb-memorydb 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "kvdb-rocksdb 0.4.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)", - "log 0.4.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.4.1 (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)", + "quickcheck 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "sc-client 0.8.0", "sc-client-api 2.0.0", "sc-executor 0.8.0", @@ -5320,7 +5307,7 @@ 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)", - "log 0.4.10 (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.2 (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 0.8.0", @@ -5360,11 +5347,11 @@ 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)", - "log 0.4.10 (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)", + "num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num-rational 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (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)", @@ -5409,7 +5396,7 @@ dependencies = [ "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.10 (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.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "sc-basic-authorship 0.8.0", "sc-client 0.8.0", @@ -5423,7 +5410,7 @@ dependencies = [ "sp-transaction-pool 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.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5432,7 +5419,7 @@ 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.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "sc-client-api 2.0.0", "sp-api 2.0.0", @@ -5452,7 +5439,7 @@ 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.10 (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.2 (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", @@ -5471,7 +5458,7 @@ dependencies = [ name = "sc-consensus-uncles" version = "0.8.0" dependencies = [ - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "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", @@ -5489,7 +5476,7 @@ 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)", "libsecp256k1 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.2 (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)", @@ -5518,7 +5505,7 @@ name = "sc-executor-common" version = "0.8.0" dependencies = [ "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "sp-allocator 2.0.0", "sp-core 2.0.0", @@ -5532,7 +5519,7 @@ dependencies = [ name = "sc-executor-wasmi" version = "0.8.0" dependencies = [ - "log 0.4.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)", "sc-executor-common 0.8.0", @@ -5553,7 +5540,7 @@ dependencies = [ "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)", - "log 0.4.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)", "sc-executor-common 0.8.0", @@ -5577,10 +5564,10 @@ 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 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sc-client 0.8.0", "sc-client-api 2.0.0", @@ -5589,7 +5576,7 @@ dependencies = [ "sc-network-gossip 0.8.0", "sc-network-test 0.8.0", "sc-telemetry 2.0.0", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "sp-api 2.0.0", "sp-arithmetic 2.0.0", "sp-blockchain 2.0.0", @@ -5615,7 +5602,7 @@ dependencies = [ "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.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (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)", @@ -5631,7 +5618,7 @@ dependencies = [ "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)", + "erased-serde 0.3.10 (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.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5640,11 +5627,11 @@ dependencies = [ "libp2p 0.15.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)", "linked_hash_set 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.2 (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)", + "quickcheck 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "sc-block-builder 0.8.0", @@ -5652,7 +5639,7 @@ dependencies = [ "sc-client-api 2.0.0", "sc-peerset 2.0.0", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (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)", @@ -5680,7 +5667,7 @@ dependencies = [ "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.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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", @@ -5696,7 +5683,7 @@ dependencies = [ "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.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.3 (registry+https://github.com/rust-lang/crates.io-index)", "sc-block-builder 0.8.0", @@ -5726,8 +5713,8 @@ dependencies = [ "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.10 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.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.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.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.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5752,9 +5739,9 @@ version = "2.0.0" dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5767,7 +5754,7 @@ dependencies = [ "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.10 (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.2 (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.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5778,7 +5765,7 @@ dependencies = [ "sc-network 0.8.0", "sc-rpc-api 0.8.0", "sc-transaction-pool 2.0.0", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "sp-api 2.0.0", "sp-blockchain 2.0.0", "sp-core 2.0.0", @@ -5804,11 +5791,11 @@ dependencies = [ "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.10 (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.2 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (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", @@ -5823,9 +5810,9 @@ dependencies = [ "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.10 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "sp-runtime 2.0.0", ] @@ -5854,7 +5841,7 @@ dependencies = [ "futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "grafana-data-source 0.8.0", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5873,7 +5860,7 @@ dependencies = [ "sc-tracing 2.0.0", "sc-transaction-pool 2.0.0", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (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", @@ -5889,9 +5876,9 @@ dependencies = [ "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.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5899,10 +5886,10 @@ 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)", + "fdlimit 0.1.2 (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.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "sc-client 0.8.0", "sc-network 0.8.0", "sc-service 0.8.0", @@ -5919,7 +5906,7 @@ name = "sc-state-db" version = "0.8.0" dependencies = [ "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.2 (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", @@ -5933,9 +5920,9 @@ 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)", "libp2p 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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)", - "pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5949,16 +5936,16 @@ dependencies = [ name = "sc-tracing" version = "2.0.0" dependencies = [ - "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "erased-serde 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", "grafana-data-source 0.8.0", - "log 0.4.10 (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)", "sc-telemetry 2.0.0", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (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)", + "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5966,10 +5953,10 @@ 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)", + "criterion 0.3.1 (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.10 (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.2 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5986,7 +5973,7 @@ 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)", "futures-diagnose 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.2 (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", @@ -6048,9 +6035,9 @@ name = "scroll_derive" version = "0.10.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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6126,24 +6113,24 @@ name = "serde_derive" version = "1.0.104" 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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.44" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.5 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "sha-1" -version = "0.8.1" +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)", @@ -6194,6 +6181,15 @@ name = "shlex" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "signal-hook-registry" +version = "1.2.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)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "slab" version = "0.4.2" @@ -6204,7 +6200,7 @@ 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)", + "erased-serde 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6213,9 +6209,9 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "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)", + "erased-serde 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6234,9 +6230,9 @@ name = "slog_derive" version = "0.2.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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6257,7 +6253,7 @@ name = "snow" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayref 0.3.6 (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)", @@ -6266,7 +6262,7 @@ dependencies = [ [[package]] name = "soketto" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6275,12 +6271,12 @@ dependencies = [ "futures 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)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.3 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6293,7 +6289,7 @@ name = "sp-allocator" version = "2.0.0" dependencies = [ "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-std 2.0.0", "sp-wasm-interface 2.0.0", @@ -6320,18 +6316,18 @@ 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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "sp-api-test" version = "2.0.0" dependencies = [ - "criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "criterion 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustversion 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "sp-api 2.0.0", "sp-blockchain 2.0.0", "sp-consensus 0.8.0", @@ -6339,7 +6335,7 @@ dependencies = [ "sp-state-machine 0.8.0", "sp-version 2.0.0", "substrate-test-runtime-client 2.0.0", - "trybuild 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "trybuild 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6368,11 +6364,11 @@ dependencies = [ 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)", + "criterion 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "integer-sqrt 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-debug-derive 2.0.0", @@ -6416,7 +6412,7 @@ name = "sp-blockchain" version = "2.0.0" dependencies = [ "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6435,7 +6431,7 @@ dependencies = [ "futures-diagnose 1.0.0 (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.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.2 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6503,18 +6499,18 @@ dependencies = [ "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.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.10 (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.11 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (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)", + "primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.1.0 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "sp-debug-derive 2.0.0", "sp-externalities 0.8.0", @@ -6534,9 +6530,9 @@ dependencies = [ name = "sp-debug-derive" version = "2.0.0" dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6586,7 +6582,7 @@ version = "2.0.0" dependencies = [ "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "libsecp256k1 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-externalities 0.8.0", @@ -6619,8 +6615,8 @@ dependencies = [ name = "sp-panic-handler" version = "2.0.0" dependencies = [ - "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6640,7 +6636,7 @@ name = "sp-rpc" version = "2.0.0" dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", ] @@ -6649,12 +6645,12 @@ name = "sp-runtime" version = "2.0.0" dependencies = [ "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.2 (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.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (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", @@ -6668,8 +6664,8 @@ name = "sp-runtime-interface" version = "2.0.0" dependencies = [ "parity-scale-codec 1.1.2 (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)", + "primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-externalities 0.8.0", "sp-io 2.0.0", @@ -6679,7 +6675,7 @@ dependencies = [ "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)", + "trybuild 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6688,9 +6684,9 @@ version = "2.0.0" dependencies = [ "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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6735,7 +6731,7 @@ name = "sp-serializer" version = "2.0.0" dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6763,8 +6759,8 @@ version = "0.8.0" dependencies = [ "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)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.10 (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.11 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.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.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6819,7 +6815,7 @@ 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.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-api 2.0.0", @@ -6910,23 +6906,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "structopt" -version = "0.3.7" +version = "0.3.8" 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.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt-derive 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "structopt-derive" -version = "0.4.0" +version = "0.4.1" 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.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-error 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6943,9 +6940,9 @@ version = "0.16.0" 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 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6967,7 +6964,7 @@ dependencies = [ "pallet-transaction-payment 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rpassword 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rpassword 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "sc-rpc 2.0.0", "sp-core 2.0.0", @@ -7017,7 +7014,7 @@ dependencies = [ "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.10 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "sc-client 0.8.0", "sc-transaction-pool 2.0.0", @@ -7058,7 +7055,7 @@ dependencies = [ "frame-support 2.0.0", "frame-system 2.0.0", "frame-system-rpc-runtime-api 2.0.0", - "log 0.4.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.18.1 (registry+https://github.com/rust-lang/crates.io-index)", "pallet-babe 2.0.0", "pallet-timestamp 2.0.0", @@ -7114,13 +7111,13 @@ version = "2.0.0" name = "substrate-wasm-builder" version = "1.0.9" dependencies = [ - "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.14 (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.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)", - "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-gc-api 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7150,10 +7147,10 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.11" +version = "1.0.14" 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)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7163,9 +7160,9 @@ name = "syn-mid" version = "0.4.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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7173,9 +7170,9 @@ name = "synstructure" version = "0.12.3" 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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7187,7 +7184,7 @@ 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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7221,10 +7218,10 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.0.5" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7233,9 +7230,9 @@ version = "0.3.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)", - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7249,25 +7246,25 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "thiserror-impl 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror-impl 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "thiserror-impl" -version = "1.0.9" +version = "1.0.10" 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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "thread_local" -version = "0.3.6" +version = "1.0.1" 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)", @@ -7278,7 +7275,7 @@ name = "threadpool" version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7323,11 +7320,11 @@ dependencies = [ [[package]] name = "tinytemplate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7338,7 +7335,7 @@ 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.21 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.12.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-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7355,15 +7352,21 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.4" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.4 (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)", - "num_cpus 1.11.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)", - "tokio-macros 0.2.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.66 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.0 (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.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-macros 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7431,16 +7434,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)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-macros" -version = "0.2.0" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7451,9 +7455,9 @@ 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.10 (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.21 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.12.0 (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.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7463,7 +7467,7 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7516,8 +7520,8 @@ 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.10 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.11.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.12.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.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7550,7 +7554,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)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.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)", @@ -7566,7 +7570,7 @@ dependencies = [ "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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.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)", @@ -7582,14 +7586,14 @@ dependencies = [ "bytes 0.5.4 (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.10 (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)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "toml" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7602,31 +7606,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "tracing" -version = "0.1.10" +version = "0.1.12" 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)", - "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing-attributes 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing-core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing-attributes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tracing-attributes" -version = "0.1.5" +version = "0.1.6" 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.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tracing-core" -version = "0.1.7" +version = "0.1.9" 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)", - "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7656,7 +7658,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "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.10 (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)", "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7686,15 +7688,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "trybuild" -version = "1.0.18" +version = "1.0.21" 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.104 (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)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7762,7 +7764,7 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7820,7 +7822,7 @@ dependencies = [ [[package]] name = "url" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7870,7 +7872,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7879,19 +7881,19 @@ name = "wabt-sys" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (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)", ] [[package]] name = "walkdir" -version = "2.2.9" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7900,7 +7902,7 @@ 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)", - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7909,13 +7911,13 @@ name = "want" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "wasi" -version = "0.7.0" +version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -7934,10 +7936,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bumpalo 3.1.2 (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.10 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.6 (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.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7966,9 +7968,9 @@ name = "wasm-bindgen-macro-support" version = "0.2.58" 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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7983,12 +7985,12 @@ name = "wasm-bindgen-webidl" version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.26 (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.10 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.6 (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.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7998,7 +8000,7 @@ name = "wasm-gc-api" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.10 (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.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -8026,8 +8028,8 @@ dependencies = [ "errno 0.2.4 (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.10 (registry+https://github.com/rust-lang/crates.io-index)", + "num-rational 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (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)", ] @@ -8050,7 +8052,7 @@ name = "wasmtime-debug" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.26 (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)", @@ -8058,7 +8060,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.9 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.10 (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)", ] @@ -8076,17 +8078,17 @@ dependencies = [ "directories 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "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)", + "indexmap 1.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)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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)", + "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.1 (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.9 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.5.6 (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)", "zstd 0.5.1+zstd.1.4.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -8097,7 +8099,7 @@ name = "wasmtime-jit" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.26 (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)", @@ -8105,7 +8107,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.9 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.10 (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)", @@ -8118,17 +8120,17 @@ name = "wasmtime-runtime" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (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)", + "indexmap 1.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)", "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.9 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.10 (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)", ] @@ -8138,7 +8140,7 @@ name = "web-sys" version = "0.3.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys 0.3.35 (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.58 (registry+https://github.com/rust-lang/crates.io-index)", @@ -8260,7 +8262,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi-util" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -8271,15 +8273,6 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "wincolor" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "ws" version = "0.9.1" @@ -8288,13 +8281,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)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.10 (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.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.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -8323,16 +8316,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "yamux" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.4 (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.10 (registry+https://github.com/rust-lang/crates.io-index)", - "nohash-hasher 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)", + "nohash-hasher 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -8353,9 +8346,9 @@ 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)", + "proc-macro2 1.0.8 (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)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -8381,7 +8374,7 @@ 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.48 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.50 (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)", ] @@ -8393,24 +8386,25 @@ dependencies = [ "checksum aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" "checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" "checksum ahash 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6f33b5018f120946c1dcf279194f238a9f146725593ead1c08fa47ff22b0b5d3" -"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" +"checksum aho-corasick 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5f56c476256dc249def911d6f7580b5fc7e875895b5d7ee88f5d602208035744" "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.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9267dff192e68f3399525901e709a48c1d3982c9c072fa32f2127a0cb0babf14" +"checksum anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" "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" +"checksum arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" "checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" "checksum asn1_der 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6fce6b6a0ffdafebd82c87e79e3f40e8d2c523e5fea5566ff6b90509bf98d638" "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-std 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94ef4b71b2f56d7f8793c2a353fa0aa254833c55ab611dc6f3e0bd63db487e2d" -"checksum async-task 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de6bd58f7b9cc49032559422595c81cbfcf04db2f2133592f70af19e258a1ced" +"checksum async-std 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0bf6039b315300e057d198b9d3ab92ee029e31c759b7f1afae538145e6f18a3e" +"checksum async-task 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f20c6fda19d0fc02406779587ca4f9a4171cd32e4a5bda0bd016f0a1334c8d4a" "checksum async-tls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce6977f57fa68da77ffe5542950d47e9c23d65f5bc7cb0a9f8700996913eec7" -"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" +"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" -"checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" +"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" +"checksum backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b4b1549d804b6c73f4817df2ba073709e96e426f12987127c48e6745568c350b" "checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" "checksum base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" @@ -8423,17 +8417,17 @@ dependencies = [ "checksum bitvec 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a993f74b4c99c1908d156b8d2e0fb6277736b0ecbd833982fd1241d39b2766a6" "checksum blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" "checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" -"checksum blake2b_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b83b7baab1e671718d78204225800d6b170e648188ac7dc992e9d6bddf87d0c0" +"checksum blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" "checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" "checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" "checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" "checksum broadcaster 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "07a1446420a56f1030271649ba0da46d23239b3a68c73591cea5247f15a788a0" "checksum bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c95ee6bba9d950218b6cc910cf62bc9e0a171d0f4537e3627b0f54d08549b188" "checksum bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b170cd256a3f9fa6b9edae3e44a7dfdfc77e8124dbc3e2612d75f9c3e2396dae" -"checksum bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6c2c5b58ab920a4f5aeaaca34b4488074e8cc7596af94e6f8c6ff247c60245" +"checksum bstr 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "fe8a65814ca90dfc9705af76bb6ba3c6e2534489a72270e797e603783bb4990b" "checksum build-helper 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdce191bf3fa4995ce948c8c83b4640a1745457a149e73c6db75b4ffe36aad5f" "checksum bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb8038c1ddc0a5f73787b130f4cc75151e96ed33e417fde765eb5a81e3532f4" -"checksum byte-slice-cast 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f6209f3b2c1edea170002e016d5ead6903d3bb0a846477f53bbeb614967a52a9" +"checksum byte-slice-cast 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "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" @@ -8443,7 +8437,7 @@ dependencies = [ "checksum c_linked_list 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" "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.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76" +"checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" "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.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" @@ -8454,9 +8448,9 @@ dependencies = [ "checksum cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62" "checksum console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211" "checksum console_log 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1e7871d2947441b0fdd8e2bd1ce2a2f75304f896582c0d572162d48290683c48" -"checksum const-random 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7b641a8c9867e341f3295564203b1c250eb8ce6cb6126e007941f78c4d2ed7fe" -"checksum const-random-macro 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c750ec12b83377637110d5a57f5ae08e895b06c4b16e2bdbf1a94ef717428c59" -"checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120" +"checksum const-random 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "2f1af9ac737b2dd2d577701e59fd09ba34822f6f2ebdb30a7647405d9e55e16a" +"checksum const-random-macro 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "25e4c606eb459dd29f7c57b2e0879f2b6f14ee130918c2b78ccb58a9624e6c7a" +"checksum constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" "checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" "checksum cranelift-bforest 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd05aac8cefcde54ce26178df8f36cb1f518ac691db650e7d2440c2b6b41c4dc" @@ -8469,24 +8463,23 @@ dependencies = [ "checksum cranelift-wasm 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "54cb82a1071f88822763a583ec1a8688ffe5e2cda02c111d4483dd4376ed14d8" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" "checksum criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394" -"checksum criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "938703e165481c8d612ea3479ac8342e5615185db37765162e762ec3523e2fc6" +"checksum criterion 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc755679c12bda8e5523a71e4d654b6bf2e14bd838dfc48cde6559a05caf7d1" "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 criterion-plot 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a01e15e0ea58e8234f96146b1f91fa9d0e4dd7a38da93ff7a75d42c0b9d3a545" "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" "checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" -"checksum crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfd6515864a82d2f877b42813d4553292c6659498c9a2aa31bab5a15243c2700" +"checksum crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db" "checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" "checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" "checksum crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" "checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" -"checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d" +"checksum csv 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "00affe7f6ab566df61b4be3ce8cf16bc2576bca0963ceb0955e45d514bf9a279" "checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c" "checksum ct-logs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4d3686f5fa27dbc1d76c751300376e167c5a43387f44bb451fd1c24776e49113" "checksum ctor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8ce37ad4184ab2ce004c33bf6379185d3b1c95801cab51026bd271bf68eedc" "checksum ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "022cd691704491df67d25d006fe8eca083098253c4d43516c2206479c58c6736" -"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" @@ -8505,7 +8498,7 @@ dependencies = [ "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.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "516aa8d7a71cb00a1c4146f0798549b93d083d4f189b3ced8f3de6b8f11ee6c4" -"checksum erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3beee4bc16478a1b26f2e80ad819a52d24745e292f521a63c16eea5f74b7eb60" +"checksum erased-serde 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)" = "cd7d80305c9bd8cd78e3c753eb9fb110f83621e5211f1a3afffcc812b104daf9" "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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "32a2c6961fdc9952371fc5f0416f03a9d90378a9dfb6862f6a7a9a3b8986b8dd" @@ -8518,10 +8511,10 @@ dependencies = [ "checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" "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 fdlimit 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9084c55bb76efb1496328976db88320fe7d9ee86e649e83c4ecce3ba7a9a35d1" "checksum file-per-thread-logger 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8505b75b31ef7285168dd237c4a7db3c1f3e0927e7d314e670bc98e854272fe9" "checksum finality-grandpa 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "52c48f8a628193ba18639b2f727c32132d75f167a4b32f44b252ea8b937f154c" -"checksum fixed-hash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72fe7539e2c5692c6989f2f9c0457e42f1e5768f96b85c87d273574670ae459f" +"checksum fixed-hash 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" "checksum fixedbitset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" "checksum flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" @@ -8557,12 +8550,12 @@ dependencies = [ "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" "checksum get_if_addrs-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d04f9fb746cf36b191c00f3ede8bde9c8e64f9f4b05ae2694a9ccf5e3f5ab48" -"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407" +"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" "checksum gimli 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "162d18ae5f2e3b90a993d202f1ba17a5633c2484426f8bcae201f86194bacd00" "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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88a79ef1f0dad46fd78075b6f80f92d97710eddf87b3e18a15a66761e8942672" +"checksum goblin 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3081214398d39e4bd7f2c1975f0488ed04614ffdd976c6fc7a0708278552c0da" "checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" "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" @@ -8571,7 +8564,7 @@ dependencies = [ "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 heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" -"checksum hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f629dc602392d3ec14bfc8a09b5e644d7ffd725102b48b81e59f90f2633621d7" +"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" "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" @@ -8593,15 +8586,16 @@ dependencies = [ "checksum impl-codec 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" "checksum impl-rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8f7a72f11830b52333f36e3b09a288333888bf54380fd0ac0790a3c31ab0f3c5" "checksum impl-serde 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "58e3cae7e99c7ff5a995da2cf78dd0a5383740eda71d98cf7b1910c301ac69b8" +"checksum impl-serde 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5bbe9ea9b182f0fb1cabbd61f4ff9b7b7b9197955e95a7e4c27de5055eb29ff8" "checksum impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" -"checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2" -"checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" +"checksum indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b54058f0a6ff80b6803da8faf8997cde53872b38f4023728f6830b06cd3c0dc" +"checksum integer-sqrt 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f65877bf7d44897a473350b1046277941cee20b263397e90869c50b6e766088b" "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.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 itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" +"checksum jobserver 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "67b06c1b455f1cf4269a8cfc320ab930a810e2375a42af5075eb8a8b36405ce0" "checksum js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "7889c7c36282151f6bf465be4700359318aef36baa951462382eae49e9577cf9" "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" @@ -8651,16 +8645,16 @@ dependencies = [ "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.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586" +"checksum lock_api 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "1b9ad466a945c9c40f6f9a449c55675547e59bc75a2722d4689042ab3ae80c9c" +"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "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 memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3197e20c7edb283f87c071ddfc7a2cca8f8e0b888c242959846a6fce03c72223" "checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" "checksum memory-db 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "881736a0f68a6fae1b596bb066c5bd16d7b3ed645a4dd8ffaefd02f585abaf71" "checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" @@ -8678,19 +8672,19 @@ dependencies = [ "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" -"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" "checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" -"checksum nohash-hasher 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4e657a6ec97f9a3ba46f6f7034ea6db9fcd5b71d25ef1074b7bc03da49be0e8e" +"checksum nohash-hasher 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "721a2bf1c26159ebf17e0a980bc4ce61f4b2fec5ec3b42d42fddd7a84a9e538f" "checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" -"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.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 num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +"checksum num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" +"checksum num-rational 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "da4dc79f9e6c81bef96148c8f6b8e72ad4541caa4a24373e900a36da07de03a3" +"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" +"checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" "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 once_cell 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b" +"checksum oorandom 11.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebcec7c9c2a95cacc7cd0ecb89d8a8454eca13906f6deb55258ffff0adeb9405" "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" "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" @@ -8699,7 +8693,7 @@ dependencies = [ "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" "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.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6de20a133b50f5120c6b8284ee88c5017fb167149208b3ee2e95f8719a434dc4" +"checksum parity-multiaddr 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80878c27f90dd162d3143333d672e80b194d6b080f05c83440e3dfda42e409f2" "checksum parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df3a17dc27848fd99e4f87eb0f8c9baba6ede0a6d555400c850ca45254ef4ce3" "checksum parity-multihash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70a4d7b05e51bff5ae2c29c7b8c3d889985bbd8f4e15b3542fcc1f6f9666d292" "checksum parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f747c06d9f3b2ad387ac881b9667298c81b1243aa9833f086e05996937c35507" @@ -8725,22 +8719,23 @@ dependencies = [ "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" "checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" "checksum petgraph 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29c127eea4a29ec6c85d153c59dc1213f33ec74cead30fe4730aecc88cc1fd92" -"checksum pin-project 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "94b90146c7216e4cb534069fb91366de4ea0ea353105ee45ed297e2d1619e469" -"checksum pin-project-internal 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "44ca92f893f0656d3cba8158dd0f2b99b94de256a4a54e870bd6922fcc6c8355" -"checksum pin-project-lite 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f0af6cbca0e6e3ce8692ee19fb8d734b641899e07b68eb73e9bbbd32f1703991" +"checksum pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7804a463a8d9572f13453c516a5faea534a2403d7ced2f0c7e100eeff072772c" +"checksum pin-project-internal 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" +"checksum pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae" "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" "checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" "checksum plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +"checksum plotters 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "4e3bb8da247d27ae212529352020f3e5ee16e83c0c258061d27b08ab92675eeb" "checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" "checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" -"checksum primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a0253db64c26d8b4e7896dd2063b516d2a1b9e0a5da26b5b78335f236d1e9522" +"checksum primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e4336f4f5d5524fa60bcbd6fe626f9223d8142a50e7053e979acdf0da41ab975" "checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" -"checksum proc-macro-error 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "53c98547ceaea14eeb26fcadf51dc70d01a2479a7839170eae133721105e4428" -"checksum proc-macro-error-attr 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c2bf5d493cf5d3e296beccfd61794e445e830dfc8070a9c248ad3ee071392c6c" +"checksum proc-macro-error 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1b79a464461615532fcc8a6ed8296fa66cc12350c18460ab3f4594a6cee0fcb6" +"checksum proc-macro-error-attr 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "23832e5eae6bac56bbac190500eef1aaede63776b5cd131eaa4ee7fe120cd892" "checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" "checksum proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" +"checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" "checksum prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96d14b1c185652833d24aaad41c5832b0be5616a590227c1fbff57c616754b23" "checksum prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212" "checksum prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb788126ea840817128183f8f603dce02cb7aea25c2a0b764359d8e20010702e" @@ -8750,8 +8745,8 @@ dependencies = [ "checksum prost-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1de482a366941c8d56d19b650fac09ca08508f2a696119ee7513ad590c8bac6f" "checksum prost-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1834f67c0697c001304b75be76f67add9c89742eda3a085ad8ee0bb38c3417aa" "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.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5ca504a2fdaa08d3517f442fbbba91ac24d1ec4c51ea68688a038765e3b2662" +"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +"checksum quickcheck 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f" "checksum quicksink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a8461ef7445f61fd72d8dcd0629ce724b9131b3c2eb36e83a5d3d4161c127530" "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" @@ -8769,37 +8764,35 @@ dependencies = [ "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" "checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -"checksum rand_os 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a788ae3edb696cfcba1c19bfd388cc4b8c21f8a408432b199c072825084da58a" "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" "checksum rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03b418169fb9c46533f326efd6eed2576699c44ca92d3052a066214a8d828929" -"checksum rand_xoshiro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e18c91676f670f6f0312764c759405f13afb98d5d73819840cf72a518487bff" "checksum raw-cpuid 7.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4a349ca83373cfa5d6dbb66fd76e58b2cca08da71a5f6400de0a0a6a9bceeaf" -"checksum rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43739f8831493b276363637423d3622d4bd6394ab6f0a9c4a552e208aeb7fddd" -"checksum rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8bf17de6f23b05473c437eb958b9c850bfc8af0961fe17b4cc92d5a627b4791" +"checksum rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098" +"checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" -"checksum redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecedbca3bf205f8d8f5c2b44d83cd0690e39ee84b951ed649e9f1841132b66d" -"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" +"checksum redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" +"checksum regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5508c1941e4e7cb19965abef075d35a9a8b5cdf0846f30b4050e9b55dc55e87" "checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9" -"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" +"checksum regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e734e891f5b408a29efbf8309e656876276f49ab6a6ac208600b4419bd893d90" "checksum region 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "448e868c6e4cfddfa49b6a72c95906c04e8547465e9536575b95c70a4044f856" "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.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 rpassword 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "99371657d3c8e4d816fb6221db98fa408242b0b53bac08f8676a41f8554fe99f" +"checksum rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" "checksum rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b25a18b1bf7387f0145e7f8324e700805aade3842dd3db2e74e4cdeb4677c09e" -"checksum rustversion 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c48f91977f4ef3be5358c15d131d3f663f6b4d7a112555bf3bf52ad23b6659e5" -"checksum rw-stream-sink 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "761d4727649dc004ee5555a0779afd53963efafd2218c969a2c5e323cdf73a09" +"checksum rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" +"checksum rw-stream-sink 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020" "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" "checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347" "checksum safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" -"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" +"checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" "checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" "checksum schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eacd8381b3c37840c9c9f40472af529e49975bdcbc24f83c31059fd6539023d3" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" @@ -8816,13 +8809,14 @@ dependencies = [ "checksum send_wrapper 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "686ef91cf020ad8d4aca9a7047641fd6add626b7b89e14546c2b6a76781cf822" "checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" "checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" -"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 serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "eab8f15f15d6c41a154c1b128a22f2dfabe350ef53c40953d84e36155c91192b" +"checksum sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" "checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" "checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" "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 signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" "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-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddc0d2aff1f8f325ef660d9a0eb6e6dcd20b30b3f581a5897f58bf42d061c37a" @@ -8831,7 +8825,7 @@ dependencies = [ "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4" "checksum snow 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "afb767eee7d257ba202f0b9b08673bc13b22281632ef45267b19f13100accd2f" -"checksum soketto 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3caa0ad6b765419f21e4cfa490ec7514a9fae4af986adef168a69477ba528671" +"checksum soketto 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c9dab3f95c9ebdf3a88268c19af668f637a3c5039c2c56ff2d40b1b2d64a25b" "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" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" @@ -8840,15 +8834,15 @@ 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.7 (registry+https://github.com/rust-lang/crates.io-index)" = "884ae79d6aad1e738f4a70dff314203fd498490a63ebc4d03ea83323c40b7b72" -"checksum structopt-derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a97f829a34a0a9d5b353a881025a23b8c9fd09d46be6045df6b22920dbd7a93" +"checksum structopt 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "df136b42d76b1fbea72e2ab3057343977b04b4a2e00836c3c7c0673829572713" +"checksum structopt-derive 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd50a87d2f7b8958055f3e73a963d78feaccca3836767a9069844e34b5b03c0a" "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.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.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238" +"checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" "checksum syn-mid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd3937748a7eccff61ba5b90af1a20dbf610858923a9192ea0ecb0cb77db1d0" "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" @@ -8856,20 +8850,20 @@ dependencies = [ "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 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 termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" "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.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 thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "205684fd018ca14432b12cce6ea3d46763311a571c3d294e71ba3f01adcf1aad" +"checksum thiserror-impl 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "57e4d2e50ca050ed44fb58309bdce3efa79948f84f9993ad1978de5eebdce5a7" +"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" "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" "checksum tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c5676413eaeb1ea35300a0224416f57abc3bd251657e0fafc12c47ff98c060" "checksum tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2" "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 tinytemplate 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "57a3c6667d3e65eb1bc3aed6fd14011c6cbc3a0665218ab7f5daf040b9ec371a" "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 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8fdd17989496f49cdc57978c96f0c9fe5e4a58a8bddc6813c449a4624f6a030b" "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-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" @@ -8877,9 +8871,9 @@ dependencies = [ "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-macros 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5795a71419535c6dcecc9b6ca95bdd3c2d6142f7e8343d7beb9923f129aa87e" +"checksum tokio-macros 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f4b1e7ed7d5d4c2af3d999904b0eebe76544897cdbfb2b9684bed2174ab20f7c" "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-rustls 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d7cf08f990090abd6c6a73cab46fed62f85e8aef8b99e4b918a9f4a637f0676" "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" @@ -8889,18 +8883,18 @@ dependencies = [ "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 toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" "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 tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1e213bd24252abeb86a0b7060e02df677d367ce6cb772cef17e9214b8390a8d3" +"checksum tracing-attributes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04cfd395def5a60236e187e1ff905cb55668a59f29928dec05e6e1b1fd2ac1f3" +"checksum tracing-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "13a46f11e372b8bd4b4398ea54353412fdd7fd42a8370c7e543e218cf7661978" "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" "checksum trie-bench 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26fd042d57ee9c987c562811162a78db78b5340ab674ac76056c85dca49b26bc" "checksum trie-db 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a0d747ae5b6f078df7e46477fcc7df66df9eb4f27a031cf4a7c890a8dd03d8e6" "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.18 (registry+https://github.com/rust-lang/crates.io-index)" = "b75e31d624df08744532e935f1d4bfedd319a277d5a162c5b15f6ced59307575" +"checksum trybuild 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "3f5b3f750c701725331ac78e389b5d143b7d25f6b6ffffd0d419759a9063ac5f" "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" @@ -8909,7 +8903,7 @@ 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.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf" +"checksum unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" "checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" "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" @@ -8918,7 +8912,7 @@ dependencies = [ "checksum unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c689459fbaeb50e56c6749275f084decfd02194ac5852e6617d95d0d3cf02eaf" "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 url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" "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" @@ -8927,10 +8921,10 @@ dependencies = [ "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3c5c5c1286c6e578416982609f47594265f9d489f9b836157d403ad605a46693" "checksum wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "af5d153dc96aad7dc13ab90835b892c69867948112d95299e522d370c4e13a08" -"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" +"checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" "checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" "checksum want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" +"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" "checksum wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c" "checksum wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "11cdb95816290b525b32587d76419facd99662a07e59d3cdb560488a819d9a45" "checksum wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8bbdd49e3e28b40dec6a9ba8d17798245ce32b019513a845369c641b275135d9" @@ -8960,14 +8954,13 @@ dependencies = [ "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" +"checksum winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9" "checksum ws 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a2c47b5798ccc774ffb93ff536aec7c4275d722fd9c740c83cdd1af1f2d94" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ee1585dc1484373cbc1cee7aafda26634665cf449436fd6e24bfd1fad230538" "checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" -"checksum yamux 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "809f4388471d280173404e3d4f889e2d36004960a37d822ce5637fbef33a0ce4" +"checksum yamux 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f937668802a2e862a4fed05267e10b20c310bf771adc89687710706d55a9a65" "checksum zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" "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" diff --git a/bin/node-template/Cargo.toml b/bin/node-template/Cargo.toml index 9ad91a973c..7001099b0b 100644 --- a/bin/node-template/Cargo.toml +++ b/bin/node-template/Cargo.toml @@ -12,9 +12,7 @@ path = "src/main.rs" [dependencies] futures = "0.3.1" -ctrlc = { version = "3.1.3", features = ["termination"] } log = "0.4.8" -tokio = { version = "0.2", features = ["rt-threaded"] } sc-cli = { version = "0.8.0", path = "../../client/cli" } sp-core = { version = "2.0.0", path = "../../primitives/core" } sc-executor = { version = "0.8", path = "../../client/executor" } @@ -31,7 +29,8 @@ grandpa-primitives = { version = "2.0.0", package = "sp-finality-grandpa", path sc-client = { version = "0.8", path = "../../client/" } node-template-runtime = { version = "2.0.0", path = "runtime" } sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } -sc-basic-authorship = { path = "../../client/basic-authorship" } +sc-basic-authorship = { path = "../../client/basic-authorship" } +structopt = "0.3.8" [build-dependencies] vergen = "3.0.4" diff --git a/bin/node-template/src/chain_spec.rs b/bin/node-template/src/chain_spec.rs index 6afb67547b..6c6ab492a3 100644 --- a/bin/node-template/src/chain_spec.rs +++ b/bin/node-template/src/chain_spec.rs @@ -145,3 +145,10 @@ fn testnet_genesis(initial_authorities: Vec<(AuraId, GrandpaId)>, }), } } + +pub fn load_spec(id: &str) -> Result, String> { + Ok(match Alternative::from(id) { + Some(spec) => Some(spec.load()?), + None => None, + }) +} diff --git a/bin/node-template/src/cli.rs b/bin/node-template/src/cli.rs index 8408f17379..0091ef7d75 100644 --- a/bin/node-template/src/cli.rs +++ b/bin/node-template/src/cli.rs @@ -1,121 +1,11 @@ -use crate::service; -use futures::{future::{select, Map, Either}, FutureExt, channel::oneshot}; -use std::cell::RefCell; -use tokio::runtime::Runtime; -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; +use sc_cli::{RunCmd, Subcommand}; +use structopt::StructOpt; -/// Parse command line arguments into service configuration. -pub fn run(args: I, exit: E, version: VersionInfo) -> error::Result<()> where - I: IntoIterator, - T: Into + Clone, - E: IntoExit, -{ - type Config = Configuration<(), T>; - match parse_and_prepare::(&version, "substrate-node", args) { - ParseAndPrepare::Run(cmd) => cmd.run(load_spec, exit, - |exit, _cli_args, _custom_args, mut config: Config<_>| { - info!("{}", version.name); - info!(" version {}", config.full_version()); - info!(" by {}, 2017, 2018", version.author); - info!("Chain specification: {}", config.chain_spec.name()); - info!("Node name: {}", config.name); - info!("Roles: {}", display_role(&config)); - let runtime = Runtime::new().map_err(|e| format!("{:?}", e))?; - config.tasks_executor = { - let runtime_handle = runtime.handle().clone(); - Some(Box::new(move |fut| { runtime_handle.spawn(fut); })) - }; - match config.roles { - ServiceRoles::LIGHT => run_until_exit( - runtime, - service::new_light(config)?, - exit - ), - _ => run_until_exit( - runtime, - service::new_full(config)?, - exit - ), - } - }), - ParseAndPrepare::BuildSpec(cmd) => cmd.run::(load_spec), - ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder(|config: Config<_>| - 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(_) => Ok(()) - }?; +#[derive(Debug, StructOpt)] +pub struct Cli { + #[structopt(subcommand)] + pub subcommand: Option, - Ok(()) -} - -fn load_spec(id: &str) -> Result, String> { - Ok(match chain_spec::Alternative::from(id) { - Some(spec) => Some(spec.load()?), - None => None, - }) -} - -fn run_until_exit( - mut runtime: Runtime, - service: T, - e: E, -) -> error::Result<()> -where - T: AbstractService, - E: IntoExit, -{ - let (exit_send, exit) = oneshot::channel(); - - let informant = informant::build(&service); - - let handle = runtime.spawn(select(exit, informant)); - - // we eagerly drop the service so that the internal exit future is fired, - // but we need to keep holding a reference to the global telemetry guard - let _telemetry = service.telemetry(); - - let exit = e.into_exit(); - let service_res = runtime.block_on(select(service, exit)); - - let _ = exit_send.send(()); - - if let Err(e) = runtime.block_on(handle) { - log::error!("Error running node: {:?}", e); - } - - match service_res { - Either::Left((res, _)) => res.map_err(error::Error::Service), - Either::Right((_, _)) => Ok(()) - } -} - -// handles ctrl-c -pub struct Exit; -impl IntoExit for Exit { - type Exit = Map, fn(Result<(), oneshot::Canceled>) -> ()>; - fn into_exit(self) -> Self::Exit { - // can't use signal directly here because CtrlC takes only `Fn`. - let (exit_send, exit) = oneshot::channel(); - - let exit_send_cell = RefCell::new(Some(exit_send)); - ctrlc::set_handler(move || { - let exit_send = exit_send_cell.try_borrow_mut().expect("signal handler not reentrant; qed").take(); - if let Some(exit_send) = exit_send { - exit_send.send(()).expect("Error sending exit notification"); - } - }).expect("Error setting Ctrl-C handler"); - - exit.map(drop) - } + #[structopt(flatten)] + pub run: RunCmd, } diff --git a/bin/node-template/src/command.rs b/bin/node-template/src/command.rs new file mode 100644 index 0000000000..86058929b0 --- /dev/null +++ b/bin/node-template/src/command.rs @@ -0,0 +1,48 @@ +// Copyright 2017-2020 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 sp_consensus_aura::sr25519::{AuthorityPair as AuraPair}; +use sc_cli::{VersionInfo, error}; +use crate::service; +use crate::chain_spec; +use crate::cli::Cli; + +/// Parse and run command line arguments +pub fn run(version: VersionInfo) -> error::Result<()> +{ + let opt = sc_cli::from_args::(&version); + + let mut config = sc_service::Configuration::default(); + config.impl_name = "node-template"; + + match opt.subcommand { + Some(subcommand) => sc_cli::run_subcommand( + config, + subcommand, + chain_spec::load_spec, + |config: _| Ok(new_full_start!(config).0), + &version, + ), + None => sc_cli::run( + config, + opt.run, + service::new_light, + service::new_full, + chain_spec::load_spec, + &version, + ) + } +} diff --git a/bin/node-template/src/main.rs b/bin/node-template/src/main.rs index ea64bc1413..9d0a57d77a 100644 --- a/bin/node-template/src/main.rs +++ b/bin/node-template/src/main.rs @@ -5,10 +5,11 @@ mod chain_spec; #[macro_use] mod service; mod cli; +mod command; -pub use sc_cli::{VersionInfo, IntoExit, error}; +pub use sc_cli::{VersionInfo, error}; -fn main() -> Result<(), cli::error::Error> { +fn main() -> Result<(), error::Error> { let version = VersionInfo { name: "Substrate Node", commit: env!("VERGEN_SHA_SHORT"), @@ -17,7 +18,8 @@ fn main() -> Result<(), cli::error::Error> { author: "Anonymous", description: "Template Node", support_url: "support.anonymous.an", + copyright_start_year: 2017, }; - cli::run(std::env::args(), cli::Exit, version) + command::run(version) } diff --git a/bin/node-template/src/service.rs b/bin/node-template/src/service.rs index bdaff5ad09..b23ada78f1 100644 --- a/bin/node-template/src/service.rs +++ b/bin/node-template/src/service.rs @@ -77,7 +77,7 @@ macro_rules! new_full_start { } /// Builds a new service for a full client. -pub fn new_full(config: Configuration) +pub fn new_full(config: Configuration) -> Result { let is_authority = config.roles.is_authority(); @@ -192,7 +192,7 @@ pub fn new_full(config: Configuration(config: Configuration) +pub fn new_light(config: Configuration) -> Result { let inherent_data_providers = InherentDataProviders::new(); diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index 585c3f57d6..ef6e90f91a 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -31,7 +31,7 @@ hex-literal = "0.2.1" jsonrpc-core = "14.0.3" log = "0.4.8" rand = "0.7.2" -structopt = "=0.3.7" +structopt = { version = "0.3.8", optional = true } # primitives sp-authority-discovery = { version = "2.0.0", path = "../../../primitives/authority-discovery" } @@ -81,9 +81,7 @@ node-primitives = { version = "2.0.0", path = "../primitives" } node-executor = { version = "2.0.0", path = "../executor" } # CLI-specific dependencies -tokio = { version = "0.2", features = ["rt-threaded"], optional = true } sc-cli = { version = "0.8.0", optional = true, path = "../../../client/cli" } -ctrlc = { version = "3.1.3", features = ["termination"], optional = true } node-transaction-factory = { version = "0.8.0", optional = true, path = "../transaction-factory" } # WASM-specific dependencies @@ -99,10 +97,19 @@ futures = "0.3.1" tempfile = "3.1.0" [build-dependencies] -sc-cli = { version = "0.8.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.7" -vergen = "3.0.4" +structopt = { version = "0.3.8", optional = true } +node-transaction-factory = { version = "0.8.0", optional = true, path = "../transaction-factory" } + +[build-dependencies.sc-cli] +version = "0.8.0" +package = "sc-cli" +path = "../../../client/cli" +optional = true + +[build-dependencies.vergen] +version = "3.0.4" +optional = true [features] default = ["cli", "wasmtime"] @@ -114,10 +121,10 @@ browser = [ cli = [ "sc-cli", "node-transaction-factory", - "tokio", - "ctrlc", "sc-service/rocksdb", "node-executor/wasmi-errno", + "vergen", + "structopt", ] wasmtime = [ "cli", diff --git a/bin/node/cli/bin/main.rs b/bin/node/cli/bin/main.rs index c766f3945c..e951c04710 100644 --- a/bin/node/cli/bin/main.rs +++ b/bin/node/cli/bin/main.rs @@ -18,31 +18,8 @@ #![warn(missing_docs)] -use futures::channel::oneshot; -use futures::{future, FutureExt}; use sc_cli::VersionInfo; -use std::cell::RefCell; - -// handles ctrl-c -struct 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`. - let (exit_send, exit) = oneshot::channel(); - - let exit_send_cell = RefCell::new(Some(exit_send)); - ctrlc::set_handler(move || { - if let Some(exit_send) = exit_send_cell.try_borrow_mut().expect("signal handler not reentrant; qed").take() { - exit_send.send(()).expect("Error sending exit notification"); - } - }).expect("Error setting Ctrl-C handler"); - - exit.map(|_| ()) - } -} - fn main() -> Result<(), sc_cli::error::Error> { let version = VersionInfo { name: "Substrate Node", @@ -52,7 +29,8 @@ fn main() -> Result<(), sc_cli::error::Error> { author: "Parity Technologies ", description: "Generic substrate node", support_url: "https://github.com/paritytech/substrate/issues/new", + copyright_start_year: 2017, }; - node_cli::run(std::env::args(), Exit, version) + node_cli::run(std::env::args(), version) } diff --git a/bin/node/cli/build.rs b/bin/node/cli/build.rs index 9e18fc6699..e824b59be6 100644 --- a/bin/node/cli/build.rs +++ b/bin/node/cli/build.rs @@ -14,39 +14,48 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use std::{fs, env, path::Path}; -use structopt::{StructOpt, clap::Shell}; -use sc_cli::{NoCustom, CoreParams}; -use vergen::{ConstantsFlags, generate_cargo_keys}; - fn main() { - build_shell_completion(); - generate_cargo_keys(ConstantsFlags::all()).expect("Failed to generate metadata files"); - - build_script_utils::rerun_if_git_head_changed(); + #[cfg(feature = "cli")] + cli::main(); } -/// Build shell completion scripts for all known shells -/// Full list in https://github.com/kbknapp/clap-rs/blob/e9d0562a1dc5dfe731ed7c767e6cee0af08f0cf9/src/app/parser.rs#L123 -fn build_shell_completion() { - for shell in &[Shell::Bash, Shell::Fish, Shell::Zsh, Shell::Elvish, Shell::PowerShell] { - build_completion(shell); +#[cfg(feature = "cli")] +mod cli { + include!("src/cli.rs"); + + use std::{fs, env, path::Path}; + use sc_cli::{structopt::clap::Shell}; + use vergen::{ConstantsFlags, generate_cargo_keys}; + + pub fn main() { + build_shell_completion(); + generate_cargo_keys(ConstantsFlags::all()).expect("Failed to generate metadata files"); + + build_script_utils::rerun_if_git_head_changed(); + } + + /// Build shell completion scripts for all known shells + /// Full list in https://github.com/kbknapp/clap-rs/blob/e9d0562a1dc5dfe731ed7c767e6cee0af08f0cf9/src/app/parser.rs#L123 + fn build_shell_completion() { + for shell in &[Shell::Bash, Shell::Fish, Shell::Zsh, Shell::Elvish, Shell::PowerShell] { + build_completion(shell); + } } -} -/// Build the shell auto-completion for a given Shell -fn build_completion(shell: &Shell) { - let outdir = match env::var_os("OUT_DIR") { - None => return, - Some(dir) => dir, - }; - let path = Path::new(&outdir) - .parent().unwrap() - .parent().unwrap() - .parent().unwrap() - .join("completion-scripts"); - - fs::create_dir(&path).ok(); - - CoreParams::::clap().gen_completions("substrate-node", *shell, &path); + /// Build the shell auto-completion for a given Shell + fn build_completion(shell: &Shell) { + let outdir = match env::var_os("OUT_DIR") { + None => return, + Some(dir) => dir, + }; + let path = Path::new(&outdir) + .parent().unwrap() + .parent().unwrap() + .parent().unwrap() + .join("completion-scripts"); + + fs::create_dir(&path).ok(); + + Cli::clap().gen_completions("substrate-node", *shell, &path); + } } diff --git a/bin/node/cli/src/browser.rs b/bin/node/cli/src/browser.rs index b41bbe6281..e05238b82d 100644 --- a/bin/node/cli/src/browser.rs +++ b/bin/node/cli/src/browser.rs @@ -38,13 +38,13 @@ async fn start_inner(wasm_ext: Transport) -> Result = browser_configuration(wasm_ext, chain_spec) + let config: Configuration<_, _> = browser_configuration(wasm_ext, chain_spec) .await?; info!("Substrate browser node"); info!(" version {}", config.full_version()); info!(" by Parity Technologies, 2017-2020"); - info!("Chain specification: {}", config.chain_spec.name()); + info!("Chain specification: {}", config.expect_chain_spec().name()); info!("Node name: {}", config.name); info!("Roles: {:?}", config.roles); diff --git a/bin/node/cli/src/cli.rs b/bin/node/cli/src/cli.rs index 2a3d60a794..201e39eabd 100644 --- a/bin/node/cli/src/cli.rs +++ b/bin/node/cli/src/cli.rs @@ -14,21 +14,26 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -pub use sc_cli::VersionInfo; -use tokio::runtime::{Builder as RuntimeBuilder, Runtime}; -use sc_cli::{IntoExit, NoCustom, SharedParams, ImportParams, error}; -use sc_service::{AbstractService, Roles as ServiceRoles, Configuration}; -use log::info; +use sc_cli::{SharedParams, ImportParams, RunCmd}; use structopt::StructOpt; -use sc_cli::{display_role, parse_and_prepare, GetSharedParams, ParseAndPrepare}; -use crate::{service, ChainSpec, load_spec}; -use crate::factory_impl::FactoryState; -use node_transaction_factory::RuntimeAdapter; -use futures::{channel::oneshot, future::{select, Either}}; -/// Custom subcommands. #[derive(Clone, Debug, StructOpt)] -pub enum CustomSubcommands { +#[structopt(settings = &[ + structopt::clap::AppSettings::GlobalVersion, + structopt::clap::AppSettings::ArgsNegateSubcommands, + structopt::clap::AppSettings::SubcommandsNegateReqs, +])] +pub struct Cli { + #[structopt(subcommand)] + pub subcommand: Option, + #[structopt(flatten)] + pub run: RunCmd, +} + +#[derive(Clone, Debug, StructOpt)] +pub enum Subcommand { + #[structopt(flatten)] + Base(sc_cli::Subcommand), /// The custom factory subcommmand for manufacturing transactions. #[structopt( name = "factory", @@ -38,14 +43,6 @@ pub enum CustomSubcommands { Factory(FactoryCmd), } -impl GetSharedParams for CustomSubcommands { - fn shared_params(&self) -> Option<&SharedParams> { - match self { - CustomSubcommands::Factory(cmd) => Some(&cmd.shared_params), - } - } -} - /// The `factory` command used to generate transactions. /// Please note: this command currently only works on an empty database! #[derive(Debug, StructOpt, Clone)] @@ -87,125 +84,3 @@ pub struct FactoryCmd { #[structopt(flatten)] pub import_params: ImportParams, } - -/// Parse command line arguments into service configuration. -pub fn run(args: I, exit: E, version: sc_cli::VersionInfo) -> error::Result<()> where - I: IntoIterator, - T: Into + Clone, - E: IntoExit, -{ - type Config = Configuration<(), A, B>; - - match parse_and_prepare::(&version, "substrate-node", args) { - ParseAndPrepare::Run(cmd) => cmd.run(load_spec, exit, - |exit, _cli_args, _custom_args, mut config: Config<_, _>| { - info!("{}", version.name); - info!(" version {}", config.full_version()); - info!(" by Parity Technologies, 2017-2020"); - info!("Chain specification: {}", config.chain_spec.name()); - info!("Node name: {}", config.name); - info!("Roles: {}", display_role(&config)); - let runtime = RuntimeBuilder::new() - .thread_name("main-tokio-") - .threaded_scheduler() - .enable_all() - .build() - .map_err(|e| format!("{:?}", e))?; - config.tasks_executor = { - let runtime_handle = runtime.handle().clone(); - Some(Box::new(move |fut| { runtime_handle.spawn(fut); })) - }; - match config.roles { - ServiceRoles::LIGHT => run_until_exit( - runtime, - service::new_light(config)?, - exit - ), - _ => run_until_exit( - runtime, - service::new_full(config)?, - exit - ), - } - }), - ParseAndPrepare::BuildSpec(cmd) => cmd.run::(load_spec), - ParseAndPrepare::ExportBlocks(cmd) => cmd.run_with_builder(|config: Config<_, _>| - 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<_, _> = sc_cli::create_config_with_db_path( - load_spec, - &cli_args.shared_params, - &version, - None, - )?; - sc_cli::fill_import_params( - &mut config, - &cli_args.import_params, - ServiceRoles::FULL, - cli_args.shared_params.dev, - )?; - - match ChainSpec::from(config.chain_spec.id()) { - Some(ref c) if c == &ChainSpec::Development || c == &ChainSpec::LocalTestnet => {}, - _ => panic!("Factory is only supported for development and local testnet."), - } - - let factory_state = FactoryState::new( - cli_args.mode.clone(), - cli_args.num, - cli_args.rounds, - ); - - let service_builder = new_full_start!(config).0; - node_transaction_factory::factory::, _, _, _, _, _>( - factory_state, - service_builder.client(), - service_builder.select_chain() - .expect("The select_chain is always initialized by new_full_start!; QED") - ).map_err(|e| format!("Error in transaction factory: {}", e))?; - - Ok(()) - } - } -} - -fn run_until_exit( - mut runtime: Runtime, - service: T, - e: E, -) -> error::Result<()> -where - T: AbstractService, - E: IntoExit, -{ - let (exit_send, exit) = oneshot::channel(); - - let informant = sc_cli::informant::build(&service); - - let handle = runtime.spawn(select(exit, informant)); - - // we eagerly drop the service so that the internal exit future is fired, - // but we need to keep holding a reference to the global telemetry guard - let _telemetry = service.telemetry(); - - let exit = e.into_exit(); - let service_res = runtime.block_on(select(service, exit)); - - let _ = exit_send.send(()); - - if let Err(e) = runtime.block_on(handle) { - log::error!("Error running node: {:?}", e); - } - - match service_res { - Either::Left((res, _)) => res.map_err(error::Error::Service), - Either::Right((_, _)) => Ok(()) - } -} diff --git a/bin/node/cli/src/command.rs b/bin/node/cli/src/command.rs new file mode 100644 index 0000000000..65015efcb2 --- /dev/null +++ b/bin/node/cli/src/command.rs @@ -0,0 +1,82 @@ +// Copyright 2017-2020 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 sc_cli::{VersionInfo, error}; +use sc_service::{Roles as ServiceRoles}; +use node_transaction_factory::RuntimeAdapter; +use crate::{Cli, service, ChainSpec, load_spec, Subcommand, factory_impl::FactoryState}; + +/// Parse command line arguments into service configuration. +pub fn run(args: I, version: sc_cli::VersionInfo) -> error::Result<()> +where + I: Iterator, + T: Into + Clone, +{ + let args: Vec<_> = args.collect(); + let opt = sc_cli::from_iter::(args.clone(), &version); + + let mut config = sc_service::Configuration::default(); + config.impl_name = "substrate-node"; + + match opt.subcommand { + None => sc_cli::run( + config, + opt.run, + service::new_light, + service::new_full, + load_spec, + &version, + ), + Some(Subcommand::Factory(cli_args)) => { + sc_cli::init(&mut config, load_spec, &cli_args.shared_params, &version)?; + + sc_cli::fill_import_params( + &mut config, + &cli_args.import_params, + ServiceRoles::FULL, + cli_args.shared_params.dev, + )?; + + match ChainSpec::from(config.expect_chain_spec().id()) { + Some(ref c) if c == &ChainSpec::Development || c == &ChainSpec::LocalTestnet => {}, + _ => panic!("Factory is only supported for development and local testnet."), + } + + let factory_state = FactoryState::new( + cli_args.mode.clone(), + cli_args.num, + cli_args.rounds, + ); + + let service_builder = new_full_start!(config).0; + node_transaction_factory::factory::, _, _, _, _, _>( + factory_state, + service_builder.client(), + service_builder.select_chain() + .expect("The select_chain is always initialized by new_full_start!; QED") + ).map_err(|e| format!("Error in transaction factory: {}", e))?; + + Ok(()) + }, + Some(Subcommand::Base(subcommand)) => sc_cli::run_subcommand( + config, + subcommand, + load_spec, + |config: service::NodeConfiguration| Ok(new_full_start!(config).0), + &version, + ), + } +} diff --git a/bin/node/cli/src/lib.rs b/bin/node/cli/src/lib.rs index d3fbf9c1ea..f5b915a2be 100644 --- a/bin/node/cli/src/lib.rs +++ b/bin/node/cli/src/lib.rs @@ -39,11 +39,15 @@ mod browser; mod cli; #[cfg(feature = "cli")] mod factory_impl; +#[cfg(feature = "cli")] +mod command; #[cfg(feature = "browser")] pub use browser::*; #[cfg(feature = "cli")] pub use cli::*; +#[cfg(feature = "cli")] +pub use command::*; /// The chain specification option. #[derive(Clone, Debug, PartialEq)] diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index 32f2d0001c..e72430e93d 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -274,10 +274,10 @@ type ConcreteTransactionPool = sc_transaction_pool::BasicPool< >; /// A specialized configuration object for setting up the node.. -pub type NodeConfiguration = Configuration; +pub type NodeConfiguration = Configuration; /// Builds a new service for a full client. -pub fn new_full(config: NodeConfiguration) +pub fn new_full(config: NodeConfiguration) -> Result< Service< ConcreteBlock, @@ -299,7 +299,7 @@ pub fn new_full(config: NodeConfiguration) } /// Builds a new service for a light client. -pub fn new_light(config: NodeConfiguration) +pub fn new_light(config: NodeConfiguration) -> Result { type RpcExtension = jsonrpc_core::IoHandler; let inherent_data_providers = InherentDataProviders::new(); diff --git a/bin/utils/chain-spec-builder/Cargo.toml b/bin/utils/chain-spec-builder/Cargo.toml index b4707a5eb4..8f122a35a0 100644 --- a/bin/utils/chain-spec-builder/Cargo.toml +++ b/bin/utils/chain-spec-builder/Cargo.toml @@ -12,4 +12,4 @@ 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.7" +structopt = "0.3.8" diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index 020ae164ef..abfb53ccb1 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -17,7 +17,7 @@ time = "0.1.42" ansi_term = "0.12.1" lazy_static = "1.4.0" app_dirs = "1.2.1" -tokio = "0.2" +tokio = { version = "0.2.9", features = [ "signal", "rt-core", "rt-threaded" ] } futures = "0.3.1" fdlimit = "0.1.1" serde_json = "1.0.41" @@ -32,8 +32,9 @@ sp-state-machine = { version = "0.8", 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.7" +structopt = "0.3.8" sc-tracing = { version = "2.0.0", path = "../tracing" } +chrono = "0.4.10" [target.'cfg(not(target_os = "unknown"))'.dependencies] rpassword = "4.0.1" diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index d9ea238ba0..c602d52ed9 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -25,47 +25,49 @@ mod params; mod execution_strategy; pub mod error; pub mod informant; +mod runtime; +mod node_key; use sc_client_api::execution_extensions::ExecutionStrategies; use sc_service::{ config::{Configuration, DatabaseConfig, KeystoreConfig}, ServiceBuilderCommand, RuntimeGenesis, ChainSpecExtension, PruningMode, ChainSpec, + AbstractService, Roles as ServiceRoles, }; use sc_network::{ self, multiaddr::Protocol, config::{ - NetworkConfiguration, TransportConfig, NonReservedPeerMode, NodeKeyConfig, build_multiaddr + NetworkConfiguration, TransportConfig, NonReservedPeerMode, }, }; -use sp_core::H256; -use execution_strategy::*; use std::{ - 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 + io::Write, iter, fmt::Debug, fs, + net::{Ipv4Addr, SocketAddr}, path::PathBuf, }; -use names::{Generator, Name}; use regex::Regex; -use structopt::{StructOpt, StructOptInternal, clap::AppSettings}; -#[doc(hidden)] -pub use structopt::clap::App; +use structopt::{StructOpt, clap}; +pub use structopt; use params::{ - RunCmd, PurgeChainCmd, RevertCmd, ImportBlocksCmd, ExportBlocksCmd, BuildSpecCmd, - NetworkConfigurationParams, MergeParameters, TransactionPoolParams, - NodeKeyParams, NodeKeyType, Cors, CheckBlockCmd, + NetworkConfigurationParams, TransactionPoolParams, Cors, +}; +pub use params::{ + SharedParams, ImportParams, ExecutionStrategy, Subcommand, RunCmd, BuildSpecCmd, + ExportBlocksCmd, ImportBlocksCmd, CheckBlockCmd, PurgeChainCmd, RevertCmd, }; -pub use params::{NoCustom, CoreParams, SharedParams, ImportParams, ExecutionStrategy}; pub use traits::GetSharedParams; use app_dirs::{AppInfo, AppDataType}; use log::info; use lazy_static::lazy_static; -use futures::{Future, executor::block_on}; use sc_telemetry::TelemetryEndpoints; -use sp_runtime::generic::BlockId; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; +pub use crate::runtime::{run_until_exit, run_service_until_exit}; +use execution_strategy::*; +use names::{Generator, Name}; +use chrono::prelude::*; /// default sub directory to store network config const DEFAULT_NETWORK_CONFIG_PATH : &'static str = "network"; @@ -77,11 +79,6 @@ const DEFAULT_KEYSTORE_CONFIG_PATH : &'static str = "keystore"; /// The maximum number of characters for a node name. const NODE_NAME_MAX_LENGTH: usize = 32; -/// The file name of the node's Ed25519 secret key inside the chain-specific -/// network config directory, if neither `--node-key` nor `--node-key-file` -/// is specified in combination with `--node-key-type=ed25519`. -const NODE_KEY_ED25519_FILE: &str = "secret_ed25519"; - /// Executable version. Used to pass version information from the root crate. #[derive(Clone)] pub struct VersionInfo { @@ -99,14 +96,8 @@ pub struct VersionInfo { pub author: &'static str, /// Support URL. pub support_url: &'static str, -} - -/// Something that can be converted into an exit signal. -pub trait IntoExit { - /// Exit signal type. - type Exit: Future + Unpin + Send + 'static; - /// Convert into exit signal. - fn into_exit(self) -> Self::Exit; + /// Copyright starting year (x-current year) + pub copyright_start_year: i32, } fn get_chain_key(cli: &SharedParams) -> String { @@ -143,13 +134,8 @@ pub fn load_spec(cli: &SharedParams, factory: F) -> error::Result, -) -> PathBuf { +fn base_path(cli: &SharedParams, version: &VersionInfo) -> PathBuf { cli.base_path.clone() - .or(default_base_path) .unwrap_or_else(|| app_dirs::get_app_root( AppDataType::UserData, @@ -161,637 +147,227 @@ fn base_path( ) } -/// Check whether a node name is considered as valid -fn is_node_name_valid(_name: &str) -> Result<(), &str> { - let name = _name.to_string(); - if name.chars().count() >= NODE_NAME_MAX_LENGTH { - return Err("Node name too long"); - } - - let invalid_chars = r"[\\.@]"; - let re = Regex::new(invalid_chars).unwrap(); - if re.is_match(&name) { - return Err("Node name should not contain invalid chars such as '.' and '@'"); - } - - let invalid_patterns = r"(https?:\\/+)?(www)+"; - let re = Regex::new(invalid_patterns).unwrap(); - if re.is_match(&name) { - return Err("Node name should not contain urls"); - } - - Ok(()) +/// Helper function used to parse the command line arguments. This is the equivalent of +/// `structopt`'s `from_args()` except that it takes a `VersionInfo` argument to provide the name of +/// the application, author, "about" and version. +/// +/// Gets the struct from the command line arguments. Print the +/// error message and quit the program in case of failure. +pub fn from_args(version: &VersionInfo) -> T +where + T: StructOpt + Sized, +{ + from_iter::(&mut std::env::args_os(), version) } -/// Parse command line interface arguments and prepares the command for execution. -/// -/// Before returning, this function performs various initializations, such as initializing the -/// panic handler and the logger, or increasing the limit for file descriptors. -/// -/// # Remarks +/// Helper function used to parse the command line arguments. This is the equivalent of +/// `structopt`'s `from_iter()` except that it takes a `VersionInfo` argument to provide the name of +/// the application, author, "about" and version. /// -/// `CC` is a custom subcommand. This needs to be an `enum`! If no custom subcommand is required, -/// `NoCustom` can be used as type here. -/// -/// `RP` are custom parameters for the run command. This needs to be a `struct`! The custom -/// parameters are visible to the user as if they were normal run command parameters. If no custom -/// parameters are required, `NoCustom` can be used as type here. -pub fn parse_and_prepare<'a, CC, RP, I>( - version: &'a VersionInfo, - impl_name: &'static str, - args: I, -) -> ParseAndPrepare<'a, CC, RP> +/// Gets the struct from any iterator such as a `Vec` of your making. +/// Print the error message and quit the program in case of failure. +pub fn from_iter(iter: I, version: &VersionInfo) -> T where - CC: StructOpt + Clone + GetSharedParams, - RP: StructOpt + Clone + StructOptInternal, + T: StructOpt + Sized, I: IntoIterator, - ::Item: Into + Clone, + I::Item: Into + Clone, { - let full_version = sc_service::config::full_version_from_strs( + let app = T::clap(); + + let mut full_version = sc_service::config::full_version_from_strs( version.version, version.commit ); + full_version.push_str("\n"); - sp_panic_handler::set(version.support_url, &full_version); - let matches = CoreParams::::clap() + let app = app .name(version.executable_name) .author(version.author) .about(version.description) - .version(&(full_version + "\n")[..]) - .setting(AppSettings::GlobalVersion) - .setting(AppSettings::ArgsNegateSubcommands) - .setting(AppSettings::SubcommandsNegateReqs) - .get_matches_from(args); - let cli_args = CoreParams::::from_clap(&matches); - fdlimit::raise_fd_limit(); - - let args = match cli_args { - params::CoreParams::Run(params) => ParseAndPrepare::Run( - ParseAndPrepareRun { params, impl_name, version } - ), - params::CoreParams::BuildSpec(params) => ParseAndPrepare::BuildSpec( - ParseAndPrepareBuildSpec { params, version } - ), - params::CoreParams::ExportBlocks(params) => ParseAndPrepare::ExportBlocks( - ParseAndPrepareExport { params, version } - ), - 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 } - ), - params::CoreParams::Revert(params) => ParseAndPrepare::RevertChain( - ParseAndPrepareRevert { params, version } - ), - params::CoreParams::Custom(params) => ParseAndPrepare::CustomCommand(params), - }; - init_logger(args.shared_params().and_then(|p| p.log.as_ref()).map(|v| v.as_ref()).unwrap_or("")); - args -} + .version(full_version.as_str()); -/// Returns a string displaying the node role, special casing the sentry mode -/// (returning `SENTRY`), since the node technically has an `AUTHORITY` role but -/// doesn't participate. -pub fn display_role(config: &Configuration) -> String { - if config.sentry_mode { - "SENTRY".to_string() - } else { - format!("{:?}", config.roles) - } -} - -/// Output of calling `parse_and_prepare`. -#[must_use] -pub enum ParseAndPrepare<'a, CC, RP> { - /// Command ready to run the main client. - Run(ParseAndPrepareRun<'a, RP>), - /// Command ready to build chain specs. - BuildSpec(ParseAndPrepareBuildSpec<'a>), - /// Command ready to export the chain. - 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. - RevertChain(ParseAndPrepareRevert<'a>), - /// An additional custom command passed to `parse_and_prepare`. - CustomCommand(CC), -} - -impl<'a, CC, RP> ParseAndPrepare<'a, CC, RP> where CC: GetSharedParams { - /// Return common set of parameters shared by all commands. - pub fn shared_params(&self) -> Option<&SharedParams> { - match self { - ParseAndPrepare::Run(c) => Some(&c.params.left.shared_params), - ParseAndPrepare::BuildSpec(c) => Some(&c.params.shared_params), - ParseAndPrepare::ExportBlocks(c) => Some(&c.params.shared_params), - ParseAndPrepare::ImportBlocks(c) => Some(&c.params.shared_params), - ParseAndPrepare::CheckBlock(c) => Some(&c.params.shared_params), - ParseAndPrepare::PurgeChain(c) => Some(&c.params.shared_params), - ParseAndPrepare::RevertChain(c) => Some(&c.params.shared_params), - ParseAndPrepare::CustomCommand(c) => c.shared_params(), - } - } + T::from_clap(&app.get_matches_from(iter)) } -impl<'a, CC, RP> ParseAndPrepare<'a, CC, RP> { - /// Convert ParseAndPrepare to Configuration - pub fn into_configuration( - self, - spec_factory: S, - default_base_path: Option, - ) -> error::Result>> - where - C: Default, - G: RuntimeGenesis, - E: ChainSpecExtension, - S: FnOnce(&str) -> Result>, String>, - { - match self { - ParseAndPrepare::Run(c) => - Some(create_run_node_config( - c.params.left, - spec_factory, - c.impl_name, - c.version, - default_base_path, - )).transpose(), - ParseAndPrepare::BuildSpec(c) => { - let spec = load_spec(&c.params.shared_params, spec_factory)?; - - Some(create_build_spec_config( - &spec, - &c.params.shared_params, - c.version, - default_base_path, - )).transpose() - }, - ParseAndPrepare::ExportBlocks(c) => - Some(create_config_with_db_path( - spec_factory, - &c.params.shared_params, - c.version, - default_base_path, - )).transpose(), - ParseAndPrepare::ImportBlocks(c) => - Some(create_config_with_db_path( - spec_factory, - &c.params.shared_params, - c.version, - default_base_path, - )).transpose(), - ParseAndPrepare::CheckBlock(c) => - Some(create_config_with_db_path( - spec_factory, - &c.params.shared_params, - c.version, - default_base_path, - )).transpose(), - ParseAndPrepare::PurgeChain(c) => - Some(create_config_with_db_path( - spec_factory, - &c.params.shared_params, - c.version, - default_base_path, - )).transpose(), - ParseAndPrepare::RevertChain(c) => - Some(create_config_with_db_path( - spec_factory, - &c.params.shared_params, - c.version, - default_base_path, - )).transpose(), - ParseAndPrepare::CustomCommand(_) => Ok(None), - } - } -} - -/// Command ready to run the main client. -pub struct ParseAndPrepareRun<'a, RP> { - params: MergeParameters, - impl_name: &'static str, - version: &'a VersionInfo, -} - -impl<'a, RP> ParseAndPrepareRun<'a, RP> { - /// Runs the command and runs the main client. - pub fn run( - self, - spec_factory: S, - exit: Exit, - run_service: RS, - ) -> error::Result<()> - where - S: FnOnce(&str) -> Result>, String>, - E: Into, - RP: StructOpt + Clone, - C: Default, - G: RuntimeGenesis, - CE: ChainSpecExtension, - Exit: IntoExit, - RS: FnOnce(Exit, RunCmd, RP, Configuration) -> Result<(), E> - { - let config = create_run_node_config( - self.params.left.clone(), - spec_factory, - self.impl_name, - self.version, - None, - )?; - - run_service(exit, self.params.left, self.params.right, config).map_err(Into::into) - } -} - -/// Command ready to build chain specs. -pub struct ParseAndPrepareBuildSpec<'a> { - params: BuildSpecCmd, - version: &'a VersionInfo, -} - -impl<'a> ParseAndPrepareBuildSpec<'a> { - /// Runs the command and build the chain specs. - pub fn run( - self, - spec_factory: S - ) -> error::Result<()> where - S: FnOnce(&str) -> Result>, String>, - C: Default, - G: RuntimeGenesis, - E: ChainSpecExtension, - { - info!("Building chain spec"); - let raw_output = self.params.raw; - let mut spec = load_spec(&self.params.shared_params, spec_factory)?; - - if spec.boot_nodes().is_empty() && !self.params.disable_default_bootnode { - let cfg = create_build_spec_config::( - &spec, - &self.params.shared_params, - self.version, - None, - )?; - 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")) - )?; - let keys = node_key.into_keypair()?; - let peer_id = keys.public().into_peer_id(); - let addr = build_multiaddr![ - Ip4([127, 0, 0, 1]), - Tcp(30333u16), - P2p(peer_id) - ]; - spec.add_boot_node(addr) - } - - let json = sc_service::chain_ops::build_spec(spec, raw_output)?; - - print!("{}", json); - - Ok(()) - } -} - -/// Command ready to export the chain. -pub struct ParseAndPrepareExport<'a> { - params: ExportBlocksCmd, - version: &'a VersionInfo, -} - -impl<'a> ParseAndPrepareExport<'a> { - /// Runs the command and exports from 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>::Header as HeaderT> - ::Number as FromStr>::Err: Debug, - C: Default, - G: RuntimeGenesis, - E: ChainSpecExtension, - Exit: IntoExit - { - let mut config = create_config_with_db_path( - spec_factory, - &self.params.shared_params, - self.version, - None, - )?; - fill_config_keystore_in_memory(&mut config)?; - - if let DatabaseConfig::Path { ref path, .. } = &config.database { - info!("DB path: {}", path.display()); - } - 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 { - Some(filename) => Box::new(File::create(filename)?), - None => Box::new(stdout()), - }; +/// Helper function used to parse the command line arguments. This is the equivalent of +/// `structopt`'s `try_from_iter()` except that it takes a `VersionInfo` argument to provide the +/// name of the application, author, "about" and version. +/// +/// Gets the struct from any iterator such as a `Vec` of your making. +/// Print the error message and quit the program in case of failure. +/// +/// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are +/// used. It will return a [`clap::Error`], where the [`kind`] is a +/// [`ErrorKind::HelpDisplayed`] or [`ErrorKind::VersionDisplayed`] respectively. You must call +/// [`Error::exit`] or perform a [`std::process::exit`]. +pub fn try_from_iter(iter: I, version: &VersionInfo) -> clap::Result +where + T: StructOpt + Sized, + I: IntoIterator, + I::Item: Into + Clone, +{ + let app = T::clap(); - // 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(); - std::thread::spawn(move || { - block_on(exit); - let _ = exit_send.send(()); - }); + let mut full_version = sc_service::config::full_version_from_strs( + version.version, + version.commit, + ); + full_version.push_str("\n"); - let mut export_fut = builder(config)? - .export_blocks(file, from.into(), to, json); - let fut = futures::future::poll_fn(|cx| { - if exit_recv.try_recv().is_ok() { - return Poll::Ready(Ok(())); - } - Pin::new(&mut export_fut).poll(cx) - }); + let app = app + .name(version.executable_name) + .author(version.author) + .about(version.description) + .version(full_version.as_str()); - let mut runtime = tokio::runtime::Runtime::new().unwrap(); - runtime.block_on(fut)?; - Ok(()) - } -} + let matches = app.get_matches_from_safe(iter)?; -/// Command ready to import the chain. -pub struct ParseAndPrepareImport<'a> { - params: ImportBlocksCmd, - version: &'a VersionInfo, + Ok(T::from_clap(&matches)) } -impl<'a> ParseAndPrepareImport<'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, - C: Default, - G: RuntimeGenesis, - E: ChainSpecExtension, - Exit: IntoExit - { - let mut config = create_config_with_db_path( - spec_factory, - &self.params.shared_params, - self.version, - None, - )?; - fill_import_params( - &mut config, - &self.params.import_params, - sc_service::Roles::FULL, - self.params.shared_params.dev, - )?; - - let file: Box = match self.params.input { - Some(filename) => Box::new(File::open(filename)?), - None => { - let mut buffer = Vec::new(); - stdin().read_to_end(&mut buffer)?; - Box::new(Cursor::new(buffer)) - }, - }; - - // 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(); - std::thread::spawn(move || { - block_on(exit); - let _ = exit_send.send(()); - }); - - let mut import_fut = builder(config)? - .import_blocks(file, false); - let fut = futures::future::poll_fn(|cx| { - if exit_recv.try_recv().is_ok() { - return Poll::Ready(Ok(())); - } - Pin::new(&mut import_fut).poll(cx) - }); - - let mut runtime = tokio::runtime::Runtime::new().unwrap(); - runtime.block_on(fut)?; - Ok(()) - } -} +/// A helper function that initializes and runs the node +pub fn run( + mut config: Configuration, + run_cmd: RunCmd, + new_light: FNL, + new_full: FNF, + spec_factory: F, + version: &VersionInfo, +) -> error::Result<()> +where + F: FnOnce(&str) -> Result>, String>, + FNL: FnOnce(Configuration) -> Result, + FNF: FnOnce(Configuration) -> Result, + G: RuntimeGenesis, + E: ChainSpecExtension, + SL: AbstractService + Unpin, + SF: AbstractService + Unpin, +{ + init(&mut config, spec_factory, &run_cmd.shared_params, version)?; -/// Command to check a block. -pub struct CheckBlock<'a> { - params: CheckBlockCmd, - version: &'a VersionInfo, + run_cmd.run(config, new_light, new_full, version) } -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, - None, - )?; - fill_import_params( - &mut config, - &self.params.import_params, - sc_service::Roles::FULL, - self.params.shared_params.dev, - )?; - fill_config_keystore_in_memory(&mut config)?; - - 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); - let mut runtime = tokio::runtime::Runtime::new().unwrap(); - runtime.block_on(check)?; - println!("Completed in {} ms.", start.elapsed().as_millis()); - Ok(()) - } -} +/// A helper function that initializes and runs any of the subcommand variants of `CoreParams`. +pub fn run_subcommand( + mut config: Configuration, + subcommand: Subcommand, + spec_factory: F, + builder: B, + version: &VersionInfo, +) -> error::Result<()> +where + F: FnOnce(&str) -> Result>, String>, + B: FnOnce(Configuration) -> Result, + G: RuntimeGenesis, + E: ChainSpecExtension, + BC: ServiceBuilderCommand + Unpin, + BB: sp_runtime::traits::Block + Debug, + <<::Header as HeaderT>::Number as std::str::FromStr>::Err: std::fmt::Debug, + ::Hash: std::str::FromStr, +{ + init(&mut config, spec_factory, &subcommand.get_shared_params(), version)?; -/// Command ready to purge the chain. -pub struct ParseAndPreparePurge<'a> { - params: PurgeChainCmd, - version: &'a VersionInfo, + subcommand.run(config, builder) } -impl<'a> ParseAndPreparePurge<'a> { - /// Runs the command and purges the chain. - pub fn run( - self, - spec_factory: S - ) -> error::Result<()> where - S: FnOnce(&str) -> Result>, String>, - G: RuntimeGenesis, - E: ChainSpecExtension, - { - let mut config = create_config_with_db_path::<(), _, _, _>( - spec_factory, - &self.params.shared_params, - self.version, - None, - )?; - fill_config_keystore_in_memory(&mut config)?; - let db_path = match config.database { - DatabaseConfig::Path { path, .. } => path, - _ => { - eprintln!("Cannot purge custom database implementation"); - return Ok(()); - } - }; - - if !self.params.yes { - print!("Are you sure to remove {:?}? [y/N]: ", &db_path); - stdout().flush().expect("failed to flush stdout"); - - let mut input = String::new(); - stdin().read_line(&mut input)?; - let input = input.trim(); +/// Initialize substrate and its configuration +/// +/// This method: +/// +/// 1. set the panic handler +/// 2. raise the FD limit +/// 3. initialize the logger +/// 4. update the configuration provided with the chain specification, config directory, +/// information (version, commit), database's path, boot nodes and telemetry endpoints +pub fn init( + mut config: &mut Configuration, + spec_factory: F, + shared_params: &SharedParams, + version: &VersionInfo, +) -> error::Result<()> +where + G: RuntimeGenesis, + E: ChainSpecExtension, + F: FnOnce(&str) -> Result>, String>, +{ + let full_version = sc_service::config::full_version_from_strs( + version.version, + version.commit + ); + sp_panic_handler::set(version.support_url, &full_version); - match input.chars().nth(0) { - Some('y') | Some('Y') => {}, - _ => { - println!("Aborted"); - return Ok(()); - }, - } - } + fdlimit::raise_fd_limit(); + init_logger(shared_params.log.as_ref().map(|v| v.as_ref()).unwrap_or("")); - match fs::remove_dir_all(&db_path) { - Result::Ok(_) => { - println!("{:?} removed.", &db_path); - Ok(()) - }, - Result::Err(ref err) if err.kind() == ErrorKind::NotFound => { - eprintln!("{:?} did not exist.", &db_path); - Ok(()) - }, - Result::Err(err) => Result::Err(err.into()) - } - } -} + config.chain_spec = Some(load_spec(shared_params, spec_factory)?); + config.config_dir = Some(base_path(shared_params, version)); + config.impl_commit = version.commit; + config.impl_version = version.version; -/// Command ready to revert the chain. -pub struct ParseAndPrepareRevert<'a> { - params: RevertCmd, - version: &'a VersionInfo, -} + config.database = DatabaseConfig::Path { + path: config + .in_chain_config_dir(DEFAULT_DB_CONFIG_PATH) + .expect("We provided a base_path/config_dir."), + cache_size: None, + }; -impl<'a> ParseAndPrepareRevert<'a> { - /// Runs the command and reverts the chain. - pub fn run_with_builder( - self, - builder: F, - spec_factory: S - ) -> error::Result<()> where - S: FnOnce(&str) -> Result>, String>, - F: FnOnce(Configuration) -> Result, - B: ServiceBuilderCommand, - <<<::Block as BlockT>::Header as HeaderT> - ::Number as FromStr>::Err: Debug, - C: Default, - G: RuntimeGenesis, - E: ChainSpecExtension, - { - let mut config = create_config_with_db_path( - spec_factory, - &self.params.shared_params, - self.version, - None, - )?; - fill_config_keystore_in_memory(&mut config)?; + config.network.boot_nodes = config.expect_chain_spec().boot_nodes().to_vec(); + config.telemetry_endpoints = config.expect_chain_spec().telemetry_endpoints().clone(); - let blocks = self.params.num.parse()?; - builder(config)?.revert_chain(blocks)?; - Ok(()) - } + Ok(()) } -/// Create a `NodeKeyConfig` from the given `NodeKeyParams` in the context -/// of an optional network config storage directory. -fn node_key_config

(params: NodeKeyParams, net_config_dir: &Option

) - -> error::Result +/// Run the node +/// +/// Builds and runs either a full or a light node, depending on the `role` within the `Configuration`. +pub fn run_node( + config: Configuration, + new_light: FNL, + new_full: FNF, + version: &VersionInfo, +) -> error::Result<()> where - P: AsRef + FNL: FnOnce(Configuration) -> Result, + FNF: FnOnce(Configuration) -> Result, + G: RuntimeGenesis, + E: ChainSpecExtension, + SL: AbstractService + Unpin, + SF: AbstractService + Unpin, { - match params.node_key_type { - NodeKeyType::Ed25519 => - 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(sc_network::config::Secret::File) - .unwrap_or(sc_network::config::Secret::New))) - .map(NodeKeyConfig::Ed25519) + info!("{}", version.name); + info!(" version {}", config.full_version()); + info!(" by {}, {}-{}", version.author, version.copyright_start_year, Local::today().year()); + info!("Chain specification: {}", config.expect_chain_spec().name()); + info!("Node name: {}", config.name); + info!("Roles: {}", display_role(&config)); + + match config.roles { + ServiceRoles::LIGHT => run_service_until_exit( + config, + new_light, + ), + _ => run_service_until_exit( + config, + new_full, + ), } } -fn net_config_file

(net_config_dir: &Option

, name: &str) -> Option -where - P: AsRef -{ - net_config_dir.as_ref().map(|d| d.as_ref().join(name)) -} - -/// Create an error caused by an invalid node key argument. -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 `sc_network::Secret`. -fn parse_ed25519_secret(hex: &String) -> error::Result { - H256::from_str(&hex).map_err(invalid_node_key).and_then(|bytes| - sc_network::config::identity::ed25519::SecretKey::from_bytes(bytes) - .map(sc_network::config::Secret::Input) - .map_err(invalid_node_key)) +/// Returns a string displaying the node role, special casing the sentry mode +/// (returning `SENTRY`), since the node technically has an `AUTHORITY` role but +/// doesn't participate. +pub fn display_role(config: &Configuration) -> String { + if config.sentry_mode { + "SENTRY".to_string() + } else { + format!("{:?}", config.roles) + } } /// Fill the given `PoolConfiguration` by looking at the cli parameters. -fn fill_transaction_pool_configuration( - options: &mut Configuration, +fn fill_transaction_pool_configuration( + options: &mut Configuration, params: TransactionPoolParams, ) -> error::Result<()> { // ready queue @@ -846,7 +422,7 @@ fn fill_network_configuration( config.public_addresses = Vec::new(); config.client_version = client_id; - config.node_key = node_key_config(cli.node_key_params, &config.net_config_path)?; + config.node_key = node_key::node_key_config(cli.node_key_params, &config.net_config_path)?; config.in_peers = cli.in_peers; config.out_peers = cli.out_peers; @@ -869,7 +445,7 @@ fn input_keystore_password() -> Result { } /// Use in memory keystore config when it is not required at all. -fn fill_config_keystore_in_memory(config: &mut sc_service::Configuration) +fn fill_config_keystore_in_memory(config: &mut sc_service::Configuration) -> Result<(), String> { match &mut config.keystore { @@ -879,8 +455,8 @@ fn fill_config_keystore_in_memory(config: &mut sc_service::Configuratio } /// Fill the password field of the given config instance. -fn fill_config_keystore_password_and_path( - config: &mut sc_service::Configuration, +fn fill_config_keystore_password_and_path( + config: &mut sc_service::Configuration, cli: &RunCmd, ) -> Result<(), String> { let password = if cli.password_interactive { @@ -911,16 +487,14 @@ fn fill_config_keystore_password_and_path( } /// Put block import CLI params into `config` object. -pub fn fill_import_params( - config: &mut Configuration, +pub fn fill_import_params( + config: &mut Configuration, cli: &ImportParams, role: sc_service::Roles, is_dev: bool, ) -> error::Result<()> - where - C: Default, - G: RuntimeGenesis, - E: ChainSpecExtension, +where + G: RuntimeGenesis, { match config.database { DatabaseConfig::Path { ref mut cache_size, .. } => @@ -975,31 +549,20 @@ pub fn fill_import_params( Ok(()) } -fn create_run_node_config( +/// Update and prepare a `Configuration` with command line parameters of `RunCmd` +pub fn update_config_for_running_node( + mut config: &mut Configuration, cli: RunCmd, - spec_factory: S, - impl_name: &'static str, - version: &VersionInfo, - default_base_path: Option, -) -> error::Result> +) -> error::Result<()> where - C: Default, G: RuntimeGenesis, - E: ChainSpecExtension, - S: FnOnce(&str) -> Result>, String>, { - let mut config = create_config_with_db_path( - spec_factory, - &cli.shared_params, - &version, - default_base_path, - )?; - fill_config_keystore_password_and_path(&mut config, &cli)?; + let keyring = cli.get_keyring(); let is_dev = cli.shared_params.dev; let is_light = cli.light; - let is_authority = (cli.validator || cli.sentry || is_dev || cli.keyring.account.is_some()) + let is_authority = (cli.validator || cli.sentry || is_dev || keyring.is_some()) && !is_light; let role = if is_light { @@ -1012,15 +575,12 @@ where fill_import_params(&mut config, &cli.import_params, role, is_dev)?; - config.impl_name = impl_name; - config.impl_commit = version.commit; - config.impl_version = version.version; - - config.name = match cli.name.or(cli.keyring.account.map(|a| a.to_string())) { - None => generate_node_name(), - Some(name) => name, + config.name = match (cli.name.as_ref(), keyring) { + (Some(name), _) => name.to_string(), + (_, Some(keyring)) => keyring.to_string(), + (None, None) => generate_node_name(), }; - match is_node_name_valid(&config.name) { + match node_key::is_node_name_valid(&config.name) { Ok(_) => (), Err(msg) => Err( error::Error::Input( @@ -1056,7 +616,7 @@ where fill_transaction_pool_configuration(&mut config, cli.pool_config)?; - config.dev_key_seed = cli.keyring.account + config.dev_key_seed = keyring .map(|a| format!("//{}", a)).or_else(|| { if is_dev && !is_light { Some("//Alice".into()) @@ -1065,15 +625,21 @@ where } }); - 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" }; + if config.rpc_http.is_none() { + let rpc_interface: &str = interface_str(cli.rpc_external, cli.unsafe_rpc_external, cli.validator)?; + config.rpc_http = Some(parse_address(&format!("{}:{}", rpc_interface, 9933), cli.rpc_port)?); + } + if config.rpc_ws.is_none() { + let ws_interface: &str = interface_str(cli.ws_external, cli.unsafe_ws_external, cli.validator)?; + config.rpc_ws = Some(parse_address(&format!("{}:{}", ws_interface, 9944), cli.ws_port)?); + } - config.rpc_http = Some(parse_address(&format!("{}:{}", rpc_interface, 9933), cli.rpc_port)?); - config.rpc_ws = Some(parse_address(&format!("{}:{}", ws_interface, 9944), cli.ws_port)?); - config.grafana_port = Some( - parse_address(&format!("{}:{}", grafana_interface, 9955), cli.grafana_port)? - ); + if config.grafana_port.is_none() { + let grafana_interface: &str = if cli.grafana_external { "0.0.0.0" } else { "127.0.0.1" }; + config.grafana_port = Some( + parse_address(&format!("{}:{}", grafana_interface, 9955), cli.grafana_port)? + ); + } config.rpc_ws_max_connections = cli.ws_max_connections; config.rpc_cors = cli.rpc_cors.unwrap_or_else(|| if is_dev { @@ -1103,7 +669,7 @@ where // Imply forced authoring on --dev config.force_authoring = cli.shared_params.dev || cli.force_authoring; - Ok(config) + Ok(()) } fn interface_str( @@ -1127,61 +693,6 @@ fn interface_str( } } -/// Creates a configuration including the database path. -pub fn create_config_with_db_path( - spec_factory: S, - cli: &SharedParams, - version: &VersionInfo, - default_base_path: Option, -) -> error::Result> -where - C: Default, - G: RuntimeGenesis, - E: ChainSpecExtension, - S: FnOnce(&str) -> Result>, String>, -{ - let spec = load_spec(cli, spec_factory)?; - let base_path = base_path(cli, version, default_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, - }; - - Ok(config) -} - -/// Creates a configuration including the base path and the shared params -fn create_build_spec_config( - spec: &ChainSpec, - cli: &SharedParams, - version: &VersionInfo, - default_base_path: Option, -) -> error::Result> -where - C: Default, - G: RuntimeGenesis, - E: ChainSpecExtension, -{ - let base_path = base_path(&cli, version, default_base_path); - let cfg = sc_service::Configuration::::default_with_spec_and_base_path( - spec.clone(), - Some(base_path), - ); - - Ok(cfg) -} - -/// Internal trait used to cast to a dynamic type that implements Read and Seek. -trait ReadPlusSeek: Read + Seek {} - -impl ReadPlusSeek for T {} - fn parse_address( address: &str, port: Option, @@ -1196,7 +707,8 @@ fn parse_address( Ok(address) } -fn init_logger(pattern: &str) { +/// Initialize the logger +pub fn init_logger(pattern: &str) { use ansi_term::Colour; let mut builder = env_logger::Builder::new(); @@ -1268,118 +780,6 @@ fn kill_color(s: &str) -> String { #[cfg(test)] mod tests { use super::*; - use sc_network::config::identity::ed25519; - - #[test] - fn tests_node_name_good() { - assert!(is_node_name_valid("short name").is_ok()); - } - - #[test] - fn tests_node_name_bad() { - assert!(is_node_name_valid("long names are not very cool for the ui").is_err()); - assert!(is_node_name_valid("Dots.not.Ok").is_err()); - assert!(is_node_name_valid("http://visit.me").is_err()); - assert!(is_node_name_valid("https://visit.me").is_err()); - assert!(is_node_name_valid("www.visit.me").is_err()); - assert!(is_node_name_valid("email@domain").is_err()); - } - - #[test] - fn test_node_key_config_input() { - fn secret_input(net_config_dir: Option) -> error::Result<()> { - NodeKeyType::variants().into_iter().try_for_each(|t| { - let node_key_type = NodeKeyType::from_str(t).unwrap(); - let sk = match node_key_type { - NodeKeyType::Ed25519 => ed25519::SecretKey::generate().as_ref().to_vec() - }; - let params = NodeKeyParams { - node_key_type, - node_key: Some(format!("{:x}", H256::from_slice(sk.as_ref()))), - node_key_file: None - }; - node_key_config(params, &net_config_dir).and_then(|c| match c { - 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())) - }) - }) - } - - assert!(secret_input(None).is_ok()); - assert!(secret_input(Some("x".to_string())).is_ok()); - } - - #[test] - fn test_node_key_config_file() { - 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 = tempfile::Builder::new().prefix("alice").tempdir()?; - let file = tmp.path().join(format!("{}_mysecret", t)).to_path_buf(); - let params = NodeKeyParams { - node_key_type, - node_key: None, - node_key_file: Some(file.clone()) - }; - node_key_config(params, &net_config_dir).and_then(|c| match c { - 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())) - }) - }) - } - - assert!(secret_file(None).is_ok()); - assert!(secret_file(Some("x".to_string())).is_ok()); - } - - #[test] - fn test_node_key_config_default() { - fn with_def_params(f: F) -> error::Result<()> - where - F: Fn(NodeKeyParams) -> error::Result<()> - { - NodeKeyType::variants().into_iter().try_for_each(|t| { - let node_key_type = NodeKeyType::from_str(t).unwrap(); - f(NodeKeyParams { - node_key_type, - node_key: None, - node_key_file: None - }) - }) - } - - fn no_config_dir() -> error::Result<()> { - with_def_params(|params| { - let typ = params.node_key_type; - node_key_config::(params, &None) - .and_then(|c| match c { - NodeKeyConfig::Ed25519(sc_network::config::Secret::New) - if typ == NodeKeyType::Ed25519 => Ok(()), - _ => Err(error::Error::Input("Unexpected node key config".into())) - }) - }) - } - - fn some_config_dir(net_config_dir: String) -> error::Result<()> { - with_def_params(|params| { - let dir = PathBuf::from(net_config_dir.clone()); - let typ = params.node_key_type; - node_key_config(params, &Some(net_config_dir.clone())) - .and_then(move |c| match c { - 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())) - }) - }) - } - - assert!(no_config_dir().is_ok()); - assert!(some_config_dir("x".to_string()).is_ok()); - } #[test] fn keystore_path_is_generated_correctly() { @@ -1391,30 +791,20 @@ mod tests { None, None, None, - None, + None::<()>, ); - let version_info = VersionInfo { - name: "test", - version: "42", - commit: "234234", - executable_name: "test", - description: "cool test", - author: "universe", - support_url: "com", - }; - for keystore_path in vec![None, Some("/keystore/path")] { - let mut run_cmds = RunCmd::from_args(); - run_cmds.shared_params.base_path = Some(PathBuf::from("/test/path")); + let args: Vec<&str> = vec![]; + let mut run_cmds = RunCmd::from_iter(args); run_cmds.keystore_path = keystore_path.clone().map(PathBuf::from); - let node_config = create_run_node_config::<(), _, _, _>( + let mut node_config = Configuration::default(); + node_config.config_dir = Some(PathBuf::from("/test/path")); + node_config.chain_spec = Some(chain_spec.clone()); + update_config_for_running_node( + &mut node_config, run_cmds.clone(), - |_| Ok(Some(chain_spec.clone())), - "test", - &version_info, - None, ).unwrap(); let expected_path = match keystore_path { @@ -1425,44 +815,4 @@ mod tests { assert_eq!(expected_path, node_config.keystore.path().unwrap().to_owned()); } } - - #[test] - fn parse_and_prepare_into_configuration() { - let chain_spec = ChainSpec::from_genesis( - "test", - "test-id", - || (), - Vec::new(), - None, - None, - None, - None, - ); - let version = VersionInfo { - name: "test", - version: "42", - commit: "234234", - executable_name: "test", - description: "cool test", - author: "universe", - support_url: "com", - }; - let spec_factory = |_: &str| Ok(Some(chain_spec.clone())); - - let args = vec!["substrate", "--dev", "--state-cache-size=42"]; - let pnp = parse_and_prepare::(&version, "test", args); - let config = pnp.into_configuration::<(), _, _, _>(spec_factory, None).unwrap().unwrap(); - assert_eq!(config.roles, sc_service::Roles::AUTHORITY); - assert_eq!(config.state_cache_size, 42); - - let args = vec!["substrate", "import-blocks", "--dev"]; - let pnp = parse_and_prepare::(&version, "test", args); - let config = pnp.into_configuration::<(), _, _, _>(spec_factory, None).unwrap().unwrap(); - assert_eq!(config.roles, sc_service::Roles::FULL); - - let args = vec!["substrate", "--base-path=/foo"]; - let pnp = parse_and_prepare::(&version, "test", args); - let config = pnp.into_configuration::<(), _, _, _>(spec_factory, Some("/bar".into())).unwrap().unwrap(); - assert_eq!(config.config_dir, Some("/foo".into())); - } } diff --git a/client/cli/src/node_key.rs b/client/cli/src/node_key.rs new file mode 100644 index 0000000000..4df3b8e9d5 --- /dev/null +++ b/client/cli/src/node_key.rs @@ -0,0 +1,208 @@ +// Copyright 2017-2020 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 sc_network::{ + self, + config::{ + NodeKeyConfig, + }, +}; +use sp_core::H256; +use regex::Regex; +use std::{path::{Path, PathBuf}, str::FromStr}; +use crate::error; +use crate::params::{NodeKeyParams, NodeKeyType}; + +/// The file name of the node's Ed25519 secret key inside the chain-specific +/// network config directory, if neither `--node-key` nor `--node-key-file` +/// is specified in combination with `--node-key-type=ed25519`. +const NODE_KEY_ED25519_FILE: &str = "secret_ed25519"; + +/// Check whether a node name is considered as valid +pub fn is_node_name_valid(_name: &str) -> Result<(), &str> { + let name = _name.to_string(); + if name.chars().count() >= crate::NODE_NAME_MAX_LENGTH { + return Err("Node name too long"); + } + + let invalid_chars = r"[\\.@]"; + let re = Regex::new(invalid_chars).unwrap(); + if re.is_match(&name) { + return Err("Node name should not contain invalid chars such as '.' and '@'"); + } + + let invalid_patterns = r"(https?:\\/+)?(www)+"; + let re = Regex::new(invalid_patterns).unwrap(); + if re.is_match(&name) { + return Err("Node name should not contain urls"); + } + + Ok(()) +} + +/// Create a `NodeKeyConfig` from the given `NodeKeyParams` in the context +/// of an optional network config storage directory. +pub fn node_key_config

(params: NodeKeyParams, net_config_dir: &Option

) + -> error::Result +where + P: AsRef +{ + match params.node_key_type { + NodeKeyType::Ed25519 => + 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(sc_network::config::Secret::File) + .unwrap_or(sc_network::config::Secret::New))) + .map(NodeKeyConfig::Ed25519) + } +} + +/// Create an error caused by an invalid node key argument. +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 `sc_network::Secret`. +fn parse_ed25519_secret(hex: &String) -> error::Result { + H256::from_str(&hex).map_err(invalid_node_key).and_then(|bytes| + sc_network::config::identity::ed25519::SecretKey::from_bytes(bytes) + .map(sc_network::config::Secret::Input) + .map_err(invalid_node_key)) +} + +fn net_config_file

(net_config_dir: &Option

, name: &str) -> Option +where + P: AsRef +{ + net_config_dir.as_ref().map(|d| d.as_ref().join(name)) +} + +mod tests { + use super::*; + use sc_network::config::identity::ed25519; + + #[test] + fn tests_node_name_good() { + assert!(is_node_name_valid("short name").is_ok()); + } + + #[test] + fn tests_node_name_bad() { + assert!(is_node_name_valid("long names are not very cool for the ui").is_err()); + assert!(is_node_name_valid("Dots.not.Ok").is_err()); + assert!(is_node_name_valid("http://visit.me").is_err()); + assert!(is_node_name_valid("https://visit.me").is_err()); + assert!(is_node_name_valid("www.visit.me").is_err()); + assert!(is_node_name_valid("email@domain").is_err()); + } + + #[test] + fn test_node_key_config_input() { + fn secret_input(net_config_dir: Option) -> error::Result<()> { + NodeKeyType::variants().into_iter().try_for_each(|t| { + let node_key_type = NodeKeyType::from_str(t).unwrap(); + let sk = match node_key_type { + NodeKeyType::Ed25519 => ed25519::SecretKey::generate().as_ref().to_vec() + }; + let params = NodeKeyParams { + node_key_type, + node_key: Some(format!("{:x}", H256::from_slice(sk.as_ref()))), + node_key_file: None + }; + node_key_config(params, &net_config_dir).and_then(|c| match c { + 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())) + }) + }) + } + + assert!(secret_input(None).is_ok()); + assert!(secret_input(Some("x".to_string())).is_ok()); + } + + #[test] + fn test_node_key_config_file() { + 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 = tempfile::Builder::new().prefix("alice").tempdir()?; + let file = tmp.path().join(format!("{}_mysecret", t)).to_path_buf(); + let params = NodeKeyParams { + node_key_type, + node_key: None, + node_key_file: Some(file.clone()) + }; + node_key_config(params, &net_config_dir).and_then(|c| match c { + 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())) + }) + }) + } + + assert!(secret_file(None).is_ok()); + assert!(secret_file(Some("x".to_string())).is_ok()); + } + + #[test] + fn test_node_key_config_default() { + fn with_def_params(f: F) -> error::Result<()> + where + F: Fn(NodeKeyParams) -> error::Result<()> + { + NodeKeyType::variants().into_iter().try_for_each(|t| { + let node_key_type = NodeKeyType::from_str(t).unwrap(); + f(NodeKeyParams { + node_key_type, + node_key: None, + node_key_file: None + }) + }) + } + + fn no_config_dir() -> error::Result<()> { + with_def_params(|params| { + let typ = params.node_key_type; + node_key_config::(params, &None) + .and_then(|c| match c { + NodeKeyConfig::Ed25519(sc_network::config::Secret::New) + if typ == NodeKeyType::Ed25519 => Ok(()), + _ => Err(error::Error::Input("Unexpected node key config".into())) + }) + }) + } + + fn some_config_dir(net_config_dir: String) -> error::Result<()> { + with_def_params(|params| { + let dir = PathBuf::from(net_config_dir.clone()); + let typ = params.node_key_type; + node_key_config(params, &Some(net_config_dir.clone())) + .and_then(move |c| match c { + 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())) + }) + }) + } + + assert!(no_config_dir().is_ok()); + assert!(some_config_dir("x".to_string()).is_ok()); + } +} diff --git a/client/cli/src/params.rs b/client/cli/src/params.rs index ccaf24454d..73d9fa59ba 100644 --- a/client/cli/src/params.rs +++ b/client/cli/src/params.rs @@ -14,10 +14,24 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use crate::traits::GetSharedParams; - use std::{str::FromStr, path::PathBuf}; -use structopt::{StructOpt, StructOptInternal, clap::{arg_enum, App, AppSettings, SubCommand, Arg}}; +use structopt::{StructOpt, clap::arg_enum}; +use sc_service::{ + AbstractService, Configuration, ChainSpecExtension, RuntimeGenesis, ServiceBuilderCommand, + config::DatabaseConfig, +}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; +use crate::VersionInfo; +use crate::error; +use std::fmt::Debug; +use log::info; +use sc_network::config::build_multiaddr; +use std::io; +use std::fs; +use std::io::{Read, Write, Seek}; +use sp_runtime::generic::BlockId; +use crate::runtime::run_until_exit; +use crate::node_key::node_key_config; use crate::execution_strategy::*; pub use crate::execution_strategy::ExecutionStrategy; @@ -408,7 +422,7 @@ pub struct RunCmd { /// available to relay to private nodes. #[structopt( long = "sentry", - conflicts_with_all = &[ "validator" ] + conflicts_with_all = &[ "validator", "light" ] )] pub sentry: bool, @@ -417,10 +431,7 @@ pub struct RunCmd { pub no_grandpa: bool, /// Experimental: Run in light client mode. - #[structopt( - long = "light", - conflicts_with_all = &[ "validator" ] - )] + #[structopt(long = "light", conflicts_with = "sentry")] pub light: bool, /// Listen to all RPC interfaces. @@ -532,9 +543,37 @@ pub struct RunCmd { #[structopt(flatten)] pub pool_config: TransactionPoolParams, - #[allow(missing_docs)] - #[structopt(flatten)] - pub keyring: Keyring, + /// Shortcut for `--name Alice --validator` with session keys for `Alice` added to keystore. + #[structopt(long, conflicts_with_all = &["bob", "charlie", "dave", "eve", "ferdie", "one", "two"])] + pub alice: bool, + + /// Shortcut for `--name Bob --validator` with session keys for `Bob` added to keystore. + #[structopt(long, conflicts_with_all = &["alice", "charlie", "dave", "eve", "ferdie", "one", "two"])] + pub bob: bool, + + /// Shortcut for `--name Charlie --validator` with session keys for `Charlie` added to keystore. + #[structopt(long, conflicts_with_all = &["alice", "bob", "dave", "eve", "ferdie", "one", "two"])] + pub charlie: bool, + + /// Shortcut for `--name Dave --validator` with session keys for `Dave` added to keystore. + #[structopt(long, conflicts_with_all = &["alice", "bob", "charlie", "eve", "ferdie", "one", "two"])] + pub dave: bool, + + /// Shortcut for `--name Eve --validator` with session keys for `Eve` added to keystore. + #[structopt(long, conflicts_with_all = &["alice", "bob", "charlie", "dave", "ferdie", "one", "two"])] + pub eve: bool, + + /// Shortcut for `--name Ferdie --validator` with session keys for `Ferdie` added to keystore. + #[structopt(long, conflicts_with_all = &["alice", "bob", "charlie", "dave", "eve", "one", "two"])] + pub ferdie: bool, + + /// Shortcut for `--name One --validator` with session keys for `One` added to keystore. + #[structopt(long, conflicts_with_all = &["alice", "bob", "charlie", "dave", "eve", "ferdie", "two"])] + pub one: bool, + + /// Shortcut for `--name Two --validator` with session keys for `Two` added to keystore. + #[structopt(long, conflicts_with_all = &["alice", "bob", "charlie", "dave", "eve", "ferdie", "one"])] + pub two: bool, /// Enable authoring even when offline. #[structopt(long = "force-authoring")] @@ -582,71 +621,20 @@ pub struct RunCmd { pub password_filename: Option } -/// Stores all required Cli values for a keyring test account. -struct KeyringTestAccountCliValues { - help: String, - conflicts_with: Vec, - name: String, - variant: sp_keyring::Sr25519Keyring, -} - -lazy_static::lazy_static! { - /// The Cli values for all test accounts. - static ref TEST_ACCOUNTS_CLI_VALUES: Vec = { - 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 = sp_keyring::Sr25519Keyring::iter() - .filter(|b| a != *b) - .map(|b| b.to_string().to_lowercase()) - .chain(std::iter::once("name".to_string())) - .collect::>(); - let name = a.to_string().to_lowercase(); - - KeyringTestAccountCliValues { - help, - conflicts_with, - name, - variant: a, - } - }).collect() - }; -} - -/// Wrapper for exposing the keyring test accounts into the Cli. -#[derive(Debug, Clone)] -pub struct Keyring { - pub account: Option, -} - -impl StructOpt for Keyring { - fn clap<'a, 'b>() -> App<'a, 'b> { - unimplemented!("Should not be called for `TestAccounts`.") - } - - fn from_clap(m: &structopt::clap::ArgMatches) -> Self { - Keyring { - account: TEST_ACCOUNTS_CLI_VALUES.iter().find(|a| m.is_present(&a.name)).map(|a| a.variant), - } - } -} - -impl StructOptInternal for Keyring { - fn augment_clap<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> { - TEST_ACCOUNTS_CLI_VALUES.iter().fold(app, |app, a| { - let conflicts_with_strs = a.conflicts_with.iter().map(|s| s.as_str()).collect::>(); - - app.arg( - Arg::with_name(&a.name) - .long(&a.name) - .help(&a.help) - .conflicts_with_all(&conflicts_with_strs) - .takes_value(false) - ) - }) +impl RunCmd { + /// Get the `Sr25519Keyring` matching one of the flag + pub fn get_keyring(&self) -> Option { + use sp_keyring::Sr25519Keyring::*; + + if self.alice { Some(Alice) } + else if self.bob { Some(Bob) } + else if self.charlie { Some(Charlie) } + else if self.dave { Some(Dave) } + else if self.eve { Some(Eve) } + else if self.ferdie { Some(Ferdie) } + else if self.one { Some(One) } + else if self.two { Some(Two) } + else { None } } } @@ -862,11 +850,8 @@ pub struct PurgeChainCmd { /// The core commands are split into multiple subcommands and `Run` is the default subcommand. From /// the CLI user perspective, it is not visible that `Run` is a subcommand. So, all parameters of /// `Run` are exported as main executable parameters. -#[derive(Debug, Clone)] -pub enum CoreParams { - /// Run a node. - Run(MergeParameters), - +#[derive(Debug, Clone, StructOpt)] +pub enum Subcommand { /// Build a spec.json file, outputing to stdout. BuildSpec(BuildSpecCmd), @@ -884,112 +869,323 @@ pub enum CoreParams { /// Remove the whole chain data. PurgeChain(PurgeChainCmd), +} + +impl Subcommand { + /// Get the shared parameters of a `CoreParams` command + pub fn get_shared_params(&self) -> &SharedParams { + use Subcommand::*; - /// Further custom subcommands. - Custom(CC), -} - -impl StructOpt for CoreParams where - CC: StructOpt + GetSharedParams, - RP: StructOpt + StructOptInternal, -{ - fn clap<'a, 'b>() -> App<'a, 'b> { - RP::augment_clap( - RunCmd::augment_clap( - CC::clap().unset_setting(AppSettings::SubcommandRequiredElseHelp) - ) - ).subcommand( - BuildSpecCmd::augment_clap(SubCommand::with_name("build-spec")) - .about("Build a spec.json file, outputting to stdout.") - ) - .subcommand( - ExportBlocksCmd::augment_clap(SubCommand::with_name("export-blocks")) - .about("Export blocks to a file. This file can only be re-imported \ - if it is in binary format (not JSON!)." - ) - ) - .subcommand( - 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.") - ) - .subcommand( - PurgeChainCmd::augment_clap(SubCommand::with_name("purge-chain")) - .about("Remove the whole chain data.") - ) + match self { + BuildSpec(params) => ¶ms.shared_params, + ExportBlocks(params) => ¶ms.shared_params, + ImportBlocks(params) => ¶ms.shared_params, + CheckBlock(params) => ¶ms.shared_params, + Revert(params) => ¶ms.shared_params, + PurgeChain(params) => ¶ms.shared_params, + } } - fn from_clap(matches: &::structopt::clap::ArgMatches) -> Self { - match matches.subcommand() { - ("build-spec", Some(matches)) => - CoreParams::BuildSpec(BuildSpecCmd::from_clap(matches)), - ("export-blocks", Some(matches)) => - 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)), - (_, None) => CoreParams::Run(MergeParameters::from_clap(matches)), - _ => CoreParams::Custom(CC::from_clap(matches)), + /// Run any `CoreParams` command + pub fn run( + self, + config: Configuration, + builder: B, + ) -> error::Result<()> + where + B: FnOnce(Configuration) -> Result, + G: RuntimeGenesis, + E: ChainSpecExtension, + BC: ServiceBuilderCommand + Unpin, + BB: sp_runtime::traits::Block + Debug, + <<::Header as HeaderT>::Number as std::str::FromStr>::Err: std::fmt::Debug, + ::Hash: std::str::FromStr, + { + assert!(config.chain_spec.is_some(), "chain_spec must be present before continuing"); + + match self { + Subcommand::BuildSpec(cmd) => cmd.run(config), + Subcommand::ExportBlocks(cmd) => cmd.run(config, builder), + Subcommand::ImportBlocks(cmd) => cmd.run(config, builder), + Subcommand::CheckBlock(cmd) => cmd.run(config, builder), + Subcommand::PurgeChain(cmd) => cmd.run(config), + Subcommand::Revert(cmd) => cmd.run(config, builder), } } } -/// A special commandline parameter that expands to nothing. -/// Should be used as custom subcommand/run arguments if no custom values are required. -#[derive(Clone, Debug, Default)] -pub struct NoCustom {} +impl RunCmd { + /// Run the command that runs the node + pub fn run( + self, + mut config: Configuration, + new_light: FNL, + new_full: FNF, + version: &VersionInfo, + ) -> error::Result<()> + where + G: RuntimeGenesis, + E: ChainSpecExtension, + FNL: FnOnce(Configuration) -> Result, + FNF: FnOnce(Configuration) -> Result, + SL: AbstractService + Unpin, + SF: AbstractService + Unpin, + { + assert!(config.chain_spec.is_some(), "chain_spec must be present before continuing"); -impl StructOpt for NoCustom { - fn clap<'a, 'b>() -> App<'a, 'b> { - App::new("NoCustom") - } + crate::update_config_for_running_node( + &mut config, + self, + )?; - fn from_clap(_: &::structopt::clap::ArgMatches) -> Self { - NoCustom {} + crate::run_node(config, new_light, new_full, &version) } } -impl StructOptInternal for NoCustom { - fn augment_clap<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> { - app +impl BuildSpecCmd { + /// Run the build-spec command + pub fn run( + self, + config: Configuration, + ) -> error::Result<()> + where + G: RuntimeGenesis, + E: ChainSpecExtension, + { + assert!(config.chain_spec.is_some(), "chain_spec must be present before continuing"); + + info!("Building chain spec"); + let mut spec = config.expect_chain_spec().clone(); + let raw_output = self.raw; + + if spec.boot_nodes().is_empty() && !self.disable_default_bootnode { + let node_key = node_key_config( + self.node_key_params.clone(), + &Some(config + .in_chain_config_dir(crate::DEFAULT_NETWORK_CONFIG_PATH) + .expect("We provided a base_path")), + )?; + let keys = node_key.into_keypair()?; + let peer_id = keys.public().into_peer_id(); + let addr = build_multiaddr![ + Ip4([127, 0, 0, 1]), + Tcp(30333u16), + P2p(peer_id) + ]; + spec.add_boot_node(addr) + } + + let json = sc_service::chain_ops::build_spec(spec, raw_output)?; + + print!("{}", json); + + Ok(()) } } -impl GetSharedParams for NoCustom { - fn shared_params(&self) -> Option<&SharedParams> { - None +impl ExportBlocksCmd { + /// Run the export-blocks command + pub fn run( + self, + mut config: Configuration, + builder: B, + ) -> error::Result<()> + where + B: FnOnce(Configuration) -> Result, + G: RuntimeGenesis, + E: ChainSpecExtension, + BC: ServiceBuilderCommand + Unpin, + BB: sp_runtime::traits::Block + Debug, + <<::Header as HeaderT>::Number as std::str::FromStr>::Err: std::fmt::Debug, + ::Hash: std::str::FromStr, + { + assert!(config.chain_spec.is_some(), "chain_spec must be present before continuing"); + + crate::fill_config_keystore_in_memory(&mut config)?; + + if let DatabaseConfig::Path { ref path, .. } = &config.database { + info!("DB path: {}", path.display()); + } + let from = self.from.as_ref().and_then(|f| f.parse().ok()).unwrap_or(1); + let to = self.to.as_ref().and_then(|t| t.parse().ok()); + + let json = self.json; + + let file: Box = match &self.output { + Some(filename) => Box::new(fs::File::create(filename)?), + None => Box::new(io::stdout()), + }; + + run_until_exit(config, |config| { + Ok(builder(config)?.export_blocks(file, from.into(), to, json)) + }) } } -/// Merge all CLI parameters of `L` and `R` into the same level. -#[derive(Clone, Debug)] -pub struct MergeParameters { - /// The left side parameters. - pub left: L, - /// The right side parameters. - pub right: R, +/// Internal trait used to cast to a dynamic type that implements Read and Seek. +trait ReadPlusSeek: Read + Seek {} + +impl ReadPlusSeek for T {} + +impl ImportBlocksCmd { + /// Run the import-blocks command + pub fn run( + self, + mut config: Configuration, + builder: B, + ) -> error::Result<()> + where + B: FnOnce(Configuration) -> Result, + G: RuntimeGenesis, + E: ChainSpecExtension, + BC: ServiceBuilderCommand + Unpin, + BB: sp_runtime::traits::Block + Debug, + <<::Header as HeaderT>::Number as std::str::FromStr>::Err: std::fmt::Debug, + ::Hash: std::str::FromStr, + { + crate::fill_import_params( + &mut config, + &self.import_params, + sc_service::Roles::FULL, + self.shared_params.dev, + )?; + + let file: Box = match &self.input { + Some(filename) => Box::new(fs::File::open(filename)?), + None => { + let mut buffer = Vec::new(); + io::stdin().read_to_end(&mut buffer)?; + Box::new(io::Cursor::new(buffer)) + }, + }; + + run_until_exit(config, |config| { + Ok(builder(config)?.import_blocks(file, false)) + }) + } } -impl StructOpt for MergeParameters where L: StructOpt + StructOptInternal, R: StructOpt { - fn clap<'a, 'b>() -> App<'a, 'b> { - L::augment_clap(R::clap()) +impl CheckBlockCmd { + /// Run the check-block command + pub fn run( + self, + mut config: Configuration, + builder: B, + ) -> error::Result<()> + where + B: FnOnce(Configuration) -> Result, + G: RuntimeGenesis, + E: ChainSpecExtension, + BC: ServiceBuilderCommand + Unpin, + BB: sp_runtime::traits::Block + Debug, + <<::Header as HeaderT>::Number as std::str::FromStr>::Err: std::fmt::Debug, + ::Hash: std::str::FromStr, + { + assert!(config.chain_spec.is_some(), "chain_spec must be present before continuing"); + + crate::fill_import_params( + &mut config, + &self.import_params, + sc_service::Roles::FULL, + self.shared_params.dev, + )?; + crate::fill_config_keystore_in_memory(&mut config)?; + + let input = if self.input.starts_with("0x") { &self.input[2..] } else { &self.input[..] }; + let block_id = match FromStr::from_str(input) { + Ok(hash) => BlockId::hash(hash), + Err(_) => match self.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(); + run_until_exit(config, |config| { + Ok(builder(config)?.check_block(block_id)) + })?; + println!("Completed in {} ms.", start.elapsed().as_millis()); + + Ok(()) } +} + +impl PurgeChainCmd { + /// Run the purge command + pub fn run( + self, + mut config: Configuration, + ) -> error::Result<()> + where + G: RuntimeGenesis, + E: ChainSpecExtension, + { + assert!(config.chain_spec.is_some(), "chain_spec must be present before continuing"); - fn from_clap(matches: &::structopt::clap::ArgMatches) -> Self { - MergeParameters { - left: L::from_clap(matches), - right: R::from_clap(matches), + crate::fill_config_keystore_in_memory(&mut config)?; + + let db_path = match config.database { + DatabaseConfig::Path { path, .. } => path, + _ => { + eprintln!("Cannot purge custom database implementation"); + return Ok(()); + } + }; + + if !self.yes { + print!("Are you sure to remove {:?}? [y/N]: ", &db_path); + io::stdout().flush().expect("failed to flush stdout"); + + let mut input = String::new(); + io::stdin().read_line(&mut input)?; + let input = input.trim(); + + match input.chars().nth(0) { + Some('y') | Some('Y') => {}, + _ => { + println!("Aborted"); + return Ok(()); + }, + } } + + match fs::remove_dir_all(&db_path) { + Ok(_) => { + println!("{:?} removed.", &db_path); + Ok(()) + }, + Err(ref err) if err.kind() == io::ErrorKind::NotFound => { + eprintln!("{:?} did not exist.", &db_path); + Ok(()) + }, + Err(err) => Result::Err(err.into()) + } + } +} + +impl RevertCmd { + /// Run the revert command + pub fn run( + self, + mut config: Configuration, + builder: B, + ) -> error::Result<()> + where + B: FnOnce(Configuration) -> Result, + G: RuntimeGenesis, + E: ChainSpecExtension, + BC: ServiceBuilderCommand + Unpin, + BB: sp_runtime::traits::Block + Debug, + <<::Header as HeaderT>::Number as std::str::FromStr>::Err: std::fmt::Debug, + ::Hash: std::str::FromStr, + { + assert!(config.chain_spec.is_some(), "chain_spec must be present before continuing"); + + crate::fill_config_keystore_in_memory(&mut config)?; + + let blocks = self.num.parse()?; + builder(config)?.revert_chain(blocks)?; + + Ok(()) } } diff --git a/client/cli/src/runtime.rs b/client/cli/src/runtime.rs new file mode 100644 index 0000000000..3eee94c049 --- /dev/null +++ b/client/cli/src/runtime.rs @@ -0,0 +1,138 @@ +// Copyright 2017-2020 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 futures::{Future, future, future::FutureExt}; +use futures::select; +use futures::pin_mut; +use sc_service::{AbstractService, Configuration}; +use crate::error; +use crate::informant; + +#[cfg(target_family = "unix")] +async fn main(func: F) -> Result<(), Box> +where + F: Future> + future::FusedFuture, + E: 'static + std::error::Error, +{ + use tokio::signal::unix::{signal, SignalKind}; + + let mut stream_int = signal(SignalKind::interrupt())?; + let mut stream_term = signal(SignalKind::terminate())?; + + let t1 = stream_int.recv().fuse(); + let t2 = stream_term.recv().fuse(); + let t3 = func; + + pin_mut!(t1, t2, t3); + + select! { + _ = t1 => {}, + _ = t2 => {}, + res = t3 => res?, + } + + Ok(()) +} + +#[cfg(not(unix))] +async fn main(func: F) -> Result<(), Box> +where + F: Future> + future::FusedFuture, + E: 'static + std::error::Error, +{ + use tokio::signal::ctrl_c; + + let t1 = ctrl_c().fuse(); + let t2 = func; + + pin_mut!(t1, t2); + + select! { + _ = t1 => {}, + res = t2 => res?, + } + + Ok(()) +} + +fn build_runtime() -> Result { + tokio::runtime::Builder::new() + .thread_name("main-tokio-") + .threaded_scheduler() + .enable_all() + .build() +} + +/// A helper function that runs a future with tokio and stops if the process receives the signal +/// SIGTERM or SIGINT +pub fn run_until_exit( + mut config: Configuration, + future_builder: F, +) -> error::Result<()> +where + F: FnOnce(Configuration) -> error::Result, + FUT: Future> + future::Future, + ERR: 'static + std::error::Error, +{ + let mut runtime = build_runtime()?; + + config.task_executor = { + let runtime_handle = runtime.handle().clone(); + Some(Box::new(move |fut| { runtime_handle.spawn(fut); })) + }; + + let f = future_builder(config)?; + let f = f.fuse(); + pin_mut!(f); + + runtime.block_on(main(f)).map_err(|e| e.to_string())?; + + Ok(()) +} + +/// A helper function that runs an `AbstractService` with tokio and stops if the process receives +/// the signal SIGTERM or SIGINT +pub fn run_service_until_exit( + mut config: Configuration, + service_builder: F, +) -> error::Result<()> +where + F: FnOnce(Configuration) -> Result, + T: AbstractService + Unpin, +{ + let mut runtime = build_runtime()?; + + config.task_executor = { + let runtime_handle = runtime.handle().clone(); + Some(Box::new(move |fut| { runtime_handle.spawn(fut); })) + }; + + let service = service_builder(config)?; + + let informant_future = informant::build(&service); + let _informant_handle = runtime.spawn(informant_future); + + // we eagerly drop the service so that the internal exit future is fired, + // but we need to keep holding a reference to the global telemetry guard + let _telemetry = service.telemetry(); + + let f = service.fuse(); + pin_mut!(f); + + runtime.block_on(main(f)).map_err(|e| e.to_string())?; + + Ok(()) +} diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index c5df969779..7a6ca8dc79 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -72,10 +72,10 @@ use grafana_data_source::{self, record_metrics}; /// The order in which the `with_*` methods are called doesn't matter, as the correct binding of /// generics is done when you call `build`. /// -pub struct ServiceBuilder { - config: Configuration, + config: Configuration, pub (crate) client: Arc, backend: Arc, keystore: Arc>, @@ -144,8 +144,8 @@ type TFullParts = ( ); /// Creates a new full client for the given config. -pub fn new_full_client( - config: &Configuration, +pub fn new_full_client( + config: &Configuration, ) -> Result, Error> where TBl: BlockT, TExecDisp: NativeExecutionDispatch + 'static, @@ -155,8 +155,8 @@ pub fn new_full_client( new_full_parts(config).map(|parts| parts.0) } -fn new_full_parts( - config: &Configuration, +fn new_full_parts( + config: &Configuration, ) -> Result, Error> where TBl: BlockT, TExecDisp: NativeExecutionDispatch + 'static, @@ -177,13 +177,14 @@ fn new_full_parts( config.default_heap_pages, ); - let fork_blocks = config.chain_spec + let chain_spec = config.expect_chain_spec(); + let fork_blocks = chain_spec .extensions() .get::>() .cloned() .unwrap_or_default(); - let bad_blocks = config.chain_spec + let bad_blocks = chain_spec .extensions() .get::>() .cloned() @@ -214,7 +215,7 @@ fn new_full_parts( sc_client_db::new_client( db_config, executor, - &config.chain_spec, + config.expect_chain_spec(), fork_blocks, bad_blocks, extensions, @@ -224,15 +225,14 @@ fn new_full_parts( Ok((client, backend, keystore)) } -impl ServiceBuilder<(), (), TCfg, TGen, TCSExt, (), (), (), (), (), (), (), (), (), ()> +impl ServiceBuilder<(), (), TGen, TCSExt, (), (), (), (), (), (), (), (), (), ()> where TGen: RuntimeGenesis, TCSExt: Extension { /// Start the service builder with a configuration. pub fn new_full( - config: Configuration + config: Configuration ) -> Result, @@ -270,11 +270,10 @@ where TGen: RuntimeGenesis, TCSExt: Extension { /// Start the service builder with a configuration. pub fn new_light( - config: Configuration + config: Configuration ) -> Result, @@ -332,7 +331,7 @@ where TGen: RuntimeGenesis, TCSExt: Extension { let remote_blockchain = backend.remote_blockchain(); let client = Arc::new(sc_client::light::new_light( backend.clone(), - &config.chain_spec, + config.expect_chain_spec(), executor, )?); @@ -355,8 +354,8 @@ where TGen: RuntimeGenesis, TCSExt: Extension { } } -impl - ServiceBuilder + ServiceBuilder { /// Returns a reference to the client that was stored in this builder. @@ -378,9 +377,9 @@ impl( self, select_chain_builder: impl FnOnce( - &Configuration, &Arc + &Configuration, &Arc ) -> Result, Error> - ) -> Result Result, Error> { let select_chain = select_chain_builder(&self.config, &self.backend)?; @@ -405,8 +404,8 @@ impl( self, - builder: impl FnOnce(&Configuration, &Arc) -> Result - ) -> Result, &Arc) -> Result + ) -> Result, Error> { self.with_opt_select_chain(|cfg, b| builder(cfg, b).map(Option::Some)) } @@ -414,9 +413,9 @@ impl( self, - builder: impl FnOnce(&Configuration, Arc, Option, Arc) + builder: impl FnOnce(&Configuration, Arc, Option, Arc) -> Result - ) -> Result Result, Error> where TSc: Clone { let import_queue = builder( @@ -447,8 +446,8 @@ impl( self, - network_protocol_builder: impl FnOnce(&Configuration) -> Result - ) -> Result) -> Result + ) -> Result, Error> { let network_protocol = network_protocol_builder(&self.config)?; @@ -477,7 +476,6 @@ impl Result Result( self, builder: impl FnOnce( - &Configuration, + &Configuration, Arc, Arc, Option, Option, Arc, ) -> Result<(UImpQu, Option), Error> - ) -> Result Result, Error> where TSc: Clone, TFchr: Clone { let (import_queue, fprb) = builder( @@ -580,14 +577,14 @@ impl( self, builder: impl FnOnce( - &Configuration, + &Configuration, Arc, Arc, Option, Option, Arc, ) -> Result<(UImpQu, UFprb), Error> - ) -> Result Result, Error> where TSc: Clone, TFchr: Clone { self.with_import_queue_and_opt_fprb(|cfg, cl, b, f, sc, tx| @@ -604,7 +601,7 @@ impl, Option, ) -> Result - ) -> Result Result, Error> where TSc: Clone, TFchr: Clone { let transaction_pool = transaction_pool_builder( @@ -641,7 +638,7 @@ impl, Option>>, ) -> Result, - ) -> Result Result, Error> where TSc: Clone, TFchr: Clone { let rpc_extensions = rpc_ext_builder( @@ -705,11 +702,10 @@ pub trait ServiceBuilderCommand { ) -> Pin> + Send>>; } -impl +impl ServiceBuilder< TBl, TRtApi, - TCfg, TGen, TCSExt, Client, @@ -733,7 +729,6 @@ ServiceBuilder< sp_api::ApiExt, TBl: BlockT, TRtApi: 'static + Send + Sync, - TCfg: Default, TGen: RuntimeGenesis, TCSExt: Extension, TBackend: 'static + sc_client_api::backend::Backend + Send, @@ -799,6 +794,7 @@ ServiceBuilder< let import_queue = Box::new(import_queue); let chain_info = client.chain_info(); + let chain_spec = config.expect_chain_spec(); let version = config.full_version(); info!("Highest known block at #{}", chain_info.best_number); @@ -821,7 +817,7 @@ ServiceBuilder< }); let protocol_id = { - let protocol_id_full = match config.chain_spec.protocol_id() { + let protocol_id_full = match chain_spec.protocol_id() { Some(pid) => pid, None => { warn!("Using default protocol ID {:?} because none is configured in the \ @@ -1030,10 +1026,10 @@ ServiceBuilder< use sc_rpc::{chain, state, author, system, offchain}; let system_info = sc_rpc::system::SystemInfo { - chain_name: config.chain_spec.name().into(), + chain_name: chain_spec.name().into(), impl_name: config.impl_name.into(), impl_version: config.impl_version.into(), - properties: config.chain_spec.properties().clone(), + properties: chain_spec.properties().clone(), }; let subscriptions = sc_rpc::Subscriptions::new(Arc::new(SpawnTaskHandle { @@ -1119,7 +1115,7 @@ ServiceBuilder< let name = config.name.clone(); let impl_name = config.impl_name.to_owned(); let version = version.clone(); - let chain_name = config.chain_spec.name().to_owned(); + let chain_name = config.expect_chain_spec().name().to_owned(); let telemetry_connection_sinks_ = telemetry_connection_sinks.clone(); let telemetry = sc_telemetry::init_telemetry(sc_telemetry::TelemetryConfig { endpoints, @@ -1188,7 +1184,7 @@ ServiceBuilder< essential_failed_rx, to_spawn_tx, to_spawn_rx, - tasks_executor: if let Some(exec) = config.tasks_executor { + task_executor: if let Some(exec) = config.task_executor { exec } else { return Err(Error::TasksExecutorRequired); diff --git a/client/service/src/chain_ops.rs b/client/service/src/chain_ops.rs index 0c2fe79718..cac1c14d0b 100644 --- a/client/service/src/chain_ops.rs +++ b/client/service/src/chain_ops.rs @@ -44,11 +44,11 @@ pub fn build_spec(spec: ChainSpec, raw: bool) -> error::Result ServiceBuilderCommand for ServiceBuilder< - TBl, TRtApi, TCfg, TGen, TCSExt, Client, + TBl, TRtApi, TGen, TCSExt, Client, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, Backend > where TBl: BlockT, diff --git a/client/service/src/config.rs b/client/service/src/config.rs index 8a145dec16..cb8170f7f4 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -23,13 +23,13 @@ pub use sc_executor::WasmExecutionMethod; use std::{future::Future, path::{PathBuf, Path}, pin::Pin, net::SocketAddr, sync::Arc}; pub use sc_transaction_pool::txpool::Options as TransactionPoolOptions; -use sc_chain_spec::{ChainSpec, RuntimeGenesis, Extension, NoExtension}; +use sc_chain_spec::{ChainSpec, NoExtension}; use sp_core::crypto::Protected; use target_info::Target; use sc_telemetry::TelemetryEndpoints; /// Service configuration. -pub struct Configuration { +pub struct Configuration { /// Implementation name pub impl_name: &'static str, /// Implementation version @@ -39,7 +39,7 @@ pub struct Configuration { /// Node roles. pub roles: Roles, /// How to spawn background tasks. Mandatory, otherwise creating a `Service` will error. - pub tasks_executor: Option + Send>>) + Send>>, + pub task_executor: Option + Send>>) + Send>>, /// Extrinsic pool configuration. pub transaction_pool: TransactionPoolOptions, /// Network configuration. @@ -57,9 +57,7 @@ pub struct Configuration { /// Pruning settings. pub pruning: PruningMode, /// Chain configuration. - pub chain_spec: ChainSpec, - /// Custom configuration. - pub custom: C, + pub chain_spec: Option>, /// Node name. pub name: String, /// Wasm execution method. @@ -146,22 +144,18 @@ pub enum DatabaseConfig { Custom(Arc), } -impl Configuration where - C: Default, - G: RuntimeGenesis, - E: Extension, -{ - /// Create a default config for given chain spec and path to configuration dir - pub fn default_with_spec_and_base_path(chain_spec: ChainSpec, config_dir: Option) -> Self { - let mut configuration = Configuration { +impl Default for Configuration { + /// Create a default config + fn default() -> Self { + let configuration = Configuration { impl_name: "parity-substrate", impl_version: "0.0.0", impl_commit: "", - chain_spec, - config_dir: config_dir.clone(), + chain_spec: None, + config_dir: None, name: Default::default(), roles: Roles::FULL, - tasks_executor: None, + task_executor: None, transaction_pool: Default::default(), network: Default::default(), keystore: KeystoreConfig::None, @@ -171,7 +165,6 @@ impl Configuration where }, state_cache_size: Default::default(), state_cache_child_ratio: Default::default(), - custom: Default::default(), pruning: PruningMode::default(), wasm_method: WasmExecutionMethod::Interpreted, execution_strategies: Default::default(), @@ -191,16 +184,13 @@ impl Configuration where tracing_targets: Default::default(), tracing_receiver: Default::default(), }; - configuration.network.boot_nodes = configuration.chain_spec.boot_nodes().to_vec(); - - configuration.telemetry_endpoints = configuration.chain_spec.telemetry_endpoints().clone(); configuration } } -impl Configuration { +impl Configuration { /// Returns full version string of this configuration. pub fn full_version(&self) -> String { full_version_from_strs(self.impl_version, self.impl_commit) @@ -216,11 +206,20 @@ impl Configuration { pub fn in_chain_config_dir(&self, sub: &str) -> Option { self.config_dir.clone().map(|mut path| { path.push("chains"); - path.push(self.chain_spec.id()); + path.push(self.expect_chain_spec().id()); path.push(sub); path }) } + + /// Return a reference to the `ChainSpec` of this `Configuration`. + /// + /// ### Panics + /// + /// This method panic if the `chain_spec` is `None` + pub fn expect_chain_spec(&self) -> &ChainSpec { + self.chain_spec.as_ref().expect("chain_spec must be specified") + } } /// Returns platform info diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 3bd8f6d290..5ba6474da6 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -96,7 +96,7 @@ pub struct Service { /// Receiver for futures that must be spawned as background tasks. to_spawn_rx: mpsc::UnboundedReceiver<(Pin + Send>>, Cow<'static, str>)>, /// How to spawn background tasks. - tasks_executor: Box + Send>>) + Send>, + task_executor: Box + Send>>) + Send>, rpc_handlers: sc_rpc_server::RpcHandler, _rpc: Box, _telemetry: Option, @@ -340,7 +340,7 @@ impl Future for } while let Poll::Ready(Some((task_to_spawn, name))) = Pin::new(&mut this.to_spawn_rx).poll_next(cx) { - (this.tasks_executor)(Box::pin(futures_diagnose::diagnose(name, task_to_spawn))); + (this.task_executor)(Box::pin(futures_diagnose::diagnose(name, task_to_spawn))); } // The service future never ends. @@ -523,8 +523,8 @@ impl Drop for /// 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 sc_rpc_server::RpcHandler>( - config: &Configuration, +fn start_rpc_servers sc_rpc_server::RpcHandler>( + config: &Configuration, mut gen_handler: H ) -> Result, error::Error> { fn maybe_start_server(address: Option, mut start: F) -> Result, io::Error> @@ -564,8 +564,8 @@ fn start_rpc_servers sc_rpc_server::RpcHandler sc_rpc_server::RpcHandler>( - _: &Configuration, +fn start_rpc_servers sc_rpc_server::RpcHandler>( + _: &Configuration, _: H ) -> Result, error::Error> { Ok(Box::new(())) diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 961c8d98ff..cb458d533f 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -133,11 +133,11 @@ fn node_config ( index: usize, spec: &ChainSpec, role: Roles, - tasks_executor: Box + Send>>) + Send>, + task_executor: Box + Send>>) + Send>, key_seed: Option, base_port: u16, root: &TempDir, -) -> Configuration<(), G, E> +) -> Configuration { let root = root.path().join(format!("node-{}", index)); @@ -175,7 +175,7 @@ fn node_config ( impl_version: "0.1", impl_commit: "", roles: role, - tasks_executor: Some(tasks_executor), + task_executor: Some(task_executor), transaction_pool: Default::default(), network: network_config, keystore: KeystoreConfig::Path { @@ -190,8 +190,7 @@ fn node_config ( state_cache_size: 16777216, state_cache_child_ratio: None, pruning: Default::default(), - chain_spec: (*spec).clone(), - custom: Default::default(), + chain_spec: Some((*spec).clone()), name: format!("Node {}", index), wasm_method: sc_service::config::WasmExecutionMethod::Interpreted, execution_strategies: Default::default(), @@ -221,11 +220,11 @@ impl TestNet where fn new( temp: &TempDir, spec: ChainSpec, - full: impl Iterator) -> Result<(F, U), Error>>, - light: impl Iterator) -> Result>, + full: impl Iterator) -> Result<(F, U), Error>>, + light: impl Iterator) -> Result>, authorities: impl Iterator) -> Result<(F, U), Error> + impl FnOnce(Configuration) -> Result<(F, U), Error> )>, base_port: u16 ) -> TestNet { @@ -248,14 +247,14 @@ impl TestNet where fn insert_nodes( &mut self, temp: &TempDir, - full: impl Iterator) -> Result<(F, U), Error>>, - light: impl Iterator) -> Result>, - authorities: impl Iterator) -> Result<(F, U), Error>)> + full: impl Iterator) -> Result<(F, U), Error>>, + light: impl Iterator) -> Result>, + authorities: impl Iterator) -> Result<(F, U), Error>)> ) { let executor = self.runtime.executor(); for (key, authority) in authorities { - let tasks_executor = { + let task_executor = { let executor = executor.clone(); Box::new(move |fut: Pin + Send>>| executor.spawn(fut.unit_error().compat())) }; @@ -263,7 +262,7 @@ impl TestNet where self.nodes, &self.chain_spec, Roles::AUTHORITY, - tasks_executor, + task_executor, Some(key), self.base_port, &temp, @@ -279,11 +278,11 @@ impl TestNet where } for full in full { - let tasks_executor = { + let task_executor = { let executor = executor.clone(); Box::new(move |fut: Pin + Send>>| executor.spawn(fut.unit_error().compat())) }; - let node_config = node_config(self.nodes, &self.chain_spec, Roles::FULL, tasks_executor, None, self.base_port, &temp); + let node_config = node_config(self.nodes, &self.chain_spec, Roles::FULL, task_executor, None, self.base_port, &temp); let addr = node_config.network.listen_addresses.iter().next().unwrap().clone(); let (service, user_data) = full(node_config).expect("Error creating test node service"); let service = SyncService::from(service); @@ -295,11 +294,11 @@ impl TestNet where } for light in light { - let tasks_executor = { + let task_executor = { let executor = executor.clone(); Box::new(move |fut: Pin + Send>>| executor.spawn(fut.unit_error().compat())) }; - let node_config = node_config(self.nodes, &self.chain_spec, Roles::LIGHT, tasks_executor, None, self.base_port, &temp); + let node_config = node_config(self.nodes, &self.chain_spec, Roles::LIGHT, task_executor, None, self.base_port, &temp); let addr = node_config.network.listen_addresses.iter().next().unwrap().clone(); let service = SyncService::from(light(node_config).expect("Error creating test node service")); @@ -321,9 +320,9 @@ pub fn connectivity( light_builder: Lb, ) where E: Clone, - Fb: Fn(Configuration<(), G, E>) -> Result, + Fb: Fn(Configuration) -> Result, F: AbstractService, - Lb: Fn(Configuration<(), G, E>) -> Result, + Lb: Fn(Configuration) -> Result, L: AbstractService, { const NUM_FULL_NODES: usize = 5; @@ -420,9 +419,9 @@ pub fn sync( mut make_block_and_import: B, mut extrinsic_factory: ExF ) where - Fb: Fn(Configuration<(), G, E>) -> Result<(F, U), Error>, + Fb: Fn(Configuration) -> Result<(F, U), Error>, F: AbstractService, - Lb: Fn(Configuration<(), G, E>) -> Result, + Lb: Fn(Configuration) -> Result, L: AbstractService, B: FnMut(&F, &mut U), ExF: FnMut(&F, &U) -> ::Extrinsic, @@ -489,9 +488,9 @@ pub fn consensus( light_builder: Lb, authorities: impl IntoIterator ) where - Fb: Fn(Configuration<(), G, E>) -> Result, + Fb: Fn(Configuration) -> Result, F: AbstractService, - Lb: Fn(Configuration<(), G, E>) -> Result, + Lb: Fn(Configuration) -> Result, L: AbstractService, E: Clone, { diff --git a/primitives/keyring/src/sr25519.rs b/primitives/keyring/src/sr25519.rs index 27627a0c50..d3776f4073 100644 --- a/primitives/keyring/src/sr25519.rs +++ b/primitives/keyring/src/sr25519.rs @@ -113,6 +113,33 @@ impl From for sp_runtime::MultiSigner { } } +#[derive(Debug)] +pub struct ParseKeyringError; + +impl std::fmt::Display for ParseKeyringError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "ParseKeyringError") + } +} + +impl std::str::FromStr for Keyring { + type Err = ParseKeyringError; + + fn from_str(s: &str) -> Result::Err> { + match s { + "alice" => Ok(Keyring::Alice), + "bob" => Ok(Keyring::Bob), + "charlie" => Ok(Keyring::Charlie), + "dave" => Ok(Keyring::Dave), + "eve" => Ok(Keyring::Eve), + "ferdie" => Ok(Keyring::Ferdie), + "one" => Ok(Keyring::One), + "two" => Ok(Keyring::Two), + _ => Err(ParseKeyringError) + } + } +} + lazy_static! { static ref PRIVATE_KEYS: HashMap = { Keyring::iter().map(|i| (i, i.pair())).collect() diff --git a/utils/browser/src/lib.rs b/utils/browser/src/lib.rs index 7b7fda4583..4f985871f5 100644 --- a/utils/browser/src/lib.rs +++ b/utils/browser/src/lib.rs @@ -34,25 +34,24 @@ pub use console_log::init_with_level as init_console_log; /// Create a service configuration from a chain spec and the websocket transport. /// /// This configuration contains good defaults for a browser light client. -pub async fn browser_configuration( +pub async fn browser_configuration( transport: Transport, chain_spec: ChainSpec, -) -> Result, Box> +) -> Result, Box> where - C: Default, G: RuntimeGenesis, E: Extension, { let name = chain_spec.name().to_string(); let transport = ExtTransport::new(transport); - let mut config = Configuration::default_with_spec_and_base_path(chain_spec, None); + let mut config = Configuration::default(); config.network.transport = network::config::TransportConfig::Normal { wasm_external_transport: Some(transport.clone()), allow_private_ipv4: true, enable_mdns: false, }; - config.tasks_executor = Some(Box::new(move |fut| { + config.task_executor = Some(Box::new(move |fut| { wasm_bindgen_futures::spawn_local(fut) })); config.telemetry_external_transport = Some(transport); -- GitLab From e931f9e5c2ae165658587f04d075c59a338061fb Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Thu, 30 Jan 2020 15:26:05 +0100 Subject: [PATCH 052/180] Remove notices regarding wasm file in check_runtime.sh (#4779) To my knowledge, we don't keep wasm blobs checked in anymore. --- .maintain/gitlab/check_runtime.sh | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.maintain/gitlab/check_runtime.sh b/.maintain/gitlab/check_runtime.sh index 102c634dd9..8c07208438 100755 --- a/.maintain/gitlab/check_runtime.sh +++ b/.maintain/gitlab/check_runtime.sh @@ -3,7 +3,7 @@ # # check for any changes in the node/src/runtime, frame/ and primitives/sr_* trees. if # there are any changes found, it should mark the PR breaksconsensus and -# "auto-fail" the PR if there isn't a change in the runtime/src/lib.rs file +# "auto-fail" the PR if there isn't a change in the runtime/src/lib.rs file # that alters the version. set -e # fail on any error @@ -40,7 +40,7 @@ if ! git diff --name-only origin/master...${CI_COMMIT_SHA} \ | grep -q -e '^bin/node/src/runtime' -e '^frame/' -e '^primitives/sr-' then boldcat <<-EOT - + no changes to the runtime source code detected EOT @@ -67,9 +67,9 @@ then github_label "B2-breaksapi" boldcat <<-EOT - + changes to the runtime sources and changes in the spec version. - + spec_version: ${sub_spec_version} -> ${add_spec_version} EOT @@ -89,7 +89,7 @@ else if [ "${add_impl_version}" != "${sub_impl_version}" ] then boldcat <<-EOT - + changes to the runtime sources and changes in the impl version. impl_version: ${sub_impl_version} -> ${add_impl_version} @@ -101,9 +101,8 @@ else boldcat <<-EOT - wasm source files changed but not the spec/impl version and the runtime - binary blob. If changes made do not alter logic, just bump 'impl_version'. - If they do change logic, bump 'spec_version' and rebuild wasm. + wasm source files changed but not the spec/impl version. If changes made do not alter logic, + just bump 'impl_version'. If they do change logic, bump 'spec_version'. source file directories: - bin/node/src/runtime -- GitLab From 8d11d1d2a1b6efe3f672e4b452c6f0370830b95b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 30 Jan 2020 16:41:03 +0100 Subject: [PATCH 053/180] Expose information about the extrinsic in the metadata (#4774) * Expose information about the extrinsic in the metadata This pr exposes some information about the extrinsic used in the runtime via metadata. The following information are exposed: - Version of the extrinsic - List of all signed extensions used by the extrinsic. * Increment `spec_version` --- Cargo.lock | 4 +- bin/node/runtime/src/lib.rs | 2 +- frame/contracts/src/lib.rs | 1 + frame/example/src/lib.rs | 1 + frame/metadata/Cargo.toml | 2 +- frame/metadata/src/lib.rs | 27 +- frame/support/Cargo.toml | 2 +- .../procedural/src/construct_runtime/mod.rs | 7 +- frame/support/src/metadata.rs | 305 +++++++++++------- frame/system/src/lib.rs | 5 + frame/transaction-payment/src/lib.rs | 1 + .../src/generic/unchecked_extrinsic.rs | 15 +- primitives/runtime/src/traits.rs | 34 ++ 13 files changed, 267 insertions(+), 139 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f28d341847..7371d9ebfd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1311,7 +1311,7 @@ dependencies = [ [[package]] name = "frame-metadata" -version = "10.0.0" +version = "11.0.0" dependencies = [ "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1324,7 +1324,7 @@ name = "frame-support" version = "2.0.0" dependencies = [ "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "frame-metadata 10.0.0", + "frame-metadata 11.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)", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 3f12957a05..aa550893f9 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -80,7 +80,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 209, + spec_version: 210, impl_version: 0, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index 6324b3fabc..9ac43cbb50 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -1103,6 +1103,7 @@ impl sp_std::fmt::Debug for CheckBlockGasLimit { } impl SignedExtension for CheckBlockGasLimit { + const IDENTIFIER: &'static str = "CheckBlockGasLimit"; type AccountId = T::AccountId; type Call = ::Call; type AdditionalSigned = (); diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index ab85de8ea9..56d3de14dc 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -603,6 +603,7 @@ impl sp_std::fmt::Debug for WatchDummy { } impl SignedExtension for WatchDummy { + const IDENTIFIER: &'static str = "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: pallet_balances::Trait`, you could also use `T::Call`. diff --git a/frame/metadata/Cargo.toml b/frame/metadata/Cargo.toml index 9cb6752926..e245f04849 100644 --- a/frame/metadata/Cargo.toml +++ b/frame/metadata/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "frame-metadata" -version = "10.0.0" +version = "11.0.0" authors = ["Parity Technologies "] edition = "2018" license = "GPL-3.0" diff --git a/frame/metadata/src/lib.rs b/frame/metadata/src/lib.rs index f6e280bed1..a7410bbfbc 100644 --- a/frame/metadata/src/lib.rs +++ b/frame/metadata/src/lib.rs @@ -316,11 +316,21 @@ pub struct StorageMetadata { pub entries: DecodeDifferent<&'static [StorageEntryMetadata], Vec>, } +/// Metadata prefixed by a u32 for reserved usage #[derive(Eq, Encode, PartialEq, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] -/// Metadata prefixed by a u32 for reserved usage pub struct RuntimeMetadataPrefixed(pub u32, pub RuntimeMetadata); +/// Metadata of the extrinsic used by the runtime. +#[derive(Eq, Encode, PartialEq, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Decode, Serialize))] +pub struct ExtrinsicMetadata { + /// Extrinsic version. + pub version: u8, + /// The signed extensions in the order they appear in the extrinsic. + pub signed_extensions: Vec, +} + /// The metadata of a runtime. /// The version ID encoded/decoded through /// the enum nature of `RuntimeMetadata`. @@ -347,8 +357,10 @@ pub enum RuntimeMetadata { V8(RuntimeMetadataDeprecated), /// Version 9 for runtime metadata. No longer used. V9(RuntimeMetadataDeprecated), - /// Version 10 for runtime metadata. - V10(RuntimeMetadataV10), + /// Version 10 for runtime metadata. No longer used. + V10(RuntimeMetadataDeprecated), + /// Version 11 for runtime metadata. + V11(RuntimeMetadataV11), } /// Enum that should fail. @@ -372,12 +384,15 @@ impl Decode for RuntimeMetadataDeprecated { /// The metadata of a runtime. #[derive(Eq, Encode, PartialEq, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Decode, Serialize))] -pub struct RuntimeMetadataV10 { +pub struct RuntimeMetadataV11 { + /// Metadata of all the modules. pub modules: DecodeDifferentArray, + /// Metadata of the extrinsic. + pub extrinsic: ExtrinsicMetadata, } /// The latest version of the metadata. -pub type RuntimeMetadataLastVersion = RuntimeMetadataV10; +pub type RuntimeMetadataLastVersion = RuntimeMetadataV11; /// All metadata about an runtime module. #[derive(Clone, PartialEq, Eq, Encode, RuntimeDebug)] @@ -402,6 +417,6 @@ impl Into for RuntimeMetadataPrefixed { impl Into for RuntimeMetadataLastVersion { fn into(self) -> RuntimeMetadataPrefixed { - RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V10(self)) + RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V11(self)) } } diff --git a/frame/support/Cargo.toml b/frame/support/Cargo.toml index 77aa3aa168..f0e9b53bf2 100644 --- a/frame/support/Cargo.toml +++ b/frame/support/Cargo.toml @@ -9,7 +9,7 @@ license = "GPL-3.0" 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 = { version = "10.0.0", default-features = false, path = "../metadata" } +frame-metadata = { version = "11.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" } diff --git a/frame/support/procedural/src/construct_runtime/mod.rs b/frame/support/procedural/src/construct_runtime/mod.rs index 7e66610641..b4eaf09f6a 100644 --- a/frame/support/procedural/src/construct_runtime/mod.rs +++ b/frame/support/procedural/src/construct_runtime/mod.rs @@ -22,7 +22,7 @@ use parse::{ModuleDeclaration, RuntimeDefinition, WhereSection}; use proc_macro::TokenStream; use proc_macro2::{Span, TokenStream as TokenStream2}; use quote::quote; -use syn::{Ident, Result}; +use syn::{Ident, Result, TypePath}; /// The fixed name of the system module. const SYSTEM_MODULE_NAME: &str = "System"; @@ -86,7 +86,7 @@ fn construct_runtime_parsed(definition: RuntimeDefinition) -> Result( runtime: &'a Ident, module_declarations: impl Iterator, scrate: &'a TokenStream2, + extrinsic: &TypePath, ) -> TokenStream2 { let modules_tokens = module_declarations .filter_map(|module_declaration| { @@ -236,7 +237,7 @@ fn decl_runtime_metadata<'a>( }); quote!( #scrate::impl_runtime_metadata!{ - for #runtime with modules + for #runtime with modules where Extrinsic = #extrinsic #(#modules_tokens)* } ) diff --git a/frame/support/src/metadata.rs b/frame/support/src/metadata.rs index 110df87c64..f3c9945f88 100644 --- a/frame/support/src/metadata.rs +++ b/frame/support/src/metadata.rs @@ -17,7 +17,8 @@ pub use frame_metadata::{ DecodeDifferent, FnEncode, RuntimeMetadata, ModuleMetadata, RuntimeMetadataLastVersion, DefaultByteGetter, RuntimeMetadataPrefixed, StorageEntryMetadata, StorageMetadata, - StorageEntryType, StorageEntryModifier, DefaultByte, StorageHasher, ModuleErrorMetadata + StorageEntryType, StorageEntryModifier, DefaultByte, StorageHasher, ModuleErrorMetadata, + ExtrinsicMetadata, }; /// Implements the metadata support for the given runtime and all its modules. @@ -43,10 +44,12 @@ pub use frame_metadata::{ ///# type Origin = u32; ///# type BlockNumber = u32; ///# } +///# +///# type UncheckedExtrinsic = sp_runtime::generic::UncheckedExtrinsic<(), (), (), ()>; /// /// struct Runtime; /// frame_support::impl_runtime_metadata! { -/// for Runtime with modules +/// for Runtime with modules where Extrinsic = UncheckedExtrinsic /// module0::Module as Module0 with, /// module1::Module as Module1 with, /// module2::Module as Module2 with Storage, @@ -57,13 +60,24 @@ pub use frame_metadata::{ #[macro_export] macro_rules! impl_runtime_metadata { ( - for $runtime:ident with modules + for $runtime:ident with modules where Extrinsic = $ext:ident $( $rest:tt )* ) => { impl $runtime { pub fn metadata() -> $crate::metadata::RuntimeMetadataPrefixed { $crate::metadata::RuntimeMetadataLastVersion { modules: $crate::__runtime_modules_to_metadata!($runtime;; $( $rest )*), + extrinsic: $crate::metadata::ExtrinsicMetadata { + version: <$ext as $crate::sp_runtime::traits::ExtrinsicMetadata>::VERSION, + signed_extensions: < + < + $ext as $crate::sp_runtime::traits::ExtrinsicMetadata + >::SignedExtensions as $crate::sp_runtime::traits::SignedExtension + >::identifier() + .into_iter() + .map($crate::metadata::DecodeDifferent::Encode) + .collect(), + }, }.into() } } @@ -232,10 +246,46 @@ mod tests { use frame_metadata::{ EventMetadata, StorageEntryModifier, StorageEntryType, FunctionMetadata, StorageEntryMetadata, ModuleMetadata, RuntimeMetadataPrefixed, DefaultByte, ModuleConstantMetadata, DefaultByteGetter, - ErrorMetadata, + ErrorMetadata, ExtrinsicMetadata, }; use codec::{Encode, Decode}; use crate::traits::Get; + use sp_runtime::transaction_validity::TransactionValidityError; + + #[derive(Clone, Eq, Debug, PartialEq, Encode, Decode)] + struct TestExtension; + impl sp_runtime::traits::SignedExtension for TestExtension { + type AccountId = u32; + type Call = u32; + type AdditionalSigned = u32; + type DispatchInfo = (); + type Pre = (); + const IDENTIFIER: &'static str = "testextension"; + fn additional_signed(&self) -> Result { + Ok(1) + } + } + + #[derive(Clone, Eq, Debug, PartialEq, Encode, Decode)] + struct TestExtension2; + impl sp_runtime::traits::SignedExtension for TestExtension2 { + type AccountId = u32; + type Call = u32; + type AdditionalSigned = u32; + type DispatchInfo = (); + type Pre = (); + const IDENTIFIER: &'static str = "testextension2"; + fn additional_signed(&self) -> Result { + Ok(1) + } + } + + struct TestExtrinsic; + + impl sp_runtime::traits::ExtrinsicMetadata for TestExtrinsic { + const VERSION: u8 = 1; + type SignedExtensions = (TestExtension, TestExtension2); + } mod system { use super::*; @@ -393,7 +443,7 @@ mod tests { } impl_runtime_metadata!( - for TestRuntime with modules + for TestRuntime with modules where Extrinsic = TestExtrinsic system::Module as System with Event, event_module::Module as Module with Event Call, event_module2::Module as Module2 with Event Storage Call, @@ -420,131 +470,138 @@ mod tests { } } - const EXPECTED_METADATA: RuntimeMetadataLastVersion = RuntimeMetadataLastVersion { - modules: DecodeDifferent::Encode(&[ - ModuleMetadata { - name: DecodeDifferent::Encode("System"), - storage: None, - calls: None, - event: Some(DecodeDifferent::Encode( - FnEncode(||&[ - EventMetadata { - name: DecodeDifferent::Encode("SystemEvent"), - arguments: DecodeDifferent::Encode(&[]), - documentation: DecodeDifferent::Encode(&[]) - } - ]) - )), - constants: DecodeDifferent::Encode( - FnEncode(|| &[ - ModuleConstantMetadata { - name: DecodeDifferent::Encode("BlockNumber"), - ty: DecodeDifferent::Encode("T::BlockNumber"), - value: DecodeDifferent::Encode( - DefaultByteGetter(&ConstantBlockNumberByteGetter) - ), - documentation: DecodeDifferent::Encode(&[" Hi, I am a comment."]), + #[test] + fn runtime_metadata() { + let expected_metadata: RuntimeMetadataLastVersion = RuntimeMetadataLastVersion { + modules: DecodeDifferent::Encode(&[ + ModuleMetadata { + name: DecodeDifferent::Encode("System"), + storage: None, + calls: None, + event: Some(DecodeDifferent::Encode( + FnEncode(||&[ + EventMetadata { + name: DecodeDifferent::Encode("SystemEvent"), + arguments: DecodeDifferent::Encode(&[]), + documentation: DecodeDifferent::Encode(&[]) + } + ]) + )), + constants: DecodeDifferent::Encode( + FnEncode(|| &[ + ModuleConstantMetadata { + name: DecodeDifferent::Encode("BlockNumber"), + ty: DecodeDifferent::Encode("T::BlockNumber"), + value: DecodeDifferent::Encode( + DefaultByteGetter(&ConstantBlockNumberByteGetter) + ), + documentation: DecodeDifferent::Encode(&[" Hi, I am a comment."]), + }, + ModuleConstantMetadata { + name: DecodeDifferent::Encode("GetType"), + ty: DecodeDifferent::Encode("T::AccountId"), + value: DecodeDifferent::Encode( + DefaultByteGetter(&ConstantGetTypeByteGetter) + ), + documentation: DecodeDifferent::Encode(&[]), + }, + ModuleConstantMetadata { + name: DecodeDifferent::Encode("ASSOCIATED_CONST"), + ty: DecodeDifferent::Encode("u64"), + value: DecodeDifferent::Encode( + DefaultByteGetter(&ConstantAssociatedConstByteGetter) + ), + documentation: DecodeDifferent::Encode(&[]), + } + ]) + ), + errors: DecodeDifferent::Encode(FnEncode(|| &[])), + }, + ModuleMetadata { + name: DecodeDifferent::Encode("Module"), + storage: None, + calls: Some( + DecodeDifferent::Encode(FnEncode(|| &[ + FunctionMetadata { + name: DecodeDifferent::Encode("aux_0"), + arguments: DecodeDifferent::Encode(&[]), + documentation: DecodeDifferent::Encode(&[]), + } + ]))), + event: Some(DecodeDifferent::Encode( + FnEncode(||&[ + EventMetadata { + name: DecodeDifferent::Encode("TestEvent"), + arguments: DecodeDifferent::Encode(&["Balance"]), + documentation: DecodeDifferent::Encode(&[" Hi, I am a comment."]) + } + ]) + )), + constants: DecodeDifferent::Encode(FnEncode(|| &[])), + errors: DecodeDifferent::Encode(FnEncode(|| &[ + ErrorMetadata { + name: DecodeDifferent::Encode("UserInputError"), + documentation: DecodeDifferent::Encode(&[" Some user input error"]), }, - ModuleConstantMetadata { - name: DecodeDifferent::Encode("GetType"), - ty: DecodeDifferent::Encode("T::AccountId"), - value: DecodeDifferent::Encode( - DefaultByteGetter(&ConstantGetTypeByteGetter) - ), - documentation: DecodeDifferent::Encode(&[]), + ErrorMetadata { + name: DecodeDifferent::Encode("BadThingHappened"), + documentation: DecodeDifferent::Encode(&[ + " Something bad happened", + " this could be due to many reasons", + ]), }, - ModuleConstantMetadata { - name: DecodeDifferent::Encode("ASSOCIATED_CONST"), - ty: DecodeDifferent::Encode("u64"), - value: DecodeDifferent::Encode( - DefaultByteGetter(&ConstantAssociatedConstByteGetter) - ), - documentation: DecodeDifferent::Encode(&[]), - } - ]) - ), - errors: DecodeDifferent::Encode(FnEncode(|| &[])), - }, - ModuleMetadata { - name: DecodeDifferent::Encode("Module"), - storage: None, - calls: Some( - DecodeDifferent::Encode(FnEncode(|| &[ - FunctionMetadata { - name: DecodeDifferent::Encode("aux_0"), - arguments: DecodeDifferent::Encode(&[]), - documentation: DecodeDifferent::Encode(&[]), - } - ]))), - event: Some(DecodeDifferent::Encode( - FnEncode(||&[ - EventMetadata { - name: DecodeDifferent::Encode("TestEvent"), - arguments: DecodeDifferent::Encode(&["Balance"]), - documentation: DecodeDifferent::Encode(&[" Hi, I am a comment."]) - } - ]) - )), - constants: DecodeDifferent::Encode(FnEncode(|| &[])), - errors: DecodeDifferent::Encode(FnEncode(|| &[ - ErrorMetadata { - name: DecodeDifferent::Encode("UserInputError"), - documentation: DecodeDifferent::Encode(&[" Some user input error"]), - }, - ErrorMetadata { - name: DecodeDifferent::Encode("BadThingHappened"), - documentation: DecodeDifferent::Encode(&[ - " Something bad happened", - " this could be due to many reasons", - ]), - }, - ])), - }, - ModuleMetadata { - name: DecodeDifferent::Encode("Module2"), - storage: Some(DecodeDifferent::Encode( - FnEncode(|| StorageMetadata { - prefix: DecodeDifferent::Encode("TestStorage"), - entries: DecodeDifferent::Encode( - &[ - StorageEntryMetadata { - name: DecodeDifferent::Encode("StorageMethod"), - modifier: StorageEntryModifier::Optional, - ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")), - default: DecodeDifferent::Encode( - DefaultByteGetter( - &event_module2::__GetByteStructStorageMethod( - std::marker::PhantomData:: + ])), + }, + ModuleMetadata { + name: DecodeDifferent::Encode("Module2"), + storage: Some(DecodeDifferent::Encode( + FnEncode(|| StorageMetadata { + prefix: DecodeDifferent::Encode("TestStorage"), + entries: DecodeDifferent::Encode( + &[ + StorageEntryMetadata { + name: DecodeDifferent::Encode("StorageMethod"), + modifier: StorageEntryModifier::Optional, + ty: StorageEntryType::Plain(DecodeDifferent::Encode("u32")), + default: DecodeDifferent::Encode( + DefaultByteGetter( + &event_module2::__GetByteStructStorageMethod( + std::marker::PhantomData:: + ) ) - ) - ), - documentation: DecodeDifferent::Encode(&[]), - } - ] - ) - }), - )), - calls: Some(DecodeDifferent::Encode(FnEncode(|| &[]))), - event: Some(DecodeDifferent::Encode( - FnEncode(||&[ - EventMetadata { - name: DecodeDifferent::Encode("TestEvent"), - arguments: DecodeDifferent::Encode(&["Balance"]), - documentation: DecodeDifferent::Encode(&[]) - } - ]) - )), - constants: DecodeDifferent::Encode(FnEncode(|| &[])), - errors: DecodeDifferent::Encode(FnEncode(|| &[])), - }, - ]) - }; + ), + documentation: DecodeDifferent::Encode(&[]), + } + ] + ) + }), + )), + calls: Some(DecodeDifferent::Encode(FnEncode(|| &[]))), + event: Some(DecodeDifferent::Encode( + FnEncode(||&[ + EventMetadata { + name: DecodeDifferent::Encode("TestEvent"), + arguments: DecodeDifferent::Encode(&["Balance"]), + documentation: DecodeDifferent::Encode(&[]) + } + ]) + )), + constants: DecodeDifferent::Encode(FnEncode(|| &[])), + errors: DecodeDifferent::Encode(FnEncode(|| &[])), + }, + ]), + extrinsic: ExtrinsicMetadata { + version: 1, + signed_extensions: vec![ + DecodeDifferent::Encode("testextension"), + DecodeDifferent::Encode("testextension2"), + ], + } + }; - #[test] - fn runtime_metadata() { let metadata_encoded = TestRuntime::metadata().encode(); let metadata_decoded = RuntimeMetadataPrefixed::decode(&mut &metadata_encoded[..]); - let expected_metadata: RuntimeMetadataPrefixed = EXPECTED_METADATA.into(); + let expected_metadata: RuntimeMetadataPrefixed = expected_metadata.into(); pretty_assertions::assert_eq!(expected_metadata, metadata_decoded.unwrap()); } diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 4e665fd385..4a06dec6ee 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -960,6 +960,7 @@ impl SignedExtension for CheckWeight { type AdditionalSigned = (); type DispatchInfo = DispatchInfo; type Pre = (); + const IDENTIFIER: &'static str = "CheckWeight"; fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } @@ -1040,6 +1041,7 @@ impl SignedExtension for CheckNonce { type AdditionalSigned = (); type DispatchInfo = DispatchInfo; type Pre = (); + const IDENTIFIER: &'static str = "CheckNonce"; fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } @@ -1124,6 +1126,7 @@ impl SignedExtension for CheckEra { type AdditionalSigned = T::Hash; type DispatchInfo = DispatchInfo; type Pre = (); + const IDENTIFIER: &'static str = "CheckEra"; fn validate( &self, @@ -1180,6 +1183,7 @@ impl SignedExtension for CheckGenesis { type AdditionalSigned = T::Hash; type DispatchInfo = DispatchInfo; type Pre = (); + const IDENTIFIER: &'static str = "CheckGenesis"; fn additional_signed(&self) -> Result { Ok(>::block_hash(T::BlockNumber::zero())) @@ -1215,6 +1219,7 @@ impl SignedExtension for CheckVersion { type AdditionalSigned = u32; type DispatchInfo = DispatchInfo; type Pre = (); + const IDENTIFIER: &'static str = "CheckVersion"; fn additional_signed(&self) -> Result { Ok(>::runtime_version().spec_version) diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 370bd87b4c..34768d808e 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -201,6 +201,7 @@ impl sp_std::fmt::Debug for ChargeTransactionPayment impl SignedExtension for ChargeTransactionPayment where BalanceOf: Send + Sync { + const IDENTIFIER: &'static str = "ChargeTransactionPayment"; type AccountId = T::AccountId; type Call = T::Call; type AdditionalSigned = (); diff --git a/primitives/runtime/src/generic/unchecked_extrinsic.rs b/primitives/runtime/src/generic/unchecked_extrinsic.rs index 0a43524248..96e7988103 100644 --- a/primitives/runtime/src/generic/unchecked_extrinsic.rs +++ b/primitives/runtime/src/generic/unchecked_extrinsic.rs @@ -20,7 +20,10 @@ 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}, + traits::{ + self, Member, MaybeDisplay, SignedExtension, Checkable, Extrinsic, ExtrinsicMetadata, + IdentifyAccount, + }, generic::CheckedExtrinsic, transaction_validity::{TransactionValidityError, InvalidTransaction}, }; @@ -130,6 +133,15 @@ where } } +impl ExtrinsicMetadata + for UncheckedExtrinsic + where + Extra: SignedExtension, +{ + const VERSION: u8 = TRANSACTION_VERSION; + type SignedExtensions = Extra; +} + /// A payload that has been signed for an unchecked extrinsics. /// /// Note that the payload that we sign to produce unchecked extrinsic signature @@ -316,6 +328,7 @@ mod tests { #[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, Ord, PartialOrd)] struct TestExtra; impl SignedExtension for TestExtra { + const IDENTIFIER: &'static str = "TestExtra"; type AccountId = u64; type Call = (); type AdditionalSigned = (); diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 3210b00c6b..f8c2ed11a4 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -608,6 +608,15 @@ pub trait Extrinsic: Sized { fn new(_call: Self::Call, _signed_data: Option) -> Option { None } } +/// Implementor is an [`Extrinsic`] and provides metadata about this extrinsic. +pub trait ExtrinsicMetadata { + /// The version of the `Extrinsic`. + const VERSION: u8; + + /// Signed extensions attached to this `Extrinsic`. + type SignedExtensions: SignedExtension; +} + /// Extract the hasher type for a block. pub type HasherFor = as Hash>::Hasher; /// Extract the hashing type for a block. @@ -668,6 +677,12 @@ pub trait Dispatchable { /// Means by which a transaction may be extended. This type embodies both the data and the logic /// that should be additionally associated with the transaction. It should be plain old data. pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq { + /// Unique identifier of this signed extension. + /// + /// This will be exposed in the metadata to identify the signed extension used + /// in an extrinsic. + const IDENTIFIER: &'static str; + /// The type which encodes the sender identity. type AccountId; @@ -765,6 +780,17 @@ pub trait SignedExtension: Codec + Debug + Sync + Send + Clone + Eq + PartialEq /// Do any post-flight stuff for a transaction. fn post_dispatch(_pre: Self::Pre, _info: Self::DispatchInfo, _len: usize) { } + + /// Returns the list of unique identifier for this signed extension. + /// + /// As a [`SignedExtension`] can be a tuple of [`SignedExtension`]`s we need to return a `Vec` + /// that holds all the unique identifiers. Each individual `SignedExtension` must return + /// *exactly* one identifier. + /// + /// This method provides a default implementation that returns `vec![SELF::IDENTIFIER]`. + fn identifier() -> Vec<&'static str> { + sp_std::vec![Self::IDENTIFIER] + } } #[impl_for_tuples(1, 12)] @@ -773,6 +799,7 @@ impl SignedExtension for Tuple { type AccountId = AccountId; type Call = Call; type DispatchInfo = Info; + const IDENTIFIER: &'static str = "You should call `identifier()`!"; for_tuples!( type AdditionalSigned = ( #( Tuple::AdditionalSigned ),* ); ); for_tuples!( type Pre = ( #( Tuple::Pre ),* ); ); @@ -823,6 +850,12 @@ impl SignedExtension for Tuple { ) { for_tuples!( #( Tuple::post_dispatch(pre.Tuple, info.clone(), len); )* ) } + + fn identifier() -> Vec<&'static str> { + let mut ids = Vec::new(); + for_tuples!( #( ids.extend(Tuple::identifier()); )* ); + ids + } } /// Only for bare bone testing when you don't care about signed extensions at all. @@ -833,6 +866,7 @@ impl SignedExtension for () { type Call = (); type Pre = (); type DispatchInfo = (); + const IDENTIFIER: &'static str = "UnitSignedExtension"; fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } } -- GitLab From f38c233c3d4de1458247f5961348c6132b0d9980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 31 Jan 2020 11:46:05 +0100 Subject: [PATCH 054/180] Fix ui tests with rust `1.41.0` (#4787) --- .../ui/impl_incorrect_method_signature.stderr | 22 +++++++------------ ...reference_in_impl_runtime_apis_call.stderr | 22 +++++++------------ 2 files changed, 16 insertions(+), 28 deletions(-) diff --git a/primitives/api/test/tests/ui/impl_incorrect_method_signature.stderr b/primitives/api/test/tests/ui/impl_incorrect_method_signature.stderr index ca7e519344..4f112e91bb 100644 --- a/primitives/api/test/tests/ui/impl_incorrect_method_signature.stderr +++ b/primitives/api/test/tests/ui/impl_incorrect_method_signature.stderr @@ -5,10 +5,10 @@ error[E0053]: method `test` has an incompatible type for trait | --- type in trait ... 19 | fn test(data: String) {} - | ^^^^^^ expected u64, found struct `std::string::String` + | ^^^^^^ expected `u64`, found struct `std::string::String` | - = note: expected type `fn(u64)` - found type `fn(std::string::String)` + = note: expected fn pointer `fn(u64)` + found fn pointer `fn(std::string::String)` error[E0053]: method `Api_test_runtime_api_impl` has an incompatible type for trait --> $DIR/impl_incorrect_method_signature.rs:17:1 @@ -23,7 +23,7 @@ error[E0053]: method `Api_test_runtime_api_impl` has an incompatible type for tr 17 | sp_api::impl_runtime_apis! { | -^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | _expected u64, found struct `std::string::String` + | _expected `u64`, found struct `std::string::String` | | 18 | | impl self::Api for Runtime { 19 | | fn test(data: String) {} @@ -33,8 +33,8 @@ 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_BLOCK__, RuntimeApiImplCall>, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId<__SR_API_BLOCK__>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option, std::vec::Vec) -> std::result::Result, >::Error>` - found type `fn(&RuntimeApiImpl<__SR_API_BLOCK__, RuntimeApiImplCall>, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId<__SR_API_BLOCK__>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option, std::vec::Vec) -> std::result::Result, >::Error>` + = note: expected fn pointer `fn(&RuntimeApiImpl<__SR_API_BLOCK__, RuntimeApiImplCall>, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId<__SR_API_BLOCK__>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option, std::vec::Vec<_>) -> std::result::Result<_, _>` + found fn pointer `fn(&RuntimeApiImpl<__SR_API_BLOCK__, RuntimeApiImplCall>, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId<__SR_API_BLOCK__>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option, std::vec::Vec<_>) -> std::result::Result<_, _>` error[E0308]: mismatched types --> $DIR/impl_incorrect_method_signature.rs:17:1 @@ -48,17 +48,11 @@ error[E0308]: mismatched types 33 | | } | | ^ | | | - | |_expected u64, found struct `std::string::String` + | |_expected `u64`, found struct `std::string::String` | in this macro invocation - | - = note: expected type `u64` - found type `std::string::String` error[E0308]: mismatched types --> $DIR/impl_incorrect_method_signature.rs:19:11 | 19 | fn test(data: String) {} - | ^^^^ expected u64, found struct `std::string::String` - | - = note: expected type `u64` - found type `std::string::String` + | ^^^^ expected `u64`, found struct `std::string::String` diff --git a/primitives/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 index b793d832ff..1d7d0a78a8 100644 --- a/primitives/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 @@ -5,10 +5,10 @@ error[E0053]: method `test` has an incompatible type for trait | --- type in trait ... 19 | fn test(data: &u64) { - | ^^^^ expected u64, found &u64 + | ^^^^ expected `u64`, found `&u64` | - = note: expected type `fn(u64)` - found type `fn(&u64)` + = note: expected fn pointer `fn(u64)` + found fn pointer `fn(&u64)` 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 @@ -23,7 +23,7 @@ error[E0053]: method `Api_test_runtime_api_impl` has an incompatible type for tr 17 | sp_api::impl_runtime_apis! { | -^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | _expected u64, found &u64 + | _expected `u64`, found `&u64` | | 18 | | impl self::Api for Runtime { 19 | | fn test(data: &u64) { @@ -33,8 +33,8 @@ 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_BLOCK__, RuntimeApiImplCall>, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId<__SR_API_BLOCK__>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option, std::vec::Vec) -> std::result::Result, >::Error>` - found type `fn(&RuntimeApiImpl<__SR_API_BLOCK__, RuntimeApiImplCall>, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId<__SR_API_BLOCK__>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option<&u64>, std::vec::Vec) -> std::result::Result, >::Error>` + = note: expected fn pointer `fn(&RuntimeApiImpl<__SR_API_BLOCK__, RuntimeApiImplCall>, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId<__SR_API_BLOCK__>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option, std::vec::Vec<_>) -> std::result::Result<_, _>` + found fn pointer `fn(&RuntimeApiImpl<__SR_API_BLOCK__, RuntimeApiImplCall>, &sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::BlockId<__SR_API_BLOCK__>, sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ExecutionContext, std::option::Option<&u64>, std::vec::Vec<_>) -> std::result::Result<_, _>` error[E0308]: mismatched types --> $DIR/type_reference_in_impl_runtime_apis_call.rs:17:1 @@ -48,11 +48,8 @@ error[E0308]: mismatched types 35 | | } | | ^ | | | - | |_expected u64, found &u64 + | |_expected `u64`, found `&u64` | in this macro invocation - | - = note: expected type `u64` - found type `&u64` error[E0308]: mismatched types --> $DIR/type_reference_in_impl_runtime_apis_call.rs:19:11 @@ -60,8 +57,5 @@ error[E0308]: mismatched types 19 | fn test(data: &u64) { | ^^^^^^^ | | - | expected u64, found &u64 + | expected `u64`, found `&u64` | help: consider removing the borrow: `data` - | - = note: expected type `u64` - found type `&u64` -- GitLab From 0f7f267a57f0f2dbf604865eadb3ae1f0b60bb2e Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Fri, 31 Jan 2020 12:32:12 +0100 Subject: [PATCH 055/180] Removed a few warnings (#4786) --- bin/node/cli/src/cli.rs | 5 +++++ bin/node/cli/src/command.rs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/bin/node/cli/src/cli.rs b/bin/node/cli/src/cli.rs index 201e39eabd..dd3ee4a596 100644 --- a/bin/node/cli/src/cli.rs +++ b/bin/node/cli/src/cli.rs @@ -17,6 +17,7 @@ use sc_cli::{SharedParams, ImportParams, RunCmd}; use structopt::StructOpt; +#[allow(missing_docs)] #[derive(Clone, Debug, StructOpt)] #[structopt(settings = &[ structopt::clap::AppSettings::GlobalVersion, @@ -24,14 +25,18 @@ use structopt::StructOpt; structopt::clap::AppSettings::SubcommandsNegateReqs, ])] pub struct Cli { + #[allow(missing_docs)] #[structopt(subcommand)] pub subcommand: Option, + #[allow(missing_docs)] #[structopt(flatten)] pub run: RunCmd, } +#[allow(missing_docs)] #[derive(Clone, Debug, StructOpt)] pub enum Subcommand { + #[allow(missing_docs)] #[structopt(flatten)] Base(sc_cli::Subcommand), /// The custom factory subcommmand for manufacturing transactions. diff --git a/bin/node/cli/src/command.rs b/bin/node/cli/src/command.rs index 65015efcb2..3395717f2f 100644 --- a/bin/node/cli/src/command.rs +++ b/bin/node/cli/src/command.rs @@ -20,7 +20,7 @@ use node_transaction_factory::RuntimeAdapter; use crate::{Cli, service, ChainSpec, load_spec, Subcommand, factory_impl::FactoryState}; /// Parse command line arguments into service configuration. -pub fn run(args: I, version: sc_cli::VersionInfo) -> error::Result<()> +pub fn run(args: I, version: VersionInfo) -> error::Result<()> where I: Iterator, T: Into + Clone, -- GitLab From 4fdffbbc94fa406664c57856f8a42aade337a0be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 31 Jan 2020 12:40:32 +0100 Subject: [PATCH 056/180] Cleanup transaction pool deps (#4782) * Cleanup transaction pool deps * Fix it properly * Fix doc test --- Cargo.lock | 16 ++++++++ Cargo.toml | 1 + bin/node-template/src/service.rs | 4 +- bin/node/cli/src/service.rs | 4 +- .../basic-authorship/src/basic_authorship.rs | 8 +++- client/basic-authorship/src/lib.rs | 2 +- client/consensus/manual-seal/Cargo.toml | 3 +- client/consensus/manual-seal/src/lib.rs | 13 +++--- client/offchain/src/lib.rs | 5 ++- client/rpc/src/author/tests.rs | 11 ++++- client/rpc/src/state/state_full.rs | 1 - client/service/src/lib.rs | 5 ++- client/transaction-pool/Cargo.toml | 20 +++++----- client/transaction-pool/src/lib.rs | 29 +++++--------- client/transaction-pool/src/testing/mod.rs | 6 +-- client/transaction-pool/src/testing/pool.rs | 21 ++++++++-- .../runtime/transaction-pool/Cargo.toml | 16 ++++++++ .../runtime/transaction-pool/src/lib.rs | 40 ++++++++++++++----- utils/frame/rpc/system/src/lib.rs | 4 +- 19 files changed, 140 insertions(+), 69 deletions(-) create mode 100644 test-utils/runtime/transaction-pool/Cargo.toml rename client/transaction-pool/src/testing/api.rs => test-utils/runtime/transaction-pool/src/lib.rs (84%) diff --git a/Cargo.lock b/Cargo.lock index 7371d9ebfd..7c8a4d25f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5409,6 +5409,7 @@ dependencies = [ "sp-runtime 2.0.0", "sp-transaction-pool 2.0.0", "substrate-test-runtime-client 2.0.0", + "substrate-test-runtime-transaction-pool 2.0.0", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -5985,6 +5986,7 @@ dependencies = [ "sp-runtime 2.0.0", "sp-transaction-pool 2.0.0", "substrate-test-runtime-client 2.0.0", + "substrate-test-runtime-transaction-pool 2.0.0", ] [[package]] @@ -7103,6 +7105,20 @@ dependencies = [ "substrate-test-runtime 2.0.0", ] +[[package]] +name = "substrate-test-runtime-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)", + "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sc-transaction-graph 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-utils" version = "2.0.0" diff --git a/Cargo.toml b/Cargo.toml index 5dd85091cb..10465042de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -147,6 +147,7 @@ members = [ "test-utils/client", "test-utils/runtime", "test-utils/runtime/client", + "test-utils/runtime/transaction-pool", "utils/browser", "utils/build-script-utils", "utils/fork-tree", diff --git a/bin/node-template/src/service.rs b/bin/node-template/src/service.rs index b23ada78f1..d113f90866 100644 --- a/bin/node-template/src/service.rs +++ b/bin/node-template/src/service.rs @@ -41,7 +41,7 @@ macro_rules! new_full_start { })? .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 pool = sc_transaction_pool::BasicPool::new(config, std::sync::Arc::new(pool_api)); Ok(pool) })? .with_import_queue(|_config, client, mut select_chain, transaction_pool| { @@ -207,7 +207,7 @@ pub fn new_light(config: Configuration) let pool_api = sc_transaction_pool::LightChainApi::new(client.clone(), fetcher.clone()); let pool = sc_transaction_pool::BasicPool::with_revalidation_type( - config, pool_api, sc_transaction_pool::RevalidationType::Light, + config, Arc::new(pool_api), sc_transaction_pool::RevalidationType::Light, ); Ok(pool) })? diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index e72430e93d..c462a60836 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -63,7 +63,7 @@ macro_rules! new_full_start { })? .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 pool = sc_transaction_pool::BasicPool::new(config, std::sync::Arc::new(pool_api)); Ok(pool) })? .with_import_queue(|_config, client, mut select_chain, _transaction_pool| { @@ -313,7 +313,7 @@ pub fn new_light(config: NodeConfiguration) .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::with_revalidation_type( - config, pool_api, sc_transaction_pool::RevalidationType::Light, + config, Arc::new(pool_api), sc_transaction_pool::RevalidationType::Light, ); Ok(pool) })? diff --git a/client/basic-authorship/src/basic_authorship.rs b/client/basic-authorship/src/basic_authorship.rs index 6c5b063020..fafc63a114 100644 --- a/client/basic-authorship/src/basic_authorship.rs +++ b/client/basic-authorship/src/basic_authorship.rs @@ -306,7 +306,9 @@ mod tests { fn should_cease_building_block_when_deadline_is_reached() { // given let client = Arc::new(substrate_test_runtime_client::new()); - let txpool = Arc::new(BasicPool::new(Default::default(), FullChainApi::new(client.clone()))); + let txpool = Arc::new( + BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone()))) + ); futures::executor::block_on( txpool.submit_at(&BlockId::number(0), vec![extrinsic(0), extrinsic(1)]) @@ -346,7 +348,9 @@ mod tests { let (client, backend) = substrate_test_runtime_client::TestClientBuilder::new() .build_with_backend(); let client = Arc::new(client); - let txpool = Arc::new(BasicPool::new(Default::default(), FullChainApi::new(client.clone()))); + let txpool = Arc::new( + BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone()))) + ); let genesis_hash = client.info().best_hash; let block_id = BlockId::Hash(genesis_hash); diff --git a/client/basic-authorship/src/lib.rs b/client/basic-authorship/src/lib.rs index f62134ce42..9f2bc6a761 100644 --- a/client/basic-authorship/src/lib.rs +++ b/client/basic-authorship/src/lib.rs @@ -26,7 +26,7 @@ //! # 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()))); +//! # let txpool = Arc::new(BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone())))); //! // The first step is to create a `ProposerFactory`. //! let mut proposer_factory = ProposerFactory { //! client: client.clone(), diff --git a/client/consensus/manual-seal/Cargo.toml b/client/consensus/manual-seal/Cargo.toml index 821b314501..de601b4ab3 100644 --- a/client/consensus/manual-seal/Cargo.toml +++ b/client/consensus/manual-seal/Cargo.toml @@ -18,7 +18,7 @@ serde = { version = "1.0", features=["derive"] } sc-client = { path = "../../../client" } sc-client-api = { path = "../../../client/api" } -sc-transaction-pool = { path = "../../transaction-pool", features = ["test-helpers"] } +sc-transaction-pool = { path = "../../transaction-pool" } sp-blockchain = { path = "../../../primitives/blockchain" } sp-consensus = { package = "sp-consensus", path = "../../../primitives/consensus/common" } sp-inherents = { path = "../../../primitives/inherents" } @@ -28,6 +28,7 @@ sp-transaction-pool = { path = "../../../primitives/transaction-pool" } [dev-dependencies] sc-basic-authorship = { path = "../../basic-authorship" } substrate-test-runtime-client = { path = "../../../test-utils/runtime/client" } +substrate-test-runtime-transaction-pool = { path = "../../../test-utils/runtime/transaction-pool" } tokio = { version = "0.2", features = ["rt-core", "macros"] } env_logger = "0.7.0" tempfile = "3.1.0" diff --git a/client/consensus/manual-seal/src/lib.rs b/client/consensus/manual-seal/src/lib.rs index 7262a62d12..029f746e62 100644 --- a/client/consensus/manual-seal/src/lib.rs +++ b/client/consensus/manual-seal/src/lib.rs @@ -231,8 +231,8 @@ mod tests { use sc_transaction_pool::{ BasicPool, txpool::Options, - testing::api::*, }; + use substrate_test_runtime_transaction_pool::{TestApi, uxt}; use sp_transaction_pool::TransactionPool; use sp_runtime::generic::BlockId; use sp_blockchain::HeaderBackend; @@ -241,8 +241,8 @@ mod tests { use sp_inherents::InherentDataProviders; use sc_basic_authorship::ProposerFactory; - fn api() -> TestApi { - TestApi::empty() + fn api() -> Arc { + Arc::new(TestApi::empty()) } #[tokio::test] @@ -385,7 +385,8 @@ mod tests { let client = Arc::new(builder.build()); let select_chain = LongestChain::new(backend.clone()); let inherent_data_providers = InherentDataProviders::new(); - let pool = Arc::new(BasicPool::new(Options::default(), api())); + let pool_api = api(); + let pool = Arc::new(BasicPool::new(Options::default(), pool_api.clone())); let env = ProposerFactory { transaction_pool: pool.clone(), client: client.clone(), @@ -419,7 +420,7 @@ mod tests { finalize: false, }).await.unwrap(); let created_block = rx.await.unwrap().unwrap(); - pool.api().increment_nonce(Alice.into()); + pool_api.increment_nonce(Alice.into()); // assert that the background task returns ok assert_eq!( @@ -449,7 +450,7 @@ mod tests { }).await.is_ok()); assert!(rx1.await.unwrap().is_ok()); assert!(backend.blockchain().header(BlockId::Number(1)).unwrap().is_some()); - pool.api().increment_nonce(Alice.into()); + pool_api.increment_nonce(Alice.into()); assert!(pool.submit_one(&BlockId::Number(2), uxt(Alice, 2)).await.is_ok()); let (tx2, rx2) = futures::channel::oneshot::channel(); diff --git a/client/offchain/src/lib.rs b/client/offchain/src/lib.rs index 3cd3b2cba5..f0a10a5409 100644 --- a/client/offchain/src/lib.rs +++ b/client/offchain/src/lib.rs @@ -202,7 +202,10 @@ mod tests { // given let _ = env_logger::try_init(); let client = Arc::new(substrate_test_runtime_client::new()); - let pool = Arc::new(TestPool(BasicPool::new(Default::default(), FullChainApi::new(client.clone())))); + let pool = Arc::new(TestPool(BasicPool::new( + Default::default(), + Arc::new(FullChainApi::new(client.clone())), + ))); client.execution_extensions() .register_transaction_pool(Arc::downgrade(&pool.clone()) as _); let db = sc_client_db::offchain::LocalStorage::new_test(); diff --git a/client/rpc/src/author/tests.rs b/client/rpc/src/author/tests.rs index 7de109bc5d..ba9b9d344c 100644 --- a/client/rpc/src/author/tests.rs +++ b/client/rpc/src/author/tests.rs @@ -56,8 +56,15 @@ struct TestSetup { impl Default for TestSetup { fn default() -> Self { let keystore = KeyStore::new(); - 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()))); + let client = Arc::new( + substrate_test_runtime_client::TestClientBuilder::new() + .set_keystore(keystore.clone()) + .build() + ); + let pool = Arc::new(BasicPool::new( + Default::default(), + Arc::new(FullChainApi::new(client.clone())), + )); TestSetup { runtime: runtime::Runtime::new().expect("Failed to create runtime in test setup"), client, diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index cd77e8b080..3f7470ae4e 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -36,7 +36,6 @@ use sp_core::{ 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, NumberFor, SaturatedConversion}, }; diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 5ba6474da6..dc158f1300 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -700,7 +700,10 @@ mod tests { // given let (client, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); let client = Arc::new(client); - let pool = Arc::new(BasicPool::new(Default::default(), FullChainApi::new(client.clone()))); + let pool = Arc::new(BasicPool::new( + Default::default(), + Arc::new(FullChainApi::new(client.clone())), + )); let best = longest_chain.best_chain().unwrap(); let transaction = Transfer { amount: 5, diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index 0bdf5efaa6..e151e9adbe 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -12,17 +12,15 @@ futures = { version = "0.3.1", features = ["compat"] } futures-diagnose = "1.0" log = "0.4.8" parking_lot = "0.9.0" -sp-core = { path = "../../primitives/core" } -sp-api = { path = "../../primitives/api" } -sp-runtime = { path = "../../primitives/runtime" } -sc-transaction-graph = { path = "./graph" } -sp-transaction-pool = { path = "../../primitives/transaction-pool" } -sc-client-api = { path = "../api" } -sp-blockchain = { path = "../../primitives/blockchain" } -substrate-test-runtime-client = { path = "../../test-utils/runtime/client" } +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] sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } - -[features] -test-helpers = [] +substrate-test-runtime-transaction-pool = { version = "2.0.0", path = "../../test-utils/runtime/transaction-pool" } +substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" } diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index 5f116dfd02..85bf2fd327 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -42,8 +42,6 @@ use sp_transaction_pool::{ MaintainedTransactionPool, PoolFuture, }; -type PoolResult = PoolFuture; - /// Basic implementation of transaction pool that can be customized by providing PoolApi. pub struct BasicPool where @@ -80,7 +78,7 @@ impl BasicPool /// Create new basic transaction pool with provided api. pub fn new( options: sc_transaction_graph::Options, - pool_api: PoolApi, + pool_api: Arc, ) -> Self { Self::with_revalidation_type(options, pool_api, RevalidationType::Full) } @@ -89,14 +87,13 @@ impl BasicPool /// revalidation type. pub fn with_revalidation_type( options: sc_transaction_graph::Options, - pool_api: PoolApi, + pool_api: Arc, revalidation_type: RevalidationType, ) -> Self { - let api = Arc::new(pool_api); - let cloned_api = api.clone(); + let cloned_api = pool_api.clone(); BasicPool { api: cloned_api, - pool: Arc::new(sc_transaction_graph::Pool::new(options, api)), + pool: Arc::new(sc_transaction_graph::Pool::new(options, pool_api)), revalidation_strategy: Arc::new(Mutex::new( match revalidation_type { RevalidationType::Light => RevalidationStrategy::Light(RevalidationStatus::NotScheduled), @@ -111,29 +108,23 @@ impl BasicPool pub fn pool(&self) -> &Arc> { &self.pool } - - /// Get reference to the inner chain api, for tests only. - #[cfg(any(feature = "test-helpers", test))] - pub fn api(&self) -> &Arc { - &self.api - } } impl TransactionPool for BasicPool where Block: BlockT, - PoolApi: 'static + sc_transaction_graph::ChainApi, + 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; + type Error = PoolApi::Error; fn submit_at( &self, at: &BlockId, xts: Vec>, - ) -> PoolResult, Self::Error>>> { + ) -> PoolFuture, Self::Error>>, Self::Error> { let pool = self.pool.clone(); let at = *at; async move { @@ -145,7 +136,7 @@ impl TransactionPool for BasicPool &self, at: &BlockId, xt: TransactionFor, - ) -> PoolResult> { + ) -> PoolFuture, Self::Error> { let pool = self.pool.clone(); let at = *at; async move { @@ -157,7 +148,7 @@ impl TransactionPool for BasicPool &self, at: &BlockId, xt: TransactionFor, - ) -> PoolResult>> { + ) -> PoolFuture>, Self::Error> { let at = *at; let pool = self.pool.clone(); @@ -287,7 +278,7 @@ impl RevalidationStatus { impl MaintainedTransactionPool for BasicPool where Block: BlockT, - PoolApi: 'static + sc_transaction_graph::ChainApi, + PoolApi: 'static + sc_transaction_graph::ChainApi, { fn maintain(&self, id: &BlockId, retracted: &[BlockHash]) -> Pin + Send>> diff --git a/client/transaction-pool/src/testing/mod.rs b/client/transaction-pool/src/testing/mod.rs index c216a17ee6..a8f40c6b64 100644 --- a/client/transaction-pool/src/testing/mod.rs +++ b/client/transaction-pool/src/testing/mod.rs @@ -16,8 +16,4 @@ //! Tests for top-level transaction pool api -#[cfg(any(feature = "test-helpers", test))] -pub mod api; - -#[cfg(test)] -mod pool; \ No newline at end of file +mod pool; diff --git a/client/transaction-pool/src/testing/pool.rs b/client/transaction-pool/src/testing/pool.rs index 30a48fbec6..d4f3d0ccb4 100644 --- a/client/transaction-pool/src/testing/pool.rs +++ b/client/transaction-pool/src/testing/pool.rs @@ -1,6 +1,21 @@ +// Copyright 2020 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::*; -use sc_transaction_graph::{self, Pool}; +use sc_transaction_graph::Pool; use futures::executor::block_on; use sp_runtime::{ generic::BlockId, @@ -10,14 +25,14 @@ use substrate_test_runtime_client::{ runtime::{Block, Hash, Index}, AccountKeyring::*, }; -use crate::testing::api::{TestApi, uxt}; +use substrate_test_runtime_transaction_pool::{TestApi, uxt}; fn pool() -> Pool { Pool::new(Default::default(), TestApi::with_alice_nonce(209).into()) } fn maintained_pool() -> BasicPool { - BasicPool::new(Default::default(), TestApi::with_alice_nonce(209)) + BasicPool::new(Default::default(), std::sync::Arc::new(TestApi::with_alice_nonce(209))) } #[test] diff --git a/test-utils/runtime/transaction-pool/Cargo.toml b/test-utils/runtime/transaction-pool/Cargo.toml new file mode 100644 index 0000000000..c10a34f938 --- /dev/null +++ b/test-utils/runtime/transaction-pool/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "substrate-test-runtime-transaction-pool" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" +license = "GPL-3.0" + +[dependencies] +substrate-test-runtime-client = { version = "2.0.0", path = "../client" } +parking_lot = "0.9.0" +codec = { package = "parity-scale-codec", version = "1.0.0" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +sp-transaction-pool = { version = "2.0.0", path = "../../../primitives/transaction-pool" } +sc-transaction-graph = { version = "2.0.0", path = "../../../client/transaction-pool/graph" } +futures = { version = "0.3.1", features = ["compat"] } +derive_more = "0.99.2" diff --git a/client/transaction-pool/src/testing/api.rs b/test-utils/runtime/transaction-pool/src/lib.rs similarity index 84% rename from client/transaction-pool/src/testing/api.rs rename to test-utils/runtime/transaction-pool/src/lib.rs index c8e4b62883..58c801d8d6 100644 --- a/client/transaction-pool/src/testing/api.rs +++ b/test-utils/runtime/transaction-pool/src/lib.rs @@ -14,22 +14,41 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Test ChainApi +//! Test utils for the transaction pool together with the test runtime. +//! +//! See [`TestApi`] for more information. -use crate::*; use codec::Encode; use parking_lot::RwLock; use sp_runtime::{ generic::{self, BlockId}, traits::{BlakeTwo256, Hash as HashT}, - transaction_validity::{TransactionValidity, ValidTransaction, TransactionValidityError, InvalidTransaction}, + transaction_validity::{ + TransactionValidity, ValidTransaction, TransactionValidityError, InvalidTransaction, + }, }; -use std::collections::HashSet; +use std::collections::{HashSet, HashMap}; use substrate_test_runtime_client::{ runtime::{Index, AccountId, Block, BlockNumber, Extrinsic, Hash, Header, Transfer}, AccountKeyring::{self, *}, }; +/// Error type used by [`TestApi`]. +#[derive(Debug, derive_more::From, derive_more::Display)] +pub struct Error(sp_transaction_pool::error::Error); + +impl sp_transaction_pool::error::IntoPoolError for Error { + fn into_pool_error(self) -> Result { + Ok(self.0) + } +} + +impl std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + Some(&self.0) + } +} + #[derive(Default)] struct ChainState { pub block_by_number: HashMap>, @@ -47,7 +66,6 @@ pub struct TestApi { } impl TestApi { - /// Test Api with Alice nonce set initially. pub fn with_alice_nonce(nonce: u64) -> Self { let api = TestApi { @@ -128,9 +146,9 @@ impl TestApi { impl sc_transaction_graph::ChainApi for TestApi { type Block = Block; type Hash = Hash; - type Error = error::Error; - type ValidationFuture = futures::future::Ready>; - type BodyFuture = futures::future::Ready>>>; + type Error = Error; + type ValidationFuture = futures::future::Ready>; + type BodyFuture = futures::future::Ready>, Error>>; fn validate_transaction( &self, @@ -149,7 +167,7 @@ impl sc_transaction_graph::ChainApi for TestApi { if self.chain.read().invalid_hashes.contains(&self.hash_and_length(&uxt).0) { return futures::future::ready(Ok( - Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(0))) + Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(0)).into()) )) } @@ -169,14 +187,14 @@ impl sc_transaction_graph::ChainApi for TestApi { fn block_id_to_number( &self, at: &BlockId, - ) -> error::Result>> { + ) -> Result>, Error> { Ok(Some(number_of(at))) } fn block_id_to_hash( &self, at: &BlockId, - ) -> error::Result>> { + ) -> Result>, Error> { Ok(match at { generic::BlockId::Hash(x) => Some(x.clone()), _ => Some(Default::default()), diff --git a/utils/frame/rpc/system/src/lib.rs b/utils/frame/rpc/system/src/lib.rs index f909e66fd6..d26821caf2 100644 --- a/utils/frame/rpc/system/src/lib.rs +++ b/utils/frame/rpc/system/src/lib.rs @@ -235,7 +235,9 @@ mod tests { // 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 pool = Arc::new( + BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone()))) + ); let new_transaction = |nonce: u64| { let t = Transfer { -- GitLab From 24a003d9f3b51f7fb457275bb6d1ce3775adc851 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Fri, 31 Jan 2020 04:26:36 -0800 Subject: [PATCH 057/180] add negative tests for signatures (#4788) --- primitives/core/src/sr25519.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/primitives/core/src/sr25519.rs b/primitives/core/src/sr25519.rs index 6e542f230f..d98aa19e1d 100644 --- a/primitives/core/src/sr25519.rs +++ b/primitives/core/src/sr25519.rs @@ -729,6 +729,26 @@ mod test { assert!(Pair::verify(&signature, &message[..], &public)); } + #[test] + fn messed_signature_should_not_work() { + let (pair, _) = Pair::generate(); + let public = pair.public(); + let message = b"Signed payload"; + let Signature(mut bytes) = pair.sign(&message[..]); + bytes[0] = bytes[2]; + let signature = Signature(bytes); + assert!(!Pair::verify(&signature, &message[..], &public)); + } + + #[test] + fn messed_message_should_not_work() { + let (pair, _) = Pair::generate(); + let public = pair.public(); + let message = b"Something important"; + let signature = pair.sign(&message[..]); + assert!(!Pair::verify(&signature, &b"Something unimportant", &public)); + } + #[test] fn seeded_pair_should_work() { let pair = Pair::from_seed(b"12345678901234567890123456789012"); -- GitLab From 95089bbb079c4533cca607464df0b5883713861c Mon Sep 17 00:00:00 2001 From: Eric Date: Sat, 1 Feb 2020 01:59:11 +1300 Subject: [PATCH 058/180] Update to the latest crate names (#4783) * Update to the latest crate names * Add to post initial rename fixes --- .maintain/rename-crates-for-2.0.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.maintain/rename-crates-for-2.0.sh b/.maintain/rename-crates-for-2.0.sh index b024cfd441..5d873d26cd 100755 --- a/.maintain/rename-crates-for-2.0.sh +++ b/.maintain/rename-crates-for-2.0.sh @@ -44,6 +44,8 @@ TO_RENAME=( "sp-sesssion sp-session" "sp-tracing-pool sp-transaction-pool" "sc-basic-authority sc-basic-authorship" + "sc-api sc-client-api" + "sc-database sc-client-db" # PRIMITIVES "substrate-application-crypto sp-application-crypto" @@ -87,7 +89,7 @@ TO_RENAME=( # # CLIENT "substrate-client sc-client" - "substrate-client-api sc-api" + "substrate-client-api sc-client-api" "substrate-authority-discovery sc-authority-discovery" "substrate-basic-authorship sc-basic-authorship" "substrate-block-builder sc-block-builder" @@ -99,7 +101,7 @@ TO_RENAME=( "substrate-consensus-pow sc-consensus-pow" "substrate-consensus-slots sc-consensus-slots" "substrate-consensus-uncles sc-consensus-uncles" - "substrate-client-db sc-database" + "substrate-client-db sc-client-db" "substrate-executor sc-executor" "substrate-runtime-test sc-runtime-test" "substrate-finality-grandpa sc-finality-grandpa" -- GitLab From 3d076d8efcfb83919d0cb8695ddce98d59facbf4 Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Fri, 31 Jan 2020 15:22:25 +0100 Subject: [PATCH 059/180] pallet-contracts: Rent projection RPC (#4754) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial approach * Introduce the pallet-contracts-common crate * Add rent::compute_rent_projection * Wire everything together * Fix build error. * Rename EvictionDate → EvictionAt. * Clean. * Renaming and cleaning. * Add documentation for rent_projection RPC. * Add documentation for rent_projection runtime API. * Refactor rent_budget. Merge it with subsistence_treshold. * Bump impl_version * Constrain RPC impl with Block::Header::Number. * Rename pallet-contracts-common into -primitives * Add a comment for `compute_rent_projection` on the usage * Small tidying --- Cargo.lock | 13 ++ bin/node/rpc/src/lib.rs | 4 +- bin/node/runtime/Cargo.toml | 4 +- bin/node/runtime/src/lib.rs | 33 ++--- frame/contracts/Cargo.toml | 2 + frame/contracts/common/Cargo.toml | 19 +++ frame/contracts/common/src/lib.rs | 47 +++++++ frame/contracts/rpc/Cargo.toml | 1 + frame/contracts/rpc/runtime-api/Cargo.toml | 2 + frame/contracts/rpc/runtime-api/src/lib.rs | 30 ++-- frame/contracts/rpc/src/lib.rs | 124 +++++++++++------ frame/contracts/src/lib.rs | 21 ++- frame/contracts/src/rent.rs | 153 +++++++++++++++++---- 13 files changed, 339 insertions(+), 114 deletions(-) create mode 100644 frame/contracts/common/Cargo.toml create mode 100644 frame/contracts/common/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 7c8a4d25f4..d5f71b9b30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3196,6 +3196,7 @@ dependencies = [ "pallet-balances 2.0.0", "pallet-collective 2.0.0", "pallet-contracts 2.0.0", + "pallet-contracts-primitives 2.0.0", "pallet-contracts-rpc-runtime-api 0.8.0", "pallet-democracy 2.0.0", "pallet-elections-phragmen 2.0.0", @@ -3631,6 +3632,7 @@ dependencies = [ "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-contracts-primitives 2.0.0", "pallet-randomness-collective-flip 2.0.0", "pallet-timestamp 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3646,6 +3648,15 @@ dependencies = [ "wasmi-validation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "pallet-contracts-primitives" +version = "2.0.0" +dependencies = [ + "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "sp-runtime 2.0.0", + "sp-std 2.0.0", +] + [[package]] name = "pallet-contracts-rpc" version = "0.8.0" @@ -3653,6 +3664,7 @@ dependencies = [ "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-primitives 2.0.0", "pallet-contracts-rpc-runtime-api 0.8.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3668,6 +3680,7 @@ dependencies = [ name = "pallet-contracts-rpc-runtime-api" version = "0.8.0" dependencies = [ + "pallet-contracts-primitives 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "sp-api 2.0.0", "sp-runtime 2.0.0", diff --git a/bin/node/rpc/src/lib.rs b/bin/node/rpc/src/lib.rs index a473b43a7f..4bf0338088 100644 --- a/bin/node/rpc/src/lib.rs +++ b/bin/node/rpc/src/lib.rs @@ -31,7 +31,7 @@ use std::sync::Arc; -use node_primitives::{Block, AccountId, Index, Balance}; +use node_primitives::{Block, BlockNumber, AccountId, Index, Balance}; use node_runtime::UncheckedExtrinsic; use sp_api::ProvideRuntimeApi; use sp_transaction_pool::TransactionPool; @@ -66,7 +66,7 @@ pub fn create( C: sc_client::blockchain::HeaderBackend, C: Send + Sync + 'static, C::Api: substrate_frame_rpc_system::AccountNonceApi, - C::Api: pallet_contracts_rpc::ContractsRuntimeApi, + C::Api: pallet_contracts_rpc::ContractsRuntimeApi, C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, F: sc_client::light::fetcher::Fetcher + 'static, P: TransactionPool + 'static, diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 35f01e32cb..7bc105b55e 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -42,6 +42,7 @@ pallet-babe = { version = "2.0.0", default-features = false, path = "../../../fr 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-primitives = { version = "2.0.0", default-features = false, path = "../../../frame/contracts/common/" } pallet-contracts-rpc-runtime-api = { version = "0.8.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" } @@ -83,8 +84,9 @@ std = [ "sp-block-builder/std", "codec/std", "pallet-collective/std", - "pallet-contracts-rpc-runtime-api/std", "pallet-contracts/std", + "pallet-contracts-primitives/std", + "pallet-contracts-rpc-runtime-api/std", "pallet-democracy/std", "pallet-elections-phragmen/std", "frame-executive/std", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index aa550893f9..df4423f850 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -81,7 +81,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 210, - impl_version: 0, + impl_version: 1, apis: RUNTIME_API_VERSIONS, }; @@ -746,7 +746,9 @@ impl_runtime_apis! { } } - impl pallet_contracts_rpc_runtime_api::ContractsApi for Runtime { + impl pallet_contracts_rpc_runtime_api::ContractsApi + for Runtime + { fn call( origin: AccountId, dest: AccountId, @@ -754,13 +756,8 @@ impl_runtime_apis! { gas_limit: u64, input_data: Vec, ) -> ContractExecResult { - let exec_result = Contracts::bare_call( - origin, - dest.into(), - value, - gas_limit, - input_data, - ); + let exec_result = + Contracts::bare_call(origin, dest.into(), value, gas_limit, input_data); match exec_result { Ok(v) => ContractExecResult::Success { status: v.status, @@ -773,16 +770,14 @@ impl_runtime_apis! { fn get_storage( address: AccountId, key: [u8; 32], - ) -> pallet_contracts_rpc_runtime_api::GetStorageResult { - Contracts::get_storage(address, key).map_err(|rpc_err| { - 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, - GetStorageError::IsTombstone => RpcGetStorageError::IsTombstone, - } - }) + ) -> pallet_contracts_primitives::GetStorageResult { + Contracts::get_storage(address, key) + } + + fn rent_projection( + address: AccountId, + ) -> pallet_contracts_primitives::RentProjectionResult { + Contracts::rent_projection(address) } } diff --git a/frame/contracts/Cargo.toml b/frame/contracts/Cargo.toml index fa4c915cc8..159e9f9d0c 100644 --- a/frame/contracts/Cargo.toml +++ b/frame/contracts/Cargo.toml @@ -18,6 +18,7 @@ sp-std = { version = "2.0.0", default-features = false, path = "../../primitives sp-sandbox = { version = "0.8.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" } +pallet-contracts-primitives = { version = "2.0.0", default-features = false, path = "common" } [dev-dependencies] wabt = "0.9.2" @@ -42,4 +43,5 @@ std = [ "parity-wasm/std", "pwasm-utils/std", "wasmi-validation/std", + "pallet-contracts-primitives/std", ] diff --git a/frame/contracts/common/Cargo.toml b/frame/contracts/common/Cargo.toml new file mode 100644 index 0000000000..6e4ee050bd --- /dev/null +++ b/frame/contracts/common/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "pallet-contracts-primitives" +version = "2.0.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +# This crate should not rely on any of the frame primitives. +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +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 = [ + "codec/std", + "sp-runtime/std", + "sp-std/std", +] diff --git a/frame/contracts/common/src/lib.rs b/frame/contracts/common/src/lib.rs new file mode 100644 index 0000000000..e54b4c8d55 --- /dev/null +++ b/frame/contracts/common/src/lib.rs @@ -0,0 +1,47 @@ +// Copyright 2020 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 crate that hosts a common definitions that are relevent for the pallet-contracts. + +#![cfg_attr(not(feature = "std"), no_std)] + +use sp_std::prelude::*; + +/// A result type of a get storage call. +pub type GetStorageResult = Result>, ContractAccessError>; + +/// The possible errors that can happen querying the storage of a contract. +#[derive(Eq, PartialEq, codec::Encode, codec::Decode, sp_runtime::RuntimeDebug)] +pub enum ContractAccessError { + /// The given address doesn't point to a contract. + DoesntExist, + /// The specified contract is a tombstone and thus cannot have any storage. + IsTombstone, +} + +/// A result type of a `rent_projection` call. +pub type RentProjectionResult = + Result, ContractAccessError>; + +#[derive(Eq, PartialEq, codec::Encode, codec::Decode, sp_runtime::RuntimeDebug)] +pub enum RentProjection { + /// Eviction is projected to happen at the specified block number. + EvictionAt(BlockNumber), + /// No eviction is scheduled. + /// + /// E.g. because the contract accumulated enough funds to offset the rent storage costs. + NoEviction, +} diff --git a/frame/contracts/rpc/Cargo.toml b/frame/contracts/rpc/Cargo.toml index 7767a762f4..d59260d11f 100644 --- a/frame/contracts/rpc/Cargo.toml +++ b/frame/contracts/rpc/Cargo.toml @@ -16,6 +16,7 @@ sp-rpc = { version = "2.0.0", path = "../../../primitives/rpc" } serde = { version = "1.0.101", features = ["derive"] } sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } sp-api = { version = "2.0.0", path = "../../../primitives/api" } +pallet-contracts-primitives = { version = "2.0.0", path = "../common" } pallet-contracts-rpc-runtime-api = { version = "0.8.0", path = "./runtime-api" } [dev-dependencies] diff --git a/frame/contracts/rpc/runtime-api/Cargo.toml b/frame/contracts/rpc/runtime-api/Cargo.toml index 0f228bc99d..dad9b92f6a 100644 --- a/frame/contracts/rpc/runtime-api/Cargo.toml +++ b/frame/contracts/rpc/runtime-api/Cargo.toml @@ -10,6 +10,7 @@ sp-api = { version = "2.0.0", default-features = false, path = "../../../../prim codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } sp-std = { version = "2.0.0", default-features = false, path = "../../../../primitives/std" } sp-runtime = { version = "2.0.0", default-features = false, path = "../../../../primitives/runtime" } +pallet-contracts-primitives = { version = "2.0.0", default-features = false, path = "../../common" } [features] default = ["std"] @@ -18,4 +19,5 @@ std = [ "codec/std", "sp-std/std", "sp-runtime/std", + "pallet-contracts-primitives/std", ] diff --git a/frame/contracts/rpc/runtime-api/src/lib.rs b/frame/contracts/rpc/runtime-api/src/lib.rs index 622cac8572..fd83ba6534 100644 --- a/frame/contracts/rpc/runtime-api/src/lib.rs +++ b/frame/contracts/rpc/runtime-api/src/lib.rs @@ -22,9 +22,10 @@ #![cfg_attr(not(feature = "std"), no_std)] -use sp_std::vec::Vec; -use codec::{Encode, Decode, Codec}; +use codec::{Codec, Decode, Encode}; +use pallet_contracts_primitives::{GetStorageResult, RentProjectionResult}; use sp_runtime::RuntimeDebug; +use sp_std::vec::Vec; /// A result of execution of a contract. #[derive(Eq, PartialEq, Encode, Decode, RuntimeDebug)] @@ -44,25 +45,12 @@ pub enum ContractExecResult { Error, } -/// A result type of the get storage call. -/// -/// See [`ContractsApi::get_storage`] for more info. -pub type GetStorageResult = Result>, GetStorageError>; - -/// The possible errors that can happen querying the storage of a contract. -#[derive(Eq, PartialEq, Encode, Decode, RuntimeDebug)] -pub enum GetStorageError { - /// The given address doesn't point on a contract. - ContractDoesntExist, - /// The specified contract is a tombstone and thus cannot have any storage. - IsTombstone, -} - sp_api::decl_runtime_apis! { /// The API to interact with contracts without using executive. - pub trait ContractsApi where + pub trait ContractsApi where AccountId: Codec, Balance: Codec, + BlockNumber: Codec, { /// Perform a call from a specified account to a given contract. /// @@ -85,5 +73,13 @@ sp_api::decl_runtime_apis! { address: AccountId, key: [u8; 32], ) -> GetStorageResult; + + /// Returns the projected time a given contract will be able to sustain paying its rent. + /// + /// The returned projection is relevent for the current block, i.e. it is as if the contract + /// was accessed at the current block. + /// + /// Returns `Err` if the contract is in a tombstone state or doesn't exist. + fn rent_projection(address: AccountId) -> RentProjectionResult; } } diff --git a/frame/contracts/rpc/src/lib.rs b/frame/contracts/rpc/src/lib.rs index 4c39bc9516..b0d6037416 100644 --- a/frame/contracts/rpc/src/lib.rs +++ b/frame/contracts/rpc/src/lib.rs @@ -18,19 +18,23 @@ use std::sync::Arc; -use sp_blockchain::HeaderBackend; use codec::Codec; use jsonrpc_core::{Error, ErrorCode, Result}; use jsonrpc_derive::rpc; -use sp_core::{H256, Bytes}; -use sp_rpc::number; +use pallet_contracts_primitives::RentProjection; use serde::{Deserialize, Serialize}; -use sp_runtime::{generic::BlockId, traits::Block as BlockT}; use sp_api::ProvideRuntimeApi; +use sp_blockchain::HeaderBackend; +use sp_core::{Bytes, H256}; +use sp_rpc::number; +use sp_runtime::{ + generic::BlockId, + traits::{Block as BlockT, Header as HeaderT}, +}; pub use self::gen_client::Client as ContractsClient; pub use pallet_contracts_rpc_runtime_api::{ - self as runtime_api, ContractExecResult, ContractsApi as ContractsRuntimeApi, GetStorageResult, + self as runtime_api, ContractExecResult, ContractsApi as ContractsRuntimeApi, }; const RUNTIME_ERROR: i64 = 1; @@ -46,13 +50,13 @@ const CONTRACT_IS_A_TOMBSTONE: i64 = 3; /// 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 { - use runtime_api::GetStorageError::*; +/// A private newtype for converting `ContractAccessError` into an RPC error. +struct ContractAccessError(pallet_contracts_primitives::ContractAccessError); +impl From for Error { + fn from(e: ContractAccessError) -> Error { + use pallet_contracts_primitives::ContractAccessError::*; match e.0 { - ContractDoesntExist => Error { + DoesntExist => Error { code: ErrorCode::ServerError(CONTRACT_DOESNT_EXIST), message: "The specified contract doesn't exist.".into(), data: None, @@ -61,7 +65,7 @@ impl From for Error { code: ErrorCode::ServerError(CONTRACT_IS_A_TOMBSTONE), message: "The contract is a tombstone and doesn't have any storage.".into(), data: None, - } + }, } } } @@ -97,19 +101,18 @@ pub enum RpcContractExecResult { 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(()) + ContractExecResult::Success { status, data } => RpcContractExecResult::Success { + status, + data: data.into(), }, + ContractExecResult::Error => RpcContractExecResult::Error(()), } } } /// Contracts RPC methods. #[rpc] -pub trait ContractsApi { +pub trait ContractsApi { /// Executes a call to a contract. /// /// This call is performed locally without submitting any transactions. Thus executing this @@ -132,6 +135,19 @@ pub trait ContractsApi { key: H256, at: Option, ) -> Result>; + + /// Returns the projected time a given contract will be able to sustain paying its rent. + /// + /// The returned projection is relevent for the given block, i.e. it is as if the contract was + /// accessed at the beginning of that block. + /// + /// Returns `None` if the contract is exempted from rent. + #[rpc(name = "contracts_rentProjection")] + fn rent_projection( + &self, + address: AccountId, + at: Option, + ) -> Result>; } /// An implementation of contract specific RPC methods. @@ -149,13 +165,22 @@ impl Contracts { } } } - -impl ContractsApi<::Hash, AccountId, Balance> - for Contracts +impl + ContractsApi< + ::Hash, + <::Header as HeaderT>::Number, + AccountId, + Balance, + > for Contracts where Block: BlockT, C: Send + Sync + 'static + ProvideRuntimeApi + HeaderBackend, - C::Api: ContractsRuntimeApi, + C::Api: ContractsRuntimeApi< + Block, + AccountId, + Balance, + <::Header as HeaderT>::Number, + >, AccountId: Codec, Balance: Codec, { @@ -188,8 +213,7 @@ where code: ErrorCode::InvalidParams, message: format!( "Requested gas limit is greater than maximum allowed: {} > {}", - gas_limit, - max_gas_limit + gas_limit, max_gas_limit ), data: None, }); @@ -197,11 +221,7 @@ where let exec_result = api .call(&at, origin, dest, value, gas_limit, input_data.to_vec()) - .map_err(|e| Error { - code: ErrorCode::ServerError(RUNTIME_ERROR), - message: "Runtime trapped while executing a contract.".into(), - data: Some(format!("{:?}", e).into()), - })?; + .map_err(|e| runtime_error_into_rpc_err(e))?; Ok(exec_result.into()) } @@ -217,19 +237,43 @@ where // If the block hash is not supplied assume the best block. self.client.info().best_hash)); - let get_storage_result = api + let result = api .get_storage(&at, address, key.into()) - .map_err(|e| - // Handle general API calling errors. - Error { - code: ErrorCode::ServerError(RUNTIME_ERROR), - message: "Runtime trapped while querying storage.".into(), - data: Some(format!("{:?}", e).into()), - })? - .map_err(GetStorageError)? + .map_err(|e| runtime_error_into_rpc_err(e))? + .map_err(ContractAccessError)? .map(Bytes); - Ok(get_storage_result) + Ok(result) + } + + fn rent_projection( + &self, + address: AccountId, + at: Option<::Hash>, + ) -> Result::Header as HeaderT>::Number>> { + 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. + self.client.info().best_hash)); + + let result = api + .rent_projection(&at, address) + .map_err(|e| runtime_error_into_rpc_err(e))? + .map_err(ContractAccessError)?; + + Ok(match result { + RentProjection::NoEviction => None, + RentProjection::EvictionAt(block_num) => Some(block_num), + }) + } +} + +/// Converts a runtime trap into an RPC error. +fn runtime_error_into_rpc_err(err: impl std::fmt::Debug) -> Error { + Error { + code: ErrorCode::ServerError(RUNTIME_ERROR), + message: "Runtime trapped".into(), + data: Some(format!("{:?}", err).into()), } } @@ -240,7 +284,7 @@ mod tests { #[test] fn should_serialize_deserialize_properly() { fn test(expected: &str) { - let res: RpcContractExecResult = serde_json::from_str(expected).unwrap(); + let res: RpcContractExecResult = serde_json::from_str(expected).unwrap(); let actual = serde_json::to_string(&res).unwrap(); assert_eq!(actual, expected); } diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index 9ac43cbb50..ff4a729b2c 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -128,6 +128,7 @@ use frame_support::{ 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; +use pallet_contracts_primitives::{RentProjection, ContractAccessError}; pub type CodeHash = ::Hash; pub type TrieId = Vec; @@ -680,14 +681,6 @@ decl_module! { } } -/// The possible errors that can happen querying the storage of a contract. -pub enum GetStorageError { - /// The given address doesn't point on a contract. - ContractDoesntExist, - /// The specified contract is a tombstone and thus cannot have any storage. - IsTombstone, -} - /// Public APIs provided by the contracts module. impl Module { /// Perform a call to a specified contract. @@ -710,11 +703,11 @@ impl Module { pub fn get_storage( address: T::AccountId, key: [u8; 32], - ) -> sp_std::result::Result>, GetStorageError> { + ) -> sp_std::result::Result>, ContractAccessError> { let contract_info = >::get(&address) - .ok_or(GetStorageError::ContractDoesntExist)? + .ok_or(ContractAccessError::DoesntExist)? .get_alive() - .ok_or(GetStorageError::IsTombstone)?; + .ok_or(ContractAccessError::IsTombstone)?; let maybe_value = AccountDb::::get_storage( &DirectAccountDb, @@ -724,6 +717,12 @@ impl Module { ); Ok(maybe_value) } + + pub fn rent_projection( + address: T::AccountId, + ) -> sp_std::result::Result, ContractAccessError> { + rent::compute_rent_projection::(&address) + } } impl Module { diff --git a/frame/contracts/src/rent.rs b/frame/contracts/src/rent.rs index 46f915e642..bbcc07c714 100644 --- a/frame/contracts/src/rent.rs +++ b/frame/contracts/src/rent.rs @@ -21,6 +21,7 @@ use crate::{ use frame_support::storage::child; use frame_support::traits::{Currency, ExistenceRequirement, Get, OnUnbalanced, WithdrawReason}; use frame_support::StorageMap; +use pallet_contracts_primitives::{ContractAccessError, RentProjection, RentProjectionResult}; use sp_runtime::traits::{Bounded, CheckedDiv, CheckedMul, SaturatedConversion, Saturating, Zero}; /// The amount to charge. @@ -74,9 +75,57 @@ enum Verdict { amount: Option>, }, /// Everything is OK, we just only take some charge. - Charge { - amount: OutstandingAmount, - }, + Charge { amount: OutstandingAmount }, +} + +/// Returns a fee charged per block from the contract. +/// +/// This function accounts for the storage rent deposit. I.e. if the contract possesses enough funds +/// then the fee can drop to zero. +fn compute_fee_per_block( + balance: &BalanceOf, + contract: &AliveContractInfo, +) -> BalanceOf { + let free_storage = balance + .checked_div(&T::RentDepositOffset::get()) + .unwrap_or_else(Zero::zero); + + let effective_storage_size = + >::from(contract.storage_size).saturating_sub(free_storage); + + effective_storage_size + .checked_mul(&T::RentByteFee::get()) + .unwrap_or(>::max_value()) +} + +/// Subsistence threshold is the extension of the minimum balance (aka existential deposit) by the +/// tombstone deposit, required for leaving a tombstone. +/// +/// Rent mechanism cannot make the balance lower than subsistence threshold. +fn subsistence_threshold() -> BalanceOf { + T::Currency::minimum_balance() + T::TombstoneDeposit::get() +} + +/// Returns amount of funds available to consume by rent mechanism. +/// +/// Rent mechanism cannot consume more than `rent_allowance` set by the contract and it cannot make +/// the balance lower than [`subsistence_threshold`]. +/// +/// In case the balance is below the subsistence threshold, this function returns `None`. +fn rent_budget( + balance: &BalanceOf, + contract: &AliveContractInfo, +) -> Option> { + let subsistence_threshold = subsistence_threshold::(); + if *balance < subsistence_threshold { + return None; + } + + let rent_allowed_to_charge = *balance - subsistence_threshold; + Some(>::min( + contract.rent_allowance, + rent_allowed_to_charge, + )) } /// Consider the case for rent payment of the given account and returns a `Verdict`. @@ -103,37 +152,27 @@ fn consider_case( let balance = T::Currency::free_balance(account); // An amount of funds to charge per block for storage taken up by the contract. - let fee_per_block = { - let free_storage = balance - .checked_div(&T::RentDepositOffset::get()) - .unwrap_or_else(Zero::zero); - - let effective_storage_size = - >::from(contract.storage_size).saturating_sub(free_storage); - - effective_storage_size - .checked_mul(&T::RentByteFee::get()) - .unwrap_or(>::max_value()) - }; - + let fee_per_block = compute_fee_per_block::(&balance, contract); if fee_per_block.is_zero() { // The rent deposit offset reduced the fee to 0. This means that the contract // gets the rent for free. return Verdict::Exempt; } - // The minimal amount of funds required for a contract not to be evicted. - let subsistence_threshold = T::Currency::minimum_balance() + T::TombstoneDeposit::get(); - - if balance < subsistence_threshold { - // The contract cannot afford to leave a tombstone, so remove the contract info altogether. - return Verdict::Kill; - } + let rent_budget = match rent_budget::(&balance, contract) { + Some(rent_budget) => rent_budget, + None => { + // The contract's balance is already below subsistence threshold. That indicates that + // the contract cannot afford to leave a tombstone. + // + // So cleanly wipe the contract. + return Verdict::Kill; + } + }; let dues = fee_per_block .checked_mul(&blocks_passed.saturated_into::().into()) .unwrap_or(>::max_value()); - let rent_budget = contract.rent_allowance.min(balance - subsistence_threshold); let insufficient_rent = rent_budget < dues; // If the rent payment cannot be withdrawn due to locks on the account balance, then evict the @@ -284,3 +323,69 @@ pub fn snitch_contract_should_be_evicted( _ => false, } } + +/// Returns the projected time a given contract will be able to sustain paying its rent. The +/// returned projection is relevent for the current block, i.e. it is as if the contract was +/// accessed at the beginning of the current block. Returns `None` in case if the contract was +/// evicted before or as a result of the rent collection. +/// +/// The returned value is only an estimation. It doesn't take into account any top ups, changing the +/// rent allowance, or any problems coming from withdrawing the dues. +/// +/// NOTE that this is not a side-effect free function! It will actually collect rent and then +/// compute the projection. This function is only used for implementation of an RPC method through +/// `RuntimeApi` meaning that the changes will be discarded anyway. +pub fn compute_rent_projection( + account: &T::AccountId, +) -> RentProjectionResult { + let contract_info = >::get(account); + let alive_contract_info = match contract_info { + None | Some(ContractInfo::Tombstone(_)) => return Err(ContractAccessError::IsTombstone), + Some(ContractInfo::Alive(contract)) => contract, + }; + let current_block_number = >::block_number(); + let verdict = consider_case::( + account, + current_block_number, + Zero::zero(), + &alive_contract_info, + ); + let new_contract_info = + enact_verdict(account, alive_contract_info, current_block_number, verdict); + + // Check what happened after enaction of the verdict. + let alive_contract_info = match new_contract_info { + None | Some(ContractInfo::Tombstone(_)) => return Err(ContractAccessError::IsTombstone), + Some(ContractInfo::Alive(contract)) => contract, + }; + + // Compute how much would the fee per block be with the *updated* balance. + let balance = T::Currency::free_balance(account); + let fee_per_block = compute_fee_per_block::(&balance, &alive_contract_info); + if fee_per_block.is_zero() { + return Ok(RentProjection::NoEviction); + } + + // Then compute how much the contract will sustain under these circumstances. + let rent_budget = rent_budget::(&balance, &alive_contract_info).expect( + "the contract exists and in the alive state; + the updated balance must be greater than subsistence deposit; + this function doesn't return `None`; + qed + ", + ); + let blocks_left = match rent_budget.checked_div(&fee_per_block) { + Some(blocks_left) => blocks_left, + None => { + // `fee_per_block` is not zero here, so `checked_div` can return `None` if + // there is an overflow. This cannot happen with integers though. Return + // `NoEviction` here just in case. + return Ok(RentProjection::NoEviction); + } + }; + + let blocks_left = blocks_left.saturated_into::().into(); + Ok(RentProjection::EvictionAt( + current_block_number + blocks_left, + )) +} -- GitLab From 59792959dc504cfba8dddc1158b3ee4d39e0dde1 Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Fri, 31 Jan 2020 17:27:10 +0100 Subject: [PATCH 060/180] Small follow-up docs improvements in rent module (#4790) * Small follow-up docs improvements in rent module * Update frame/contracts/src/rent.rs Co-Authored-By: thiolliere * Use a shorter version of the sentence Co-authored-by: thiolliere --- frame/contracts/src/rent.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frame/contracts/src/rent.rs b/frame/contracts/src/rent.rs index bbcc07c714..49beebbf0c 100644 --- a/frame/contracts/src/rent.rs +++ b/frame/contracts/src/rent.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +//! A module responsible for computing the right amount of weight and charging it. + use crate::{ AliveContractInfo, BalanceOf, ContractInfo, ContractInfoOf, Module, RawEvent, TombstoneContractInfo, Trait, @@ -130,8 +132,8 @@ fn rent_budget( /// Consider the case for rent payment of the given account and returns a `Verdict`. /// -/// The `current_block_number` must be equal to the current block number. Use `handicap` do -/// change the reference block number. (See `snitch_contract_should_be_evicted` for more details). +/// Use `handicap` in case you want to change the reference block number. (To get more details see +/// `snitch_contract_should_be_evicted` ). fn consider_case( account: &T::AccountId, current_block_number: T::BlockNumber, @@ -285,7 +287,7 @@ pub fn collect_rent(account: &T::AccountId) -> Option> enact_verdict(account, alive_contract_info, current_block_number, verdict) } -/// Process a snitch that a contract under the given address should be evicted. +/// Process a report that a contract under the given address should be evicted. /// /// Enact the eviction right away if the contract should be evicted and return true. /// Otherwise, **do nothing** and return false. -- GitLab From 2547be441e66db8214fb0baf40e287cfe2ca98f1 Mon Sep 17 00:00:00 2001 From: thiolliere Date: Fri, 31 Jan 2020 18:49:02 +0100 Subject: [PATCH 061/180] remove ambiguous into_iter (#4794) --- client/api/src/notifications.rs | 2 +- client/cli/src/node_key.rs | 6 +++--- frame/staking/reward-curve/src/lib.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/api/src/notifications.rs b/client/api/src/notifications.rs index 13bf06396d..72a9f357fc 100644 --- a/client/api/src/notifications.rs +++ b/client/api/src/notifications.rs @@ -323,7 +323,7 @@ mod tests { let child_filters = Some([ (StorageKey(vec![4]), None), (StorageKey(vec![5]), None), - ].into_iter().cloned().collect()); + ].iter().cloned().collect()); StorageChangeSet { changes: Arc::new(changes.0), child_changes: Arc::new(changes.1), diff --git a/client/cli/src/node_key.rs b/client/cli/src/node_key.rs index 4df3b8e9d5..88102acc63 100644 --- a/client/cli/src/node_key.rs +++ b/client/cli/src/node_key.rs @@ -113,7 +113,7 @@ mod tests { #[test] fn test_node_key_config_input() { fn secret_input(net_config_dir: Option) -> error::Result<()> { - NodeKeyType::variants().into_iter().try_for_each(|t| { + NodeKeyType::variants().iter().try_for_each(|t| { let node_key_type = NodeKeyType::from_str(t).unwrap(); let sk = match node_key_type { NodeKeyType::Ed25519 => ed25519::SecretKey::generate().as_ref().to_vec() @@ -139,7 +139,7 @@ mod tests { #[test] fn test_node_key_config_file() { fn secret_file(net_config_dir: Option) -> error::Result<()> { - NodeKeyType::variants().into_iter().try_for_each(|t| { + NodeKeyType::variants().iter().try_for_each(|t| { let node_key_type = NodeKeyType::from_str(t).unwrap(); let tmp = tempfile::Builder::new().prefix("alice").tempdir()?; let file = tmp.path().join(format!("{}_mysecret", t)).to_path_buf(); @@ -166,7 +166,7 @@ mod tests { where F: Fn(NodeKeyParams) -> error::Result<()> { - NodeKeyType::variants().into_iter().try_for_each(|t| { + NodeKeyType::variants().iter().try_for_each(|t| { let node_key_type = NodeKeyType::from_str(t).unwrap(); f(NodeKeyParams { node_key_type, diff --git a/frame/staking/reward-curve/src/lib.rs b/frame/staking/reward-curve/src/lib.rs index 89a1980d19..3c31cecc21 100644 --- a/frame/staking/reward-curve/src/lib.rs +++ b/frame/staking/reward-curve/src/lib.rs @@ -386,7 +386,7 @@ fn generate_test_module(input: &INposInput) -> TokenStream2 { #[test] fn reward_curve_precision() { - for &base in [MILLION, u32::max_value()].into_iter() { + for &base in [MILLION, u32::max_value()].iter() { let number_of_check = 100_000.min(base); for check_index in 0..=number_of_check { let i = (check_index as u64 * base as u64 / number_of_check as u64) as u32; -- GitLab From 0cd747cc8398275f3218ce5fcf6f7bc10bdb9a18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 31 Jan 2020 19:59:49 +0100 Subject: [PATCH 062/180] Refactor im-online and print more debug info. (#4771) * Initial version. * Fix tests. * Refactor using StorageValueRef. * Add tests and apply review suggestions. * Bump runtime. Co-authored-by: Gavin Wood --- bin/node/runtime/src/lib.rs | 4 +- frame/im-online/src/lib.rs | 336 +++++++++++---------- frame/im-online/src/tests.rs | 13 +- primitives/runtime/src/offchain/mod.rs | 1 + primitives/runtime/src/offchain/storage.rs | 156 ++++++++++ 5 files changed, 353 insertions(+), 157 deletions(-) create mode 100644 primitives/runtime/src/offchain/storage.rs diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index df4423f850..a4a1c90665 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -80,8 +80,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 210, - impl_version: 1, + spec_version: 211, + impl_version: 0, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index ab1c6d7fd3..ff06cb37d4 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -72,13 +72,14 @@ mod tests; use sp_application_crypto::RuntimeAppPublic; use codec::{Encode, Decode}; -use sp_core::offchain::{OpaqueNetworkState, StorageKind}; +use sp_core::offchain::OpaqueNetworkState; use sp_std::prelude::*; use sp_std::convert::TryInto; use pallet_session::historical::IdentificationTuple; use sp_runtime::{ + offchain::storage::StorageValueRef, RuntimeDebug, - traits::{Convert, Member, Printable, Saturating}, Perbill, + traits::{Convert, Member, Saturating, SimpleArithmetic}, Perbill, transaction_validity::{ TransactionValidity, ValidTransaction, InvalidTransaction, TransactionPriority, @@ -89,7 +90,7 @@ use sp_staking::{ offence::{ReportOffence, Offence, Kind}, }; use frame_support::{ - decl_module, decl_event, decl_storage, print, Parameter, debug, decl_error, + decl_module, decl_event, decl_storage, Parameter, debug, decl_error, traits::Get, }; use frame_system::{self as system, ensure_none}; @@ -129,37 +130,70 @@ pub mod ed25519 { pub type AuthorityId = app_ed25519::Public; } -/// The local storage database key under which the worker progress status -/// is tracked. -const DB_KEY: &[u8] = b"parity/im-online-worker-status"; +const DB_PREFIX: &[u8] = b"parity/im-online-heartbeat/"; +/// How many blocks do we wait for heartbeat transaction to be included +/// before sending another one. +const INCLUDE_THRESHOLD: u32 = 3; -/// It's important to persist the worker state, since e.g. the -/// server could be restarted while starting the gossip process, but before -/// finishing it. With every execution of the off-chain worker we check -/// if we need to recover and resume gossipping or if there is already -/// another off-chain worker in the process of gossipping. +/// Status of the offchain worker code. +/// +/// This stores the block number at which heartbeat was requested and when the worker +/// has actually managed to produce it. +/// Note we store such status for every `authority_index` separately. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] -struct WorkerStatus { - done: bool, - gossipping_at: BlockNumber, +struct HeartbeatStatus { + /// An index of the session that we are supposed to send heartbeat for. + pub session_index: SessionIndex, + /// A block number at which the heartbeat for that session has been actually sent. + /// + /// It may be 0 in case the sending failed. In such case we should just retry + /// as soon as possible (i.e. in a worker running for the next block). + pub sent_at: BlockNumber, +} + +impl HeartbeatStatus { + /// Returns true if heartbeat has been recently sent. + /// + /// Parameters: + /// `session_index` - index of current session. + /// `now` - block at which the offchain worker is running. + /// + /// This function will return `true` iff: + /// 1. the session index is the same (we don't care if it went up or down) + /// 2. the heartbeat has been sent recently (within the threshold) + /// + /// The reasoning for 1. is that it's better to send an extra heartbeat than + /// to stall or not send one in case of a bug. + fn is_recent(&self, session_index: SessionIndex, now: BlockNumber) -> bool { + self.session_index == session_index && self.sent_at + INCLUDE_THRESHOLD.into() > now + } } /// Error which may occur while executing the off-chain code. -#[derive(RuntimeDebug)] -enum OffchainErr { - DecodeWorkerStatus, +#[cfg_attr(test, derive(PartialEq))] +enum OffchainErr { + TooEarly(BlockNumber), + WaitingForInclusion(BlockNumber), + AlreadyOnline(u32), FailedSigning, + FailedToAcquireLock, NetworkState, SubmitTransaction, } -impl Printable for OffchainErr { - fn print(&self) { - match self { - OffchainErr::DecodeWorkerStatus => print("Offchain error: decoding WorkerStatus failed!"), - OffchainErr::FailedSigning => print("Offchain error: signing failed!"), - OffchainErr::NetworkState => print("Offchain error: fetching network state failed!"), - OffchainErr::SubmitTransaction => print("Offchain error: submitting transaction failed!"), +impl sp_std::fmt::Debug for OffchainErr { + fn fmt(&self, fmt: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + match *self { + OffchainErr::TooEarly(ref block) => + write!(fmt, "Too early to send heartbeat, next expected at {:?}", block), + OffchainErr::WaitingForInclusion(ref block) => + write!(fmt, "Heartbeat already sent at {:?}. Waiting for inclusion.", block), + OffchainErr::AlreadyOnline(auth_idx) => + write!(fmt, "Authority {} is already online", auth_idx), + OffchainErr::FailedSigning => write!(fmt, "Failed to sign heartbeat"), + OffchainErr::FailedToAcquireLock => write!(fmt, "Failed to acquire lock"), + OffchainErr::NetworkState => write!(fmt, "Failed to fetch network state"), + OffchainErr::SubmitTransaction => write!(fmt, "Failed to submit transaction"), } } } @@ -197,7 +231,9 @@ pub trait Trait: frame_system::Trait + pallet_session::historical::Trait { /// An expected duration of the session. /// /// This parameter is used to determine the longevity of `heartbeat` transaction - /// and a rough time when the heartbeat should be sent. + /// and a rough time when we should start considering sending hearbeats, + /// since the workers avoids sending them at the very beginning of the session, assuming + /// there is a chance the authority will produce a block and they won't be necessary. type SessionDuration: Get; /// A type that gives us the ability to submit unresponsiveness offence reports. @@ -225,8 +261,13 @@ decl_event!( decl_storage! { trait Store for Module as ImOnline { - /// The block number when we should gossip. - GossipAt get(fn gossip_at): T::BlockNumber; + /// The block number after which it's ok to send heartbeats in current session. + /// + /// At the beginning of each session we set this to a value that should + /// fall roughly in the middle of the session duration. + /// The idea is to first wait for the validators to produce a block + /// in the current session, so that the heartbeat later on will not be necessary. + HeartbeatAfter get(fn heartbeat_after): T::BlockNumber; /// The current set of keys that may issue a heartbeat. Keys get(fn keys): Vec; @@ -302,12 +343,29 @@ decl_module! { // Only send messages if we are a potential validator. if sp_io::offchain::is_validator() { - Self::offchain(now); + for res in Self::send_heartbeats(now).into_iter().flatten() { + if let Err(e) = res { + debug::debug!( + target: "imonline", + "Skipping heartbeat at {:?}: {:?}", + now, + e, + ) + } + } + } else { + debug::trace!( + target: "imonline", + "Skipping heartbeat at {:?}. Not a validator.", + now, + ) } } } } +type OffchainResult = Result::BlockNumber>>; + /// Keep track of number of authored blocks per authority, uncles are counted as /// well since they're a valid proof of onlineness. impl pallet_authorship::EventHandler for Module { @@ -365,156 +423,128 @@ impl Module { ); } - pub(crate) fn offchain(now: T::BlockNumber) { - let next_gossip = >::get(); - let check = Self::check_not_yet_gossipped(now, next_gossip); - let (curr_worker_status, not_yet_gossipped) = match check { - Ok((s, v)) => (s, v), - Err(err) => { - print(err); - return; - }, - }; - if next_gossip < now && not_yet_gossipped { - let value_set = Self::compare_and_set_worker_status(now, false, curr_worker_status); - if !value_set { - // value could not be set in local storage, since the value was - // different from `curr_worker_status`. this indicates that - // another worker was running in parallel. - return; - } - - match Self::do_gossip_at(now) { - Ok(_) => {}, - Err(err) => print(err), - } - } else { - debug::native::debug!( - target: "imonline", - "Skipping gossip at: {:?} >= {:?} || {:?}", - next_gossip, - now, - if not_yet_gossipped { "not gossipped" } else { "gossipped" } - ); + pub(crate) fn send_heartbeats(block_number: T::BlockNumber) + -> OffchainResult>> + { + let heartbeat_after = >::get(); + if block_number < heartbeat_after { + return Err(OffchainErr::TooEarly(heartbeat_after)) } + + let session_index = >::current_index(); + Ok(Self::local_authority_keys() + .map(move |(authority_index, key)| + Self::send_single_heartbeat(authority_index, key, session_index, block_number) + )) } - fn do_gossip_at(block_number: T::BlockNumber) -> Result<(), OffchainErr> { - // we run only when a local authority key is configured - let authorities = Keys::::get(); - let mut results = Vec::new(); - let mut local_keys = T::AuthorityId::all(); - local_keys.sort(); - - for (authority_index, key) in authorities.into_iter() - .enumerate() - .filter_map(|(index, authority)| { - local_keys.binary_search(&authority) - .ok() - .map(|location| (index as u32, &local_keys[location])) - }) - { - if Self::is_online(authority_index) { - debug::native::info!( - target: "imonline", - "[index: {:?}] Skipping sending heartbeat at block: {:?}. Already online.", - authority_index, - block_number - ); - continue; - } + fn send_single_heartbeat( + authority_index: u32, + key: T::AuthorityId, + session_index: SessionIndex, + block_number: T::BlockNumber + ) -> OffchainResult { + // A helper function to prepare heartbeat call. + let prepare_heartbeat = || -> OffchainResult> { 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, authority_index, }; - let signature = key.sign(&heartbeat_data.encode()).ok_or(OffchainErr::FailedSigning)?; - let call = Call::heartbeat(heartbeat_data, signature); - - debug::info!( - target: "imonline", - "[index: {:?}] Reporting im-online at block: {:?}", - authority_index, - block_number - ); + Ok(Call::heartbeat(heartbeat_data, signature)) + }; - results.push( - T::SubmitTransaction::submit_unsigned(call) - .map_err(|_| OffchainErr::SubmitTransaction) - ); + if Self::is_online(authority_index) { + return Err(OffchainErr::AlreadyOnline(authority_index)); } - // fail only after trying all keys. - results.into_iter().collect::, OffchainErr>>()?; - - // once finished we set the worker status without comparing - // if the existing value changed in the meantime. this is - // because at this point the heartbeat was definitely submitted. - Self::set_worker_status(block_number, true); + // acquire lock for that authority at current heartbeat to make sure we don't + // send concurrent heartbeats. + Self::with_heartbeat_lock( + authority_index, + session_index, + block_number, + || { + let call = prepare_heartbeat()?; + debug::info!( + target: "imonline", + "[index: {:?}] Reporting im-online at block: {:?} (session: {:?}): {:?}", + authority_index, + block_number, + session_index, + call, + ); - Ok(()) - } + T::SubmitTransaction::submit_unsigned(call) + .map_err(|_| OffchainErr::SubmitTransaction)?; - fn compare_and_set_worker_status( - gossipping_at: T::BlockNumber, - done: bool, - curr_worker_status: Option>, - ) -> bool { - let enc = WorkerStatus { - done, - gossipping_at, - }; - sp_io::offchain::local_storage_compare_and_set( - StorageKind::PERSISTENT, - DB_KEY, - curr_worker_status, - &enc.encode() + Ok(()) + }, ) } - fn set_worker_status( - gossipping_at: T::BlockNumber, - done: bool, - ) { - let enc = WorkerStatus { - done, - gossipping_at, - }; - sp_io::offchain::local_storage_set(StorageKind::PERSISTENT, DB_KEY, &enc.encode()); + fn local_authority_keys() -> impl Iterator { + // we run only when a local authority key is configured + let authorities = Keys::::get(); + let mut local_keys = T::AuthorityId::all(); + local_keys.sort(); + + authorities.into_iter() + .enumerate() + .filter_map(move |(index, authority)| { + local_keys.binary_search(&authority) + .ok() + .map(|location| (index as u32, local_keys[location].clone())) + }) } - // Checks if a heartbeat gossip already occurred at this block number. - // Returns a tuple of `(current worker status, bool)`, whereby the bool - // is true if not yet gossipped. - fn check_not_yet_gossipped( + fn with_heartbeat_lock( + authority_index: u32, + session_index: SessionIndex, now: T::BlockNumber, - next_gossip: T::BlockNumber, - ) -> Result<(Option>, bool), OffchainErr> { - 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[..]) - .map_err(|_| OffchainErr::DecodeWorkerStatus)?; - - let was_aborted = !worker_status.done && worker_status.gossipping_at < now; + f: impl FnOnce() -> OffchainResult, + ) -> OffchainResult { + let key = { + let mut key = DB_PREFIX.to_vec(); + key.extend(authority_index.encode()); + key + }; + let storage = StorageValueRef::persistent(&key); + let res = storage.mutate(|status: Option>>| { + // Check if there is already a lock for that particular block. + // This means that the heartbeat has already been sent, and we are just waiting + // for it to be included. However if it doesn't get included for INCLUDE_THRESHOLD + // we will re-send it. + match status { + // we are still waiting for inclusion. + Some(Some(status)) if status.is_recent(session_index, now) => { + Err(OffchainErr::WaitingForInclusion(status.sent_at)) + }, + // attempt to set new status + _ => Ok(HeartbeatStatus { + session_index, + sent_at: now, + }), + } + })?; - // another off-chain worker is currently in the process of submitting - let already_submitting = - !worker_status.done && worker_status.gossipping_at == now; + let mut new_status = res.map_err(|_| OffchainErr::FailedToAcquireLock)?; - let not_yet_gossipped = - worker_status.done && worker_status.gossipping_at < next_gossip; + // we got the lock, let's try to send the heartbeat. + let res = f(); - let ret = (was_aborted && !already_submitting) || not_yet_gossipped; - Ok((Some(last), ret)) - }, - None => Ok((None, true)), + // clear the lock in case we have failed to send transaction. + if res.is_err() { + new_status.sent_at = 0.into(); + storage.set(&new_status); } + + res } fn initialize_keys(keys: &[T::AuthorityId]) { @@ -544,10 +574,10 @@ impl pallet_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. + // the heartbeat is defered a bit to prevent spaming. let block_number = >::block_number(); let half_session = T::SessionDuration::get() / 2.into(); - >::put(block_number + half_session); + >::put(block_number + half_session); // Remember who the authorities are for the new session. Keys::::put(validators.map(|x| x.1).collect::>()); diff --git a/frame/im-online/src/tests.rs b/frame/im-online/src/tests.rs index 34eac233ae..adc126094b 100644 --- a/frame/im-online/src/tests.rs +++ b/frame/im-online/src/tests.rs @@ -210,7 +210,11 @@ fn should_generate_heartbeats() { // when UintAuthorityId::set_all_keys(vec![0, 1, 2]); - ImOnline::offchain(2); + ImOnline::send_heartbeats(2) + .unwrap() + // make sure to consume the iterator and check there are no errors. + .collect::, _>>().unwrap(); + // then let transaction = state.write().transactions.pop().unwrap(); @@ -315,7 +319,12 @@ fn should_not_send_a_report_if_already_online() { // when UintAuthorityId::set_all_keys(vec![0]); // all authorities use pallet_session key 0 - ImOnline::offchain(4); + // we expect error, since the authority is already online. + let mut res = ImOnline::send_heartbeats(4).unwrap(); + assert_eq!(res.next().unwrap().unwrap(), ()); + assert_eq!(res.next().unwrap().unwrap_err(), OffchainErr::AlreadyOnline(1)); + assert_eq!(res.next().unwrap().unwrap_err(), OffchainErr::AlreadyOnline(2)); + assert_eq!(res.next(), None); // then let transaction = pool_state.write().transactions.pop().unwrap(); diff --git a/primitives/runtime/src/offchain/mod.rs b/primitives/runtime/src/offchain/mod.rs index 742388f9ec..dfc15360c6 100644 --- a/primitives/runtime/src/offchain/mod.rs +++ b/primitives/runtime/src/offchain/mod.rs @@ -17,3 +17,4 @@ //! A collection of higher lever helpers for offchain calls. pub mod http; +pub mod storage; diff --git a/primitives/runtime/src/offchain/storage.rs b/primitives/runtime/src/offchain/storage.rs new file mode 100644 index 0000000000..d5c2b47298 --- /dev/null +++ b/primitives/runtime/src/offchain/storage.rs @@ -0,0 +1,156 @@ +// Copyright 2020 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 set of storage helpers for offchain workers. + +use sp_core::offchain::StorageKind; + +/// A storage value with a static key. +pub type StorageValue = StorageValueRef<'static>; + +/// An abstraction over local storage value. +pub struct StorageValueRef<'a> { + key: &'a [u8], + kind: StorageKind, +} + +impl<'a> StorageValueRef<'a> { + /// Create a new reference to a value in the persistent local storage. + pub fn persistent(key: &'a [u8]) -> Self { + Self { key, kind: StorageKind::PERSISTENT } + } + + /// Create a new reference to a value in the fork-aware local storage. + pub fn local(key: &'a [u8]) -> Self { + Self { key, kind: StorageKind::LOCAL } + } + + /// Set the value of the storage to encoding of given parameter. + /// + /// Note that the storage may be accessed by workers running concurrently, + /// if you happen to write a `get-check-set` pattern you should most likely + /// be using `mutate` instead. + pub fn set(&self, value: &impl codec::Encode) { + value.using_encoded(|val| { + sp_io::offchain::local_storage_set(self.kind, self.key, val) + }) + } + + /// Retrieve & decode the value from storage. + /// + /// Note that if you want to do some checks based on the value + /// and write changes after that you should rather be using `mutate`. + /// + /// The function returns `None` if the value was not found in storage, + /// otherwise a decoding of the value to requested type. + pub fn get(&self) -> Option> { + sp_io::offchain::local_storage_get(self.kind, self.key) + .map(|val| T::decode(&mut &*val).ok()) + } + + /// Retrieve & decode the value and set it to a new one atomicaly. + /// + /// Function `f` should return a new value that we should attempt to write to storage. + /// This function returns: + /// 1. `Ok(Ok(T))` in case the value has been succesfuly set. + /// 2. `Ok(Err(T))` in case the value was returned, but it couldn't have been set. + /// 3. `Err(_)` in case `f` returns an error. + pub fn mutate(&self, f: F) -> Result, E> where + T: codec::Codec, + F: FnOnce(Option>) -> Result + { + let value = sp_io::offchain::local_storage_get(self.kind, self.key); + let decoded = value.as_deref().map(|mut v| T::decode(&mut v).ok()); + let val = f(decoded)?; + let set = val.using_encoded(|new_val| { + sp_io::offchain::local_storage_compare_and_set( + self.kind, + self.key, + value, + new_val, + ) + }); + + if set { + Ok(Ok(val)) + } else { + Ok(Err(val)) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use sp_io::TestExternalities; + use sp_core::offchain::{ + OffchainExt, + OffchainStorage, + testing, + }; + + #[test] + fn should_set_and_get() { + let (offchain, state) = testing::TestOffchainExt::new(); + let mut t = TestExternalities::default(); + t.register_extension(OffchainExt::new(offchain)); + + t.execute_with(|| { + let val = StorageValue::persistent(b"testval"); + + assert_eq!(val.get::(), None); + + val.set(&15_u32); + + assert_eq!(val.get::(), Some(Some(15_u32))); + assert_eq!(val.get::>(), Some(None)); + assert_eq!( + state.read().persistent_storage.get(b"", b"testval"), + Some(vec![15_u8, 0, 0, 0]) + ); + }) + } + + #[test] + fn should_mutate() { + let (offchain, state) = testing::TestOffchainExt::new(); + let mut t = TestExternalities::default(); + t.register_extension(OffchainExt::new(offchain)); + + t.execute_with(|| { + let val = StorageValue::persistent(b"testval"); + + let result = val.mutate::(|val| { + assert_eq!(val, None); + + Ok(16_u32) + }); + assert_eq!(result, Ok(Ok(16_u32))); + assert_eq!(val.get::(), Some(Some(16_u32))); + assert_eq!( + state.read().persistent_storage.get(b"", b"testval"), + Some(vec![16_u8, 0, 0, 0]) + ); + + // mutate again, but this time early-exit. + let res = val.mutate::(|val| { + assert_eq!(val, Some(Some(16_u32))); + Err(()) + }); + assert_eq!(res, Err(())); + }) + } +} -- GitLab From e65957e5efceea82d88f8b4e1248171eb3c2167e Mon Sep 17 00:00:00 2001 From: Benjamin Kampmann Date: Fri, 31 Jan 2020 20:01:32 +0100 Subject: [PATCH 063/180] Adding Serde Deserialisation to UncheckExtrinsics (#4793) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adding Serde:Deserialise to UncheckExtrinsics to be able to use the ChainApi RPC from the client side * Update primitives/runtime/src/generic/unchecked_extrinsic.rs Co-authored-by: Bastian Köcher --- .../runtime/src/generic/unchecked_extrinsic.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/primitives/runtime/src/generic/unchecked_extrinsic.rs b/primitives/runtime/src/generic/unchecked_extrinsic.rs index 96e7988103..1625d42e93 100644 --- a/primitives/runtime/src/generic/unchecked_extrinsic.rs +++ b/primitives/runtime/src/generic/unchecked_extrinsic.rs @@ -274,6 +274,19 @@ impl s } } +#[cfg(feature = "std")] +impl<'a, Address: Decode, Signature: Decode, Call: Decode, Extra: SignedExtension> serde::Deserialize<'a> + for UncheckedExtrinsic +{ + fn deserialize(de: D) -> Result where + D: serde::Deserializer<'a>, + { + let r = sp_core::bytes::deserialize(de)?; + Decode::decode(&mut &r[..]) + .map_err(|e| serde::de::Error::custom(format!("Decode error: {}", e))) + } +} + impl fmt::Debug for UncheckedExtrinsic where -- GitLab From 85b65a38330e732689c5d8d5cfe75ba53b9dc873 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Fri, 31 Jan 2020 19:12:03 +0000 Subject: [PATCH 064/180] client/finality-grandpa: Add regression test for observer polling network (was #4778) (#4795) * client/finality-grandpa: Add regression test observer polling network Ensure `Future` implementation of `ObserverWork` is polling its `NetworkBridge`. Regression test for bug introduced in d4fbb897c and fixed in 7d58ceeb4. When polled, `NetworkBridge` forwards reputation change requests from the `GossipValidator` to the underlying `dyn Network`. This test triggers a reputation change by calling `GossipValidator::validate` with an invalid gossip message. After polling the `ObserverWork` which should poll the `NetworkBridge`, the reputation change should be forwarded to the test network. * Nits Co-authored-by: Max Inden --- Cargo.lock | 1 + client/finality-grandpa/Cargo.toml | 1 + .../finality-grandpa/src/communication/mod.rs | 2 +- .../src/communication/tests.rs | 21 +++-- client/finality-grandpa/src/observer.rs | 76 +++++++++++++++++++ 5 files changed, 94 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d5f71b9b30..df45454de0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5572,6 +5572,7 @@ dependencies = [ name = "sc-finality-grandpa" version = "0.8.0" dependencies = [ + "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "finality-grandpa 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "fork-tree 2.0.0", diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index e1fe3f0361..68efa2e644 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -12,6 +12,7 @@ futures-timer = "2.0.2" log = "0.4.8" parking_lot = "0.9.0" rand = "0.7.2" +assert_matches = "1.3.0" parity-scale-codec = { version = "1.0.0", features = ["derive"] } sp-arithmetic = { version = "2.0.0", path = "../../primitives/arithmetic" } sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } diff --git a/client/finality-grandpa/src/communication/mod.rs b/client/finality-grandpa/src/communication/mod.rs index 42f26aa77e..227ecaa370 100644 --- a/client/finality-grandpa/src/communication/mod.rs +++ b/client/finality-grandpa/src/communication/mod.rs @@ -62,7 +62,7 @@ pub mod gossip; mod periodic; #[cfg(test)] -mod tests; +pub(crate) mod tests; pub use sp_finality_grandpa::GRANDPA_ENGINE_ID; diff --git a/client/finality-grandpa/src/communication/tests.rs b/client/finality-grandpa/src/communication/tests.rs index a5435bdfdc..e10d24a16a 100644 --- a/client/finality-grandpa/src/communication/tests.rs +++ b/client/finality-grandpa/src/communication/tests.rs @@ -31,7 +31,8 @@ use sp_finality_grandpa::{AuthorityList, GRANDPA_ENGINE_ID}; use super::gossip::{self, GossipValidator}; use super::{AuthorityId, VoterSet, Round, SetId}; -enum Event { +#[derive(Debug)] +pub(crate) enum Event { EventStream(mpsc::UnboundedSender), WriteNotification(sc_network::PeerId, Vec), Report(sc_network::PeerId, sc_network::ReputationChange), @@ -39,7 +40,7 @@ enum Event { } #[derive(Clone)] -struct TestNetwork { +pub(crate) struct TestNetwork { sender: mpsc::UnboundedSender, } @@ -101,10 +102,10 @@ impl sc_network_gossip::ValidatorContext for TestNetwork { fn send_topic(&mut self, _: &sc_network::PeerId, _: Hash, _: bool) { } } -struct Tester { - net_handle: super::NetworkBridge, +pub(crate) struct Tester { + pub(crate) net_handle: super::NetworkBridge, gossip_validator: Arc>, - events: mpsc::UnboundedReceiver, + pub(crate) events: mpsc::UnboundedReceiver, } impl Tester { @@ -122,6 +123,14 @@ impl Tester { } }) } + + pub(crate) fn trigger_gossip_validator_reputation_change(&self, p: &PeerId) { + self.gossip_validator.validate( + &mut crate::communication::tests::NoopContext, + p, + &vec![1, 2, 3], + ); + } } // some random config (not really needed) @@ -156,7 +165,7 @@ fn voter_set_state() -> SharedVoterSetState { } // needs to run in a tokio runtime. -fn make_test_network(executor: &impl futures::task::Spawn) -> ( +pub(crate) fn make_test_network(executor: &impl futures::task::Spawn) -> ( impl Future, TestNetwork, ) { diff --git a/client/finality-grandpa/src/observer.rs b/client/finality-grandpa/src/observer.rs index ef85bede1c..7e6d1e7793 100644 --- a/client/finality-grandpa/src/observer.rs +++ b/client/finality-grandpa/src/observer.rs @@ -370,3 +370,79 @@ where Future::poll(Pin::new(&mut self.network), cx) } } + +#[cfg(test)] +mod tests { + use super::*; + + use assert_matches::assert_matches; + use crate::{aux_schema, communication::tests::{Event, make_test_network}}; + use substrate_test_runtime_client::{TestClientBuilder, TestClientBuilderExt}; + use sc_network::PeerId; + + use futures::executor::{self, ThreadPool}; + + /// Ensure `Future` implementation of `ObserverWork` is polling its `NetworkBridge`. Regression + /// test for bug introduced in d4fbb897c and fixed in b7af8b339. + /// + /// When polled, `NetworkBridge` forwards reputation change requests from the `GossipValidator` + /// to the underlying `dyn Network`. This test triggers a reputation change by calling + /// `GossipValidator::validate` with an invalid gossip message. After polling the `ObserverWork` + /// which should poll the `NetworkBridge`, the reputation change should be forwarded to the test + /// network. + #[test] + fn observer_work_polls_underlying_network_bridge() { + let thread_pool = ThreadPool::new().unwrap(); + + // Create a test network. + let (tester_fut, _network) = make_test_network(&thread_pool); + let mut tester = executor::block_on(tester_fut); + + // Create an observer. + let (client, backend) = { + let builder = TestClientBuilder::with_default_backend(); + let backend = builder.backend(); + let (client, _) = builder.build_with_longest_chain(); + (Arc::new(client), backend) + }; + + let persistent_data = aux_schema::load_persistent( + &*backend, + client.chain_info().genesis_hash, + 0, + || Ok(vec![]), + ).unwrap(); + + let (_tx, voter_command_rx) = mpsc::unbounded(); + let observer = ObserverWork::new( + client, + tester.net_handle.clone(), + persistent_data, + None, + voter_command_rx, + ); + + // Trigger a reputation change through the gossip validator. + let peer_id = PeerId::random(); + tester.trigger_gossip_validator_reputation_change(&peer_id); + + executor::block_on(async move { + // Ignore initial event stream request by gossip engine. + match tester.events.next().now_or_never() { + Some(Some(Event::EventStream(_))) => {}, + _ => panic!("expected event stream request"), + }; + + assert!( + tester.events.next().now_or_never().is_none(), + "expect no further network events", + ); + + // Poll the observer once and have it forward the reputation change from the gossip + // validator to the test network. + assert!(observer.now_or_never().is_none()); + + assert_matches!(tester.events.next().now_or_never(), Some(Some(Event::Report(_, _)))); + }); + } +} -- GitLab From 92e76a7fd0ba4842ea56d4420d7d53e616cfb443 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Sat, 1 Feb 2020 00:27:53 -0800 Subject: [PATCH 065/180] Increase transaction pool default limits (#4792) * increase limits, improve logging * format in kB --- client/basic-authorship/src/basic_authorship.rs | 3 ++- client/cli/src/params.rs | 4 ++-- client/transaction-pool/graph/src/validated_pool.rs | 12 ++++++++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/client/basic-authorship/src/basic_authorship.rs b/client/basic-authorship/src/basic_authorship.rs index fafc63a114..a9e3d28e21 100644 --- a/client/basic-authorship/src/basic_authorship.rs +++ b/client/basic-authorship/src/basic_authorship.rs @@ -251,10 +251,11 @@ impl ProposerInner, let (block, storage_changes, proof) = block_builder.build()?.into_inner(); - info!("Prepared block for proposing at {} [hash: {:?}; parent_hash: {}; extrinsics: [{}]]", + info!("Prepared block for proposing at {} [hash: {:?}; parent_hash: {}; extrinsics ({}): [{}]]", block.header().number(), ::Hash::from(block.header().hash()), block.header().parent_hash(), + block.extrinsics().len(), block.extrinsics() .iter() .map(|xt| format!("{}", BlakeTwo256::hash_of(xt))) diff --git a/client/cli/src/params.rs b/client/cli/src/params.rs index 73d9fa59ba..eddd8578b3 100644 --- a/client/cli/src/params.rs +++ b/client/cli/src/params.rs @@ -300,10 +300,10 @@ pub struct NodeKeyParams { #[derive(Debug, StructOpt, Clone)] pub struct TransactionPoolParams { /// Maximum number of transactions in the transaction pool. - #[structopt(long = "pool-limit", value_name = "COUNT", default_value = "512")] + #[structopt(long = "pool-limit", value_name = "COUNT", default_value = "8192")] pub pool_limit: usize, /// Maximum number of kilobytes of all transactions stored in the pool. - #[structopt(long = "pool-kbytes", value_name = "COUNT", default_value = "10240")] + #[structopt(long = "pool-kbytes", value_name = "COUNT", default_value = "20480")] pub pool_kbytes: usize, } diff --git a/client/transaction-pool/graph/src/validated_pool.rs b/client/transaction-pool/graph/src/validated_pool.rs index 44e51a7a61..c7e60deb4a 100644 --- a/client/transaction-pool/graph/src/validated_pool.rs +++ b/client/transaction-pool/graph/src/validated_pool.rs @@ -150,9 +150,16 @@ impl ValidatedPool { let future_limit = &self.options.future; debug!(target: "txpool", "Pool Status: {:?}", status); - if ready_limit.is_exceeded(status.ready, status.ready_bytes) - || future_limit.is_exceeded(status.future, status.future_bytes) { + || future_limit.is_exceeded(status.future, status.future_bytes) + { + debug!( + target: "txpool", + "Enforcing limits ({}/{}kB ready, {}/{}kB future", + ready_limit.count, ready_limit.total_bytes / 1024, + future_limit.count, future_limit.total_bytes / 1024, + ); + // clean up the pool let removed = { let mut pool = self.pool.write(); @@ -163,6 +170,7 @@ impl ValidatedPool { removed }; // run notifications + debug!(target: "txpool", "Enforcing limits: {} dropped", removed.len()); let mut listener = self.listener.write(); for h in &removed { listener.dropped(h, None); -- GitLab From 1294685848c35114769fb4f766643f1b5bd1b516 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Sat, 1 Feb 2020 03:33:14 -0800 Subject: [PATCH 066/180] update prost-build (#4789) --- Cargo.lock | 86 +-------------------------- client/authority-discovery/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 86 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index df45454de0..b3b2c36611 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1244,11 +1244,6 @@ dependencies = [ "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "fixedbitset" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "fixedbitset" version = "0.2.0" @@ -2988,11 +2983,6 @@ name = "more-asserts" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "multimap" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "multimap" version = "0.8.0" @@ -4392,14 +4382,6 @@ name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "petgraph" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "petgraph" version = "0.5.0" @@ -4549,16 +4531,6 @@ dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "prost" -version = "0.5.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)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "prost" version = "0.6.1" @@ -4568,23 +4540,6 @@ dependencies = [ "prost-derive 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "prost-build" -version = "0.5.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)", - "heck 0.3.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)", - "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "prost-build" version = "0.6.1" @@ -4602,18 +4557,6 @@ dependencies = [ "which 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "prost-derive" -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.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)", -] - [[package]] name = "prost-derive" version = "0.6.1" @@ -4626,15 +4569,6 @@ dependencies = [ "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "prost-types" -version = "0.5.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)", - "prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "prost-types" version = "0.6.1" @@ -5098,7 +5032,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "quickcheck 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sc-client-api 2.0.0", @@ -7165,16 +7099,6 @@ name = "subtle" version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "syn" -version = "0.15.44" -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)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "syn" version = "1.0.14" @@ -8545,7 +8469,6 @@ dependencies = [ "checksum file-per-thread-logger 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8505b75b31ef7285168dd237c4a7db3c1f3e0927e7d314e670bc98e854272fe9" "checksum finality-grandpa 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "52c48f8a628193ba18639b2f727c32132d75f167a4b32f44b252ea8b937f154c" "checksum fixed-hash 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" -"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" "checksum fixedbitset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" "checksum flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" @@ -8696,7 +8619,6 @@ dependencies = [ "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 multimap 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a97fbd5d00e0e37bfb10f433af8f5aaf631e739368dc9fc28286ca81ca4948dc" "checksum multistream-select 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f938ffe420493e77c8b6cbcc3f282283f68fc889c5dcbc8e51668d5f3a01ad94" "checksum names 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef320dab323286b50fb5cdda23f61c796a72a89998ab565ca32525c5c556f2da" @@ -8747,7 +8669,6 @@ dependencies = [ "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" -"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" "checksum petgraph 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29c127eea4a29ec6c85d153c59dc1213f33ec74cead30fe4730aecc88cc1fd92" "checksum pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7804a463a8d9572f13453c516a5faea534a2403d7ced2f0c7e100eeff072772c" "checksum pin-project-internal 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" @@ -8766,13 +8687,9 @@ dependencies = [ "checksum proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" -"checksum prost 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96d14b1c185652833d24aaad41c5832b0be5616a590227c1fbff57c616754b23" "checksum prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212" -"checksum prost-build 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb788126ea840817128183f8f603dce02cb7aea25c2a0b764359d8e20010702e" "checksum prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "02b10678c913ecbd69350e8535c3aef91a8676c0773fc1d7b95cdd196d7f2f26" -"checksum prost-derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e7dc378b94ac374644181a2247cebf59a6ec1c88b49ac77f3a94b86b79d0e11" "checksum prost-derive 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72" -"checksum prost-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1de482a366941c8d56d19b650fac09ca08508f2a696119ee7513ad590c8bac6f" "checksum prost-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1834f67c0697c001304b75be76f67add9c89742eda3a085ad8ee0bb38c3417aa" "checksum pwasm-utils 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f7a12f176deee919f4ba55326ee17491c8b707d0987aed822682c821b660192" "checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" @@ -8871,7 +8788,6 @@ dependencies = [ "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.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.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" "checksum syn-mid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd3937748a7eccff61ba5b90af1a20dbf610858923a9192ea0ecb0cb77db1d0" "checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index 0c267cbcc6..68144625b3 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -7,7 +7,7 @@ build = "build.rs" license = "GPL-3.0" [build-dependencies] -prost-build = "0.5.0" +prost-build = "0.6.1" [dependencies] bytes = "0.4.12" -- GitLab From 298ff5a9d03ebcf8403fe589d3ab5d13f748a373 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Sat, 1 Feb 2020 14:02:10 +0100 Subject: [PATCH 067/180] Remove warning about connecting to non-Substrate nodes (#4797) --- client/network/src/behaviour.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index faaa25c660..c31fd84eff 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -164,9 +164,6 @@ impl, H: ExHashT> NetworkBehaviourEventPr for Behaviour { fn inject_event(&mut self, event: debug_info::DebugInfoEvent) { let debug_info::DebugInfoEvent::Identified { peer_id, mut info } = event; - if !info.protocol_version.contains("substrate") { - warn!(target: "sub-libp2p", "Connected to a non-Substrate node: {:?}", info); - } if info.listen_addrs.len() > 30 { debug!(target: "sub-libp2p", "Node {:?} has reported more than 30 addresses; \ it is identified by {:?} and {:?}", peer_id, info.protocol_version, -- GitLab From 3c80891f4120903b75d75a54c6a040ecf6724865 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Sat, 1 Feb 2020 13:20:16 +0000 Subject: [PATCH 068/180] Refactor the balances module (#4649) * Initially scoping out of the problem * Remove need for exiry in balance locks. * Remove expiry from locks. * Remove supefluous balance test * Amalgamate pieces of balance module * Split out vesting * Fix tests * Fixes for vesting. * Docs. * Weight docs. * Refactor things in terms of set_balances. * Switch out ED to be free + reserved. * Remove on_free_balance_zero and some docs. * Build fixes * Update frame/vesting/src/lib.rs Co-Authored-By: Xiliang Chen * Update frame/vesting/src/lib.rs Co-Authored-By: Xiliang Chen * Migration * Remove superfluous code. * Test fixes * Fix some tests * Fix repatriate reserve * Fixes * Add test for migration * Final cleanups * Fix * Indentation. * Undo unneeded referencing * Bump runtime version * Fixes Co-authored-by: Xiliang Chen --- Cargo.lock | 20 + Cargo.toml | 1 + bin/node-template/runtime/src/lib.rs | 4 - bin/node-template/src/chain_spec.rs | 1 - bin/node/cli/src/chain_spec.rs | 1 - bin/node/executor/tests/basic.rs | 47 +- bin/node/executor/tests/fees.rs | 14 +- bin/node/executor/tests/submit_transaction.rs | 3 +- bin/node/runtime/src/lib.rs | 6 +- bin/node/testing/src/genesis.rs | 1 - frame/balances/Cargo.toml | 4 +- frame/balances/src/lib.rs | 954 +++++++++--------- frame/balances/src/migration.rs | 84 ++ frame/balances/src/mock.rs | 33 +- frame/balances/src/tests.rs | 411 +++----- frame/contracts/src/account_db.rs | 2 +- frame/contracts/src/exec.rs | 2 +- frame/contracts/src/lib.rs | 18 +- frame/contracts/src/tests.rs | 28 +- frame/democracy/Cargo.toml | 2 + frame/democracy/src/lib.rs | 183 +++- frame/elections-phragmen/src/lib.rs | 7 +- frame/elections/src/lib.rs | 3 +- frame/elections/src/mock.rs | 7 +- frame/elections/src/tests.rs | 6 +- frame/example/src/lib.rs | 3 - frame/executive/src/lib.rs | 8 +- frame/generic-asset/src/lib.rs | 37 +- frame/identity/src/lib.rs | 4 - frame/nicks/src/lib.rs | 20 +- frame/recovery/src/mock.rs | 4 - frame/recovery/src/tests.rs | 6 +- frame/scored-pool/src/mock.rs | 4 - frame/scored-pool/src/tests.rs | 14 +- frame/session/src/lib.rs | 8 +- frame/society/src/mock.rs | 4 - frame/staking/src/lib.rs | 8 +- frame/staking/src/mock.rs | 6 +- frame/staking/src/tests.rs | 180 ++-- frame/support/src/lib.rs | 3 +- frame/support/src/traits.rs | 36 +- frame/transaction-payment/src/lib.rs | 18 +- frame/treasury/src/lib.rs | 55 +- frame/utility/src/lib.rs | 4 - frame/vesting/Cargo.toml | 33 + frame/vesting/src/lib.rs | 610 +++++++++++ 46 files changed, 1742 insertions(+), 1165 deletions(-) create mode 100644 frame/balances/src/migration.rs create mode 100644 frame/vesting/Cargo.toml create mode 100644 frame/vesting/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index b3b2c36611..64652d30ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3683,6 +3683,7 @@ 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", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3690,6 +3691,7 @@ dependencies = [ "sp-io 2.0.0", "sp-runtime 2.0.0", "sp-std 2.0.0", + "sp-storage 2.0.0", ] [[package]] @@ -4125,6 +4127,24 @@ dependencies = [ "sp-std 2.0.0", ] +[[package]] +name = "pallet-vesting" +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", + "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pallet-balances 2.0.0", + "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (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-storage 2.0.0", +] + [[package]] name = "parity-bytes" version = "0.1.1" diff --git a/Cargo.toml b/Cargo.toml index 10465042de..0bd6b4c0b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -99,6 +99,7 @@ members = [ "frame/transaction-payment/rpc/runtime-api", "frame/treasury", "frame/utility", + "frame/vesting", "primitives/allocator", "primitives/application-crypto", "primitives/application-crypto/test", diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 1276f20d17..ea4535e26d 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -196,15 +196,12 @@ impl timestamp::Trait for Runtime { parameter_types! { pub const ExistentialDeposit: u128 = 500; - pub const TransferFee: u128 = 0; pub const CreationFee: u128 = 0; } impl balances::Trait for Runtime { /// The type for recording an account's balance. type Balance = Balance; - /// What to do if an account's free balance gets zeroed. - type OnFreeBalanceZero = (); /// What to do if an account is fully reaped from the system. type OnReapAccount = System; /// What to do if a new account is created. @@ -214,7 +211,6 @@ impl balances::Trait for Runtime { type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; type CreationFee = CreationFee; } diff --git a/bin/node-template/src/chain_spec.rs b/bin/node-template/src/chain_spec.rs index 6c6ab492a3..aa50d06b23 100644 --- a/bin/node-template/src/chain_spec.rs +++ b/bin/node-template/src/chain_spec.rs @@ -132,7 +132,6 @@ fn testnet_genesis(initial_authorities: Vec<(AuraId, GrandpaId)>, }), balances: Some(BalancesConfig { balances: endowed_accounts.iter().cloned().map(|k|(k, 1 << 60)).collect(), - vesting: vec![], }), sudo: Some(SudoConfig { key: root_key, diff --git a/bin/node/cli/src/chain_spec.rs b/bin/node/cli/src/chain_spec.rs index b8ff948b01..4ce0c8f49b 100644 --- a/bin/node/cli/src/chain_spec.rs +++ b/bin/node/cli/src/chain_spec.rs @@ -237,7 +237,6 @@ pub fn testnet_genesis( .map(|k| (k, ENDOWMENT)) .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) .collect(), - vesting: vec![], }), pallet_indices: Some(IndicesConfig { ids: endowed_accounts.iter().cloned() diff --git a/bin/node/executor/tests/basic.rs b/bin/node/executor/tests/basic.rs index 817ebbb173..b306852f45 100644 --- a/bin/node/executor/tests/basic.rs +++ b/bin/node/executor/tests/basic.rs @@ -35,8 +35,7 @@ use frame_system::{self, EventRecord, Phase}; use node_runtime::{ Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances, - System, TransactionPayment, Event, - TransferFee, TransactionBaseFee, TransactionByteFee, + System, TransactionPayment, Event, TransactionBaseFee, TransactionByteFee, CreationFee, constants::currency::*, }; use node_primitives::{Balance, Hash}; @@ -62,7 +61,7 @@ fn transfer_fee(extrinsic: &E, fee_multiplier: Fixed64) -> Balance { ::WeightToFee::convert(weight); let base_fee = TransactionBaseFee::get(); - base_fee + fee_multiplier.saturated_multiply_accumulate(length_fee + weight_fee) + TransferFee::get() + base_fee + fee_multiplier.saturated_multiply_accumulate(length_fee + weight_fee) } fn xt() -> UncheckedExtrinsic { @@ -164,8 +163,8 @@ fn block_with_size(time: u64, nonce: u32, size: usize) -> (Vec, Hash) { fn panic_execution_with_foreign_code_gives_error() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, Storage { top: map![ - >::hashed_key_for(alice()) => { - 69_u128.encode() + >::hashed_key_for(alice()) => { + (69u128, 0u128, 0u128, 0u128).encode() }, >::hashed_key().to_vec() => { 69_u128.encode() @@ -203,8 +202,8 @@ fn panic_execution_with_foreign_code_gives_error() { fn bad_extrinsic_with_native_equivalent_code_gives_error() { let mut t = TestExternalities::::new_with_code(COMPACT_CODE, Storage { top: map![ - >::hashed_key_for(alice()) => { - 69_u128.encode() + >::hashed_key_for(alice()) => { + (69u128, 0u128, 0u128, 0u128).encode() }, >::hashed_key().to_vec() => { 69_u128.encode() @@ -242,8 +241,8 @@ fn bad_extrinsic_with_native_equivalent_code_gives_error() { fn successful_execution_with_native_equivalent_code_gives_ok() { let mut t = TestExternalities::::new_with_code(COMPACT_CODE, Storage { top: map![ - >::hashed_key_for(alice()) => { - (111 * DOLLARS).encode() + >::hashed_key_for(alice()) => { + (111 * DOLLARS, 0u128, 0u128, 0u128).encode() }, >::hashed_key().to_vec() => { (111 * DOLLARS).encode() @@ -275,7 +274,8 @@ fn successful_execution_with_native_equivalent_code_gives_ok() { assert!(r.is_ok()); t.execute_with(|| { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt(), fm)); + let fees = transfer_fee(&xt(), fm) + CreationFee::get(); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); } @@ -284,8 +284,8 @@ fn successful_execution_with_native_equivalent_code_gives_ok() { fn successful_execution_with_foreign_code_gives_ok() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, Storage { top: map![ - >::hashed_key_for(alice()) => { - (111 * DOLLARS).encode() + >::hashed_key_for(alice()) => { + (111 * DOLLARS, 0u128, 0u128, 0u128).encode() }, >::hashed_key().to_vec() => { (111 * DOLLARS).encode() @@ -317,7 +317,8 @@ fn successful_execution_with_foreign_code_gives_ok() { assert!(r.is_ok()); t.execute_with(|| { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt(), fm)); + let fees = transfer_fee(&xt(), fm) + CreationFee::get(); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); } @@ -340,7 +341,8 @@ fn full_native_block_import_works() { ).0.unwrap(); t.execute_with(|| { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt(), fm)); + let fees = transfer_fee(&xt(), fm); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees); assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS); alice_last_known_balance = Balances::total_balance(&alice()); let events = vec![ @@ -362,7 +364,7 @@ fn full_native_block_import_works() { alice().into(), bob().into(), 69 * DOLLARS, - 1 * CENTS, + 0, )), topics: vec![], }, @@ -416,7 +418,7 @@ fn full_native_block_import_works() { bob().into(), alice().into(), 5 * DOLLARS, - 1 * CENTS, + 0, ) ), topics: vec![], @@ -440,7 +442,7 @@ fn full_native_block_import_works() { alice().into(), bob().into(), 15 * DOLLARS, - 1 * CENTS, + 0, ) ), topics: vec![], @@ -710,8 +712,8 @@ fn native_big_block_import_fails_on_fallback() { fn panic_execution_gives_error() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, Storage { top: map![ - >::hashed_key_for(alice()) => { - 0_u128.encode() + >::hashed_key_for(alice()) => { + (0_u128, 0_u128, 0_u128, 0_u128).encode() }, >::hashed_key().to_vec() => { 0_u128.encode() @@ -745,8 +747,8 @@ fn panic_execution_gives_error() { fn successful_execution_gives_ok() { let mut t = TestExternalities::::new_with_code(COMPACT_CODE, Storage { top: map![ - >::hashed_key_for(alice()) => { - (111 * DOLLARS).encode() + >::hashed_key_for(alice()) => { + (111 * DOLLARS, 0u128, 0u128, 0u128).encode() }, >::hashed_key().to_vec() => { (111 * DOLLARS).encode() @@ -779,7 +781,8 @@ fn successful_execution_gives_ok() { .expect("Extrinsic did not fail"); t.execute_with(|| { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - 1 * transfer_fee(&xt(), fm)); + let fees = transfer_fee(&xt(), fm) + CreationFee::get(); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); } diff --git a/bin/node/executor/tests/fees.rs b/bin/node/executor/tests/fees.rs index ca34452031..155cefa4cc 100644 --- a/bin/node/executor/tests/fees.rs +++ b/bin/node/executor/tests/fees.rs @@ -30,7 +30,7 @@ use sp_runtime::{ }; use node_runtime::{ CheckedExtrinsic, Call, Runtime, Balances, - TransactionPayment, TransferFee, TransactionBaseFee, TransactionByteFee, + TransactionPayment, TransactionBaseFee, TransactionByteFee, WeightFeeCoefficient, constants::currency::*, }; use node_runtime::impls::LinearWeightToFee; @@ -134,14 +134,14 @@ fn transaction_fee_is_correct_ultimate() { // (this baed on assigning 0.1 CENT to the cheapest tx with `weight = 100`) let mut t = TestExternalities::::new_with_code(COMPACT_CODE, Storage { top: map![ - >::hashed_key_for(alice()) => { - (100 * DOLLARS).encode() + >::hashed_key_for(alice()) => { + (100 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS).encode() }, - >::hashed_key_for(bob()) => { - (10 * DOLLARS).encode() + >::hashed_key_for(bob()) => { + (10 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS).encode() }, >::hashed_key().to_vec() => { - (110 * DOLLARS).encode() + (110 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS).encode() }, >::hashed_key().to_vec() => vec![0u8; 16], >::hashed_key_for(0) => vec![0u8; 32] @@ -193,9 +193,7 @@ fn transaction_fee_is_correct_ultimate() { // we know that weight to fee multiplier is effect-less in block 1. assert_eq!(weight_fee as Balance, MILLICENTS); balance_alice -= weight_fee; - balance_alice -= tip; - balance_alice -= TransferFee::get(); assert_eq!(Balances::total_balance(&alice()), balance_alice); }); diff --git a/bin/node/executor/tests/submit_transaction.rs b/bin/node/executor/tests/submit_transaction.rs index 9e91ffc76b..40c0c6b80f 100644 --- a/bin/node/executor/tests/submit_transaction.rs +++ b/bin/node/executor/tests/submit_transaction.rs @@ -167,7 +167,8 @@ fn submitted_transaction_should_be_valid() { // add balance to the account let author = extrinsic.signature.clone().unwrap().0; let address = Indices::lookup(author).unwrap(); - >::insert(&address, 5_000_000_000_000); + let account = pallet_balances::AccountData { free: 5_000_000_000_000, ..Default::default() }; + >::insert(&address, account); // check validity let res = Executive::validate_transaction(extrinsic); diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index a4a1c90665..0e6a337a8b 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -167,20 +167,17 @@ impl pallet_indices::Trait for Runtime { parameter_types! { pub const ExistentialDeposit: Balance = 1 * DOLLARS; - pub const TransferFee: Balance = 1 * CENTS; pub const CreationFee: Balance = 1 * CENTS; } impl pallet_balances::Trait for Runtime { type Balance = Balance; - type OnFreeBalanceZero = ((Staking, Contracts), Session); - type OnReapAccount = (System, Recovery); + type OnReapAccount = ((((System, Staking), Contracts), Session), Recovery); type OnNewAccount = Indices; type Event = Event; type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; type CreationFee = CreationFee; } @@ -430,7 +427,6 @@ impl pallet_contracts::Trait for Runtime { type RentByteFee = RentByteFee; type RentDepositOffset = RentDepositOffset; type SurchargeReward = SurchargeReward; - type TransferFee = ContractTransferFee; type CreationFee = ContractCreationFee; type TransactionBaseFee = ContractTransactionBaseFee; type TransactionByteFee = ContractTransactionByteFee; diff --git a/bin/node/testing/src/genesis.rs b/bin/node/testing/src/genesis.rs index 183515f272..5949781275 100644 --- a/bin/node/testing/src/genesis.rs +++ b/bin/node/testing/src/genesis.rs @@ -49,7 +49,6 @@ pub fn config(support_changes_trie: bool, code: Option<&[u8]>) -> GenesisConfig (eve(), 101 * DOLLARS), (ferdie(), 100 * DOLLARS), ], - vesting: vec![], }), pallet_session: Some(SessionConfig { keys: vec![ diff --git a/frame/balances/Cargo.toml b/frame/balances/Cargo.toml index f2e24dbae4..871290b182 100644 --- a/frame/balances/Cargo.toml +++ b/frame/balances/Cargo.toml @@ -9,6 +9,7 @@ license = "GPL-3.0" serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } 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" } @@ -24,7 +25,8 @@ std = [ "serde", "codec/std", "sp-std/std", - "frame-support/std", + "sp-io/std", "sp-runtime/std", + "frame-support/std", "frame-system/std", ] diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index 77d28e89e9..65ad226d53 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -38,37 +38,31 @@ //! ### Terminology //! //! - **Existential Deposit:** The minimum balance required to create or keep an account open. This prevents -//! "dust accounts" from filling storage. -//! - **Total Issuance:** The total number of units in existence in a system. -//! - **Reaping an account:** The act of removing an account by resetting its nonce. Happens after its balance is set -//! to zero. -//! - **Free Balance:** The portion of a balance that is not reserved. The free balance is the only -//! balance that matters for most operations. When this balance falls below the existential -//! deposit, most functionality of the account is removed. When both it and the reserved balance -//! are deleted, then the account is said to be dead. -//! -//! No account should ever have a free balance that is strictly between 0 and the existential +//! "dust accounts" from filling storage. When the free plus the reserved balance (i.e. the total balance) +//! fall below this, then the account is said to be dead; and it loses its functionality as well as any +//! prior history and all information on it is removed from the chain's state. +//! No account should ever have a total balance that is strictly between 0 and the existential //! deposit (exclusive). If this ever happens, it indicates either a bug in this module or an //! erroneous raw mutation of storage. //! +//! - **Total Issuance:** The total number of units in existence in a system. +//! +//! - **Reaping an account:** The act of removing an account by resetting its nonce. Happens after its +//! total balance has become zero (or, strictly speaking, less than the Existential Deposit). +//! +//! - **Free Balance:** The portion of a balance that is not reserved. The free balance is the only +//! balance that matters for most operations. +//! //! - **Reserved Balance:** Reserved balance still belongs to the account holder, but is suspended. //! Reserved balance can still be slashed, but only after all the free balance has been slashed. -//! If the reserved balance falls below the existential deposit, it and any related functionality -//! will be deleted. When both it and the free balance are deleted, then the account is said to -//! be dead. -//! -//! No account should ever have a reserved balance that is strictly between 0 and the existential -//! deposit (exclusive). If this ever happens, it indicates either a bug in this module or an -//! erroneous raw mutation of storage. //! //! - **Imbalance:** A condition when some funds were credited or debited without equal and opposite accounting //! (i.e. a difference between total issuance and account balances). Functions that result in an imbalance will //! return an object of the `Imbalance` trait that can be managed within your runtime logic. (If an imbalance is //! simply dropped, it should automatically maintain any book-keeping such as total issuance.) +//! //! - **Lock:** A freeze on a specified amount of an account's free balance until a specified block number. Multiple //! locks always operate over the same funds, so they "overlay" rather than "stack". -//! - **Vesting:** Similar to a lock, this is another, but independent, liquidity restriction that reduces linearly -//! over time. //! //! ### Implementations //! @@ -94,10 +88,6 @@ //! - `transfer` - Transfer some liquid free balance to another account. //! - `set_balance` - Set the balances of a given account. The origin of this call must be root. //! -//! ### Public Functions -//! -//! - `vesting_balance` - Get the amount that is currently being vested and cannot be transferred out of this account. -//! //! ## Usage //! //! The following examples show how to use the Balances module in your custom module. @@ -141,7 +131,6 @@ //! STAKING_ID, //! &ledger.stash, //! ledger.total, -//! T::BlockNumber::max_value(), //! WithdrawReasons::all() //! ); //! // >::insert(controller, ledger); // Commented out as we don't have access to Staking's storage here. @@ -159,44 +148,39 @@ #![cfg_attr(not(feature = "std"), no_std)] +#[cfg(test)] +mod mock; +#[cfg(test)] +mod tests; +mod migration; + use sp_std::prelude::*; -use sp_std::{cmp, result, mem, fmt::Debug}; +use sp_std::{cmp, result, mem, fmt::Debug, ops::BitOr}; use codec::{Codec, Encode, Decode}; use frame_support::{ - StorageValue, Parameter, decl_event, decl_storage, decl_module, decl_error, - traits::{ - UpdateBalanceOutcome, Currency, OnFreeBalanceZero, OnReapAccount, OnUnbalanced, TryDrop, + StorageValue, Parameter, decl_event, decl_storage, decl_module, decl_error, ensure, + weights::SimpleDispatchInfo, traits::{ + UpdateBalanceOutcome, Currency, OnReapAccount, OnUnbalanced, TryDrop, WithdrawReason, WithdrawReasons, LockIdentifier, LockableCurrency, ExistenceRequirement, - Imbalance, SignedImbalance, ReservableCurrency, Get, VestingCurrency, - }, - weights::SimpleDispatchInfo, + Imbalance, SignedImbalance, ReservableCurrency, Get, ExistenceRequirement::KeepAlive + } }; use sp_runtime::{ RuntimeDebug, DispatchResult, DispatchError, traits::{ - Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDeserialize, - Saturating, Bounded, + Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub, + MaybeSerializeDeserialize, Saturating, Bounded, }, }; use frame_system::{self as system, IsDeadAccount, OnNewAccount, ensure_signed, ensure_root}; - -#[cfg(test)] -mod mock; -#[cfg(test)] -mod tests; +use migration::{get_storage_value, put_storage_value, StorageIterator}; pub use self::imbalances::{PositiveImbalance, NegativeImbalance}; pub trait Subtrait: frame_system::Trait { /// The balance of an account. type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + - MaybeSerializeDeserialize + Debug + From; - - /// A function that is invoked when the free-balance has fallen below the existential deposit and - /// has been reduced to zero. - /// - /// Gives a chance to clean up resources associated with the given account. - type OnFreeBalanceZero: OnFreeBalanceZero; + MaybeSerializeDeserialize + Debug; /// A function that is invoked when the free-balance and the reserved-balance has fallen below /// the existential deposit and both have been reduced to zero. @@ -210,23 +194,15 @@ pub trait Subtrait: frame_system::Trait { /// The minimum amount required to keep an account open. type ExistentialDeposit: Get; - /// The fee required to make a transfer. - type TransferFee: Get; - - /// The fee required to create an account. + /// The fee required to create an account. If you're doing significant stuff with `OnNewAccount` + /// then you'll probably want to make this non-zero. type CreationFee: Get; } pub trait Trait: frame_system::Trait { /// The balance of an account. type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + - MaybeSerializeDeserialize + Debug + From; - - /// A function that is invoked when the free-balance has fallen below the existential deposit and - /// has been reduced to zero. - /// - /// Gives a chance to clean up resources associated with the given account. - type OnFreeBalanceZero: OnFreeBalanceZero; + MaybeSerializeDeserialize + Debug; /// A function that is invoked when the free-balance and the reserved-balance has fallen below /// the existential deposit and both have been reduced to zero. @@ -250,20 +226,15 @@ pub trait Trait: frame_system::Trait { /// The minimum amount required to keep an account open. type ExistentialDeposit: Get; - /// The fee required to make a transfer. - type TransferFee: Get; - /// The fee required to create an account. type CreationFee: Get; } impl, I: Instance> Subtrait for T { type Balance = T::Balance; - type OnFreeBalanceZero = T::OnFreeBalanceZero; type OnReapAccount = T::OnReapAccount; type OnNewAccount = T::OnNewAccount; type ExistentialDeposit = T::ExistentialDeposit; - type TransferFee = T::TransferFee; type CreationFee = T::CreationFee; } @@ -306,40 +277,91 @@ decl_error! { } } -/// Struct to encode the vesting schedule of an individual account. -#[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug)] -pub struct VestingSchedule { - /// Locked amount at genesis. - pub locked: Balance, - /// Amount that gets unlocked every block after `starting_block`. - pub per_block: Balance, - /// Starting block for unlocking(vesting). - pub starting_block: BlockNumber, +/// Simplified reasons for withdrawing balance. +#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug)] +pub enum Reasons { + /// Paying system transaction fees. + Fee = 0, + /// Any reason other than paying system transaction fees. + Misc = 1, + /// Any reason at all. + All = 2, } -impl VestingSchedule { - /// Amount locked at block `n`. - pub fn locked_at(&self, n: BlockNumber) -> Balance - where Balance: From - { - // Number of blocks that count toward vesting - // Saturating to 0 when n < starting_block - let vested_block_count = n.saturating_sub(self.starting_block); - // Return amount that is still locked in vesting - if let Some(x) = Balance::from(vested_block_count).checked_mul(&self.per_block) { - self.locked.max(x) - x +impl From for Reasons { + fn from(r: WithdrawReasons) -> Reasons { + if r == WithdrawReasons::from(WithdrawReason::TransactionPayment) { + Reasons::Fee + } else if r.contains(WithdrawReason::TransactionPayment) { + Reasons::All } else { - Zero::zero() + Reasons::Misc } } } +impl BitOr for Reasons { + type Output = Reasons; + fn bitor(self, other: Reasons) -> Reasons { + if self == other { return self } + Reasons::All + } +} + +/// A single lock on a balance. There can be many of these on an account and they "overlap", so the +/// same balance is frozen by multiple locks. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] -pub struct BalanceLock { +pub struct BalanceLock { + /// An identifier for this lock. Only one lock may be in existence for each identifier. pub id: LockIdentifier, + /// The amount which the free balance may not drop below when this lock is in effect. pub amount: Balance, - pub until: BlockNumber, - pub reasons: WithdrawReasons, + /// If true, then the lock remains in effect even for payment of transaction fees. + pub reasons: Reasons, +} + +/// All balance information for an account. +#[derive(Encode, Decode, Clone, PartialEq, Eq, Default, RuntimeDebug)] +pub struct AccountData { + /// Non-reserved part of the balance. There may still be restrictions on this, but it is the + /// total pool what may in principle be transferred, reserved and used for tipping. + /// + /// This is the only balance that matters in terms of most operations on tokens. It + /// alone is used to determine the balance when in the contract execution environment. + pub free: Balance, + /// Balance which is reserved and may not be used at all. + /// + /// This can still get slashed, but gets slashed last of all. + /// + /// This balance is a 'reserve' balance that other subsystems use in order to set aside tokens + /// that are still 'owned' by the account holder, but which are suspendable. + pub reserved: Balance, + /// The amount that `free` may not drop below when withdrawing for *anything except transaction + /// fee payment*. + pub misc_frozen: Balance, + /// The amount that `free` may not drop below when withdrawing specifically for transaction + /// fee payment. + pub fee_frozen: Balance, +} + +impl AccountData { + /// How much this account's balance can be reduced for the given `reasons`. + fn usable(&self, reasons: Reasons) -> Balance { + self.free.saturating_sub(self.frozen(reasons)) + } + /// The amount that this account's free balance may not be reduced beyond for the given + /// `reasons`. + fn frozen(&self, reasons: Reasons) -> Balance { + match reasons { + Reasons::All => self.misc_frozen.max(self.fee_frozen), + Reasons::Misc => self.misc_frozen, + Reasons::Fee => self.fee_frozen, + } + } + /// The total balance in this account including any that is reserved and ignoring any frozen. + fn total(&self) -> Balance { + self.free.saturating_add(self.reserved) + } } decl_storage! { @@ -349,71 +371,25 @@ decl_storage! { config.balances.iter().fold(Zero::zero(), |acc: T::Balance, &(_, n)| acc + n) }): T::Balance; - /// Information regarding the vesting of a given account. - pub Vesting get(fn vesting) build(|config: &GenesisConfig| { - // Generate initial vesting configuration - // * who - Account which we are generating vesting configuration for - // * begin - Block when the account will start to vest - // * length - Number of blocks from `begin` until fully vested - // * liquid - Number of units which can be spent before vesting begins - config.vesting.iter().filter_map(|&(ref who, begin, length, liquid)| { - let length = >::from(length); - - config.balances.iter() - .find(|&&(ref w, _)| w == who) - .map(|&(_, balance)| { - // 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(sp_runtime::traits::One::one()); - - (who.clone(), VestingSchedule { - locked: locked, - per_block: per_block, - starting_block: begin - }) - }) - }).collect::>() - }): - map hasher(blake2_256) T::AccountId - => Option>; - - /// The 'free' balance of a given account. - /// - /// This is the only balance that matters in terms of most operations on tokens. It - /// alone is used to determine the balance when in the contract execution environment. When this - /// balance falls below the value of `ExistentialDeposit`, then the 'current account' is - /// deleted: specifically `FreeBalance`. Further, the `OnFreeBalanceZero` callback - /// is invoked, giving a chance to external modules to clean up data associated with - /// the deleted account. - /// - /// `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()): - map hasher(blake2_256) T::AccountId => T::Balance; - - /// The amount of the balance of a given account that is externally reserved; this can still get - /// slashed, but gets slashed last of all. + /// The balance of an account. /// - /// This balance is a 'reserve' balance that other subsystems use in order to set aside tokens - /// that are still 'owned' by the account holder, but which are suspendable. - /// - /// When this balance falls below the value of `ExistentialDeposit`, then this 'reserve account' - /// is deleted: specifically, `ReservedBalance`. - /// - /// `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 hasher(blake2_256) T::AccountId => T::Balance; + /// NOTE: THIS MAY NEVER BE IN EXISTENCE AND YET HAVE A `total().is_zero()`. If the total + /// is ever zero, then the entry *MUST* be removed. + pub Account get(fn account) + build(|config: &GenesisConfig| config.balances.iter() + .map(|&(ref who, free)| (who.clone(), AccountData { free, .. Default::default() })) + .collect::>() + ): map hasher(blake2_256) T::AccountId => AccountData; /// Any liquidity locks on some account balances. - pub Locks get(fn locks): - map hasher(blake2_256) T::AccountId => Vec>; + /// NOTE: Should only be accessed when setting, changing and freeing a lock. + pub Locks get(fn locks): map hasher(blake2_256) T::AccountId => Vec>; + + /// True if network has been upgraded to this version. + IsUpgraded: bool; } add_extra_genesis { config(balances): Vec<(T::AccountId, T::Balance)>; - config(vesting): Vec<(T::AccountId, T::BlockNumber, T::BlockNumber, T::Balance)>; // ^^ begin, length, amount liquid at genesis build(|config: &GenesisConfig| { for (_, balance) in &config.balances { @@ -433,9 +409,6 @@ decl_module! { /// The minimum amount required to keep an account open. const ExistentialDeposit: T::Balance = T::ExistentialDeposit::get(); - /// The fee required to make a transfer. - const TransferFee: T::Balance = T::TransferFee::get(); - /// The fee required to create an account. const CreationFee: T::Balance = T::CreationFee::get(); @@ -460,8 +433,7 @@ decl_module! { /// - `ensure_can_withdraw` is always called internally but has a bounded complexity. /// - Transferring balances to accounts that did not exist before will cause /// `T::OnNewAccount::on_new_account` to be called. - /// - Removing enough funds from an account will trigger - /// `T::DustRemoval::on_unbalanced` and `T::OnFreeBalanceZero::on_free_balance_zero`. + /// - Removing enough funds from an account will trigger `T::DustRemoval::on_unbalanced`. /// - `transfer_keep_alive` works the same way as `transfer`, but has an additional /// check that the transfer will not kill the origin account. /// @@ -501,26 +473,28 @@ decl_module! { 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 wipeout = new_free + new_reserved < existential_deposit; + let new_free = if wipeout { Zero::zero() } else { new_free }; + let new_reserved = if wipeout { Zero::zero() } else { new_reserved }; - let current_free = >::get(&who); - if new_free > current_free { - mem::drop(PositiveImbalance::::new(new_free - current_free)); - } else if new_free < current_free { - mem::drop(NegativeImbalance::::new(current_free - new_free)); + let old_account = Account::::get(&who); + + if new_free > old_account.free { + mem::drop(PositiveImbalance::::new(new_free - old_account.free)); + } else if new_free < old_account.free { + mem::drop(NegativeImbalance::::new(old_account.free - new_free)); } - Self::set_free_balance(&who, new_free); - let current_reserved = >::get(&who); - if new_reserved > current_reserved { - mem::drop(PositiveImbalance::::new(new_reserved - current_reserved)); - } else if new_reserved < current_reserved { - mem::drop(NegativeImbalance::::new(current_reserved - new_reserved)); + if new_reserved > old_account.reserved { + mem::drop(PositiveImbalance::::new(new_reserved - old_account.reserved)); + } else if new_reserved < old_account.reserved { + mem::drop(NegativeImbalance::::new(old_account.reserved - new_reserved)); } - Self::set_reserved_balance(&who, new_reserved); - Self::deposit_event(RawEvent::BalanceSet(who, new_free, new_reserved)); + let account = AccountData { free: new_free, reserved: new_reserved, ..old_account }; + Self::set_account(&who, &account, &old_account); + + Self::deposit_event(RawEvent::BalanceSet(who, account.free, account.reserved)); } /// Exactly as `transfer`, except the origin must be root and the source account may be @@ -552,52 +526,154 @@ decl_module! { ) { let transactor = ensure_signed(origin)?; let dest = T::Lookup::lookup(dest)?; - >::transfer(&transactor, &dest, value, ExistenceRequirement::KeepAlive)?; + >::transfer(&transactor, &dest, value, KeepAlive)?; } + fn on_initialize() { + if !IsUpgraded::::get() { + IsUpgraded::::put(true); + Self::do_upgrade(); + } + } + } +} + +#[derive(Decode)] +struct OldBalanceLock { + id: LockIdentifier, + amount: Balance, + until: BlockNumber, + reasons: WithdrawReasons, +} + +impl OldBalanceLock { + fn upgraded(self) -> (BalanceLock, BlockNumber) { + (BalanceLock { + id: self.id, + amount: self.amount, + reasons: self.reasons.into(), + }, self.until) } } impl, I: Instance> Module { // PRIVATE MUTABLES - /// Set the reserved balance of an account to some new value. Will enforce `ExistentialDeposit` - /// law, annulling the account as needed. - /// - /// Doesn't do any preparatory work for creating a new account, so should only be used when it - /// is known that the account already exists. - /// - /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that - /// the caller will do this. - fn set_reserved_balance(who: &T::AccountId, balance: T::Balance) -> UpdateBalanceOutcome { - if balance < T::ExistentialDeposit::get() { - >::insert(who, balance); - Self::on_reserved_too_low(who); - UpdateBalanceOutcome::AccountKilled - } else { - >::insert(who, balance); - UpdateBalanceOutcome::Updated + // Upgrade from the pre-#4649 balances/vesting into the new balances. + pub fn do_upgrade() { + // First, migrate from old FreeBalance to new Account. + // We also move all locks across since only accounts with FreeBalance values have locks. + // FreeBalance: map T::AccountId => T::Balance + for (hash, free) in StorageIterator::::new(b"Balances", b"FreeBalance").drain() { + let mut account = AccountData { free, ..Default::default() }; + // Locks: map T::AccountId => Vec + let old_locks = get_storage_value::>>(b"Balances", b"Locks", &hash); + if let Some(locks) = old_locks { + let locks = locks.into_iter() + .map(|i| { + let (result, expiry) = i.upgraded(); + if expiry != T::BlockNumber::max_value() { + // Any `until`s that are not T::BlockNumber::max_value come from + // democracy and need to be migrated over there. + // Democracy: Locks get(locks): map T::AccountId => Option; + put_storage_value(b"Democracy", b"Locks", &hash, expiry); + } + result + }) + .collect::>(); + for l in locks.iter() { + if l.reasons == Reasons::All || l.reasons == Reasons::Misc { + account.misc_frozen = account.misc_frozen.max(l.amount); + } + if l.reasons == Reasons::All || l.reasons == Reasons::Fee { + account.fee_frozen = account.fee_frozen.max(l.amount); + } + } + put_storage_value(b"Balances", b"Locks", &hash, locks); + } + put_storage_value(b"Balances", b"Account", &hash, account); + } + // Second, migrate old ReservedBalance into new Account. + // ReservedBalance: map T::AccountId => T::Balance + for (hash, reserved) in StorageIterator::::new(b"Balances", b"ReservedBalance").drain() { + let mut account = get_storage_value::>(b"Balances", b"Account", &hash).unwrap_or_default(); + account.reserved = reserved; + put_storage_value(b"Balances", b"Account", &hash, account); + } + + // Finally, migrate vesting and ensure locks are in place. We will be lazy and just lock + // for the maximum amount (i.e. at genesis). Users will need to call "vest" to reduce the + // lock to something sensible. + // pub Vesting: map T::AccountId => Option; + for (hash, vesting) in StorageIterator::<(T::Balance, T::Balance, T::BlockNumber)>::new(b"Balances", b"Vesting").drain() { + let mut account = get_storage_value::>(b"Balances", b"Account", &hash).unwrap_or_default(); + let mut locks = get_storage_value::>>(b"Balances", b"Locks", &hash).unwrap_or_default(); + locks.push(BalanceLock { + id: *b"vesting ", + amount: vesting.0.clone(), + reasons: Reasons::Misc, + }); + account.misc_frozen = account.misc_frozen.max(vesting.0.clone()); + put_storage_value(b"Vesting", b"Vesting", &hash, vesting); + put_storage_value(b"Balances", b"Locks", &hash, locks); + put_storage_value(b"Balances", b"Account", &hash, account); } } - /// Set the free balance of an account to some new value. Will enforce `ExistentialDeposit` - /// law, annulling the account as needed. + /// Get the free balance of an account. + pub fn free_balance(who: impl sp_std::borrow::Borrow) -> T::Balance { + Account::::get(who.borrow()).free + } + + /// Get the balance of an account that can be used for transfers, reservations, or any other + /// non-locking, non-transaction-fee activity. Will be at most `free_balance`. + pub fn usable_balance(who: impl sp_std::borrow::Borrow) -> T::Balance { + Account::::get(who.borrow()).usable(Reasons::Misc) + } + + /// Get the balance of an account that can be used for paying transaction fees (not tipping, + /// or any other kind of fees, though). Will be at most `free_balance`. + pub fn usable_balance_for_fees(who: impl sp_std::borrow::Borrow) -> T::Balance { + Account::::get(who.borrow()).usable(Reasons::Fee) + } + + /// Get the reserved balance of an account. + pub fn reserved_balance(who: impl sp_std::borrow::Borrow) -> T::Balance { + Account::::get(who.borrow()).reserved + } + + /// Set both the free and reserved balance of an account to some new value. Will enforce + /// `ExistentialDeposit` law, annulling the account as needed. /// - /// Doesn't do any preparatory work for creating a new account, so should only be used when it - /// is known that the account already exists. + /// Will return `AccountKilled` if either reserved or free are too low. + /// + /// NOTE: This assumes that `account` is the same as `Self::account(who)` except for altered + /// values of `free` and `balance`. + /// + /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used + /// when it is known that the account already exists. /// /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that /// the caller will do this. - fn set_free_balance(who: &T::AccountId, balance: T::Balance) -> UpdateBalanceOutcome { - // Commented out for now - but consider it instructive. - // assert!(!Self::total_balance(who).is_zero()); - // assert!(Self::free_balance(who) > T::ExistentialDeposit::get()); - if balance < T::ExistentialDeposit::get() { - >::insert(who, balance); - Self::on_free_too_low(who); - UpdateBalanceOutcome::AccountKilled + fn set_account( + who: &T::AccountId, + account: &AccountData, + old: &AccountData, + ) -> UpdateBalanceOutcome { + let total = account.free + account.reserved; + if total < T::ExistentialDeposit::get() { + T::DustRemoval::on_unbalanced(NegativeImbalance::new(total)); + if !old.total().is_zero() { + Self::reap_account(who, total); + UpdateBalanceOutcome::AccountKilled + } else { + UpdateBalanceOutcome::StillDead + } } else { - >::insert(who, balance); + if old.total().is_zero() { + Self::about_to_create_account(who, account.free); + } + Account::::insert(who, account); UpdateBalanceOutcome::Updated } } @@ -605,7 +681,7 @@ impl, I: Instance> Module { /// Register a new account (with existential balance). /// /// This just calls appropriate hooks. It doesn't (necessarily) make any state changes. - fn new_account(who: &T::AccountId, balance: T::Balance) { + fn about_to_create_account(who: &T::AccountId, balance: T::Balance) { T::OnNewAccount::on_new_account(&who); Self::deposit_event(RawEvent::NewAccount(who.clone(), balance.clone())); } @@ -614,61 +690,27 @@ impl, I: Instance> Module { /// /// This just removes the nonce and leaves an event. fn reap_account(who: &T::AccountId, dust: T::Balance) { + Locks::::remove(who); + Account::::remove(who); T::OnReapAccount::on_reap_account(who); Self::deposit_event(RawEvent::ReapedAccount(who.clone(), dust)); } - /// Account's free balance has dropped below existential deposit. Kill its - /// free side and the account completely if its reserved size is already dead. - /// - /// Will maintain total issuance. - fn on_free_too_low(who: &T::AccountId) { - let dust = >::take(who); - >::remove(who); - - T::OnFreeBalanceZero::on_free_balance_zero(who); - - let mut reserved_balance = Self::reserved_balance(who); - - if !dust.is_zero() { - 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)); - } - } - - if reserved_balance.is_zero() { - Self::reap_account(who, dust); - } - } - - /// Account's reserved balance has dropped below existential deposit. Kill its - /// reserved side and the account completely if its free size is already dead. - /// - /// Will maintain total issuance. - fn on_reserved_too_low(who: &T::AccountId) { - let dust = >::take(who); - - let mut free_balance = Self::free_balance(who); - - if !dust.is_zero() { - 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)); + /// Update the account entry for `who`, given the locks. + fn update_locks(who: &T::AccountId, locks: &[BalanceLock]) { + Account::::mutate(who, |b| { + b.misc_frozen = Zero::zero(); + b.fee_frozen = Zero::zero(); + for l in locks.iter() { + if l.reasons == Reasons::All || l.reasons == Reasons::Misc { + b.misc_frozen = b.misc_frozen.max(l.amount); + } + if l.reasons == Reasons::All || l.reasons == Reasons::Fee { + b.fee_frozen = b.fee_frozen.max(l.amount); + } } - } - - if free_balance.is_zero() { - Self::reap_account(who, dust); - } + }); + Locks::::insert(who, locks); } } @@ -866,19 +908,16 @@ impl, I: Instance> frame_system::Trait for ElevatedTrait { } impl, I: Instance> Trait for ElevatedTrait { type Balance = T::Balance; - type OnFreeBalanceZero = T::OnFreeBalanceZero; type OnReapAccount = T::OnReapAccount; type OnNewAccount = T::OnNewAccount; type Event = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = T::ExistentialDeposit; - type TransferFee = T::TransferFee; type CreationFee = T::CreationFee; } -impl, I: Instance> Currency for Module -where +impl, I: Instance> Currency for Module where T::Balance: MaybeSerializeDeserialize + Debug { type Balance = T::Balance; @@ -886,11 +925,10 @@ where type NegativeImbalance = NegativeImbalance; fn total_balance(who: &T::AccountId) -> Self::Balance { - Self::free_balance(who) + Self::reserved_balance(who) + Self::account(who).total() } // Check if `value` amount of free balance can be slashed from `who`. - // Is a no-op if value to be slashed is zero. fn can_slash(who: &T::AccountId, value: Self::Balance) -> bool { if value.is_zero() { return true } Self::free_balance(who) >= value @@ -905,7 +943,7 @@ where } fn free_balance(who: &T::AccountId) -> Self::Balance { - >::get(who) + Account::::get(who).free } // Burn funds from the total issuance, returning a positive imbalance for the amount burned. @@ -950,75 +988,60 @@ where new_balance: T::Balance, ) -> DispatchResult { if amount.is_zero() { return Ok(()) } - if reasons.intersects(WithdrawReason::Reserve | WithdrawReason::Transfer) - && Self::vesting_balance(who) > new_balance - { - Err(Error::::VestingBalance)? - } - let locks = Self::locks(who); - if locks.is_empty() { - return Ok(()) - } - - let now = >::block_number(); - if locks.into_iter() - .all(|l| - now >= l.until - || new_balance >= l.amount - || !l.reasons.intersects(reasons) - ) - { - Ok(()) - } else { - Err(Error::::LiquidityRestrictions.into()) - } + let min_balance = Account::::get(who).frozen(reasons.into()); + ensure!(new_balance >= min_balance, Error::::LiquidityRestrictions); + Ok(()) } // Transfer some free balance from `transactor` to `dest`, respecting existence requirements. - // Is a no-op if value to be transferred is zero. + // Is a no-op if value to be transferred is zero or the `transactor` is the same as `dest`. fn transfer( transactor: &T::AccountId, dest: &T::AccountId, value: Self::Balance, existence_requirement: ExistenceRequirement, ) -> DispatchResult { - if value.is_zero() { return Ok(()) } - 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() }; + if value.is_zero() || transactor == dest { return Ok(()) } + + let old_from_account = Self::account(transactor); + let mut from_account = old_from_account.clone(); + let old_to_account = Self::account(dest); + let mut to_account = old_to_account.clone(); + + let would_create = to_account.total().is_zero(); + let fee = if would_create { T::CreationFee::get() } else { Zero::zero() }; let liability = value.checked_add(&fee).ok_or(Error::::Overflow)?; - let new_from_balance = from_balance.checked_sub(&liability).ok_or(Error::::InsufficientBalance)?; - if would_create && value < T::ExistentialDeposit::get() { - Err(Error::::ExistentialDeposit)? - } - Self::ensure_can_withdraw(transactor, value, WithdrawReason::Transfer.into(), new_from_balance)?; + from_account.free = from_account.free.checked_sub(&liability) + .ok_or(Error::::InsufficientBalance)?; // NOTE: total stake being stored in the same type means that this could never overflow // but better to be safe than sorry. - let new_to_balance = to_balance.checked_add(&value).ok_or(Error::::Overflow)?; + to_account.free = to_account.free.checked_add(&value).ok_or(Error::::Overflow)?; - if transactor != dest { - if existence_requirement == ExistenceRequirement::KeepAlive { - if new_from_balance < Self::minimum_balance() { - Err(Error::::KeepAlive)? - } - } + let ed = T::ExistentialDeposit::get(); + ensure!(to_account.free >= ed, Error::::ExistentialDeposit); - Self::set_free_balance(transactor, new_from_balance); - if !>::exists(dest) { - Self::new_account(dest, new_to_balance); - } + Self::ensure_can_withdraw( + transactor, + value, + WithdrawReason::Transfer.into(), + from_account.free, + )?; - // Emit transfer event. - Self::deposit_event(RawEvent::Transfer(transactor.clone(), dest.clone(), value, fee)); + let allow_death = existence_requirement == ExistenceRequirement::AllowDeath; + ensure!(allow_death || from_account.free >= ed, Error::::KeepAlive); - // 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::set_account(transactor, &from_account, &old_from_account); + + // Take action on the set_account call. + // This will emit events that _resulted_ from the transfer. + Self::set_account(dest, &to_account, &old_to_account); + + // Emit transfer event. + Self::deposit_event(RawEvent::Transfer(transactor.clone(), dest.clone(), value, fee)); + + T::TransferPayment::on_unbalanced(NegativeImbalance::new(fee)); Ok(()) } @@ -1033,95 +1056,122 @@ where ) -> result::Result { if value.is_zero() { return Ok(NegativeImbalance::zero()); } - let old_balance = Self::free_balance(who); - if let Some(new_balance) = old_balance.checked_sub(&value) { + let old_account = Self::account(who); + let mut account = old_account.clone(); + if let Some(new_free_account) = account.free.checked_sub(&value) { // if we need to keep the account alive... if liveness == ExistenceRequirement::KeepAlive // ...and it would be dead afterwards... - && new_balance < T::ExistentialDeposit::get() + && new_free_account < T::ExistentialDeposit::get() // ...yet is was alive before - && old_balance >= T::ExistentialDeposit::get() + && account.free >= T::ExistentialDeposit::get() { Err(Error::::KeepAlive)? } - Self::ensure_can_withdraw(who, value, reasons, new_balance)?; - Self::set_free_balance(who, new_balance); + Self::ensure_can_withdraw(who, value, reasons, new_free_account)?; + account.free = new_free_account; + Self::set_account(who, &account, &old_account); Ok(NegativeImbalance::new(value)) } else { Err(Error::::InsufficientBalance)? } } - // Slash an account, returning the negative imbalance created and any left over - // amount that could not be slashed. - // Is a no-op if value to be slashed is zero. + /// Slash a target account `who`, returning the negative imbalance created and any left over + /// amount that could not be slashed. + /// + /// Is a no-op if `value` to be slashed is zero. + /// + /// NOTE: `slash()` prefers free balance, but assumes that reserve balance can be drawn + /// from in extreme circumstances. `can_slash()` should be used prior to `slash()` to avoid having + /// to draw from reserved funds, however we err on the side of punishment if things are inconsistent + /// or `can_slash` wasn't used appropriately. fn slash( who: &T::AccountId, value: Self::Balance ) -> (Self::NegativeImbalance, Self::Balance) { if value.is_zero() { return (NegativeImbalance::zero(), Zero::zero()) } - let free_balance = Self::free_balance(who); - let free_slash = cmp::min(free_balance, value); + let old_account = Self::account(who); + let mut account = old_account.clone(); + + let free_slash = cmp::min(account.free, value); + account.free -= free_slash; - 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 - // from in extreme circumstances. `can_slash()` should be used prior to `slash()` to avoid having - // to draw from reserved funds, however we err on the side of punishment if things are inconsistent - // or `can_slash` wasn't used appropriately. - if !remaining_slash.is_zero() { - let reserved_balance = Self::reserved_balance(who); - let reserved_slash = cmp::min(reserved_balance, remaining_slash); - Self::set_reserved_balance(who, reserved_balance - reserved_slash); + let result = if !remaining_slash.is_zero() { + let reserved_slash = cmp::min(account.reserved, remaining_slash); + account.reserved -= reserved_slash; (NegativeImbalance::new(free_slash + reserved_slash), remaining_slash - reserved_slash) } else { (NegativeImbalance::new(value), Zero::zero()) - } + }; + Self::set_account(who, &account, &old_account); + result } - // Deposit some `value` into the free balance of an existing account. - // Is a no-op if the value to be deposited is zero. + /// Deposit some `value` into the free balance of an existing target account `who`. + /// + /// Is a no-op if the `value` to be deposited is zero. fn deposit_into_existing( who: &T::AccountId, value: Self::Balance ) -> result::Result { if value.is_zero() { return Ok(PositiveImbalance::zero()) } - if Self::total_balance(who).is_zero() { - Err(Error::::DeadAccount)? - } - Self::set_free_balance(who, Self::free_balance(who) + value); + let old_account = Self::account(who); + let mut account = old_account.clone(); + ensure!(!account.total().is_zero(), Error::::DeadAccount); + account.free = account.free.checked_add(&value).ok_or(Error::::Overflow)?; + + Self::set_account(who, &account, &old_account); Ok(PositiveImbalance::new(value)) } - // Deposit some `value` into the free balance of `who`, possibly creating a new account. - // Is a no-op if the value to be deposited is zero. + /// Deposit some `value` into the free balance of `who`, possibly creating a new account. + /// + /// This function is a no-op if: + /// - the `value` to be deposited is zero; or + /// - if the `value` to be deposited is less than the ED and the account does not yet exist; or + /// - `value` is so large it would cause the balance of `who` to overflow. fn deposit_creating( who: &T::AccountId, value: Self::Balance, ) -> Self::PositiveImbalance { if value.is_zero() { return Self::PositiveImbalance::zero() } - let (imbalance, _) = Self::make_free_balance_be(who, Self::free_balance(who) + value); - if let SignedImbalance::Positive(p) = imbalance { - p - } else { - // Impossible, but be defensive. - Self::PositiveImbalance::zero() - } + let old_account = Self::account(who); + let mut account = old_account.clone(); + let ed = T::ExistentialDeposit::get(); + + // bail if not yet created and this operation wouldn't be enough to create it. + if value < ed && account.total().is_zero() { return Self::PositiveImbalance::zero() } + + // defensive only: overflow should never happen, however in case it does, then this + // operation is a no-op. + account.free = match account.free.checked_add(&value) { + Some(f) => f, + None => return Self::PositiveImbalance::zero(), + }; + + Self::set_account(who, &account, &old_account); + + PositiveImbalance::new(value) } - fn make_free_balance_be(who: &T::AccountId, balance: Self::Balance) -> ( + /// Force the new free balance of a target account `who` to some new value `balance`. + fn make_free_balance_be(who: &T::AccountId, value: Self::Balance) -> ( SignedImbalance, UpdateBalanceOutcome ) { - let original = Self::free_balance(who); - if balance < T::ExistentialDeposit::get() && original.is_zero() { + let old_account = Self::account(who); + let mut account = old_account.clone(); + + if value < T::ExistentialDeposit::get() && account.free.is_zero() { // If we're attempting to set an existing account to less than ED, then // bypass the entire operation. It's a no-op if you follow it through, but // since this is an instance where we might account for a negative imbalance - // (in the dust cleaner of set_free_balance) before we account for its actual + // (in the dust cleaner of set_account) before we account for its actual // equal and opposite cause (returned as an Imbalance), then in the // instance that there's no other accounts on the system at all, we might // underflow the issuance and our arithmetic will be off. @@ -1130,42 +1180,31 @@ where UpdateBalanceOutcome::AccountKilled, ) } - let imbalance = if original <= balance { - SignedImbalance::Positive(PositiveImbalance::new(balance - original)) + let imbalance = if account.free <= value { + SignedImbalance::Positive(PositiveImbalance::new(value - account.free)) } else { - SignedImbalance::Negative(NegativeImbalance::new(original - balance)) + SignedImbalance::Negative(NegativeImbalance::new(account.free - value)) }; + account.free = value; + // If the balance is too low, then the account is reaped. - // NOTE: There are two balances for every account: `reserved_balance` and - // `free_balance`. This contract subsystem only cares about the latter: whenever - // the term "balance" is used *here* it should be assumed to mean "free balance" - // in the rest of the module. // Free balance can never be less than ED. If that happens, it gets reduced to zero // and the account information relevant to this subsystem is deleted (i.e. the // account is reaped). - let outcome = if balance < T::ExistentialDeposit::get() { - Self::set_free_balance(who, balance); - UpdateBalanceOutcome::AccountKilled - } else { - if !>::exists(who) { - Self::new_account(&who, balance); - } - Self::set_free_balance(who, balance); - UpdateBalanceOutcome::Updated - }; + let outcome = Self::set_account(who, &account, &old_account); (imbalance, outcome) } } -impl, I: Instance> ReservableCurrency for Module -where +impl, I: Instance> ReservableCurrency for Module where T::Balance: MaybeSerializeDeserialize + Debug { - // Check if `who` can reserve `value` from their free balance. - // Is a no-op if value to be reserved is zero. + /// Check if `who` can reserve `value` from their free balance. + /// + /// Always `true` if value to be reserved is zero. fn can_reserve(who: &T::AccountId, value: Self::Balance) -> bool { if value.is_zero() { return true } - Self::free_balance(who) + Self::account(who).free .checked_sub(&value) .map_or(false, |new_balance| Self::ensure_can_withdraw(who, value, WithdrawReason::Reserve.into(), new_balance).is_ok() @@ -1173,66 +1212,97 @@ where } fn reserved_balance(who: &T::AccountId) -> Self::Balance { - >::get(who) + Self::account(who).reserved } - // Move `value` from the free balance from `who` to their reserved balance. - // Is a no-op if value to be reserved is zero. + /// Move `value` from the free balance from `who` to their reserved balance. + /// + /// Is a no-op if value to be reserved is zero. fn reserve(who: &T::AccountId, value: Self::Balance) -> result::Result<(), DispatchError> { if value.is_zero() { return Ok(()) } - let b = Self::free_balance(who); - if b < value { - Err(Error::::InsufficientBalance)? - } - let new_balance = b - value; - Self::ensure_can_withdraw(who, value, WithdrawReason::Reserve.into(), new_balance)?; - Self::set_reserved_balance(who, Self::reserved_balance(who) + value); - Self::set_free_balance(who, new_balance); + + let old_account = Self::account(who); + let mut account = old_account.clone(); + + account.free = account.free.checked_sub(&value).ok_or(Error::::InsufficientBalance)?; + account.reserved = account.reserved.checked_add(&value).ok_or(Error::::Overflow)?; + Self::ensure_can_withdraw(who, value, WithdrawReason::Reserve.into(), account.free)?; + + Self::set_account(who, &account, &old_account); Ok(()) } - // Unreserve some funds, returning any amount that was unable to be unreserved. - // Is a no-op if the value to be unreserved is zero. + /// Unreserve some funds, returning any amount that was unable to be unreserved. + /// + /// Is a no-op if the value to be unreserved is zero. fn unreserve(who: &T::AccountId, value: Self::Balance) -> Self::Balance { if value.is_zero() { return Zero::zero() } - let b = Self::reserved_balance(who); - let actual = cmp::min(b, value); - Self::set_free_balance(who, Self::free_balance(who) + actual); - Self::set_reserved_balance(who, b - actual); + + let old_account = Self::account(who); + let mut account = old_account.clone(); + + let actual = cmp::min(account.reserved, value); + account.reserved -= actual; + // defensive only: this can never fail since total issuance which is at least free+reserved + // fits into the same datatype. + account.free = account.free.saturating_add(actual); + + Self::set_account(who, &account, &old_account); + value - actual } - // Slash from reserved balance, returning the negative imbalance created, - // and any amount that was unable to be slashed. - // Is a no-op if the value to be slashed is zero. + /// Slash from reserved balance, returning the negative imbalance created, + /// and any amount that was unable to be slashed. + /// + /// Is a no-op if the value to be slashed is zero. fn slash_reserved( who: &T::AccountId, value: Self::Balance ) -> (Self::NegativeImbalance, Self::Balance) { if value.is_zero() { return (NegativeImbalance::zero(), Zero::zero()) } - let b = Self::reserved_balance(who); - let slash = cmp::min(b, value); + + let old_account = Self::account(who); + let mut account = old_account.clone(); + // underflow should never happen, but it if does, there's nothing to be done here. - Self::set_reserved_balance(who, b - slash); - (NegativeImbalance::new(slash), value - slash) + let actual = cmp::min(account.reserved, value); + account.reserved -= actual; + + Self::set_account(who, &account, &old_account); + + (NegativeImbalance::new(actual), value - actual) } - // Move the reserved balance of one account into the free balance of another. - // Is a no-op if the value to be moved is zero. + /// Move the reserved balance of one account into the free balance of another. + /// + /// Is a no-op if the value to be moved is zero. fn repatriate_reserved( slashed: &T::AccountId, beneficiary: &T::AccountId, value: Self::Balance, ) -> result::Result { if value.is_zero() { return Ok (Zero::zero()) } - if Self::total_balance(beneficiary).is_zero() { - Err(Error::::DeadAccount)? + + if slashed == beneficiary { + return Ok(Self::unreserve(slashed, value)); } - let b = Self::reserved_balance(slashed); - let slash = cmp::min(b, value); - Self::set_free_balance(beneficiary, Self::free_balance(beneficiary) + slash); - Self::set_reserved_balance(slashed, b - slash); - Ok(value - slash) + + let old_to_account = Self::account(beneficiary); + let mut to_account = old_to_account.clone(); + ensure!(!to_account.total().is_zero(), Error::::DeadAccount); + + let old_from_account = Self::account(slashed); + let mut from_account = old_from_account.clone(); + let actual = cmp::min(from_account.reserved, value); + + to_account.free = to_account.free.checked_add(&actual).ok_or(Error::::Overflow)?; + from_account.reserved -= actual; + + Self::set_account(slashed, &from_account, &old_from_account); + Self::set_account(beneficiary, &to_account, &old_to_account); + + Ok(value - actual) } } @@ -1243,119 +1313,62 @@ where type Moment = T::BlockNumber; // Set a lock on the balance of `who`. - // Is a no-op if lock amount is zero. + // Is a no-op if lock amount is zero or `reasons` `is_none()`. fn set_lock( id: LockIdentifier, who: &T::AccountId, amount: T::Balance, - until: T::BlockNumber, reasons: WithdrawReasons, ) { - if amount.is_zero() { return } - let now = >::block_number(); - let mut new_lock = Some(BalanceLock { id, amount, until, reasons }); + if amount.is_zero() || reasons.is_none() { return } + let mut new_lock = Some(BalanceLock { id, amount, reasons: reasons.into() }); let mut locks = Self::locks(who).into_iter().filter_map(|l| if l.id == id { new_lock.take() - } else if l.until > now { - Some(l) } else { - None + Some(l) }).collect::>(); if let Some(lock) = new_lock { locks.push(lock) } - >::insert(who, locks); + Self::update_locks(who, &locks[..]); } + // Extend a lock on the balance of `who`. + // Is a no-op if lock amount is zero or `reasons` `is_none()`. fn extend_lock( id: LockIdentifier, who: &T::AccountId, amount: T::Balance, - until: T::BlockNumber, reasons: WithdrawReasons, ) { - let now = >::block_number(); - let mut new_lock = Some(BalanceLock { id, amount, until, reasons }); + if amount.is_zero() || reasons.is_none() { return } + let mut new_lock = Some(BalanceLock { id, amount, reasons: reasons.into() }); let mut locks = Self::locks(who).into_iter().filter_map(|l| if l.id == id { new_lock.take().map(|nl| { BalanceLock { id: l.id, amount: l.amount.max(nl.amount), - until: l.until.max(nl.until), reasons: l.reasons | nl.reasons, } }) - } else if l.until > now { - Some(l) } else { - None + Some(l) }).collect::>(); if let Some(lock) = new_lock { locks.push(lock) } - >::insert(who, locks); + Self::update_locks(who, &locks[..]); } fn remove_lock( id: LockIdentifier, who: &T::AccountId, ) { - let now = >::block_number(); - let locks = Self::locks(who).into_iter().filter_map(|l| - if l.until > now && l.id != id { - Some(l) - } else { - None - }).collect::>(); - >::insert(who, locks); - } -} - -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. - /// Is a no-op if the amount to be vested is zero. - fn add_vesting_schedule( - who: &T::AccountId, - locked: T::Balance, - per_block: T::Balance, - starting_block: T::BlockNumber - ) -> DispatchResult { - if locked.is_zero() { return Ok(()) } - if >::exists(who) { - Err(Error::::ExistingVestingSchedule)? - } - 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); + let mut locks = Self::locks(who); + locks.retain(|l| l.id != id); + Self::update_locks(who, &locks[..]); } } @@ -1364,6 +1377,7 @@ where T::Balance: MaybeSerializeDeserialize + Debug { fn is_dead_account(who: &T::AccountId) -> bool { - Self::total_balance(who).is_zero() + // this should always be exactly equivalent to `Self::account(who).total().is_zero()` + !Account::::exists(who) } } diff --git a/frame/balances/src/migration.rs b/frame/balances/src/migration.rs new file mode 100644 index 0000000000..4748cf3913 --- /dev/null +++ b/frame/balances/src/migration.rs @@ -0,0 +1,84 @@ +// Copyright 2017-2020 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 . + +//! Some utilities for helping access storage with arbitrary key types. + +use sp_std::prelude::*; +use codec::{Encode, Decode}; +use frame_support::{StorageHasher, Twox128}; + +pub struct StorageIterator { + prefix: [u8; 32], + previous_key: Vec, + drain: bool, + _phantom: ::sp_std::marker::PhantomData, +} + +impl StorageIterator { + pub fn new(module: &[u8], item: &[u8]) -> Self { + let mut prefix = [0u8; 32]; + prefix[0..16].copy_from_slice(&Twox128::hash(module)); + prefix[16..32].copy_from_slice(&Twox128::hash(item)); + Self { prefix, previous_key: prefix[..].to_vec(), drain: false, _phantom: Default::default() } + } + pub fn drain(mut self) -> Self { + self.drain = true; + self + } +} + +impl Iterator for StorageIterator { + type Item = (Vec, T); + + fn next(&mut self) -> Option<(Vec, T)> { + loop { + let maybe_next = sp_io::storage::next_key(&self.previous_key) + .filter(|n| n.starts_with(&self.prefix)); + break match maybe_next { + Some(next) => { + self.previous_key = next.clone(); + let maybe_value = frame_support::storage::unhashed::get::(&next); + match maybe_value { + Some(value) => { + if self.drain { + frame_support::storage::unhashed::kill(&next); + } + Some((self.previous_key[32..].to_vec(), value)) + } + None => continue, + } + } + None => None, + } + } + } +} + +pub fn get_storage_value(module: &[u8], item: &[u8], hash: &[u8]) -> Option { + let mut key = vec![0u8; 32 + hash.len()]; + key[0..16].copy_from_slice(&Twox128::hash(module)); + key[16..32].copy_from_slice(&Twox128::hash(item)); + key[32..].copy_from_slice(hash); + frame_support::storage::unhashed::get::(&key) +} + +pub fn put_storage_value(module: &[u8], item: &[u8], hash: &[u8], value: T) { + let mut key = vec![0u8; 32 + hash.len()]; + key[0..16].copy_from_slice(&Twox128::hash(module)); + key[16..32].copy_from_slice(&Twox128::hash(item)); + key[32..].copy_from_slice(hash); + frame_support::storage::unhashed::put(&key, &value); +} diff --git a/frame/balances/src/mock.rs b/frame/balances/src/mock.rs index 5a3d671e8d..5eb722733f 100644 --- a/frame/balances/src/mock.rs +++ b/frame/balances/src/mock.rs @@ -32,7 +32,6 @@ impl_outer_origin!{ thread_local! { pub(crate) static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); - static TRANSFER_FEE: RefCell = RefCell::new(0); static CREATION_FEE: RefCell = RefCell::new(0); } @@ -41,11 +40,6 @@ impl Get for ExistentialDeposit { fn get() -> u64 { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow()) } } -pub struct TransferFee; -impl Get for TransferFee { - fn get() -> u64 { TRANSFER_FEE.with(|v| *v.borrow()) } -} - pub struct CreationFee; impl Get for CreationFee { fn get() -> u64 { CREATION_FEE.with(|v| *v.borrow()) } @@ -92,32 +86,26 @@ impl pallet_transaction_payment::Trait for Test { } impl Trait for Test { type Balance = u64; - type OnFreeBalanceZero = (); type OnReapAccount = System; type OnNewAccount = (); type Event = (); type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; type CreationFee = CreationFee; } pub struct ExtBuilder { existential_deposit: u64, - transfer_fee: u64, creation_fee: u64, monied: bool, - vesting: bool, } impl Default for ExtBuilder { fn default() -> Self { Self { existential_deposit: 0, - transfer_fee: 0, creation_fee: 0, monied: false, - vesting: false, } } } @@ -126,11 +114,6 @@ impl ExtBuilder { self.existential_deposit = existential_deposit; self } - #[allow(dead_code)] - pub fn transfer_fee(mut self, transfer_fee: u64) -> Self { - self.transfer_fee = transfer_fee; - self - } pub fn creation_fee(mut self, creation_fee: u64) -> Self { self.creation_fee = creation_fee; self @@ -142,13 +125,8 @@ impl ExtBuilder { } self } - pub fn vesting(mut self, vesting: bool) -> Self { - self.vesting = vesting; - self - } pub fn set_associated_consts(&self) { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); - TRANSFER_FEE.with(|v| *v.borrow_mut() = self.transfer_fee); CREATION_FEE.with(|v| *v.borrow_mut() = self.creation_fee); } pub fn build(self) -> sp_io::TestExternalities { @@ -166,15 +144,6 @@ impl ExtBuilder { } else { vec![] }, - vesting: if self.vesting && self.monied { - vec![ - (1, 0, 10, 5 * self.existential_deposit), - (2, 10, 20, 0), - (12, 10, 20, 5 * self.existential_deposit) - ] - } else { - vec![] - }, }.assimilate_storage(&mut t).unwrap(); t.into() } @@ -187,5 +156,5 @@ 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 { - DispatchInfo { weight: w, ..Default::default() } + DispatchInfo { weight: w, pays_fee: true, ..Default::default() } } diff --git a/frame/balances/src/tests.rs b/frame/balances/src/tests.rs index 175e87aea4..816768901b 100644 --- a/frame/balances/src/tests.rs +++ b/frame/balances/src/tests.rs @@ -18,7 +18,7 @@ use super::*; use mock::{Balances, ExtBuilder, Test, System, info_from_weight, CALL}; -use sp_runtime::traits::{SignedExtension, BadOrigin}; +use sp_runtime::{Fixed64, traits::{SignedExtension, BadOrigin}}; use frame_support::{ assert_noop, assert_ok, assert_err, traits::{LockableCurrency, LockIdentifier, WithdrawReason, WithdrawReasons, @@ -29,13 +29,12 @@ use frame_system::RawOrigin; const ID_1: LockIdentifier = *b"1 "; const ID_2: LockIdentifier = *b"2 "; -const ID_3: LockIdentifier = *b"3 "; #[test] fn basic_locking_should_work() { ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - assert_eq!(Balances::free_balance(&1), 10); - Balances::set_lock(ID_1, &1, 9, u64::max_value(), WithdrawReasons::all()); + assert_eq!(Balances::free_balance(1), 10); + Balances::set_lock(ID_1, &1, 9, WithdrawReasons::all()); assert_noop!( >::transfer(&1, &2, 5, AllowDeath), Error::::LiquidityRestrictions @@ -46,7 +45,7 @@ fn basic_locking_should_work() { #[test] fn partial_locking_should_work() { ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - Balances::set_lock(ID_1, &1, 5, u64::max_value(), WithdrawReasons::all()); + Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); }); } @@ -54,7 +53,7 @@ fn partial_locking_should_work() { #[test] fn lock_removal_should_work() { ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - Balances::set_lock(ID_1, &1, u64::max_value(), u64::max_value(), WithdrawReasons::all()); + Balances::set_lock(ID_1, &1, u64::max_value(), WithdrawReasons::all()); Balances::remove_lock(ID_1, &1); assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); }); @@ -63,8 +62,8 @@ fn lock_removal_should_work() { #[test] fn lock_replacement_should_work() { ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - Balances::set_lock(ID_1, &1, u64::max_value(), u64::max_value(), WithdrawReasons::all()); - Balances::set_lock(ID_1, &1, 5, u64::max_value(), WithdrawReasons::all()); + Balances::set_lock(ID_1, &1, u64::max_value(), WithdrawReasons::all()); + Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); }); } @@ -72,8 +71,8 @@ fn lock_replacement_should_work() { #[test] fn double_locking_should_work() { ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - Balances::set_lock(ID_1, &1, 5, u64::max_value(), WithdrawReasons::all()); - Balances::set_lock(ID_2, &1, 5, u64::max_value(), WithdrawReasons::all()); + Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); + Balances::set_lock(ID_2, &1, 5, WithdrawReasons::all()); assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); }); } @@ -81,9 +80,8 @@ fn double_locking_should_work() { #[test] fn combination_locking_should_work() { ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - Balances::set_lock(ID_1, &1, u64::max_value(), 0, WithdrawReasons::none()); - Balances::set_lock(ID_2, &1, 0, u64::max_value(), WithdrawReasons::none()); - Balances::set_lock(ID_3, &1, 0, 0, WithdrawReasons::all()); + Balances::set_lock(ID_1, &1, u64::max_value(), WithdrawReasons::none()); + Balances::set_lock(ID_2, &1, 0, WithdrawReasons::all()); assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); }); } @@ -91,17 +89,17 @@ fn combination_locking_should_work() { #[test] fn lock_value_extension_should_work() { ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - Balances::set_lock(ID_1, &1, 5, u64::max_value(), WithdrawReasons::all()); + Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); assert_noop!( >::transfer(&1, &2, 6, AllowDeath), Error::::LiquidityRestrictions ); - Balances::extend_lock(ID_1, &1, 2, u64::max_value(), WithdrawReasons::all()); + Balances::extend_lock(ID_1, &1, 2, WithdrawReasons::all()); assert_noop!( >::transfer(&1, &2, 6, AllowDeath), Error::::LiquidityRestrictions ); - Balances::extend_lock(ID_1, &1, 8, u64::max_value(), WithdrawReasons::all()); + Balances::extend_lock(ID_1, &1, 8, WithdrawReasons::all()); assert_noop!( >::transfer(&1, &2, 3, AllowDeath), Error::::LiquidityRestrictions @@ -116,23 +114,12 @@ fn lock_reasons_should_work() { .monied(true) .build() .execute_with(|| { - Balances::set_lock(ID_1, &1, 10, u64::max_value(), WithdrawReason::Transfer.into()); + pallet_transaction_payment::NextFeeMultiplier::put(Fixed64::from_natural(1)); + Balances::set_lock(ID_1, &1, 10, WithdrawReason::Reserve.into()); assert_noop!( >::transfer(&1, &2, 1, AllowDeath), Error::::LiquidityRestrictions ); - assert_ok!(>::reserve(&1, 1)); - // NOTE: this causes a fee payment. - assert!( as SignedExtension>::pre_dispatch( - ChargeTransactionPayment::from(1), - &1, - CALL, - info_from_weight(1), - 0, - ).is_ok()); - - Balances::set_lock(ID_1, &1, 10, u64::max_value(), WithdrawReason::Reserve.into()); - assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); assert_noop!( >::reserve(&1, 1), Error::::LiquidityRestrictions @@ -142,10 +129,17 @@ fn lock_reasons_should_work() { &1, CALL, info_from_weight(1), - 0, + 1, + ).is_err()); + assert!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(0), + &1, + CALL, + info_from_weight(1), + 1, ).is_ok()); - Balances::set_lock(ID_1, &1, 10, u64::max_value(), WithdrawReason::TransactionPayment.into()); + Balances::set_lock(ID_1, &1, 10, WithdrawReason::TransactionPayment.into()); assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); assert_ok!(>::reserve(&1, 1)); assert!( as SignedExtension>::pre_dispatch( @@ -153,40 +147,33 @@ fn lock_reasons_should_work() { &1, CALL, info_from_weight(1), - 0, + 1, + ).is_err()); + assert!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(0), + &1, + CALL, + info_from_weight(1), + 1, ).is_err()); }); } -#[test] -fn lock_block_number_should_work() { - ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - Balances::set_lock(ID_1, &1, 10, 2, WithdrawReasons::all()); - assert_noop!( - >::transfer(&1, &2, 1, AllowDeath), - Error::::LiquidityRestrictions - ); - - System::set_block_number(2); - assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); - }); -} - #[test] fn lock_block_number_extension_should_work() { ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - Balances::set_lock(ID_1, &1, 10, 2, WithdrawReasons::all()); + Balances::set_lock(ID_1, &1, 10, WithdrawReasons::all()); assert_noop!( >::transfer(&1, &2, 6, AllowDeath), Error::::LiquidityRestrictions ); - Balances::extend_lock(ID_1, &1, 10, 1, WithdrawReasons::all()); + Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); assert_noop!( >::transfer(&1, &2, 6, AllowDeath), Error::::LiquidityRestrictions ); System::set_block_number(2); - Balances::extend_lock(ID_1, &1, 10, 8, WithdrawReasons::all()); + Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); assert_noop!( >::transfer(&1, &2, 3, AllowDeath), Error::::LiquidityRestrictions @@ -197,17 +184,17 @@ fn lock_block_number_extension_should_work() { #[test] fn lock_reasons_extension_should_work() { ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - Balances::set_lock(ID_1, &1, 10, 10, WithdrawReason::Transfer.into()); + Balances::set_lock(ID_1, &1, 10, WithdrawReason::Transfer.into()); assert_noop!( >::transfer(&1, &2, 6, AllowDeath), Error::::LiquidityRestrictions ); - Balances::extend_lock(ID_1, &1, 10, 10, WithdrawReasons::none()); + Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::none()); assert_noop!( >::transfer(&1, &2, 6, AllowDeath), Error::::LiquidityRestrictions ); - Balances::extend_lock(ID_1, &1, 10, 10, WithdrawReason::Reserve.into()); + Balances::extend_lock(ID_1, &1, 10, WithdrawReason::Reserve.into()); assert_noop!( >::transfer(&1, &2, 6, AllowDeath), Error::::LiquidityRestrictions @@ -230,7 +217,7 @@ fn default_indexing_on_new_accounts_should_not_work2() { Error::::ExistentialDeposit, ); assert_eq!(Balances::is_dead_account(&5), true); // account 5 should not exist - assert_eq!(Balances::free_balance(&1), 100); + assert_eq!(Balances::free_balance(1), 100); }); } @@ -247,7 +234,7 @@ fn reserved_balance_should_prevent_reclaim_count() { assert_eq!(Balances::total_balance(&2), 256 * 20); 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::free_balance(2), 255); // "free" account deleted." 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); @@ -322,11 +309,11 @@ fn dust_account_removal_should_work2() { fn balance_works() { ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 42); - assert_eq!(Balances::free_balance(&1), 42); - assert_eq!(Balances::reserved_balance(&1), 0); + assert_eq!(Balances::free_balance(1), 42); + assert_eq!(Balances::reserved_balance(1), 0); assert_eq!(Balances::total_balance(&1), 42); - assert_eq!(Balances::free_balance(&2), 0); - assert_eq!(Balances::reserved_balance(&2), 0); + assert_eq!(Balances::free_balance(2), 0); + assert_eq!(Balances::reserved_balance(2), 0); assert_eq!(Balances::total_balance(&2), 0); }); } @@ -361,14 +348,14 @@ fn reserving_balance_should_work() { let _ = Balances::deposit_creating(&1, 111); assert_eq!(Balances::total_balance(&1), 111); - assert_eq!(Balances::free_balance(&1), 111); - assert_eq!(Balances::reserved_balance(&1), 0); + assert_eq!(Balances::free_balance(1), 111); + assert_eq!(Balances::reserved_balance(1), 0); assert_ok!(Balances::reserve(&1, 69)); assert_eq!(Balances::total_balance(&1), 111); - assert_eq!(Balances::free_balance(&1), 42); - assert_eq!(Balances::reserved_balance(&1), 69); + assert_eq!(Balances::free_balance(1), 42); + assert_eq!(Balances::reserved_balance(1), 69); }); } @@ -389,7 +376,7 @@ fn deducting_balance_should_work() { ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 69)); - assert_eq!(Balances::free_balance(&1), 42); + assert_eq!(Balances::free_balance(1), 42); }); } @@ -397,10 +384,11 @@ fn deducting_balance_should_work() { fn refunding_balance_should_work() { ExtBuilder::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 42); - Balances::set_reserved_balance(&1, 69); + let account = Balances::account(&1); + Balances::set_account(&1, &AccountData { reserved: 69, ..account }, &account); Balances::unreserve(&1, 69); - assert_eq!(Balances::free_balance(&1), 111); - assert_eq!(Balances::reserved_balance(&1), 0); + assert_eq!(Balances::free_balance(1), 111); + assert_eq!(Balances::reserved_balance(1), 0); }); } @@ -410,8 +398,8 @@ fn slashing_balance_should_work() { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 69)); assert!(Balances::slash(&1, 69).1.is_zero()); - assert_eq!(Balances::free_balance(&1), 0); - assert_eq!(Balances::reserved_balance(&1), 42); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(1), 42); assert_eq!(>::get(), 42); }); } @@ -422,8 +410,8 @@ fn slashing_incomplete_balance_should_work() { let _ = Balances::deposit_creating(&1, 42); assert_ok!(Balances::reserve(&1, 21)); assert_eq!(Balances::slash(&1, 69).1, 27); - assert_eq!(Balances::free_balance(&1), 0); - assert_eq!(Balances::reserved_balance(&1), 0); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(1), 0); assert_eq!(>::get(), 0); }); } @@ -434,8 +422,8 @@ fn unreserving_balance_should_work() { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 111)); Balances::unreserve(&1, 42); - assert_eq!(Balances::reserved_balance(&1), 69); - assert_eq!(Balances::free_balance(&1), 42); + assert_eq!(Balances::reserved_balance(1), 69); + assert_eq!(Balances::free_balance(1), 42); }); } @@ -445,8 +433,8 @@ fn slashing_reserved_balance_should_work() { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 111)); assert_eq!(Balances::slash_reserved(&1, 42).1, 0); - assert_eq!(Balances::reserved_balance(&1), 69); - assert_eq!(Balances::free_balance(&1), 0); + assert_eq!(Balances::reserved_balance(1), 69); + assert_eq!(Balances::free_balance(1), 0); assert_eq!(>::get(), 69); }); } @@ -457,8 +445,8 @@ fn slashing_incomplete_reserved_balance_should_work() { let _ = Balances::deposit_creating(&1, 111); assert_ok!(Balances::reserve(&1, 42)); assert_eq!(Balances::slash_reserved(&1, 69).1, 27); - assert_eq!(Balances::free_balance(&1), 69); - assert_eq!(Balances::reserved_balance(&1), 0); + assert_eq!(Balances::free_balance(1), 69); + assert_eq!(Balances::reserved_balance(1), 0); assert_eq!(>::get(), 69); }); } @@ -470,10 +458,10 @@ fn transferring_reserved_balance_should_work() { let _ = Balances::deposit_creating(&2, 1); assert_ok!(Balances::reserve(&1, 110)); assert_ok!(Balances::repatriate_reserved(&1, &2, 41), 0); - assert_eq!(Balances::reserved_balance(&1), 69); - assert_eq!(Balances::free_balance(&1), 0); - assert_eq!(Balances::reserved_balance(&2), 0); - assert_eq!(Balances::free_balance(&2), 42); + assert_eq!(Balances::reserved_balance(1), 69); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(2), 0); + assert_eq!(Balances::free_balance(2), 42); }); } @@ -493,26 +481,26 @@ fn transferring_incomplete_reserved_balance_should_work() { let _ = Balances::deposit_creating(&2, 1); assert_ok!(Balances::reserve(&1, 41)); assert_ok!(Balances::repatriate_reserved(&1, &2, 69), 28); - assert_eq!(Balances::reserved_balance(&1), 0); - assert_eq!(Balances::free_balance(&1), 69); - assert_eq!(Balances::reserved_balance(&2), 0); - assert_eq!(Balances::free_balance(&2), 42); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(Balances::free_balance(1), 69); + assert_eq!(Balances::reserved_balance(2), 0); + assert_eq!(Balances::free_balance(2), 42); }); } #[test] fn transferring_too_high_value_should_not_panic() { ExtBuilder::default().build().execute_with(|| { - >::insert(1, u64::max_value()); - >::insert(2, 1); + Account::::insert(1, AccountData { free: u64::max_value(), .. Default::default() }); + Account::::insert(2, AccountData { free: 1, .. Default::default() }); assert_err!( Balances::transfer(Some(1).into(), 2, u64::max_value()), Error::::Overflow, ); - assert_eq!(Balances::free_balance(&1), u64::max_value()); - assert_eq!(Balances::free_balance(&2), 1); + assert_eq!(Balances::free_balance(1), u64::max_value()); + assert_eq!(Balances::free_balance(2), 1); }); } @@ -524,7 +512,7 @@ fn account_create_on_free_too_low_with_other() { // No-op. let _ = Balances::deposit_creating(&2, 50); - assert_eq!(Balances::free_balance(&2), 0); + assert_eq!(Balances::free_balance(2), 0); assert_eq!(>::get(), 100); }) } @@ -535,7 +523,7 @@ fn account_create_on_free_too_low() { ExtBuilder::default().existential_deposit(100).build().execute_with(|| { // No-op. let _ = Balances::deposit_creating(&2, 50); - assert_eq!(Balances::free_balance(&2), 0); + assert_eq!(Balances::free_balance(2), 0); assert_eq!(>::get(), 0); }) } @@ -549,8 +537,8 @@ fn account_removal_on_free_too_low() { let _ = Balances::deposit_creating(&1, 110); let _ = Balances::deposit_creating(&2, 110); - assert_eq!(Balances::free_balance(&1), 110); - assert_eq!(Balances::free_balance(&2), 110); + assert_eq!(Balances::free_balance(1), 110); + assert_eq!(Balances::free_balance(2), 110); assert_eq!(>::get(), 220); // Transfer funds from account 1 of such amount that after this transfer @@ -559,8 +547,8 @@ fn account_removal_on_free_too_low() { assert_ok!(Balances::transfer(Some(1).into(), 2, 20)); // Verify free balance removal of account 1. - assert_eq!(Balances::free_balance(&1), 0); - assert_eq!(Balances::free_balance(&2), 130); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::free_balance(2), 130); // Verify that TotalIssuance tracks balance removal when free balance is too low. assert_eq!(>::get(), 130); @@ -580,160 +568,6 @@ fn transfer_overflow_isnt_exploitable() { }); } -#[test] -fn check_vesting_status() { - ExtBuilder::default() - .existential_deposit(256) - .monied(true) - .vesting(true) - .build() - .execute_with(|| { - assert_eq!(System::block_number(), 1); - let user1_free_balance = Balances::free_balance(&1); - let user2_free_balance = Balances::free_balance(&2); - let user12_free_balance = Balances::free_balance(&12); - assert_eq!(user1_free_balance, 256 * 10); // Account 1 has free balance - assert_eq!(user2_free_balance, 256 * 20); // Account 2 has free balance - assert_eq!(user12_free_balance, 256 * 10); // Account 12 has free balance - let user1_vesting_schedule = VestingSchedule { - locked: 256 * 5, - per_block: 128, // Vesting over 10 blocks - starting_block: 0, - }; - let user2_vesting_schedule = VestingSchedule { - locked: 256 * 20, - per_block: 256, // Vesting over 20 blocks - starting_block: 10, - }; - let user12_vesting_schedule = VestingSchedule { - locked: 256 * 5, - per_block: 64, // Vesting over 20 blocks - starting_block: 10, - }; - assert_eq!(Balances::vesting(&1), Some(user1_vesting_schedule)); // Account 1 has a vesting schedule - assert_eq!(Balances::vesting(&2), Some(user2_vesting_schedule)); // Account 2 has a vesting schedule - assert_eq!(Balances::vesting(&12), Some(user12_vesting_schedule)); // Account 12 has a vesting schedule - - // Account 1 has only 128 units vested from their illiquid 256 * 5 units at block 1 - assert_eq!(Balances::vesting_balance(&1), 128 * 9); - // Account 2 has their full balance locked - assert_eq!(Balances::vesting_balance(&2), user2_free_balance); - // Account 12 has only their illiquid funds locked - assert_eq!(Balances::vesting_balance(&12), user12_free_balance - 256 * 5); - - System::set_block_number(10); - assert_eq!(System::block_number(), 10); - - // Account 1 has fully vested by block 10 - assert_eq!(Balances::vesting_balance(&1), 0); - // Account 2 has started vesting by block 10 - assert_eq!(Balances::vesting_balance(&2), user2_free_balance); - // Account 12 has started vesting by block 10 - assert_eq!(Balances::vesting_balance(&12), user12_free_balance - 256 * 5); - - System::set_block_number(30); - assert_eq!(System::block_number(), 30); - - assert_eq!(Balances::vesting_balance(&1), 0); // Account 1 is still fully vested, and not negative - assert_eq!(Balances::vesting_balance(&2), 0); // Account 2 has fully vested by block 30 - assert_eq!(Balances::vesting_balance(&12), 0); // Account 2 has fully vested by block 30 - - }); -} - -#[test] -fn unvested_balance_should_not_transfer() { - ExtBuilder::default() - .existential_deposit(10) - .monied(true) - .vesting(true) - .build() - .execute_with(|| { - assert_eq!(System::block_number(), 1); - let user1_free_balance = Balances::free_balance(&1); - assert_eq!(user1_free_balance, 100); // Account 1 has free balance - // Account 1 has only 5 units vested at block 1 (plus 50 unvested) - assert_eq!(Balances::vesting_balance(&1), 45); - assert_noop!( - Balances::transfer(Some(1).into(), 2, 56), - Error::::VestingBalance, - ); // Account 1 cannot send more than vested amount - }); -} - -#[test] -fn vested_balance_should_transfer() { - ExtBuilder::default() - .existential_deposit(10) - .monied(true) - .vesting(true) - .build() - .execute_with(|| { - assert_eq!(System::block_number(), 1); - let user1_free_balance = Balances::free_balance(&1); - assert_eq!(user1_free_balance, 100); // Account 1 has free balance - // Account 1 has only 5 units vested at block 1 (plus 50 unvested) - assert_eq!(Balances::vesting_balance(&1), 45); - assert_ok!(Balances::transfer(Some(1).into(), 2, 55)); - }); -} - -#[test] -fn extra_balance_should_transfer() { - ExtBuilder::default() - .existential_deposit(10) - .monied(true) - .vesting(true) - .build() - .execute_with(|| { - assert_eq!(System::block_number(), 1); - assert_ok!(Balances::transfer(Some(3).into(), 1, 100)); - assert_ok!(Balances::transfer(Some(3).into(), 2, 100)); - - let user1_free_balance = Balances::free_balance(&1); - assert_eq!(user1_free_balance, 200); // Account 1 has 100 more free balance than normal - - let user2_free_balance = Balances::free_balance(&2); - assert_eq!(user2_free_balance, 300); // Account 2 has 100 more free balance than normal - - // Account 1 has only 5 units vested at block 1 (plus 150 unvested) - assert_eq!(Balances::vesting_balance(&1), 45); - assert_ok!(Balances::transfer(Some(1).into(), 3, 155)); // Account 1 can send extra units gained - - // Account 2 has no units vested at block 1, but gained 100 - assert_eq!(Balances::vesting_balance(&2), 200); - assert_ok!(Balances::transfer(Some(2).into(), 3, 100)); // Account 2 can send extra units gained - }); -} - -#[test] -fn liquid_funds_should_transfer_with_delayed_vesting() { - ExtBuilder::default() - .existential_deposit(256) - .monied(true) - .vesting(true) - .build() - .execute_with(|| { - assert_eq!(System::block_number(), 1); - let user12_free_balance = Balances::free_balance(&12); - - assert_eq!(user12_free_balance, 2560); // Account 12 has free balance - // Account 12 has liquid funds - assert_eq!(Balances::vesting_balance(&12), user12_free_balance - 256 * 5); - - // Account 12 has delayed vesting - let user12_vesting_schedule = VestingSchedule { - locked: 256 * 5, - per_block: 64, // Vesting over 20 blocks - starting_block: 10, - }; - assert_eq!(Balances::vesting(&12), Some(user12_vesting_schedule)); - - // Account 12 can still send liquid funds - assert_ok!(Balances::transfer(Some(12).into(), 3, 256 * 5)); - }); -} - #[test] fn burn_must_work() { ExtBuilder::default().monied(true).build().execute_with(|| { @@ -766,45 +600,58 @@ fn cannot_set_genesis_value_below_ed() { 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); + .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, 0)); + // Check balance + assert_eq!(Balances::free_balance(1), 100); + assert_eq!(Balances::reserved_balance(1), 0); + + // Reserve some free balance + assert_ok!(Balances::reserve(&1, 50)); + // Check balance, the account should be ok. + assert_eq!(Balances::free_balance(1), 50); + assert_eq!(Balances::reserved_balance(1), 50); + + // Reserve the rest of the free balance + assert_ok!(Balances::reserve(&1, 50)); + // Check balance, the account should be ok. + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(1), 100); + + // Unreserve everything + Balances::unreserve(&1, 100); + // Check balance, all 100 should move to free_balance + assert_eq!(Balances::free_balance(1), 100); + assert_eq!(Balances::reserved_balance(1), 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); - }); +#[test] +fn account_deleted_when_just_dust() { + 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, 50, 50)); + // Check balance + assert_eq!(Balances::free_balance(1), 50); + assert_eq!(Balances::reserved_balance(1), 50); + + // Reserve some free balance + let _ = Balances::slash(&1, 1); + // The account should be dead. + assert!(Balances::is_dead_account(&1)); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(1), 0); + }); } diff --git a/frame/contracts/src/account_db.rs b/frame/contracts/src/account_db.rs index 3615673f2d..814983c586 100644 --- a/frame/contracts/src/account_db.rs +++ b/frame/contracts/src/account_db.rs @@ -149,7 +149,7 @@ impl AccountDb for DirectAccountDb { let (imbalance, outcome) = T::Currency::make_free_balance_be(&address, balance); total_imbalance = total_imbalance.merge(imbalance); if let UpdateBalanceOutcome::AccountKilled = outcome { - // Account killed. This will ultimately lead to calling `OnFreeBalanceZero` callback + // Account killed. This will ultimately lead to calling `OnReapAccount` callback // which will make removal of CodeHashOf and AccountStorage for this account. // In order to avoid writing over the deleted properties we `continue` here. continue; diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index cfbefa2a72..d0033e0bd1 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -573,7 +573,7 @@ impl Token for TransferFeeToken> { let balance_fee = match self.kind { TransferFeeKind::ContractInstantiate => metadata.contract_account_instantiate_fee, TransferFeeKind::AccountCreate => metadata.account_create_fee, - TransferFeeKind::Transfer => metadata.transfer_fee, + TransferFeeKind::Transfer => return metadata.schedule.transfer_cost, }; approx_gas_for_balance(self.gas_price, balance_fee) } diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index ff4a729b2c..bd1e91f1a9 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -125,7 +125,7 @@ use frame_support::{ parameter_types, IsSubType, weights::DispatchInfo, }; -use frame_support::traits::{OnFreeBalanceZero, OnUnbalanced, Currency, Get, Time, Randomness}; +use frame_support::traits::{OnReapAccount, 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; use pallet_contracts_primitives::{RentProjection, ContractAccessError}; @@ -401,9 +401,6 @@ pub trait Trait: frame_system::Trait { /// to removal of a contract. type SurchargeReward: Get>; - /// The fee required to make a transfer. - type TransferFee: Get>; - /// The fee required to create an account. type CreationFee: Get>; @@ -520,9 +517,6 @@ decl_module! { /// to removal of a contract. const SurchargeReward: BalanceOf = T::SurchargeReward::get(); - /// The fee required to make a transfer. - const TransferFee: BalanceOf = T::TransferFee::get(); - /// The fee required to create an account. const CreationFee: BalanceOf = T::CreationFee::get(); @@ -953,8 +947,8 @@ decl_storage! { } } -impl OnFreeBalanceZero for Module { - fn on_free_balance_zero(who: &T::AccountId) { +impl OnReapAccount for Module { + fn on_reap_account(who: &T::AccountId) { if let Some(ContractInfo::Alive(info)) = >::take(who) { child::kill_storage(&info.trie_id, info.child_trie_unique_id()); } @@ -973,7 +967,6 @@ pub struct Config { pub max_value_size: u32, pub contract_account_instantiate_fee: BalanceOf, pub account_create_fee: BalanceOf, - pub transfer_fee: BalanceOf, } impl Config { @@ -986,7 +979,6 @@ impl Config { max_value_size: T::MaxValueSize::get(), contract_account_instantiate_fee: T::ContractFee::get(), account_create_fee: T::CreationFee::get(), - transfer_fee: T::TransferFee::get(), } } } @@ -1031,6 +1023,9 @@ pub struct Schedule { /// Gas cost per one byte written to the sandbox memory. pub sandbox_data_write_cost: Gas, + /// Cost for a simple balance transfer. + pub transfer_cost: Gas, + /// The maximum number of topics supported by an event. pub max_event_topics: u32, @@ -1069,6 +1064,7 @@ impl Default for Schedule { instantiate_base_cost: 175, sandbox_data_read_cost: 1, sandbox_data_write_cost: 1, + transfer_cost: 100, max_event_topics: 4, max_stack_height: 64 * 1024, max_memory_pages: 16, diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 9a2ef36bb8..5eb7bce48a 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -121,14 +121,12 @@ impl frame_system::Trait for Test { } impl pallet_balances::Trait for Test { type Balance = u64; - type OnFreeBalanceZero = Contract; - type OnReapAccount = System; + type OnReapAccount = (System, Contract); type OnNewAccount = (); type Event = MetaEvent; type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; type CreationFee = CreationFee; } parameter_types! { @@ -171,7 +169,6 @@ impl Trait for Test { type RentByteFee = RentByteFee; type RentDepositOffset = RentDepositOffset; type SurchargeReward = SurchargeReward; - type TransferFee = TransferFee; type CreationFee = CreationFee; type TransactionBaseFee = TransactionBaseFee; type TransactionByteFee = TransactionByteFee; @@ -278,7 +275,6 @@ impl ExtBuilder { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![], - vesting: vec![], }.assimilate_storage(&mut t).unwrap(); GenesisConfig:: { current_schedule: Schedule { @@ -311,7 +307,7 @@ fn refunds_unused_gas() { assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, Vec::new())); // 2 * 135 - gas price multiplied by the call base fee. - assert_eq!(Balances::free_balance(&ALICE), 100_000_000 - (2 * 135)); + assert_eq!(Balances::free_balance(ALICE), 100_000_000 - (2 * 135)); }); } @@ -1018,7 +1014,7 @@ fn removals(trigger_call: impl Fn() -> bool) { // Trigger rent must have no effect assert!(trigger_call()); assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); - assert_eq!(Balances::free_balance(&BOB), 100); + assert_eq!(Balances::free_balance(BOB), 100); // Advance blocks initialize_block(10); @@ -1026,7 +1022,7 @@ fn removals(trigger_call: impl Fn() -> bool) { // Trigger rent through call assert!(trigger_call()); assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - assert_eq!(Balances::free_balance(&BOB), subsistence_threshold); + assert_eq!(Balances::free_balance(BOB), subsistence_threshold); // Advance blocks initialize_block(20); @@ -1034,7 +1030,7 @@ fn removals(trigger_call: impl Fn() -> bool) { // Trigger rent must have no effect assert!(trigger_call()); assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - assert_eq!(Balances::free_balance(&BOB), subsistence_threshold); + assert_eq!(Balances::free_balance(BOB), subsistence_threshold); }); // Allowance exceeded @@ -1052,7 +1048,7 @@ fn removals(trigger_call: impl Fn() -> bool) { // Trigger rent must have no effect assert!(trigger_call()); assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 100); - assert_eq!(Balances::free_balance(&BOB), 1_000); + assert_eq!(Balances::free_balance(BOB), 1_000); // Advance blocks initialize_block(10); @@ -1061,7 +1057,7 @@ fn removals(trigger_call: impl Fn() -> bool) { assert!(trigger_call()); assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); // Balance should be initial balance - initial rent_allowance - assert_eq!(Balances::free_balance(&BOB), 900); + assert_eq!(Balances::free_balance(BOB), 900); // Advance blocks initialize_block(20); @@ -1069,7 +1065,7 @@ fn removals(trigger_call: impl Fn() -> bool) { // Trigger rent must have no effect assert!(trigger_call()); assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - assert_eq!(Balances::free_balance(&BOB), 900); + assert_eq!(Balances::free_balance(BOB), 900); }); // Balance reached and inferior to subsistence threshold @@ -1087,12 +1083,12 @@ fn removals(trigger_call: impl Fn() -> bool) { // Trigger rent must have no effect assert!(trigger_call()); assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); - assert_eq!(Balances::free_balance(&BOB), 50 + Balances::minimum_balance()); + assert_eq!(Balances::free_balance(BOB), 50 + Balances::minimum_balance()); // Transfer funds assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::transfer())); assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); - assert_eq!(Balances::free_balance(&BOB), Balances::minimum_balance()); + assert_eq!(Balances::free_balance(BOB), Balances::minimum_balance()); // Advance blocks initialize_block(10); @@ -1100,7 +1096,7 @@ fn removals(trigger_call: impl Fn() -> bool) { // Trigger rent through call assert!(trigger_call()); assert!(ContractInfoOf::::get(BOB).is_none()); - assert_eq!(Balances::free_balance(&BOB), Balances::minimum_balance()); + assert_eq!(Balances::free_balance(BOB), Balances::minimum_balance()); // Advance blocks initialize_block(20); @@ -1108,7 +1104,7 @@ fn removals(trigger_call: impl Fn() -> bool) { // Trigger rent must have no effect assert!(trigger_call()); assert!(ContractInfoOf::::get(BOB).is_none()); - assert_eq!(Balances::free_balance(&BOB), Balances::minimum_balance()); + assert_eq!(Balances::free_balance(BOB), Balances::minimum_balance()); }); } diff --git a/frame/democracy/Cargo.toml b/frame/democracy/Cargo.toml index 12d5dfc158..2428d2c154 100644 --- a/frame/democracy/Cargo.toml +++ b/frame/democracy/Cargo.toml @@ -17,6 +17,8 @@ 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" } +sp-storage = { version = "2.0.0", path = "../../primitives/storage" } +hex-literal = "0.2.1" [features] default = ["std"] diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index 682ce59f25..da0cccb1d0 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -30,7 +30,7 @@ use frame_support::{ weights::SimpleDispatchInfo, traits::{ Currency, ReservableCurrency, LockableCurrency, WithdrawReason, LockIdentifier, Get, - OnFreeBalanceZero, OnUnbalanced + OnReapAccount, OnUnbalanced } }; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -305,6 +305,10 @@ decl_storage! { pub Delegations get(fn delegations): linked_map hasher(blake2_256) T::AccountId => (T::AccountId, Conviction); + /// Accounts for which there are locks in action which may be removed at some point in the + /// future. The value is the block number at which the lock expires and may be removed. + pub Locks get(locks): map hasher(blake2_256) T::AccountId => Option; + /// True if the last referendum tabled was submitted externally. False if it was a public /// proposal. pub LastTabledWasExternal: bool; @@ -364,6 +368,8 @@ decl_event! { PreimageMissing(Hash, ReferendumIndex), /// A registered preimage was removed and the deposit collected by the reaper (last item). PreimageReaped(Hash, AccountId, Balance, AccountId), + /// An account has been unlocked successfully. + Unlocked(AccountId), } } @@ -413,6 +419,10 @@ decl_error! { PreimageInvalid, /// No proposals waiting NoneWaiting, + /// The target account does not have a lock. + NotLocked, + /// The lock on the account to be unlocked has not yet expired. + NotExpired, } } @@ -701,9 +711,9 @@ decl_module! { DEMOCRACY_ID, &who, Bounded::max_value(), - T::BlockNumber::max_value(), WithdrawReason::Transfer.into() ); + Locks::::remove(&who); Self::deposit_event(RawEvent::Delegated(who, to)); } @@ -720,12 +730,12 @@ decl_module! { // Indefinite lock is reduced to the maximum voting lock that could be possible. let now = >::block_number(); let locked_until = now + T::EnactmentPeriod::get() * conviction.lock_periods().into(); + Locks::::insert(&who, locked_until); T::Currency::set_lock( DEMOCRACY_ID, &who, Bounded::max_value(), - locked_until, - WithdrawReason::Transfer.into() + WithdrawReason::Transfer.into(), ); Self::deposit_event(RawEvent::Undelegated(who)); } @@ -796,6 +806,18 @@ decl_module! { >::remove(&proposal_hash); Self::deposit_event(RawEvent::PreimageReaped(proposal_hash, old, deposit, who)); } + + #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + fn unlock(origin, target: T::AccountId) { + ensure_signed(origin)?; + + let expiry = Locks::::get(&target).ok_or(Error::::NotLocked)?; + ensure!(expiry <= system::Module::::block_number(), Error::::NotExpired); + + T::Currency::remove_lock(DEMOCRACY_ID, &target); + Locks::::remove(&target); + Self::deposit_event(RawEvent::Unlocked(target)); + } } } @@ -1081,14 +1103,15 @@ impl Module { // now plus: the base lock period multiplied by the number of periods this voter // offered to lock should they win... let locked_until = now + T::EnactmentPeriod::get() * conviction.lock_periods().into(); + Locks::::insert(&a, locked_until); // ...extend their bondage until at least then. T::Currency::extend_lock( DEMOCRACY_ID, &a, Bounded::max_value(), - locked_until, WithdrawReason::Transfer.into() ); + } Self::clear_referendum(index); @@ -1139,8 +1162,8 @@ impl Module { } } -impl OnFreeBalanceZero for Module { - fn on_free_balance_zero(who: &T::AccountId) { +impl OnReapAccount for Module { + fn on_reap_account(who: &T::AccountId) { >::remove(who) } } @@ -1155,11 +1178,12 @@ mod tests { }; use sp_core::H256; use sp_runtime::{ - traits::{BlakeTwo256, IdentityLookup, Bounded, BadOrigin}, + traits::{BlakeTwo256, IdentityLookup, Bounded, BadOrigin, OnInitialize}, testing::Header, Perbill, }; use pallet_balances::{BalanceLock, Error as BalancesError}; use frame_system::EnsureSignedBy; + use sp_storage::Storage; const AYE: Vote = Vote{ aye: true, conviction: Conviction::None }; const NAY: Vote = Vote{ aye: false, conviction: Conviction::None }; @@ -1206,19 +1230,16 @@ mod tests { } 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 OnReapAccount = System; type OnNewAccount = (); type Event = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; type CreationFee = CreationFee; } parameter_types! { @@ -1273,7 +1294,6 @@ mod tests { 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(); sp_io::TestExternalities::new(t) @@ -1283,11 +1303,60 @@ mod tests { type Balances = pallet_balances::Module; type Democracy = Module; + #[test] + fn lock_info_via_migration_should_work() { + let mut s = Storage::default(); + use hex_literal::hex; + // A dump of data from the previous version for which we know account 1 has 5 of its 10 + // reserved and 3 of the rest is locked for misc. Account 2 has all 20 locked until block 5 + // for everything and additionally 3 locked for just fees. + let data = vec![ + (hex!["26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac"].to_vec(), hex!["0100000000000000"].to_vec()), + (hex!["26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850"].to_vec(), hex!["02000000"].to_vec()), + (hex!["26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7"].to_vec(), hex!["08000000000000000000000000"].to_vec()), + (hex!["26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc"].to_vec(), hex!["4545454545454545454545454545454545454545454545454545454545454545"].to_vec()), + (hex!["26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c11874681e47a19e6b29b0a65b9591762ce5143ed30d0261e5d24a3201752506b20f15c"].to_vec(), hex!["4545454545454545454545454545454545454545454545454545454545454545"].to_vec()), + (hex!["3a636f6465"].to_vec(), hex![""].to_vec()), + (hex!["3a65787472696e7369635f696e646578"].to_vec(), hex!["00000000"].to_vec()), + (hex!["3a686561707061676573"].to_vec(), hex!["0800000000000000"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc61dbd7d0b561a41d23c2a469ad42fbd70d5438bae826f6fd607413190c37c363b"].to_vec(), hex!["046d697363202020200300000000000000ffffffffffffffff04"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc66cddb367afbd583bb48f9bbd7d5ba3b1d0738b4881b1cddd38169526d8158137"].to_vec(), hex!["0474786665657320200300000000000000ffffffffffffffff01"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6e88b43fded6323ef02ffeffbd8c40846ee09bf316271bd22369659c959dd733a"].to_vec(), hex!["08616c6c20202020200300000000000000ffffffffffffffff1f64656d6f63726163ffffffffffffffff030000000000000002"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f3c22813def93ef32c365b55cb92f10f91dbd7d0b561a41d23c2a469ad42fbd70d5438bae826f6fd607413190c37c363b"].to_vec(), hex!["0500000000000000"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80"].to_vec(), hex!["d200000000000000"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243b8788bb218b185b63e3e92653953f29b6b143fb8cf5159fc908632e6fe490501"].to_vec(), hex!["1e0000000000000006000000000000000200000000000000"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b41dbd7d0b561a41d23c2a469ad42fbd70d5438bae826f6fd607413190c37c363b"].to_vec(), hex!["0500000000000000"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b46cddb367afbd583bb48f9bbd7d5ba3b1d0738b4881b1cddd38169526d8158137"].to_vec(), hex!["1e00000000000000"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4b8788bb218b185b63e3e92653953f29b6b143fb8cf5159fc908632e6fe490501"].to_vec(), hex!["3c00000000000000"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e88b43fded6323ef02ffeffbd8c40846ee09bf316271bd22369659c959dd733a"].to_vec(), hex!["1400000000000000"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e96760d274653a39b429a87ebaae9d3aa4fdf58b9096cf0bebc7c4e5a4c2ed8d"].to_vec(), hex!["2800000000000000"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4effb728943197fd12e694cbf3f3ede28fbf7498b0370c6dfa0013874b417c178"].to_vec(), hex!["3200000000000000"].to_vec()), + (hex!["f2794c22e353e9a839f12faab03a911b7f17cdfbfa73331856cca0acddd7842e"].to_vec(), hex!["00000000"].to_vec()), + (hex!["f2794c22e353e9a839f12faab03a911bbdcb0c5143a8617ed38ae3810dd45bc6"].to_vec(), hex!["00000000"].to_vec()), + (hex!["f2794c22e353e9a839f12faab03a911be2f6cb0456905c189bcb0458f9440f13"].to_vec(), hex!["00000000"].to_vec()), + ]; + s.top = data.into_iter().collect(); + sp_io::TestExternalities::new(s).execute_with(|| { + Balances::on_initialize(1); + assert_eq!(Balances::free_balance(1), 5); + assert_eq!(Balances::reserved_balance(1), 5); + assert_eq!(Balances::usable_balance(&1), 2); + assert_eq!(Balances::usable_balance_for_fees(&1), 5); + assert_eq!(Balances::free_balance(2), 20); + assert_eq!(Balances::reserved_balance(2), 0); + assert_eq!(Balances::usable_balance(&2), 0); + assert_eq!(Balances::usable_balance_for_fees(&2), 17); + fast_forward_to(5); + assert_ok!(Democracy::unlock(Origin::signed(2), 2)); + assert_eq!(Balances::usable_balance(&2), 17); + }); + } + #[test] fn params_should_work() { new_test_ext().execute_with(|| { assert_eq!(Democracy::referendum_count(), 0); - assert_eq!(Balances::free_balance(&42), 0); + assert_eq!(Balances::free_balance(42), 0); assert_eq!(Balances::total_issuance(), 210); }); } @@ -1353,7 +1422,7 @@ mod tests { next_block(); next_block(); - assert_eq!(Balances::free_balance(&42), 0); + assert_eq!(Balances::free_balance(42), 0); }); } @@ -1405,8 +1474,8 @@ mod tests { 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); + assert_eq!(Balances::reserved_balance(6), 0); }); } @@ -1869,7 +1938,7 @@ mod tests { // referendum passes and wait another two blocks for enactment. fast_forward_to(6); - assert_eq!(Balances::free_balance(&42), 2); + assert_eq!(Balances::free_balance(42), 2); }); } @@ -1942,7 +2011,7 @@ mod tests { assert_eq!(Democracy::tally(r), (1, 0, 1)); fast_forward_to(6); - assert_eq!(Balances::free_balance(&42), 2); + assert_eq!(Balances::free_balance(42), 2); }); } @@ -1967,7 +2036,7 @@ mod tests { fast_forward_to(6); - assert_eq!(Balances::free_balance(&42), 2); + assert_eq!(Balances::free_balance(42), 2); }); } @@ -1993,7 +2062,7 @@ mod tests { fast_forward_to(6); - assert_eq!(Balances::free_balance(&42), 2); + assert_eq!(Balances::free_balance(42), 2); }); } @@ -2020,7 +2089,7 @@ mod tests { fast_forward_to(6); - assert_eq!(Balances::free_balance(&42), 2); + assert_eq!(Balances::free_balance(42), 2); }); } @@ -2048,7 +2117,7 @@ mod tests { fast_forward_to(6); - assert_eq!(Balances::free_balance(&42), 2); + assert_eq!(Balances::free_balance(42), 2); }); } @@ -2080,7 +2149,7 @@ mod tests { fast_forward_to(6); - assert_eq!(Balances::free_balance(&42), 2); + assert_eq!(Balances::free_balance(42), 2); }); } @@ -2093,9 +2162,9 @@ mod tests { assert_ok!(Democracy::second(Origin::signed(5), 0)); assert_ok!(Democracy::second(Origin::signed(5), 0)); assert_ok!(Democracy::second(Origin::signed(5), 0)); - assert_eq!(Balances::free_balance(&1), 5); - assert_eq!(Balances::free_balance(&2), 15); - assert_eq!(Balances::free_balance(&5), 35); + assert_eq!(Balances::free_balance(1), 5); + assert_eq!(Balances::free_balance(2), 15); + assert_eq!(Balances::free_balance(5), 35); }); } @@ -2109,9 +2178,9 @@ mod tests { assert_ok!(Democracy::second(Origin::signed(5), 0)); assert_ok!(Democracy::second(Origin::signed(5), 0)); fast_forward_to(3); - assert_eq!(Balances::free_balance(&1), 10); - assert_eq!(Balances::free_balance(&2), 20); - assert_eq!(Balances::free_balance(&5), 50); + assert_eq!(Balances::free_balance(1), 10); + assert_eq!(Balances::free_balance(2), 20); + assert_eq!(Balances::free_balance(5), 50); }); } @@ -2179,7 +2248,7 @@ mod tests { assert_eq!(Democracy::tally(r2), (1, 0, 1)); next_block(); - assert_eq!(Balances::free_balance(&42), 2); + assert_eq!(Balances::free_balance(42), 2); assert_ok!(Democracy::vote(Origin::signed(1), r1, AYE)); assert_eq!(Democracy::voters_for(r1), vec![1]); @@ -2187,7 +2256,7 @@ mod tests { assert_eq!(Democracy::tally(r1), (1, 0, 1)); next_block(); - assert_eq!(Balances::free_balance(&42), 3); + assert_eq!(Balances::free_balance(42), 3); }); } @@ -2210,7 +2279,7 @@ mod tests { next_block(); next_block(); - assert_eq!(Balances::free_balance(&42), 2); + assert_eq!(Balances::free_balance(42), 2); }); } @@ -2230,7 +2299,7 @@ mod tests { next_block(); next_block(); - assert_eq!(Balances::free_balance(&42), 0); + assert_eq!(Balances::free_balance(42), 0); }); } @@ -2253,7 +2322,7 @@ mod tests { next_block(); next_block(); - assert_eq!(Balances::free_balance(&42), 0); + assert_eq!(Balances::free_balance(42), 0); }); } @@ -2280,7 +2349,7 @@ mod tests { next_block(); next_block(); - assert_eq!(Balances::free_balance(&42), 2); + assert_eq!(Balances::free_balance(42), 2); }); } @@ -2304,11 +2373,11 @@ mod tests { assert_eq!(Democracy::tally(r), (21, 0, 21)); next_block(); - assert_eq!(Balances::free_balance(&42), 0); + assert_eq!(Balances::free_balance(42), 0); next_block(); - assert_eq!(Balances::free_balance(&42), 2); + assert_eq!(Balances::free_balance(42), 2); }); } @@ -2330,14 +2399,14 @@ mod tests { next_block(); next_block(); - assert_eq!(Balances::free_balance(&42), 0); + assert_eq!(Balances::free_balance(42), 0); }); } #[test] fn passing_low_turnout_voting_should_work() { new_test_ext().execute_with(|| { - assert_eq!(Balances::free_balance(&42), 0); + assert_eq!(Balances::free_balance(42), 0); assert_eq!(Balances::total_issuance(), 210); System::set_block_number(1); @@ -2356,7 +2425,7 @@ mod tests { next_block(); next_block(); - assert_eq!(Balances::free_balance(&42), 2); + assert_eq!(Balances::free_balance(42), 2); }); } @@ -2399,24 +2468,44 @@ mod tests { assert_eq!(Balances::locks(2), vec![BalanceLock { id: DEMOCRACY_ID, amount: u64::max_value(), - until: 18, - reasons: WithdrawReason::Transfer.into() + reasons: pallet_balances::Reasons::Misc, }]); + assert_eq!(Democracy::locks(2), Some(18)); assert_eq!(Balances::locks(3), vec![BalanceLock { id: DEMOCRACY_ID, amount: u64::max_value(), - until: 10, - reasons: WithdrawReason::Transfer.into() + reasons: pallet_balances::Reasons::Misc, }]); + assert_eq!(Democracy::locks(3), Some(10)); assert_eq!(Balances::locks(4), vec![BalanceLock { id: DEMOCRACY_ID, amount: u64::max_value(), - until: 6, - reasons: WithdrawReason::Transfer.into() + reasons: pallet_balances::Reasons::Misc, }]); + assert_eq!(Democracy::locks(4), Some(6)); assert_eq!(Balances::locks(5), vec![]); - assert_eq!(Balances::free_balance(&42), 2); + assert_eq!(Balances::free_balance(42), 2); + + assert_noop!(Democracy::unlock(Origin::signed(1), 1), Error::::NotLocked); + + fast_forward_to(5); + assert_noop!(Democracy::unlock(Origin::signed(1), 4), Error::::NotExpired); + fast_forward_to(6); + assert_ok!(Democracy::unlock(Origin::signed(1), 4)); + assert_noop!(Democracy::unlock(Origin::signed(1), 4), Error::::NotLocked); + + fast_forward_to(9); + assert_noop!(Democracy::unlock(Origin::signed(1), 3), Error::::NotExpired); + fast_forward_to(10); + assert_ok!(Democracy::unlock(Origin::signed(1), 3)); + assert_noop!(Democracy::unlock(Origin::signed(1), 3), Error::::NotLocked); + + fast_forward_to(17); + assert_noop!(Democracy::unlock(Origin::signed(1), 2), Error::::NotExpired); + fast_forward_to(18); + assert_ok!(Democracy::unlock(Origin::signed(1), 2)); + assert_noop!(Democracy::unlock(Origin::signed(1), 2), Error::::NotLocked); }); } @@ -2453,7 +2542,7 @@ mod tests { next_block(); next_block(); - assert_eq!(Balances::free_balance(&42), 2); + assert_eq!(Balances::free_balance(42), 2); }); } } diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index e022b24f01..33d4c46e91 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -83,7 +83,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use sp_std::prelude::*; -use sp_runtime::{print, DispatchResult, DispatchError, traits::{Zero, StaticLookup, Bounded, Convert}}; +use sp_runtime::{print, DispatchResult, DispatchError, traits::{Zero, StaticLookup, Convert}}; use frame_support::{ decl_storage, decl_event, ensure, decl_module, decl_error, weights::SimpleDispatchInfo, traits::{ @@ -260,7 +260,6 @@ decl_module! { MODULE_ID, &who, locked_balance, - T::BlockNumber::max_value(), WithdrawReasons::except(WithdrawReason::TransactionPayment), ); >::insert(&who, locked_balance); @@ -816,20 +815,17 @@ mod tests { parameter_types! { pub const ExistentialDeposit: u64 = 1; - pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Test { type Balance = u64; type OnNewAccount = (); - type OnFreeBalanceZero = (); type OnReapAccount = System; type Event = Event; type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; type CreationFee = CreationFee; } @@ -989,7 +985,6 @@ mod tests { (5, 50 * self.balance_factor), (6, 60 * self.balance_factor) ], - vesting: vec![], }), }.build_storage().unwrap().into() } diff --git a/frame/elections/src/lib.rs b/frame/elections/src/lib.rs index 504aa5d8a0..899fcfac8a 100644 --- a/frame/elections/src/lib.rs +++ b/frame/elections/src/lib.rs @@ -26,7 +26,7 @@ use sp_std::prelude::*; use sp_runtime::{ RuntimeDebug, DispatchResult, print, - traits::{Zero, One, StaticLookup, Bounded, Saturating}, + traits::{Zero, One, StaticLookup, Saturating}, }; use frame_support::{ decl_storage, decl_event, ensure, decl_module, decl_error, @@ -894,7 +894,6 @@ impl Module { MODULE_ID, &who, locked_balance, - T::BlockNumber::max_value(), WithdrawReasons::all(), ); diff --git a/frame/elections/src/mock.rs b/frame/elections/src/mock.rs index 178637e088..3274dd57b4 100644 --- a/frame/elections/src/mock.rs +++ b/frame/elections/src/mock.rs @@ -58,19 +58,16 @@ impl frame_system::Trait for Test { 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 OnNewAccount = (); - type OnFreeBalanceZero = (); type OnReapAccount = System; type Event = Event; type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; type CreationFee = CreationFee; } @@ -222,7 +219,6 @@ impl ExtBuilder { (5, 50 * self.balance_factor), (6, 60 * self.balance_factor) ], - vesting: vec![], }), elections: Some(elections::GenesisConfig::{ members: vec![], @@ -270,7 +266,8 @@ pub(crate) fn create_candidate(i: u64, index: u32) { } pub(crate) fn balances(who: &u64) -> (u64, u64) { - (Balances::free_balance(who), Balances::reserved_balance(who)) + let a = Balances::account(who); + (a.free, a.reserved) } pub(crate) fn locks(who: &u64) -> Vec { diff --git a/frame/elections/src/tests.rs b/frame/elections/src/tests.rs index 48161bcee4..e26f031290 100644 --- a/frame/elections/src/tests.rs +++ b/frame/elections/src/tests.rs @@ -1179,14 +1179,14 @@ fn election_present_when_presenter_is_poor_should_not_work() { // -3 assert_ok!(Elections::submit_candidacy(Origin::signed(1), 0)); - assert_eq!(Balances::free_balance(&1), 12); + assert_eq!(Balances::free_balance(1), 12); // -2 -5 assert_ok!(Elections::set_approvals(Origin::signed(1), vec![true], 0, 0, 15)); assert_ok!(Elections::end_block(System::block_number())); System::set_block_number(6); - assert_eq!(Balances::free_balance(&1), 5); - assert_eq!(Balances::reserved_balance(&1), 5); + assert_eq!(Balances::free_balance(1), 5); + assert_eq!(Balances::reserved_balance(1), 5); if p > 5 { assert_noop!(Elections::present_winner( Origin::signed(1), 1, 10, 0), diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index 56d3de14dc..b3a86b6acd 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -690,19 +690,16 @@ mod tests { } 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 OnReapAccount = System; type OnNewAccount = (); type Event = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; type CreationFee = CreationFee; } impl Trait for Test { diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index cafb9fad27..936da70211 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -454,19 +454,16 @@ mod tests { } parameter_types! { pub const ExistentialDeposit: u64 = 0; - pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Runtime { type Balance = u64; - type OnFreeBalanceZero = (); type OnReapAccount = System; type OnNewAccount = (); type Event = MetaEvent; type DustRemoval = (); type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; type CreationFee = CreationFee; } @@ -528,7 +525,6 @@ mod tests { 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 = sp_runtime::testing::TestXt(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(2, 69))); let weight = xt.get_dispatch_info().weight as u64; @@ -552,7 +548,6 @@ mod tests { 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(); t.into() } @@ -564,7 +559,7 @@ mod tests { header: Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("c6b01b27df520ba23adb96e7fc032acb7c586ba1b477c6282de43184111f2091").into(), + state_root: hex!("a0b84fec49718caf59350dab6ec2993f12db399a7cccdb80f3cf79618ed93bd8").into(), extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(), digest: Digest { logs: vec![], }, }, @@ -711,7 +706,6 @@ mod tests { id, &1, 110, - Bounded::max_value(), lock, ); let xt = sp_runtime::testing::TestXt( diff --git a/frame/generic-asset/src/lib.rs b/frame/generic-asset/src/lib.rs index 8b7668dc12..3b8ebe0535 100644 --- a/frame/generic-asset/src/lib.rs +++ b/frame/generic-asset/src/lib.rs @@ -427,10 +427,9 @@ decl_module! { } #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] -pub struct BalanceLock { +pub struct BalanceLock { pub id: LockIdentifier, pub amount: Balance, - pub until: BlockNumber, pub reasons: WithdrawReasons, } @@ -459,7 +458,7 @@ decl_storage! { /// Any liquidity locks on some account balances. pub Locks get(fn locks): - map hasher(blake2_256) T::AccountId => Vec>; + map hasher(blake2_256) T::AccountId => Vec>; /// The identity of the asset which is the one that is designated for the chain's staking system. pub StakingAssetId get(fn staking_asset_id) config(): T::AssetId; @@ -796,10 +795,8 @@ impl Module { if locks.is_empty() { return Ok(()); } - let now = >::block_number(); if Self::locks(who) - .into_iter() - .all(|l| now >= l.until || new_balance >= l.amount || !l.reasons.intersects(reasons)) + .into_iter().all(|l| new_balance >= l.amount || !l.reasons.intersects(reasons)) { Ok(()) } else { @@ -825,14 +822,11 @@ impl Module { id: LockIdentifier, who: &T::AccountId, amount: T::Balance, - until: T::BlockNumber, reasons: WithdrawReasons, ) { - let now = >::block_number(); let mut new_lock = Some(BalanceLock { id, amount, - until, reasons, }); let mut locks = >::locks(who) @@ -840,10 +834,8 @@ impl Module { .filter_map(|l| { if l.id == id { new_lock.take() - } else if l.until > now { - Some(l) } else { - None + Some(l) } }) .collect::>(); @@ -857,14 +849,11 @@ impl Module { id: LockIdentifier, who: &T::AccountId, amount: T::Balance, - until: T::BlockNumber, reasons: WithdrawReasons, ) { - let now = >::block_number(); let mut new_lock = Some(BalanceLock { id, amount, - until, reasons, }); let mut locks = >::locks(who) @@ -874,13 +863,10 @@ impl Module { new_lock.take().map(|nl| BalanceLock { id: l.id, amount: l.amount.max(nl.amount), - until: l.until.max(nl.until), reasons: l.reasons | nl.reasons, }) - } else if l.until > now { - Some(l) } else { - None + Some(l) } }) .collect::>(); @@ -891,11 +877,8 @@ impl Module { } fn remove_lock(id: LockIdentifier, who: &T::AccountId) { - let now = >::block_number(); - let locks = >::locks(who) - .into_iter() - .filter_map(|l| if l.until > now && l.id != id { Some(l) } else { None }) - .collect::>(); + let mut locks = >::locks(who); + locks.retain(|l| l.id != id); >::insert(who, locks); } } @@ -1339,20 +1322,18 @@ where id: LockIdentifier, who: &T::AccountId, amount: T::Balance, - until: T::BlockNumber, reasons: WithdrawReasons, ) { - >::set_lock(id, who, amount, until, reasons) + >::set_lock(id, who, amount, reasons) } fn extend_lock( id: LockIdentifier, who: &T::AccountId, amount: T::Balance, - until: T::BlockNumber, reasons: WithdrawReasons, ) { - >::extend_lock(id, who, amount, until, reasons) + >::extend_lock(id, who, amount, reasons) } fn remove_lock(id: LockIdentifier, who: &T::AccountId) { diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index b16e87ff81..56960b2d1d 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -925,19 +925,16 @@ mod tests { } 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 OnReapAccount = System; type OnNewAccount = (); type Event = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; type CreationFee = CreationFee; } parameter_types! { @@ -981,7 +978,6 @@ mod tests { (20, 100), (30, 100), ], - vesting: vec![], }.assimilate_storage(&mut t).unwrap(); t.into() } diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index 1067e9a5de..82aea43ad4 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -288,19 +288,16 @@ mod tests { } 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 OnReapAccount = System; type OnNewAccount = (); type Event = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; type CreationFee = CreationFee; } parameter_types! { @@ -334,7 +331,6 @@ mod tests { (1, 10), (2, 10), ], - vesting: vec![], }.assimilate_storage(&mut t).unwrap(); t.into() } @@ -359,9 +355,9 @@ mod tests { ); assert_ok!(Nicks::set_name(Origin::signed(2), b"Dave".to_vec())); - assert_eq!(Balances::reserved_balance(&2), 2); + assert_eq!(Balances::reserved_balance(2), 2); assert_ok!(Nicks::force_name(Origin::signed(1), 2, b"Dr. David Brubeck, III".to_vec())); - assert_eq!(Balances::reserved_balance(&2), 2); + assert_eq!(Balances::reserved_balance(2), 2); assert_eq!(>::get(2).unwrap(), (b"Dr. David Brubeck, III".to_vec(), 2)); }); } @@ -370,18 +366,18 @@ mod tests { fn normal_operation_should_work() { new_test_ext().execute_with(|| { assert_ok!(Nicks::set_name(Origin::signed(1), b"Gav".to_vec())); - assert_eq!(Balances::reserved_balance(&1), 2); - assert_eq!(Balances::free_balance(&1), 8); + assert_eq!(Balances::reserved_balance(1), 2); + assert_eq!(Balances::free_balance(1), 8); assert_eq!(>::get(1).unwrap().0, b"Gav".to_vec()); assert_ok!(Nicks::set_name(Origin::signed(1), b"Gavin".to_vec())); - assert_eq!(Balances::reserved_balance(&1), 2); - assert_eq!(Balances::free_balance(&1), 8); + assert_eq!(Balances::reserved_balance(1), 2); + assert_eq!(Balances::free_balance(1), 8); assert_eq!(>::get(1).unwrap().0, b"Gavin".to_vec()); assert_ok!(Nicks::clear_name(Origin::signed(1))); - assert_eq!(Balances::reserved_balance(&1), 0); - assert_eq!(Balances::free_balance(&1), 10); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(Balances::free_balance(1), 10); }); } diff --git a/frame/recovery/src/mock.rs b/frame/recovery/src/mock.rs index be9ed5c97e..fa074e1faf 100644 --- a/frame/recovery/src/mock.rs +++ b/frame/recovery/src/mock.rs @@ -81,20 +81,17 @@ impl frame_system::Trait for Test { parameter_types! { pub const ExistentialDeposit: u64 = 1; - pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Test { type Balance = u128; - type OnFreeBalanceZero = (); type OnReapAccount = (System, Recovery); type OnNewAccount = (); type Event = TestEvent; type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; type CreationFee = CreationFee; } @@ -126,7 +123,6 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 100), (2, 100), (3, 100), (4, 100), (5, 100)], - vesting: vec![], }.assimilate_storage(&mut t).unwrap(); t.into() } diff --git a/frame/recovery/src/tests.rs b/frame/recovery/src/tests.rs index 76f05156ef..cfc8e25b12 100644 --- a/frame/recovery/src/tests.rs +++ b/frame/recovery/src/tests.rs @@ -35,7 +35,7 @@ fn basic_setup_works() { assert_eq!(Recovery::active_recovery(&1, &2), None); assert_eq!(Recovery::recovery_config(&1), None); // Everyone should have starting balance of 100 - assert_eq!(Balances::free_balance(&1), 100); + assert_eq!(Balances::free_balance(1), 100); }); } @@ -219,7 +219,7 @@ fn initiate_recovery_handles_basic_errors() { assert_ok!(Recovery::initiate_recovery(Origin::signed(1), 5)); assert_noop!(Recovery::initiate_recovery(Origin::signed(1), 5), Error::::AlreadyStarted); // No double deposit - assert_eq!(Balances::reserved_balance(&1), 10); + assert_eq!(Balances::reserved_balance(1), 10); }); } @@ -234,7 +234,7 @@ fn initiate_recovery_works() { // Recovery can be initiated assert_ok!(Recovery::initiate_recovery(Origin::signed(1), 5)); // Deposit is reserved - assert_eq!(Balances::reserved_balance(&1), 10); + assert_eq!(Balances::reserved_balance(1), 10); // Recovery status object is created correctly let recovery_status = ActiveRecovery { created: 1, diff --git a/frame/scored-pool/src/mock.rs b/frame/scored-pool/src/mock.rs index dd59bbc84f..fa8b11e69e 100644 --- a/frame/scored-pool/src/mock.rs +++ b/frame/scored-pool/src/mock.rs @@ -47,7 +47,6 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); pub const ExistentialDeposit: u64 = 0; - pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; } ord_parameter_types! { @@ -76,14 +75,12 @@ impl frame_system::Trait for Test { impl pallet_balances::Trait for Test { type Balance = u64; - type OnFreeBalanceZero = (); type OnReapAccount = System; type OnNewAccount = (); type Event = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; type CreationFee = CreationFee; } @@ -144,7 +141,6 @@ pub fn new_test_ext() -> sp_io::TestExternalities { (40, 500_000), (99, 1), ], - vesting: vec![], }.assimilate_storage(&mut t).unwrap(); GenesisConfig::{ pool: vec![ diff --git a/frame/scored-pool/src/tests.rs b/frame/scored-pool/src/tests.rs index d8c887f4ec..4b21339505 100644 --- a/frame/scored-pool/src/tests.rs +++ b/frame/scored-pool/src/tests.rs @@ -30,8 +30,8 @@ type Balances = pallet_balances::Module; fn query_membership_works() { new_test_ext().execute_with(|| { assert_eq!(ScoredPool::members(), vec![20, 40]); - assert_eq!(Balances::reserved_balance(&31), CandidateDeposit::get()); - assert_eq!(Balances::reserved_balance(&40), CandidateDeposit::get()); + assert_eq!(Balances::reserved_balance(31), CandidateDeposit::get()); + assert_eq!(Balances::reserved_balance(40), CandidateDeposit::get()); assert_eq!(MEMBERS.with(|m| m.borrow().clone()), vec![20, 40]); }); } @@ -61,7 +61,7 @@ fn submit_candidacy_works() { assert_eq!(fetch_from_pool(15), Some((who, None))); // then - assert_eq!(Balances::reserved_balance(&who), CandidateDeposit::get()); + assert_eq!(Balances::reserved_balance(who), CandidateDeposit::get()); }); } @@ -117,7 +117,7 @@ fn kicking_works() { new_test_ext().execute_with(|| { // given let who = 40; - assert_eq!(Balances::reserved_balance(&who), CandidateDeposit::get()); + assert_eq!(Balances::reserved_balance(who), CandidateDeposit::get()); assert_eq!(find_in_pool(who), Some(0)); // when @@ -128,7 +128,7 @@ fn kicking_works() { assert_eq!(find_in_pool(who), None); assert_eq!(ScoredPool::members(), vec![20, 31]); assert_eq!(MEMBERS.with(|m| m.borrow().clone()), ScoredPool::members()); - assert_eq!(Balances::reserved_balance(&who), 0); // deposit must have been returned + assert_eq!(Balances::reserved_balance(who), 0); // deposit must have been returned }); } @@ -246,7 +246,7 @@ fn withdraw_scored_candidacy_must_work() { new_test_ext().execute_with(|| { // given let who = 40; - assert_eq!(Balances::reserved_balance(&who), CandidateDeposit::get()); + assert_eq!(Balances::reserved_balance(who), CandidateDeposit::get()); // when let index = find_in_pool(who).expect("entity must be in pool") as u32; @@ -255,7 +255,7 @@ fn withdraw_scored_candidacy_must_work() { // then assert_eq!(fetch_from_pool(who), None); assert_eq!(ScoredPool::members(), vec![20, 31]); - assert_eq!(Balances::reserved_balance(&who), 0); + assert_eq!(Balances::reserved_balance(who), 0); }); } diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index f98e334cbb..a18d55d26c 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -106,7 +106,7 @@ 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, decl_error}; -use frame_support::{ensure, traits::{OnFreeBalanceZero, Get, FindAuthor, ValidatorRegistration}, Parameter}; +use frame_support::{ensure, traits::{OnReapAccount, Get, FindAuthor, ValidatorRegistration}, Parameter}; use frame_system::{self as system, ensure_signed}; #[cfg(test)] @@ -676,8 +676,8 @@ impl Module { } } -impl OnFreeBalanceZero for Module { - fn on_free_balance_zero(who: &T::ValidatorId) { +impl OnReapAccount for Module { + fn on_reap_account(who: &T::ValidatorId) { Self::prune_dead_keys(who); } } @@ -754,7 +754,7 @@ mod tests { let id = DUMMY; assert_eq!(Session::key_owner(id, UintAuthorityId(1).get_raw(id)), Some(1)); - Session::on_free_balance_zero(&1); + Session::on_reap_account(&1); assert_eq!(Session::load_keys(&1), None); assert_eq!(Session::key_owner(id, UintAuthorityId(1).get_raw(id)), None); }) diff --git a/frame/society/src/mock.rs b/frame/society/src/mock.rs index b8f249f35c..5c772478c8 100644 --- a/frame/society/src/mock.rs +++ b/frame/society/src/mock.rs @@ -51,7 +51,6 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); pub const ExistentialDeposit: u64 = 0; - pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; } @@ -81,13 +80,11 @@ impl frame_system::Trait for Test { 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; type OnReapAccount = System; } @@ -146,7 +143,6 @@ impl EnvBuilder { self.balances.push((Society::account_id(), self.balance.max(self.pot))); pallet_balances::GenesisConfig:: { balances: self.balances, - vesting: vec![], }.assimilate_storage(&mut t).unwrap(); GenesisConfig::{ members: self.members, diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 757f75bf0a..ca2a2bf092 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -261,7 +261,7 @@ use frame_support::{ decl_module, decl_event, decl_storage, ensure, decl_error, weights::SimpleDispatchInfo, traits::{ - Currency, OnFreeBalanceZero, LockIdentifier, LockableCurrency, + Currency, LockIdentifier, LockableCurrency, WithdrawReasons, OnUnbalanced, Imbalance, Get, Time } }; @@ -284,6 +284,7 @@ use sp_runtime::{Serialize, Deserialize}; use frame_system::{self as system, ensure_signed, ensure_root}; use sp_phragmen::ExtendedBalance; +use frame_support::traits::OnReapAccount; const DEFAULT_MINIMUM_VALIDATOR_COUNT: u32 = 4; const MAX_NOMINATIONS: usize = 16; @@ -1286,7 +1287,6 @@ impl Module { STAKING_ID, &ledger.stash, ledger.total, - T::BlockNumber::max_value(), WithdrawReasons::all(), ); >::insert(controller, ledger); @@ -1682,8 +1682,8 @@ impl SessionManager> } } -impl OnFreeBalanceZero for Module { - fn on_free_balance_zero(stash: &T::AccountId) { +impl OnReapAccount for Module { + fn on_reap_account(stash: &T::AccountId) { Self::ensure_storage_upgraded(); Self::kill_stash(stash); } diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 8aa20c19c6..3b2443c2ce 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -140,19 +140,16 @@ impl frame_system::Trait for Test { type ModuleToIndex = (); } parameter_types! { - pub const TransferFee: Balance = 0; pub const CreationFee: Balance = 0; } impl pallet_balances::Trait for Test { type Balance = Balance; - type OnFreeBalanceZero = Staking; - type OnReapAccount = System; + type OnReapAccount = (System, Staking); type OnNewAccount = (); type Event = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; type CreationFee = CreationFee; } parameter_types! { @@ -323,7 +320,6 @@ impl ExtBuilder { // This allow us to have a total_payout different from 0. (999, 1_000_000_000_000), ], - vesting: vec![], }.assimilate_storage(&mut storage); let stake_21 = if self.fair { 1000 } else { 2000 }; diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index 43a2d00791..a9b6e16598 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -110,8 +110,8 @@ fn basic_setup_works() { assert_eq!(Staking::current_era(), 0); // Account 10 has `balance_factor` free balance - assert_eq!(Balances::free_balance(&10), 1); - assert_eq!(Balances::free_balance(&10), 1); + assert_eq!(Balances::free_balance(10), 1); + assert_eq!(Balances::free_balance(10), 1); // New era is not being forced assert_eq!(Staking::force_era(), Forcing::NotForcing); @@ -759,7 +759,7 @@ fn cannot_transfer_staked_balance() { // Confirm account 11 is stashed assert_eq!(Staking::bonded(&11), Some(10)); // Confirm account 11 has some free balance - assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(11), 1000); // Confirm account 11 (via controller 10) is totally staked assert_eq!(Staking::stakers(&11).total, 1000); // Confirm account 11 cannot transfer as a result @@ -788,7 +788,7 @@ fn cannot_transfer_staked_balance_2() { // Confirm account 21 is stashed assert_eq!(Staking::bonded(&21), Some(20)); // Confirm account 21 has some free balance - assert_eq!(Balances::free_balance(&21), 2000); + assert_eq!(Balances::free_balance(21), 2000); // Confirm account 21 (via controller 20) is totally staked assert_eq!(Staking::stakers(&21).total, 1000); // Confirm account 21 can transfer at most 1000 @@ -811,7 +811,7 @@ fn cannot_reserve_staked_balance() { // Confirm account 11 is stashed assert_eq!(Staking::bonded(&11), Some(10)); // Confirm account 11 has some free balance - assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(11), 1000); // Confirm account 11 (via controller 10) is totally staked assert_eq!(Staking::stakers(&11).own, 1000); // Confirm account 11 cannot transfer as a result @@ -838,9 +838,9 @@ fn reward_destination_works() { // Check that account 11 is a validator assert!(Staking::current_elected().contains(&11)); // Check the balance of the validator account - assert_eq!(Balances::free_balance(&10), 1); + assert_eq!(Balances::free_balance(10), 1); // Check the balance of the stash account - assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(11), 1000); // Check how much is at stake assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, @@ -859,7 +859,7 @@ fn reward_destination_works() { // Check that RewardDestination is Staked (default) assert_eq!(Staking::payee(&11), RewardDestination::Staked); // Check that reward went to the stash account of validator - assert_eq!(Balances::free_balance(&11), 1000 + total_payout_0); + assert_eq!(Balances::free_balance(11), 1000 + total_payout_0); // Check that amount at stake increased accordingly assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, @@ -881,7 +881,7 @@ fn reward_destination_works() { // Check that RewardDestination is Stash assert_eq!(Staking::payee(&11), RewardDestination::Stash); // Check that reward went to the stash account - assert_eq!(Balances::free_balance(&11), 1000 + total_payout_0 + total_payout_1); + assert_eq!(Balances::free_balance(11), 1000 + total_payout_0 + total_payout_1); // Record this value let recorded_stash_balance = 1000 + total_payout_0 + total_payout_1; // Check that amount at stake is NOT increased @@ -896,7 +896,7 @@ fn reward_destination_works() { >::insert(&11, RewardDestination::Controller); // Check controller balance - assert_eq!(Balances::free_balance(&10), 1); + assert_eq!(Balances::free_balance(10), 1); // Compute total payout now for whole duration as other parameter won't change let total_payout_2 = current_total_payout_for_duration(3000); @@ -908,7 +908,7 @@ fn reward_destination_works() { // Check that RewardDestination is Controller assert_eq!(Staking::payee(&11), RewardDestination::Controller); // Check that reward went to the controller account - assert_eq!(Balances::free_balance(&10), 1 + total_payout_2); + assert_eq!(Balances::free_balance(10), 1 + total_payout_2); // Check that amount at stake is NOT increased assert_eq!(Staking::ledger(&10), Some(StakingLedger { stash: 11, @@ -917,7 +917,7 @@ fn reward_destination_works() { unlocking: vec![], })); // Check that amount in staked account is NOT increased. - assert_eq!(Balances::free_balance(&11), recorded_stash_balance); + assert_eq!(Balances::free_balance(11), recorded_stash_balance); }); } @@ -1422,9 +1422,9 @@ fn on_free_balance_zero_stash_removes_validator() { // Tests that storage items are untouched when controller is empty ExtBuilder::default().existential_deposit(10).build().execute_with(|| { // Check the balance of the validator account - assert_eq!(Balances::free_balance(&10), 256); + assert_eq!(Balances::free_balance(10), 256); // Check the balance of the stash account - assert_eq!(Balances::free_balance(&11), 256000); + assert_eq!(Balances::free_balance(11), 256000); // Check these two accounts are bonded assert_eq!(Staking::bonded(&11), Some(10)); @@ -1442,7 +1442,7 @@ fn on_free_balance_zero_stash_removes_validator() { let _ = Balances::slash(&10, u64::max_value()); // Check the balance of the stash account has not been touched - assert_eq!(Balances::free_balance(&11), 256000); + assert_eq!(Balances::free_balance(11), 256000); // Check these two accounts are still bonded assert_eq!(Staking::bonded(&11), Some(10)); @@ -1476,9 +1476,9 @@ fn on_free_balance_zero_stash_removes_nominator() { // Check that account 10 is a nominator assert!(>::exists(11)); // Check the balance of the nominator account - assert_eq!(Balances::free_balance(&10), 256); + assert_eq!(Balances::free_balance(10), 256); // Check the balance of the stash account - assert_eq!(Balances::free_balance(&11), 256000); + assert_eq!(Balances::free_balance(11), 256000); // Set payee information assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Stash)); @@ -1495,7 +1495,7 @@ fn on_free_balance_zero_stash_removes_nominator() { assert_eq!(Balances::total_balance(&10), 0); // Check the balance of the stash account has not been touched - assert_eq!(Balances::free_balance(&11), 256000); + assert_eq!(Balances::free_balance(11), 256000); // Check these two accounts are still bonded assert_eq!(Staking::bonded(&11), Some(10)); @@ -1689,9 +1689,9 @@ fn bond_with_little_staked_value_bounded_by_slot_stake() { assert_eq!(Staking::slot_stake(), 1); // Old ones are rewarded. - assert_eq!(Balances::free_balance(&10), init_balance_10 + total_payout_0 / 3); + assert_eq!(Balances::free_balance(10), init_balance_10 + total_payout_0 / 3); // no rewards paid to 2. This was initial election. - assert_eq!(Balances::free_balance(&2), init_balance_2); + assert_eq!(Balances::free_balance(2), init_balance_2); let total_payout_1 = current_total_payout_for_duration(3000); assert!(total_payout_1 > 100); // Test is meaningfull if reward something @@ -1701,7 +1701,7 @@ fn bond_with_little_staked_value_bounded_by_slot_stake() { assert_eq_uvec!(validator_controllers(), vec![20, 10, 2]); assert_eq!(Staking::slot_stake(), 1); - assert_eq!(Balances::free_balance(&2), init_balance_2 + total_payout_1 / 3); + assert_eq!(Balances::free_balance(2), init_balance_2 + total_payout_1 / 3); assert_eq!( Balances::free_balance(&10), init_balance_10 + total_payout_0 / 3 + total_payout_1 / 3, @@ -2008,7 +2008,7 @@ fn slashing_performed_according_exposure() { ); // The stash account should be slashed for 250 (50% of 500). - assert_eq!(Balances::free_balance(&11), 1000 - 250); + assert_eq!(Balances::free_balance(11), 1000 - 250); }); } @@ -2102,8 +2102,8 @@ fn reporters_receive_their_slice() { // 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_eq!(Balances::free_balance(1), 10 + reward_each); + assert_eq!(Balances::free_balance(2), 20 + reward_each); assert_ledger_consistent(11); }); } @@ -2132,7 +2132,7 @@ fn subsequent_reports_in_same_span_pay_out_less() { // F1 * (reward_proportion * slash - 0) // 50% * (10% * initial_balance * 20%) let reward = (initial_balance / 5) / 20; - assert_eq!(Balances::free_balance(&1), 10 + reward); + assert_eq!(Balances::free_balance(1), 10 + reward); on_offence_now( &[OffenceDetails { @@ -2150,7 +2150,7 @@ fn subsequent_reports_in_same_span_pay_out_less() { // 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_eq!(Balances::free_balance(1), 10 + prior_payout + reward); assert_ledger_consistent(11); }); } @@ -2159,8 +2159,8 @@ fn subsequent_reports_in_same_span_pay_out_less() { 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!(Balances::free_balance(11), 1000); + assert_eq!(Balances::free_balance(21), 2000); let exposure = Staking::stakers(&21); let initial_balance = Staking::slashable_balance_of(&21); @@ -2183,9 +2183,9 @@ fn invulnerables_are_not_slashed() { ); // The validator 11 hasn't been slashed, but 21 has been. - assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(11), 1000); // 2000 - (0.2 * initial_balance) - assert_eq!(Balances::free_balance(&21), 2000 - (2 * initial_balance / 10)); + 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) { @@ -2203,7 +2203,7 @@ fn invulnerables_are_not_slashed() { fn dont_slash_if_fraction_is_zero() { // Don't slash if the fraction is zero. ExtBuilder::default().build().execute_with(|| { - assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(11), 1000); on_offence_now( &[OffenceDetails { @@ -2217,7 +2217,7 @@ 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_eq!(Balances::free_balance(11), 1000); assert_ledger_consistent(11); }); } @@ -2225,7 +2225,7 @@ fn dont_slash_if_fraction_is_zero() { #[test] fn only_slash_for_max_in_era() { ExtBuilder::default().build().execute_with(|| { - assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(11), 1000); on_offence_now( &[ @@ -2238,7 +2238,7 @@ fn only_slash_for_max_in_era() { ); // The validator has been slashed and has been force-chilled. - assert_eq!(Balances::free_balance(&11), 500); + assert_eq!(Balances::free_balance(11), 500); assert_eq!(Staking::force_era(), Forcing::ForceNew); on_offence_now( @@ -2252,7 +2252,7 @@ fn only_slash_for_max_in_era() { ); // The validator has not been slashed additionally. - assert_eq!(Balances::free_balance(&11), 500); + assert_eq!(Balances::free_balance(11), 500); on_offence_now( &[ @@ -2265,7 +2265,7 @@ fn only_slash_for_max_in_era() { ); // The validator got slashed 10% more. - assert_eq!(Balances::free_balance(&11), 400); + assert_eq!(Balances::free_balance(11), 400); assert_ledger_consistent(11); }) } @@ -2273,7 +2273,7 @@ fn only_slash_for_max_in_era() { #[test] fn garbage_collection_after_slashing() { ExtBuilder::default().existential_deposit(1).build().execute_with(|| { - assert_eq!(Balances::free_balance(&11), 256_000); + assert_eq!(Balances::free_balance(11), 256_000); on_offence_now( &[ @@ -2285,7 +2285,7 @@ fn garbage_collection_after_slashing() { &[Perbill::from_percent(10)], ); - assert_eq!(Balances::free_balance(&11), 256_000 - 25_600); + 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); @@ -2302,7 +2302,7 @@ fn garbage_collection_after_slashing() { // 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_eq!(Balances::free_balance(11), 0); assert!(::SlashingSpans::get(&11).is_none()); assert_eq!(::SpanSlash::get(&(11, 0)).amount_slashed(), &0); }) @@ -2313,10 +2313,10 @@ fn garbage_collection_on_window_pruning() { ExtBuilder::default().build().execute_with(|| { start_era(1); - assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(11), 1000); let exposure = Staking::stakers(&11); - assert_eq!(Balances::free_balance(&101), 2000); + assert_eq!(Balances::free_balance(101), 2000); let nominated_value = exposure.others.iter().find(|o| o.who == 101).unwrap().value; on_offence_now( @@ -2331,8 +2331,8 @@ fn garbage_collection_on_window_pruning() { let now = Staking::current_era(); - assert_eq!(Balances::free_balance(&11), 900); - assert_eq!(Balances::free_balance(&101), 2000 - (nominated_value / 10)); + 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()); @@ -2357,15 +2357,15 @@ fn slashing_nominators_by_span_max() { 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!(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); + 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; @@ -2380,10 +2380,10 @@ fn slashing_nominators_by_span_max() { 2, ); - assert_eq!(Balances::free_balance(&11), 900); + 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); + assert_eq!(Balances::free_balance(101), 2000 - slash_1_amount); let expected_spans = vec![ slashing::SlashingSpan { index: 1, start: 4, length: None }, @@ -2415,14 +2415,14 @@ fn slashing_nominators_by_span_max() { ); // 11 was not further slashed, but 21 and 101 were. - assert_eq!(Balances::free_balance(&11), 900); - assert_eq!(Balances::free_balance(&21), 1700); + 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); + 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. @@ -2438,15 +2438,15 @@ fn slashing_nominators_by_span_max() { ); // 11 was further slashed, but 21 and 101 were not. - assert_eq!(Balances::free_balance(&11), 800); - assert_eq!(Balances::free_balance(&21), 1700); + 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); + assert_eq!(Balances::free_balance(101), 2000 - slash_2_amount); }); } @@ -2457,7 +2457,7 @@ fn slashes_are_summed_across_spans() { start_era(2); start_era(3); - assert_eq!(Balances::free_balance(&21), 2000); + assert_eq!(Balances::free_balance(21), 2000); assert_eq!(Staking::slashable_balance_of(&21), 1000); let get_span = |account| ::SlashingSpans::get(&account).unwrap(); @@ -2478,7 +2478,7 @@ fn slashes_are_summed_across_spans() { ]; assert_eq!(get_span(21).iter().collect::>(), expected_spans); - assert_eq!(Balances::free_balance(&21), 1900); + 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(); @@ -2504,7 +2504,7 @@ fn slashes_are_summed_across_spans() { ]; assert_eq!(get_span(21).iter().collect::>(), expected_spans); - assert_eq!(Balances::free_balance(&21), 1810); + assert_eq!(Balances::free_balance(21), 1810); }); } @@ -2513,10 +2513,10 @@ fn deferred_slashes_are_deferred() { ExtBuilder::default().slash_defer_duration(2).build().execute_with(|| { start_era(1); - assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(11), 1000); let exposure = Staking::stakers(&11); - assert_eq!(Balances::free_balance(&101), 2000); + assert_eq!(Balances::free_balance(101), 2000); let nominated_value = exposure.others.iter().find(|o| o.who == 101).unwrap().value; on_offence_now( @@ -2529,25 +2529,25 @@ fn deferred_slashes_are_deferred() { &[Perbill::from_percent(10)], ); - assert_eq!(Balances::free_balance(&11), 1000); - assert_eq!(Balances::free_balance(&101), 2000); + 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); + 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); + 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)); + assert_eq!(Balances::free_balance(11), 900); + assert_eq!(Balances::free_balance(101), 2000 - (nominated_value / 10)); }) } @@ -2556,10 +2556,10 @@ fn remove_deferred() { ExtBuilder::default().slash_defer_duration(2).build().execute_with(|| { start_era(1); - assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(11), 1000); let exposure = Staking::stakers(&11); - assert_eq!(Balances::free_balance(&101), 2000); + assert_eq!(Balances::free_balance(101), 2000); let nominated_value = exposure.others.iter().find(|o| o.who == 101).unwrap().value; on_offence_now( @@ -2572,8 +2572,8 @@ fn remove_deferred() { &[Perbill::from_percent(10)], ); - assert_eq!(Balances::free_balance(&11), 1000); - assert_eq!(Balances::free_balance(&101), 2000); + assert_eq!(Balances::free_balance(11), 1000); + assert_eq!(Balances::free_balance(101), 2000); start_era(2); @@ -2590,21 +2590,21 @@ fn remove_deferred() { Staking::cancel_deferred_slash(Origin::ROOT, 1, vec![0]).unwrap(); - assert_eq!(Balances::free_balance(&11), 1000); - assert_eq!(Balances::free_balance(&101), 2000); + 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); + 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); + assert_eq!(Balances::free_balance(11), 1000); + assert_eq!(Balances::free_balance(101), 2000); start_era(5); @@ -2616,8 +2616,8 @@ fn remove_deferred() { 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); + assert_eq!(Balances::free_balance(11), 950); + assert_eq!(Balances::free_balance(101), 2000 - actual_slash); }) } @@ -2626,10 +2626,10 @@ fn remove_multi_deferred() { ExtBuilder::default().slash_defer_duration(2).build().execute_with(|| { start_era(1); - assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(11), 1000); let exposure = Staking::stakers(&11); - assert_eq!(Balances::free_balance(&101), 2000); + assert_eq!(Balances::free_balance(101), 2000); on_offence_now( &[ @@ -2682,10 +2682,10 @@ fn slash_kicks_validators_not_nominators() { ExtBuilder::default().build().execute_with(|| { start_era(1); - assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(11), 1000); let exposure = Staking::stakers(&11); - assert_eq!(Balances::free_balance(&101), 2000); + assert_eq!(Balances::free_balance(101), 2000); let nominated_value = exposure.others.iter().find(|o| o.who == 101).unwrap().value; on_offence_now( @@ -2698,8 +2698,8 @@ fn slash_kicks_validators_not_nominators() { &[Perbill::from_percent(10)], ); - assert_eq!(Balances::free_balance(&11), 900); - assert_eq!(Balances::free_balance(&101), 2000 - (nominated_value / 10)); + assert_eq!(Balances::free_balance(11), 900); + assert_eq!(Balances::free_balance(101), 2000 - (nominated_value / 10)); // This is the best way to check that the validator was chilled; `get` will // return default value. @@ -2771,10 +2771,10 @@ fn zero_slash_keeps_nominators() { ExtBuilder::default().build().execute_with(|| { start_era(1); - assert_eq!(Balances::free_balance(&11), 1000); + assert_eq!(Balances::free_balance(11), 1000); let exposure = Staking::stakers(&11); - assert_eq!(Balances::free_balance(&101), 2000); + assert_eq!(Balances::free_balance(101), 2000); on_offence_now( &[ @@ -2786,8 +2786,8 @@ fn zero_slash_keeps_nominators() { &[Perbill::from_percent(0)], ); - assert_eq!(Balances::free_balance(&11), 1000); - assert_eq!(Balances::free_balance(&101), 2000); + assert_eq!(Balances::free_balance(11), 1000); + assert_eq!(Balances::free_balance(101), 2000); // This is the best way to check that the validator was chilled; `get` will // return default value. diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index e601544b01..531f255714 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -67,7 +67,8 @@ pub mod traits; pub mod weights; pub use self::hash::{ - Twox256, Twox128, Blake2_256, Blake2_128, Twox64Concat, Blake2_128Concat, Hashable + Twox256, Twox128, Blake2_256, Blake2_128, Twox64Concat, Blake2_128Concat, Hashable, + StorageHasher }; pub use self::storage::{ StorageValue, StorageMap, StorageLinkedMap, StorageDoubleMap, StoragePrefixedMap diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index cb22283924..02e6085046 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -64,13 +64,6 @@ pub trait Contains { fn count() -> usize { Self::sorted_members().len() } } -/// The account with the given id was killed. -#[impl_trait_for_tuples::impl_for_tuples(30)] -pub trait OnFreeBalanceZero { - /// The account with the given id was killed. - fn on_free_balance_zero(who: &AccountId); -} - /// The account with the given id was reaped. #[impl_trait_for_tuples::impl_for_tuples(30)] pub trait OnReapAccount { @@ -84,6 +77,12 @@ pub enum UpdateBalanceOutcome { Updated, /// The update led to killing the account. AccountKilled, + /// Free balance became zero as a result of this update. + FreeBalanceZero, + /// Reserved balance became zero as a result of this update. + ReservedBalanceZero, + /// The account started and ended non-existent. + StillDead, } /// A trait for finding the author of a block header based on the `PreRuntime` digests contained @@ -376,9 +375,7 @@ pub trait Currency { /// This is the only balance that matters in terms of most operations on tokens. It alone /// is used to determine the balance when in the contract execution environment. When this /// balance falls below the value of `ExistentialDeposit`, then the 'current account' is - /// deleted: specifically `FreeBalance`. Further, the `OnFreeBalanceZero` callback - /// is invoked, giving a chance to external modules to clean up data associated with - /// the deleted account. + /// deleted: specifically `FreeBalance`. /// /// `system::AccountNonce` is also deleted if `ReservedBalance` is also zero (it also gets /// collapsed to zero if it ever becomes less than `ExistentialDeposit`. @@ -581,7 +578,6 @@ pub trait LockableCurrency: Currency { id: LockIdentifier, who: &AccountId, amount: Self::Balance, - until: Self::Moment, reasons: WithdrawReasons, ); @@ -592,13 +588,11 @@ pub trait LockableCurrency: Currency { /// applies the most severe constraints of the two, while `set_lock` replaces the lock /// with the new parameters. As in, `extend_lock` will set: /// - maximum `amount` - /// - farthest duration (`until`) /// - bitwise mask of all `reasons` fn extend_lock( id: LockIdentifier, who: &AccountId, amount: Self::Balance, - until: Self::Moment, reasons: WithdrawReasons, ); @@ -609,13 +603,17 @@ pub trait LockableCurrency: Currency { ); } -/// A currency whose accounts can have balances which vest over time. -pub trait VestingCurrency: Currency { +/// A vesting schedule over a currency. This allows a particular currency to have vesting limits +/// applied to it. +pub trait VestingSchedule { /// The quantity used to denote time; usually just a `BlockNumber`. type Moment; + /// The currency that this schedule applies to. + type Currency: Currency; + /// Get the amount that is currently being vested and cannot be transferred out of this account. - fn vesting_balance(who: &AccountId) -> Self::Balance; + fn vesting_balance(who: &AccountId) -> >::Balance; /// Adds a vesting schedule to a given account. /// @@ -623,8 +621,8 @@ pub trait VestingCurrency: Currency { /// and nothing is updated. fn add_vesting_schedule( who: &AccountId, - locked: Self::Balance, - per_block: Self::Balance, + locked: >::Balance, + per_block: >::Balance, starting_block: Self::Moment, ) -> DispatchResult; @@ -644,7 +642,7 @@ bitmask! { TransactionPayment = 0b00000001, /// In order to transfer ownership. Transfer = 0b00000010, - /// In order to reserve some funds for a later return or repatriation + /// In order to reserve some funds for a later return or repatriation. Reserve = 0b00000100, /// In order to pay some other (higher-level) fees. Fee = 0b00001000, diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 34768d808e..645c3f8af5 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -76,7 +76,7 @@ pub trait Trait: frame_system::Trait { decl_storage! { trait Store for Module as Balances { - NextFeeMultiplier get(fn next_fee_multiplier): Multiplier = Multiplier::from_parts(0); + pub NextFeeMultiplier get(fn next_fee_multiplier): Multiplier = Multiplier::from_parts(0); } } @@ -178,9 +178,7 @@ impl ChargeTransactionPayment { let adjusted_fee = targeted_fee_adjustment.saturated_multiply_accumulate(adjustable_fee); let base_fee = T::TransactionBaseFee::get(); - let final_fee = base_fee.saturating_add(adjusted_fee).saturating_add(tip); - - final_fee + base_fee.saturating_add(adjusted_fee).saturating_add(tip) } else { tip } @@ -307,21 +305,18 @@ mod tests { } parameter_types! { - pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; pub const ExistentialDeposit: u64 = 0; } impl pallet_balances::Trait for Runtime { type Balance = u64; - type OnFreeBalanceZero = (); type OnReapAccount = System; type OnNewAccount = (); type Event = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; type CreationFee = CreationFee; } @@ -407,7 +402,6 @@ mod tests { (5, 50 * self.balance_factor), (6, 60 * self.balance_factor) ], - vesting: vec![], }.assimilate_storage(&mut t).unwrap(); t.into() } @@ -432,14 +426,14 @@ mod tests { .pre_dispatch(&1, CALL, info_from_weight(5), len) .is_ok() ); - assert_eq!(Balances::free_balance(&1), 100 - 5 - 5 - 10); + assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10); assert!( ChargeTransactionPayment::::from(5 /* tipped */) .pre_dispatch(&2, CALL, info_from_weight(3), len) .is_ok() ); - assert_eq!(Balances::free_balance(&2), 200 - 5 - 10 - 3 - 5); + assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 3 - 5); }); } @@ -474,7 +468,7 @@ mod tests { .execute_with(|| { // 1 ain't have a penny. - assert_eq!(Balances::free_balance(&1), 0); + assert_eq!(Balances::free_balance(1), 0); let len = 100; @@ -521,7 +515,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); }) } diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index 8d1c25ad66..0872bc718c 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -759,19 +759,16 @@ mod tests { } parameter_types! { pub const ExistentialDeposit: u64 = 1; - pub const TransferFee: u64 = 0; pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Test { type Balance = u64; type OnNewAccount = (); - type OnFreeBalanceZero = (); type OnReapAccount = System; type Event = (); type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; type CreationFee = CreationFee; } pub struct TenToFourteen; @@ -818,7 +815,6 @@ mod tests { pallet_balances::GenesisConfig::{ // Total issuance will be 200 with treasury account initialized at ED. balances: vec![(0, 100), (1, 98), (2, 1)], - vesting: vec![], }.assimilate_storage(&mut t).unwrap(); GenesisConfig::default().assimilate_storage::(&mut t).unwrap(); t.into() @@ -853,8 +849,8 @@ mod tests { new_test_ext().execute_with(|| { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Treasury::report_awesome(Origin::signed(0), b"awesome.dot".to_vec(), 3)); - assert_eq!(Balances::reserved_balance(&0), 12); - assert_eq!(Balances::free_balance(&0), 88); + assert_eq!(Balances::reserved_balance(0), 12); + assert_eq!(Balances::free_balance(0), 88); // other reports don't count. assert_noop!( @@ -869,9 +865,9 @@ mod tests { assert_noop!(Treasury::tip(Origin::signed(9), h.clone(), 10), BadOrigin); System::set_block_number(2); assert_ok!(Treasury::close_tip(Origin::signed(100), h.into())); - assert_eq!(Balances::reserved_balance(&0), 0); - assert_eq!(Balances::free_balance(&0), 102); - assert_eq!(Balances::free_balance(&3), 8); + assert_eq!(Balances::reserved_balance(0), 0); + assert_eq!(Balances::free_balance(0), 102); + assert_eq!(Balances::free_balance(3), 8); }); } @@ -880,16 +876,16 @@ mod tests { new_test_ext().execute_with(|| { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Treasury::report_awesome(Origin::signed(0), b"awesome.dot".to_vec(), 0)); - assert_eq!(Balances::reserved_balance(&0), 12); - assert_eq!(Balances::free_balance(&0), 88); + assert_eq!(Balances::reserved_balance(0), 12); + assert_eq!(Balances::free_balance(0), 88); let h = BlakeTwo256::hash_of(&(BlakeTwo256::hash(b"awesome.dot"), 0u64)); assert_ok!(Treasury::tip(Origin::signed(10), h.clone(), 10)); assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); System::set_block_number(2); assert_ok!(Treasury::close_tip(Origin::signed(100), h.into())); - assert_eq!(Balances::reserved_balance(&0), 0); - assert_eq!(Balances::free_balance(&0), 110); + assert_eq!(Balances::reserved_balance(0), 0); + assert_eq!(Balances::free_balance(0), 110); }); } @@ -910,7 +906,7 @@ mod tests { System::set_block_number(2); assert_noop!(Treasury::close_tip(Origin::NONE, h.into()), BadOrigin); assert_ok!(Treasury::close_tip(Origin::signed(0), h.into())); - assert_eq!(Balances::free_balance(&3), 10); + assert_eq!(Balances::free_balance(3), 10); assert_noop!(Treasury::close_tip(Origin::signed(100), h.into()), Error::::UnknownTip); }); @@ -942,7 +938,7 @@ mod tests { assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 1000000)); System::set_block_number(2); assert_ok!(Treasury::close_tip(Origin::signed(0), h.into())); - assert_eq!(Balances::free_balance(&3), 10); + assert_eq!(Balances::free_balance(3), 10); }); } @@ -961,7 +957,7 @@ mod tests { assert_ok!(Treasury::tip(Origin::signed(10), h.clone(), 10)); System::set_block_number(2); assert_ok!(Treasury::close_tip(Origin::signed(0), h.into())); - assert_eq!(Balances::free_balance(&3), 10); + assert_eq!(Balances::free_balance(3), 10); }); } @@ -978,8 +974,8 @@ mod tests { fn spend_proposal_takes_min_deposit() { new_test_ext().execute_with(|| { assert_ok!(Treasury::propose_spend(Origin::signed(0), 1, 3)); - assert_eq!(Balances::free_balance(&0), 99); - assert_eq!(Balances::reserved_balance(&0), 1); + assert_eq!(Balances::free_balance(0), 99); + assert_eq!(Balances::reserved_balance(0), 1); }); } @@ -987,8 +983,8 @@ mod tests { fn spend_proposal_takes_proportional_deposit() { new_test_ext().execute_with(|| { assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); - assert_eq!(Balances::free_balance(&0), 95); - assert_eq!(Balances::reserved_balance(&0), 5); + assert_eq!(Balances::free_balance(0), 95); + assert_eq!(Balances::reserved_balance(0), 5); }); } @@ -1011,7 +1007,7 @@ mod tests { assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); >::on_finalize(1); - assert_eq!(Balances::free_balance(&3), 0); + assert_eq!(Balances::free_balance(3), 0); assert_eq!(Treasury::pot(), 100); }); } @@ -1038,7 +1034,7 @@ mod tests { assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0)); >::on_finalize(2); - assert_eq!(Balances::free_balance(&3), 0); + assert_eq!(Balances::free_balance(3), 0); assert_eq!(Treasury::pot(), 50); }); } @@ -1089,7 +1085,7 @@ mod tests { assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); >::on_finalize(2); - assert_eq!(Balances::free_balance(&3), 100); + assert_eq!(Balances::free_balance(3), 100); assert_eq!(Treasury::pot(), 0); }); } @@ -1108,7 +1104,7 @@ mod tests { let _ = Balances::deposit_into_existing(&Treasury::account_id(), 100).unwrap(); >::on_finalize(4); - assert_eq!(Balances::free_balance(&3), 150); // Fund has been spent + assert_eq!(Balances::free_balance(3), 150); // Fund has been spent assert_eq!(Treasury::pot(), 25); // Pot has finally changed }); } @@ -1133,7 +1129,7 @@ mod tests { >::on_finalize(4); assert_eq!(Treasury::pot(), 0); // Pot is emptied - assert_eq!(Balances::free_balance(&Treasury::account_id()), 1); // but the account is still there + assert_eq!(Balances::free_balance(Treasury::account_id()), 1); // but the account is still there }); } @@ -1144,13 +1140,12 @@ mod tests { 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: sp_io::TestExternalities = t.into(); t.execute_with(|| { - assert_eq!(Balances::free_balance(&Treasury::account_id()), 0); // Account does not exist + assert_eq!(Balances::free_balance(Treasury::account_id()), 0); // Account does not exist assert_eq!(Treasury::pot(), 0); // Pot is empty assert_ok!(Treasury::propose_spend(Origin::signed(0), 99, 3)); @@ -1159,16 +1154,16 @@ mod tests { assert_ok!(Treasury::approve_proposal(Origin::ROOT, 1)); >::on_finalize(2); assert_eq!(Treasury::pot(), 0); // Pot hasn't changed - assert_eq!(Balances::free_balance(&3), 0); // Balance of `3` hasn't changed + assert_eq!(Balances::free_balance(3), 0); // Balance of `3` hasn't changed Balances::make_free_balance_be(&Treasury::account_id(), 100); assert_eq!(Treasury::pot(), 99); // Pot now contains funds - assert_eq!(Balances::free_balance(&Treasury::account_id()), 100); // Account does exist + assert_eq!(Balances::free_balance(Treasury::account_id()), 100); // Account does exist >::on_finalize(4); assert_eq!(Treasury::pot(), 0); // Pot has changed - assert_eq!(Balances::free_balance(&3), 99); // Balance of `3` has changed + assert_eq!(Balances::free_balance(3), 99); // Balance of `3` has changed }); } } diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index 7344294684..fcd340eef5 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -703,19 +703,16 @@ mod tests { } 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 OnReapAccount = System; type OnNewAccount = (); type Event = TestEvent; type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type TransferFee = TransferFee; type CreationFee = CreationFee; } parameter_types! { @@ -742,7 +739,6 @@ mod tests { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); pallet_balances::GenesisConfig:: { balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 10)], - vesting: vec![], }.assimilate_storage(&mut t).unwrap(); t.into() } diff --git a/frame/vesting/Cargo.toml b/frame/vesting/Cargo.toml new file mode 100644 index 0000000000..6923297af5 --- /dev/null +++ b/frame/vesting/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "pallet-vesting" +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" } +sp-storage = { version = "2.0.0", path = "../../primitives/storage" } +hex-literal = "0.2.1" + +[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/vesting/src/lib.rs b/frame/vesting/src/lib.rs new file mode 100644 index 0000000000..4a079e7693 --- /dev/null +++ b/frame/vesting/src/lib.rs @@ -0,0 +1,610 @@ +// Copyright 2019-2020 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 . + +//! # Vesting Module +//! +//! - [`vesting::Trait`](./trait.Trait.html) +//! - [`Call`](./enum.Call.html) +//! +//! ## Overview +//! +//! A simple module providing a means of placing a linear curve on an account's locked balance. This +//! module ensures that there is a lock in place preventing the balance to drop below the *unvested* +//! amount for any reason other than transaction fee payment. +//! +//! As the amount vested increases over time, the amount unvested reduces. However, locks remain in +//! place and explicit action is needed on behalf of the user to ensure that the amount locked is +//! equivalent to the amount remaining to be vested. This is done through a dispatchable function, +//! either `vest` (in typical case where the sender is calling on their own behalf) or `vest_other` +//! in case the sender is calling on another account's behalf. +//! +//! ## Interface +//! +//! This module implements the `VestingSchedule` trait. +//! +//! ### Dispatchable Functions +//! +//! - `vest` - Update the lock, reducing it in line with the amount "vested" so far. +//! - `vest_other` - Update the lock of another account, reducing it in line with the amount +//! "vested" so far. +//! +//! [`Call`]: ./enum.Call.html +//! [`Trait`]: ./trait.Trait.html + +#![cfg_attr(not(feature = "std"), no_std)] + +use sp_std::prelude::*; +use sp_std::fmt::Debug; +use codec::{Encode, Decode}; +use sp_runtime::{DispatchResult, RuntimeDebug, traits::{ + StaticLookup, Zero, SimpleArithmetic, MaybeSerializeDeserialize, Saturating, Convert +}}; +use frame_support::{decl_module, decl_event, decl_storage, ensure, decl_error}; +use frame_support::traits::{ + Currency, LockableCurrency, VestingSchedule, WithdrawReason, LockIdentifier +}; +use frame_system::{self as system, ensure_signed}; + +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; + +pub trait Trait: frame_system::Trait { + /// The overarching event type. + type Event: From> + Into<::Event>; + + /// The currency trait. + type Currency: LockableCurrency; + + /// Convert the block number into a balance. + type BlockNumberToBalance: Convert>; +} + +const VESTING_ID: LockIdentifier = *b"vesting "; + +/// Struct to encode the vesting schedule of an individual account. +#[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug)] +pub struct VestingInfo { + /// Locked amount at genesis. + pub locked: Balance, + /// Amount that gets unlocked every block after `starting_block`. + pub per_block: Balance, + /// Starting block for unlocking(vesting). + pub starting_block: BlockNumber, +} + +impl< + Balance: SimpleArithmetic + Copy, + BlockNumber: SimpleArithmetic + Copy, +> VestingInfo { + /// Amount locked at block `n`. + pub fn locked_at< + BlockNumberToBalance: Convert + >(&self, n: BlockNumber) -> Balance { + // Number of blocks that count toward vesting + // Saturating to 0 when n < starting_block + let vested_block_count = n.saturating_sub(self.starting_block); + let vested_block_count = BlockNumberToBalance::convert(vested_block_count); + // Return amount that is still locked in vesting + let maybe_balance = vested_block_count.checked_mul(&self.per_block); + if let Some(balance) = maybe_balance { + self.locked.saturating_sub(balance) + } else { + Zero::zero() + } + } +} + +decl_storage! { + trait Store for Module as Vesting { + /// Information regarding the vesting of a given account. + pub Vesting get(fn vesting): + map hasher(blake2_256) T::AccountId => Option, T::BlockNumber>>; + } + add_extra_genesis { + config(vesting): Vec<(T::AccountId, T::BlockNumber, T::BlockNumber, BalanceOf)>; + build(|config: &GenesisConfig| { + // Generate initial vesting configuration + // * who - Account which we are generating vesting configuration for + // * begin - Block when the account will start to vest + // * length - Number of blocks from `begin` until fully vested + // * liquid - Number of units which can be spent before vesting begins + for &(ref who, begin, length, liquid) in config.vesting.iter() { + let balance = T::Currency::free_balance(who); + assert!(!balance.is_zero(), "Currencies must be init'd before vesting"); + // Total genesis `balance` minus `liquid` equals funds locked for vesting + let locked = balance.saturating_sub(liquid); + let length_as_balance = T::BlockNumberToBalance::convert(length); + let per_block = locked / length_as_balance.max(sp_runtime::traits::One::one()); + + Vesting::::insert(who, VestingInfo { + locked: locked, + per_block: per_block, + starting_block: begin + }); + let reasons = WithdrawReason::Transfer | WithdrawReason::Reserve; + T::Currency::set_lock(VESTING_ID, who, locked, reasons); + } + }) + } +} + +decl_event!( + pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { + /// The amount vested has been updated. This could indicate more funds are available. The + /// balance given is the amount which is left unvested (and thus locked). + VestingUpdated(AccountId, Balance), + /// An account (given) has become fully vested. No further vesting can happen. + VestingCompleted(AccountId), + } +); + +decl_error! { + /// Error for the vesting module. + pub enum Error for Module { + /// The account given is not vesting. + NotVesting, + /// An existing vesting schedule already exists for this account that cannot be clobbered. + ExistingVestingSchedule, + } +} + +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; + + /// Unlock any vested funds of the sender account. + /// + /// The dispatch origin for this call must be _Signed_ and the sender must have funds still + /// locked under this module. + /// + /// Emits either `VestingCompleted` or `VestingUpdated`. + /// + /// # + /// - `O(1)`. + /// - One balance-lock operation. + /// - One storage read (codec `O(1)`) and up to one removal. + /// - One event. + /// # + fn vest(origin) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::update_lock(who) + } + + /// Unlock any vested funds of a `target` account. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// - `target`: The account whose vested funds should be unlocked. Must have funds still + /// locked under this module. + /// + /// Emits either `VestingCompleted` or `VestingUpdated`. + /// + /// # + /// - `O(1)`. + /// - Up to one account lookup. + /// - One balance-lock operation. + /// - One storage read (codec `O(1)`) and up to one removal. + /// - One event. + /// # + fn vest_other(origin, target: ::Source) -> DispatchResult { + ensure_signed(origin)?; + Self::update_lock(T::Lookup::lookup(target)?) + } + } +} + +impl Module { + /// (Re)set or remove the module's currency lock on `who`'s account in accordance with their + /// current unvested amount. + fn update_lock(who: T::AccountId) -> DispatchResult { + ensure!(Vesting::::exists(&who), Error::::NotVesting); + let unvested = Self::vesting_balance(&who); + if unvested.is_zero() { + T::Currency::remove_lock(VESTING_ID, &who); + Vesting::::remove(&who); + Self::deposit_event(RawEvent::VestingCompleted(who)); + } else { + let reasons = WithdrawReason::Transfer | WithdrawReason::Reserve; + T::Currency::set_lock(VESTING_ID, &who, unvested, reasons); + Self::deposit_event(RawEvent::VestingUpdated(who, unvested)); + } + Ok(()) + } +} + +impl VestingSchedule for Module where + BalanceOf: MaybeSerializeDeserialize + Debug +{ + type Moment = T::BlockNumber; + type Currency = T::Currency; + + /// Get the amount that is currently being vested and cannot be transferred out of this account. + fn vesting_balance(who: &T::AccountId) -> BalanceOf { + if let Some(v) = Self::vesting(who) { + let now = >::block_number(); + let locked_now = v.locked_at::(now); + T::Currency::free_balance(who).min(locked_now) + } 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. + /// + /// Is a no-op if the amount to be vested is zero. + fn add_vesting_schedule( + who: &T::AccountId, + locked: BalanceOf, + per_block: BalanceOf, + starting_block: T::BlockNumber + ) -> DispatchResult { + if locked.is_zero() { return Ok(()) } + if Vesting::::exists(who) { + Err(Error::::ExistingVestingSchedule)? + } + let vesting_schedule = VestingInfo { + locked, + per_block, + starting_block + }; + Vesting::::insert(who, vesting_schedule); + // it can't fail, but even if somehow it did, we don't really care. + let _ = Self::update_lock(who.clone()); + Ok(()) + } + + /// Remove a vesting schedule for a given account. + fn remove_vesting_schedule(who: &T::AccountId) { + Vesting::::remove(who); + // it can't fail, but even if somehow it did, we don't really care. + let _ = Self::update_lock(who.clone()); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use std::cell::RefCell; + use frame_support::{ + assert_ok, assert_noop, impl_outer_origin, parameter_types, weights::Weight, + traits::Get + }; + 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 sp_runtime::{ + Perbill, testing::Header, traits::{BlakeTwo256, IdentityLookup, Identity, OnInitialize}, + }; + use sp_storage::Storage; + + 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 CreationFee: u64 = 0; + } + impl pallet_balances::Trait for Test { + type Balance = u64; + type OnReapAccount = System; + type OnNewAccount = (); + type Event = (); + type TransferPayment = (); + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type CreationFee = CreationFee; + } + impl Trait for Test { + type Event = (); + type Currency = Balances; + type BlockNumberToBalance = Identity; + } + type System = frame_system::Module; + type Balances = pallet_balances::Module; + type Vesting = Module; + + thread_local! { + static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); + } + pub struct ExistentialDeposit; + impl Get for ExistentialDeposit { + fn get() -> u64 { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow()) } + } + + pub struct ExtBuilder { + existential_deposit: u64, + } + impl Default for ExtBuilder { + fn default() -> Self { + Self { + existential_deposit: 1, + } + } + } + impl ExtBuilder { + pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { + self.existential_deposit = existential_deposit; + self + } + pub fn build(self) -> sp_io::TestExternalities { + EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![ + (1, 10 * self.existential_deposit), + (2, 20 * self.existential_deposit), + (3, 30 * self.existential_deposit), + (4, 40 * self.existential_deposit), + (12, 10 * self.existential_deposit) + ], + }.assimilate_storage(&mut t).unwrap(); + GenesisConfig:: { + vesting: vec![ + (1, 0, 10, 5 * self.existential_deposit), + (2, 10, 20, 0), + (12, 10, 20, 5 * self.existential_deposit) + ], + }.assimilate_storage(&mut t).unwrap(); + t.into() + } + } + + #[test] + fn vesting_info_via_migration_should_work() { + let mut s = Storage::default(); + use hex_literal::hex; + // A dump of data from the previous version for which we know account 6 vests 30 of its 60 + // over 5 blocks from block 3. + let data = vec![ + (hex!["26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac"].to_vec(), hex!["0100000000000000"].to_vec()), + (hex!["26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850"].to_vec(), hex!["02000000"].to_vec()), + (hex!["26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7"].to_vec(), hex!["08000000000000000000000000"].to_vec()), + (hex!["26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc"].to_vec(), hex!["4545454545454545454545454545454545454545454545454545454545454545"].to_vec()), + (hex!["26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c11874681e47a19e6b29b0a65b9591762ce5143ed30d0261e5d24a3201752506b20f15c"].to_vec(), hex!["4545454545454545454545454545454545454545454545454545454545454545"].to_vec()), + (hex!["3a636f6465"].to_vec(), hex![""].to_vec()), + (hex!["3a65787472696e7369635f696e646578"].to_vec(), hex!["00000000"].to_vec()), + (hex!["3a686561707061676573"].to_vec(), hex!["0800000000000000"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc61dbd7d0b561a41d23c2a469ad42fbd70d5438bae826f6fd607413190c37c363b"].to_vec(), hex!["046d697363202020200300000000000000ffffffffffffffff04"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc66cddb367afbd583bb48f9bbd7d5ba3b1d0738b4881b1cddd38169526d8158137"].to_vec(), hex!["0474786665657320200300000000000000ffffffffffffffff01"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6e88b43fded6323ef02ffeffbd8c40846ee09bf316271bd22369659c959dd733a"].to_vec(), hex!["08616c6c20202020200300000000000000ffffffffffffffff1f64656d6f63726163ffffffffffffffff030000000000000002"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f3c22813def93ef32c365b55cb92f10f91dbd7d0b561a41d23c2a469ad42fbd70d5438bae826f6fd607413190c37c363b"].to_vec(), hex!["0500000000000000"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80"].to_vec(), hex!["d200000000000000"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f5f27b51b5ec208ee9cb25b55d8728243b8788bb218b185b63e3e92653953f29b6b143fb8cf5159fc908632e6fe490501"].to_vec(), hex!["1e0000000000000006000000000000000200000000000000"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b41dbd7d0b561a41d23c2a469ad42fbd70d5438bae826f6fd607413190c37c363b"].to_vec(), hex!["0500000000000000"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b46cddb367afbd583bb48f9bbd7d5ba3b1d0738b4881b1cddd38169526d8158137"].to_vec(), hex!["1e00000000000000"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4b8788bb218b185b63e3e92653953f29b6b143fb8cf5159fc908632e6fe490501"].to_vec(), hex!["3c00000000000000"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e88b43fded6323ef02ffeffbd8c40846ee09bf316271bd22369659c959dd733a"].to_vec(), hex!["1400000000000000"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4e96760d274653a39b429a87ebaae9d3aa4fdf58b9096cf0bebc7c4e5a4c2ed8d"].to_vec(), hex!["2800000000000000"].to_vec()), + (hex!["c2261276cc9d1f8598ea4b6a74b15c2f6482b9ade7bc6657aaca787ba1add3b4effb728943197fd12e694cbf3f3ede28fbf7498b0370c6dfa0013874b417c178"].to_vec(), hex!["3200000000000000"].to_vec()), + (hex!["f2794c22e353e9a839f12faab03a911b7f17cdfbfa73331856cca0acddd7842e"].to_vec(), hex!["00000000"].to_vec()), + (hex!["f2794c22e353e9a839f12faab03a911bbdcb0c5143a8617ed38ae3810dd45bc6"].to_vec(), hex!["00000000"].to_vec()), + (hex!["f2794c22e353e9a839f12faab03a911be2f6cb0456905c189bcb0458f9440f13"].to_vec(), hex!["00000000"].to_vec()), + ]; + s.top = data.into_iter().collect(); + sp_io::TestExternalities::new(s).execute_with(|| { + Balances::on_initialize(1); + assert_eq!(Balances::free_balance(6), 60); + assert_eq!(Balances::usable_balance(&6), 30); + System::set_block_number(2); + assert_ok!(Vesting::vest(Origin::signed(6))); + assert_eq!(Balances::usable_balance(&6), 30); + System::set_block_number(3); + assert_ok!(Vesting::vest(Origin::signed(6))); + assert_eq!(Balances::usable_balance(&6), 36); + System::set_block_number(4); + assert_ok!(Vesting::vest(Origin::signed(6))); + assert_eq!(Balances::usable_balance(&6), 42); + }); + } + + #[test] + fn check_vesting_status() { + ExtBuilder::default() + .existential_deposit(256) + .build() + .execute_with(|| { + assert_eq!(System::block_number(), 1); + let user1_free_balance = Balances::free_balance(&1); + let user2_free_balance = Balances::free_balance(&2); + let user12_free_balance = Balances::free_balance(&12); + assert_eq!(user1_free_balance, 256 * 10); // Account 1 has free balance + assert_eq!(user2_free_balance, 256 * 20); // Account 2 has free balance + assert_eq!(user12_free_balance, 256 * 10); // Account 12 has free balance + let user1_vesting_schedule = VestingInfo { + locked: 256 * 5, + per_block: 128, // Vesting over 10 blocks + starting_block: 0, + }; + let user2_vesting_schedule = VestingInfo { + locked: 256 * 20, + per_block: 256, // Vesting over 20 blocks + starting_block: 10, + }; + let user12_vesting_schedule = VestingInfo { + locked: 256 * 5, + per_block: 64, // Vesting over 20 blocks + starting_block: 10, + }; + assert_eq!(Vesting::vesting(&1), Some(user1_vesting_schedule)); // Account 1 has a vesting schedule + assert_eq!(Vesting::vesting(&2), Some(user2_vesting_schedule)); // Account 2 has a vesting schedule + assert_eq!(Vesting::vesting(&12), Some(user12_vesting_schedule)); // Account 12 has a vesting schedule + + // Account 1 has only 128 units vested from their illiquid 256 * 5 units at block 1 + assert_eq!(Vesting::vesting_balance(&1), 128 * 9); + // Account 2 has their full balance locked + assert_eq!(Vesting::vesting_balance(&2), user2_free_balance); + // Account 12 has only their illiquid funds locked + assert_eq!(Vesting::vesting_balance(&12), user12_free_balance - 256 * 5); + + System::set_block_number(10); + assert_eq!(System::block_number(), 10); + + // Account 1 has fully vested by block 10 + assert_eq!(Vesting::vesting_balance(&1), 0); + // Account 2 has started vesting by block 10 + assert_eq!(Vesting::vesting_balance(&2), user2_free_balance); + // Account 12 has started vesting by block 10 + assert_eq!(Vesting::vesting_balance(&12), user12_free_balance - 256 * 5); + + System::set_block_number(30); + assert_eq!(System::block_number(), 30); + + assert_eq!(Vesting::vesting_balance(&1), 0); // Account 1 is still fully vested, and not negative + assert_eq!(Vesting::vesting_balance(&2), 0); // Account 2 has fully vested by block 30 + assert_eq!(Vesting::vesting_balance(&12), 0); // Account 2 has fully vested by block 30 + + }); + } + + #[test] + fn unvested_balance_should_not_transfer() { + ExtBuilder::default() + .existential_deposit(10) + .build() + .execute_with(|| { + assert_eq!(System::block_number(), 1); + let user1_free_balance = Balances::free_balance(&1); + assert_eq!(user1_free_balance, 100); // Account 1 has free balance + // Account 1 has only 5 units vested at block 1 (plus 50 unvested) + assert_eq!(Vesting::vesting_balance(&1), 45); + assert_noop!( + Balances::transfer(Some(1).into(), 2, 56), + pallet_balances::Error::::LiquidityRestrictions, + ); // Account 1 cannot send more than vested amount + }); + } + + #[test] + fn vested_balance_should_transfer() { + ExtBuilder::default() + .existential_deposit(10) + .build() + .execute_with(|| { + assert_eq!(System::block_number(), 1); + let user1_free_balance = Balances::free_balance(&1); + assert_eq!(user1_free_balance, 100); // Account 1 has free balance + // Account 1 has only 5 units vested at block 1 (plus 50 unvested) + assert_eq!(Vesting::vesting_balance(&1), 45); + assert_ok!(Vesting::vest(Some(1).into())); + assert_ok!(Balances::transfer(Some(1).into(), 2, 55)); + }); + } + + #[test] + fn vested_balance_should_transfer_using_vest_other() { + ExtBuilder::default() + .existential_deposit(10) + .build() + .execute_with(|| { + assert_eq!(System::block_number(), 1); + let user1_free_balance = Balances::free_balance(&1); + assert_eq!(user1_free_balance, 100); // Account 1 has free balance + // Account 1 has only 5 units vested at block 1 (plus 50 unvested) + assert_eq!(Vesting::vesting_balance(&1), 45); + assert_ok!(Vesting::vest_other(Some(2).into(), 1)); + assert_ok!(Balances::transfer(Some(1).into(), 2, 55)); + }); + } + + #[test] + fn extra_balance_should_transfer() { + ExtBuilder::default() + .existential_deposit(10) + .build() + .execute_with(|| { + assert_eq!(System::block_number(), 1); + assert_ok!(Balances::transfer(Some(3).into(), 1, 100)); + assert_ok!(Balances::transfer(Some(3).into(), 2, 100)); + + let user1_free_balance = Balances::free_balance(&1); + assert_eq!(user1_free_balance, 200); // Account 1 has 100 more free balance than normal + + let user2_free_balance = Balances::free_balance(&2); + assert_eq!(user2_free_balance, 300); // Account 2 has 100 more free balance than normal + + // Account 1 has only 5 units vested at block 1 (plus 150 unvested) + assert_eq!(Vesting::vesting_balance(&1), 45); + assert_ok!(Vesting::vest(Some(1).into())); + assert_ok!(Balances::transfer(Some(1).into(), 3, 155)); // Account 1 can send extra units gained + + // Account 2 has no units vested at block 1, but gained 100 + assert_eq!(Vesting::vesting_balance(&2), 200); + assert_ok!(Vesting::vest(Some(2).into())); + assert_ok!(Balances::transfer(Some(2).into(), 3, 100)); // Account 2 can send extra units gained + }); + } + + #[test] + fn liquid_funds_should_transfer_with_delayed_vesting() { + ExtBuilder::default() + .existential_deposit(256) + .build() + .execute_with(|| { + assert_eq!(System::block_number(), 1); + let user12_free_balance = Balances::free_balance(&12); + + assert_eq!(user12_free_balance, 2560); // Account 12 has free balance + // Account 12 has liquid funds + assert_eq!(Vesting::vesting_balance(&12), user12_free_balance - 256 * 5); + + // Account 12 has delayed vesting + let user12_vesting_schedule = VestingInfo { + locked: 256 * 5, + per_block: 64, // Vesting over 20 blocks + starting_block: 10, + }; + assert_eq!(Vesting::vesting(&12), Some(user12_vesting_schedule)); + + // Account 12 can still send liquid funds + assert_ok!(Balances::transfer(Some(12).into(), 3, 256 * 5)); + }); + } +} -- GitLab From 4d9baeb7c72923a3de6d4a31fd0cebe42c97edca Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 1 Feb 2020 13:28:37 +0000 Subject: [PATCH 069/180] Urgent patch --- frame/balances/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index 65ad226d53..3395ef0f1a 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -386,7 +386,7 @@ decl_storage! { pub Locks get(fn locks): map hasher(blake2_256) T::AccountId => Vec>; /// True if network has been upgraded to this version. - IsUpgraded: bool; + IsUpgraded: bool = true; } add_extra_genesis { config(balances): Vec<(T::AccountId, T::Balance)>; -- GitLab From a52588de7ef5d261f3616eb501eb7eb29487ba33 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Sat, 1 Feb 2020 16:35:05 +0100 Subject: [PATCH 070/180] fork-tree: add support for find_node_mut_where (#4784) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fork-tree: add support for find_node_mut_where * Update utils/fork-tree/src/lib.rs Co-Authored-By: Bastian Köcher * Update utils/fork-tree/src/lib.rs Co-Authored-By: Bastian Köcher * Update utils/fork-tree/src/lib.rs Co-Authored-By: Bastian Köcher * Fix calling name * Update utils/fork-tree/src/lib.rs Co-Authored-By: Robert Habermeier * doc: be precise what is "least significant" index Co-authored-by: Bastian Köcher Co-authored-by: Robert Habermeier --- utils/fork-tree/src/lib.rs | 121 ++++++++++++++++++++++++++++++++----- 1 file changed, 107 insertions(+), 14 deletions(-) diff --git a/utils/fork-tree/src/lib.rs b/utils/fork-tree/src/lib.rs index 1aa085c3da..8ce0b729c6 100644 --- a/utils/fork-tree/src/lib.rs +++ b/utils/fork-tree/src/lib.rs @@ -200,7 +200,7 @@ impl ForkTree where data, hash: hash, number: number, - children: Vec::new(), + children: Vec::new(), }); self.rebalance(); @@ -232,10 +232,10 @@ impl ForkTree where number: &N, is_descendent_of: &F, predicate: &P, - ) -> Result>, Error> - where E: std::error::Error, - F: Fn(&H, &H) -> Result, - P: Fn(&V) -> bool, + ) -> Result>, Error> where + E: std::error::Error, + F: Fn(&H, &H) -> Result, + P: Fn(&V) -> bool, { // search for node starting from all roots for root in self.roots.iter() { @@ -250,6 +250,31 @@ impl ForkTree where Ok(None) } + /// Same as [`find_node_where`](Self::find_node_where), but returns mutable reference. + pub fn find_node_where_mut( + &mut self, + hash: &H, + number: &N, + is_descendent_of: &F, + predicate: &P, + ) -> Result>, Error> where + E: std::error::Error, + F: Fn(&H, &H) -> Result, + P: Fn(&V) -> bool, + { + // search for node starting from all roots + for root in self.roots.iter_mut() { + let node = root.find_node_where_mut(hash, number, is_descendent_of, predicate)?; + + // found the node, early exit + if let FindOutcome::Found(node) = node { + return Ok(Some(node)); + } + } + + Ok(None) + } + /// Finalize a root in the tree and return it, return `None` in case no root /// with the given hash exists. All other roots are pruned, and the children /// of the finalized node become the new roots. @@ -609,16 +634,17 @@ mod node_implementation { /// when the predicate fails. /// The given function `is_descendent_of` should return `true` if the second hash (target) /// is a descendent of the first hash (base). - // FIXME: it would be useful if this returned a mutable reference but - // rustc can't deal with lifetimes properly. an option would be to try - // an iterative definition instead. - pub fn find_node_where( + /// + /// The returned indices are from last to first. The earliest index in the traverse path + /// goes last, and the final index in the traverse path goes first. An empty list means + /// that the current node is the result. + pub fn find_node_index_where( &self, hash: &H, number: &N, is_descendent_of: &F, predicate: &P, - ) -> Result>, Error> + ) -> Result>, Error> where E: std::error::Error, F: Fn(&H, &H) -> Result, P: Fn(&V) -> bool, @@ -631,11 +657,14 @@ mod node_implementation { let mut known_descendent_of = false; // continue depth-first search through all children - for node in self.children.iter() { + for (i, node) in self.children.iter().enumerate() { // found node, early exit - match node.find_node_where(hash, number, is_descendent_of, predicate)? { + match node.find_node_index_where(hash, number, is_descendent_of, predicate)? { FindOutcome::Abort => return Ok(FindOutcome::Abort), - FindOutcome::Found(x) => return Ok(FindOutcome::Found(x)), + FindOutcome::Found(mut x) => { + x.push(i); + return Ok(FindOutcome::Found(x)) + }, FindOutcome::Failure(true) => { // if the block was a descendent of this child, // then it cannot be a descendent of any others, @@ -655,7 +684,7 @@ mod node_implementation { if is_descendent_of { // if the predicate passes we return the node if predicate(&self.data) { - return Ok(FindOutcome::Found(self)); + return Ok(FindOutcome::Found(Vec::new())); } } @@ -663,6 +692,70 @@ mod node_implementation { // the block was a descendent. Ok(FindOutcome::Failure(is_descendent_of)) } + + /// Find a node in the tree that is the deepest ancestor of the given + /// block hash which also passes the given predicate, backtracking + /// when the predicate fails. + /// The given function `is_descendent_of` should return `true` if the second hash (target) + /// is a descendent of the first hash (base). + pub fn find_node_where( + &self, + hash: &H, + number: &N, + is_descendent_of: &F, + predicate: &P, + ) -> Result>, Error> + where E: std::error::Error, + F: Fn(&H, &H) -> Result, + P: Fn(&V) -> bool, + { + let outcome = self.find_node_index_where(hash, number, is_descendent_of, predicate)?; + + match outcome { + FindOutcome::Abort => Ok(FindOutcome::Abort), + FindOutcome::Failure(f) => Ok(FindOutcome::Failure(f)), + FindOutcome::Found(mut indexes) => { + let mut cur = self; + + while let Some(i) = indexes.pop() { + cur = &cur.children[i]; + } + Ok(FindOutcome::Found(cur)) + }, + } + } + + /// Find a node in the tree that is the deepest ancestor of the given + /// block hash which also passes the given predicate, backtracking + /// when the predicate fails. + /// The given function `is_descendent_of` should return `true` if the second hash (target) + /// is a descendent of the first hash (base). + pub fn find_node_where_mut( + &mut self, + hash: &H, + number: &N, + is_descendent_of: &F, + predicate: &P, + ) -> Result>, Error> + where E: std::error::Error, + F: Fn(&H, &H) -> Result, + P: Fn(&V) -> bool, + { + let outcome = self.find_node_index_where(hash, number, is_descendent_of, predicate)?; + + match outcome { + FindOutcome::Abort => Ok(FindOutcome::Abort), + FindOutcome::Failure(f) => Ok(FindOutcome::Failure(f)), + FindOutcome::Found(mut indexes) => { + let mut cur = self; + + while let Some(i) = indexes.pop() { + cur = &mut cur.children[i]; + } + Ok(FindOutcome::Found(cur)) + }, + } + } } } -- GitLab From de2ffd937db78093efaa58d7cc08f5599a8f4728 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Sat, 1 Feb 2020 18:08:39 +0000 Subject: [PATCH 071/180] Don't attempt to upgrade balances module on chain start (#4802) * Introduce vesting to node, debug message for upgrades and fix them * Bump spec version --- Cargo.lock | 1 + bin/node/cli/src/chain_spec.rs | 3 ++- bin/node/runtime/Cargo.toml | 2 ++ bin/node/runtime/src/lib.rs | 12 +++++++++--- bin/node/testing/src/genesis.rs | 1 + frame/balances/src/lib.rs | 5 ++++- 6 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 64652d30ed..814cfbbe2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3209,6 +3209,7 @@ dependencies = [ "pallet-transaction-payment-rpc-runtime-api 2.0.0", "pallet-treasury 2.0.0", "pallet-utility 2.0.0", + "pallet-vesting 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/bin/node/cli/src/chain_spec.rs b/bin/node/cli/src/chain_spec.rs index 4ce0c8f49b..868b991480 100644 --- a/bin/node/cli/src/chain_spec.rs +++ b/bin/node/cli/src/chain_spec.rs @@ -298,7 +298,8 @@ pub fn testnet_genesis( members: endowed_accounts[0..3].to_vec(), pot: 0, max_members: 999, - }) + }), + pallet_vesting: Some(Default::default()), } } diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 7bc105b55e..3f8e8b6731 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -65,6 +65,7 @@ pallet-treasury = { version = "2.0.0", default-features = false, path = "../../. 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/" } +pallet-vesting = { version = "2.0.0", default-features = false, path = "../../../frame/vesting" } [build-dependencies] wasm-builder-runner = { version = "1.0.4", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } @@ -125,4 +126,5 @@ std = [ "sp-version/std", "pallet-society/std", "pallet-recovery/std", + "pallet-vesting/std", ] diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 0e6a337a8b..f2c374cedd 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -35,8 +35,7 @@ use sp_runtime::{ use sp_runtime::curve::PiecewiseLinear; use sp_runtime::transaction_validity::TransactionValidity; use sp_runtime::traits::{ - self, BlakeTwo256, Block as BlockT, StaticLookup, SaturatedConversion, - OpaqueKeys, + self, BlakeTwo256, Block as BlockT, StaticLookup, SaturatedConversion, ConvertInto, OpaqueKeys, }; use sp_version::RuntimeVersion; #[cfg(any(feature = "std", test))] @@ -80,7 +79,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 211, + spec_version: 212, impl_version: 0, apis: RUNTIME_API_VERSIONS, }; @@ -586,6 +585,12 @@ impl pallet_society::Trait for Runtime { type ChallengePeriod = ChallengePeriod; } +impl pallet_vesting::Trait for Runtime { + type Event = Event; + type Currency = Balances; + type BlockNumberToBalance = ConvertInto; +} + construct_runtime!( pub enum Runtime where Block = Block, @@ -619,6 +624,7 @@ construct_runtime!( Identity: pallet_identity::{Module, Call, Storage, Event}, Society: pallet_society::{Module, Call, Storage, Event, Config}, Recovery: pallet_recovery::{Module, Call, Storage, Event}, + Vesting: pallet_vesting::{Module, Call, Storage, Event, Config}, } ); diff --git a/bin/node/testing/src/genesis.rs b/bin/node/testing/src/genesis.rs index 5949781275..8c5514defa 100644 --- a/bin/node/testing/src/genesis.rs +++ b/bin/node/testing/src/genesis.rs @@ -100,5 +100,6 @@ pub fn config(support_changes_trie: bool, code: Option<&[u8]>) -> GenesisConfig pot: 0, max_members: 999, }), + pallet_vesting: Some(Default::default()), } } diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index 3395ef0f1a..4b3e88eb9f 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -386,7 +386,9 @@ decl_storage! { pub Locks get(fn locks): map hasher(blake2_256) T::AccountId => Vec>; /// True if network has been upgraded to this version. - IsUpgraded: bool = true; + /// + /// True for new networks. + IsUpgraded build(|_: &GenesisConfig| true): bool; } add_extra_genesis { config(balances): Vec<(T::AccountId, T::Balance)>; @@ -561,6 +563,7 @@ impl, I: Instance> Module { // Upgrade from the pre-#4649 balances/vesting into the new balances. pub fn do_upgrade() { + sp_runtime::print("Upgrading account balances..."); // First, migrate from old FreeBalance to new Account. // We also move all locks across since only accounts with FreeBalance values have locks. // FreeBalance: map T::AccountId => T::Balance -- GitLab From 2dc9b5504ce67c67317faec9fc4694b7f5651a5c Mon Sep 17 00:00:00 2001 From: Demi Obenour <48690212+DemiMarie-parity@users.noreply.github.com> Date: Mon, 3 Feb 2020 08:13:55 +0000 Subject: [PATCH 072/180] Bump dependencies (#4808) This pulls in the latest release of *ring* and also removes some duplicate dependencies. --- Cargo.lock | 238 ++++++++++++------------ primitives/arithmetic/fuzzer/Cargo.lock | 214 +++++++++------------ 2 files changed, 204 insertions(+), 248 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 814cfbbe2a..c468e3e7c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,7 +6,7 @@ version = "0.11.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)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -179,7 +179,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", "webpki-roots 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -205,7 +205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "backtrace" -version = "0.3.42" +version = "0.3.43" 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)", @@ -276,7 +276,7 @@ dependencies = [ "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.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (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)", ] @@ -478,7 +478,7 @@ dependencies = [ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -494,7 +494,7 @@ name = "cc" version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "jobserver 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -519,7 +519,7 @@ dependencies = [ "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sc-keystore 2.0.0", "sp-core 2.0.0", - "structopt 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -656,7 +656,7 @@ dependencies = [ "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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.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.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -690,7 +690,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cranelift-codegen 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)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "target-lexicon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -747,7 +747,7 @@ dependencies = [ "rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "tinytemplate 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -768,10 +768,10 @@ dependencies = [ "oorandom 11.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "plotters 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "tinytemplate 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1058,7 +1058,7 @@ dependencies = [ "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 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)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1070,7 +1070,7 @@ dependencies = [ "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 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)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1176,7 +1176,7 @@ name = "failure" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1518,7 +1518,7 @@ dependencies = [ "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1704,7 +1704,7 @@ dependencies = [ "bstr 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1726,12 +1726,12 @@ dependencies = [ "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)", - "hyper 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.13.2 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1975,7 +1975,7 @@ dependencies = [ [[package]] name = "hyper" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2007,7 +2007,7 @@ dependencies = [ "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-rustls 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", "webpki-roots 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2131,7 +2131,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "jobserver" -version = "0.1.19" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2158,7 +2158,7 @@ dependencies = [ "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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (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.24.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2173,7 +2173,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2287,7 +2287,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "parity-bytes 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2313,9 +2313,9 @@ dependencies = [ "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem 0.4.1 (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.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "rocksdb 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2395,7 +2395,7 @@ dependencies = [ "parity-multihash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2421,10 +2421,10 @@ dependencies = [ "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.16.10 (registry+https://github.com/rust-lang/crates.io-index)", "rw-stream-sink 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2475,7 +2475,7 @@ dependencies = [ "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2498,7 +2498,7 @@ dependencies = [ "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2514,7 +2514,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2537,7 +2537,7 @@ dependencies = [ "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "uint 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2560,7 +2560,7 @@ dependencies = [ "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)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.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.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2593,7 +2593,7 @@ dependencies = [ "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.16.10 (registry+https://github.com/rust-lang/crates.io-index)", "snow 0.6.2 (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.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2649,7 +2649,7 @@ dependencies = [ "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "quicksink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.16.10 (registry+https://github.com/rust-lang/crates.io-index)", "rw-stream-sink 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2667,7 +2667,7 @@ dependencies = [ "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.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.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2726,7 +2726,7 @@ dependencies = [ "rw-stream-sink 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "soketto 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", "webpki-roots 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2996,7 +2996,7 @@ dependencies = [ "bytes 0.5.4 (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)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (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.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3017,9 +3017,9 @@ dependencies = [ "lazy_static 1.4.0 (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.26 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.10.27 (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.53 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.54 (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)", @@ -3091,7 +3091,7 @@ dependencies = [ "sp-runtime 2.0.0", "sp-timestamp 2.0.0", "sp-transaction-pool 2.0.0", - "structopt 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-build-script-utils 2.0.0", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3254,7 +3254,7 @@ dependencies = [ "sp-inherents 2.0.0", "sp-runtime 2.0.0", "sp-transaction-pool 2.0.0", - "structopt 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-build-script-utils 2.0.0", "vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3444,7 +3444,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "openssl" -version = "0.10.26" +version = "0.10.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3452,7 +3452,7 @@ dependencies = [ "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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.54 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3462,10 +3462,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "openssl-sys" -version = "0.9.53" +version = "0.9.54" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.50 (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)", @@ -3659,7 +3659,7 @@ dependencies = [ "pallet-contracts-rpc-runtime-api 0.8.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "sp-api 2.0.0", "sp-blockchain 2.0.0", "sp-core 2.0.0", @@ -4092,7 +4092,7 @@ dependencies = [ "frame-support 2.0.0", "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "sp-api 2.0.0", "sp-runtime 2.0.0", "sp-std 2.0.0", @@ -4260,7 +4260,7 @@ dependencies = [ "impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "parity-util-mem-derive 0.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)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4350,7 +4350,7 @@ dependencies = [ "cloudabi 0.0.3 (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)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4499,10 +4499,10 @@ dependencies = [ [[package]] name = "proc-macro-error" -version = "0.4.5" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro-error-attr 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-error-attr 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.8 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4511,14 +4511,14 @@ dependencies = [ [[package]] name = "proc-macro-error-attr" -version = "0.4.5" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.8 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", - "syn-mid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syn-mid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4872,12 +4872,12 @@ dependencies = [ [[package]] name = "regex" -version = "1.3.3" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4891,7 +4891,7 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -4915,7 +4915,7 @@ dependencies = [ [[package]] name = "ring" -version = "0.16.9" +version = "0.16.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4989,9 +4989,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.16.10 (registry+https://github.com/rust-lang/crates.io-index)", "sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5060,7 +5060,7 @@ dependencies = [ "sc-keystore 2.0.0", "sc-network 0.8.0", "sc-peerset 2.0.0", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (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", @@ -5117,7 +5117,7 @@ dependencies = [ "sc-network 0.8.0", "sc-telemetry 2.0.0", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", "sp-runtime 2.0.0", ] @@ -5148,21 +5148,21 @@ dependencies = [ "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.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "sc-client-api 2.0.0", "sc-network 0.8.0", "sc-service 0.8.0", "sc-telemetry 2.0.0", "sc-tracing 2.0.0", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (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 0.8.0", - "structopt 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.3.9 (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.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5546,7 +5546,7 @@ dependencies = [ "sc-network-gossip 0.8.0", "sc-network-test 0.8.0", "sc-telemetry 2.0.0", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "sp-api 2.0.0", "sp-arithmetic 2.0.0", "sp-blockchain 2.0.0", @@ -5572,7 +5572,7 @@ dependencies = [ "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.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (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)", @@ -5609,7 +5609,7 @@ dependencies = [ "sc-client-api 2.0.0", "sc-peerset 2.0.0", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (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)", @@ -5711,7 +5711,7 @@ dependencies = [ "libp2p 0.15.0 (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.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -5735,7 +5735,7 @@ dependencies = [ "sc-network 0.8.0", "sc-rpc-api 0.8.0", "sc-transaction-pool 2.0.0", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "sp-api 2.0.0", "sp-blockchain 2.0.0", "sp-core 2.0.0", @@ -5765,7 +5765,7 @@ dependencies = [ "parity-scale-codec 1.1.2 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (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", @@ -5782,7 +5782,7 @@ dependencies = [ "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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "sp-runtime 2.0.0", ] @@ -5830,7 +5830,7 @@ dependencies = [ "sc-tracing 2.0.0", "sc-transaction-pool 2.0.0", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (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", @@ -5912,7 +5912,7 @@ dependencies = [ "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "sc-telemetry 2.0.0", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (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.12 (registry+https://github.com/rust-lang/crates.io-index)", "tracing-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6016,7 +6016,7 @@ name = "sct" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.16.10 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6091,7 +6091,7 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.45" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6182,7 +6182,7 @@ dependencies = [ "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "erased-serde 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6216,7 +6216,7 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -6226,7 +6226,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayref 0.3.6 (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)", + "ring 0.16.10 (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)", ] @@ -6245,7 +6245,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6477,11 +6477,11 @@ dependencies = [ "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 2.1.0 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "sp-debug-derive 2.0.0", "sp-externalities 0.8.0", @@ -6586,7 +6586,7 @@ dependencies = [ name = "sp-panic-handler" version = "2.0.0" dependencies = [ - "backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -6607,7 +6607,7 @@ name = "sp-rpc" version = "2.0.0" dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "sp-core 2.0.0", ] @@ -6621,7 +6621,7 @@ dependencies = [ "paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (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", @@ -6702,7 +6702,7 @@ name = "sp-serializer" version = "2.0.0" dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6877,21 +6877,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "structopt" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt-derive 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt-derive 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "structopt-derive" -version = "0.4.1" +version = "0.4.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-macro-error 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-error 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7132,7 +7132,7 @@ dependencies = [ [[package]] name = "syn-mid" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -7299,7 +7299,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7450,7 +7450,7 @@ dependencies = [ "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7636,7 +7636,7 @@ dependencies = [ "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)", "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7669,7 +7669,7 @@ 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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -7742,7 +7742,7 @@ name = "unicode-normalization" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7847,7 +7847,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -8124,10 +8124,10 @@ dependencies = [ [[package]] name = "webpki" -version = "0.21.0" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.16.10 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -8136,7 +8136,7 @@ name = "webpki-roots" version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -8144,7 +8144,7 @@ name = "webpki-roots" version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -8379,7 +8379,7 @@ dependencies = [ "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" -"checksum backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b4b1549d804b6c73f4817df2ba073709e96e426f12987127c48e6745568c350b" +"checksum backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = "7f80256bc78f67e7df7e36d77366f636ed976895d91fe2ab9efa3973e8fe8c4f" "checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" "checksum base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" @@ -8552,7 +8552,7 @@ dependencies = [ "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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8bf49cfb32edee45d890537d9057d1b02ed55f53b7b6a30bae83a38c9231749e" +"checksum hyper 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fa1c527bbc634be72aa7ba31e4e4def9bbb020f5416916279b7c705cd838893e" "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" @@ -8569,7 +8569,7 @@ dependencies = [ "checksum ipnet 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f4b06b21db0228860c8dfd17d2106c49c7c6bd07477a4036985347d84def04" "checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" "checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" -"checksum jobserver 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "67b06c1b455f1cf4269a8cfc320ab930a810e2375a42af5075eb8a8b36405ce0" +"checksum jobserver 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2" "checksum js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "7889c7c36282151f6bf465be4700359318aef36baa951462382eae49e9577cf9" "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" @@ -8659,9 +8659,9 @@ dependencies = [ "checksum once_cell 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b" "checksum oorandom 11.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebcec7c9c2a95cacc7cd0ecb89d8a8454eca13906f6deb55258ffff0adeb9405" "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" -"checksum openssl 0.10.26 (registry+https://github.com/rust-lang/crates.io-index)" = "3a3cc5799d98e1088141b8e01ff760112bbd9f19d850c124500566ca6901a585" +"checksum openssl 0.10.27 (registry+https://github.com/rust-lang/crates.io-index)" = "e176a45fedd4c990e26580847a525e39e16ec32ac78957dbf62ded31b3abfd6f" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)" = "465d16ae7fc0e313318f7de5cecf57b2fbe7511fd213978b457e1c96ff46736f" +"checksum openssl-sys 0.9.54 (registry+https://github.com/rust-lang/crates.io-index)" = "1024c0a59774200a555087a6da3f253a9095a5f344e353b212ac4c8b8e450986" "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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0c276d76c5333b8c2579e02d49a06733a55b8282d2d9b13e8d53b6406bd7e30a" @@ -8702,8 +8702,8 @@ dependencies = [ "checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" "checksum primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e4336f4f5d5524fa60bcbd6fe626f9223d8142a50e7053e979acdf0da41ab975" "checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" -"checksum proc-macro-error 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1b79a464461615532fcc8a6ed8296fa66cc12350c18460ab3f4594a6cee0fcb6" -"checksum proc-macro-error-attr 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "23832e5eae6bac56bbac190500eef1aaede63776b5cd131eaa4ee7fe120cd892" +"checksum proc-macro-error 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "875077759af22fa20b610ad4471d8155b321c89c3f2785526c9839b099be4e0a" +"checksum proc-macro-error-attr 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c5717d9fa2664351a01ed73ba5ef6df09c01a521cb42cb65a061432a826f3c7a" "checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" "checksum proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" @@ -8741,12 +8741,12 @@ dependencies = [ "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" -"checksum regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5508c1941e4e7cb19965abef075d35a9a8b5cdf0846f30b4050e9b55dc55e87" +"checksum regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" "checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9" -"checksum regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e734e891f5b408a29efbf8309e656876276f49ab6a6ac208600b4419bd893d90" +"checksum regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06" "checksum region 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "448e868c6e4cfddfa49b6a72c95906c04e8547465e9536575b95c70a4044f856" "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 ring 0.16.10 (registry+https://github.com/rust-lang/crates.io-index)" = "113f53b644c5442e20ff3a299be3d6c61ba143737af5bd2ab298e248a7575b2d" "checksum rlp 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3a44d5ae8afcb238af8b75640907edc6c931efcfab2c854e81ed35fa080f84cd" "checksum rocksdb 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "12069b106981c6103d3eab7dd1c86751482d0779a520b7c14954c8b586c1e643" "checksum rpassword 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "99371657d3c8e4d816fb6221db98fa408242b0b53bac08f8676a41f8554fe99f" @@ -8777,7 +8777,7 @@ dependencies = [ "checksum send_wrapper 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "686ef91cf020ad8d4aca9a7047641fd6add626b7b89e14546c2b6a76781cf822" "checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" "checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" -"checksum serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "eab8f15f15d6c41a154c1b128a22f2dfabe350ef53c40953d84e36155c91192b" +"checksum serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)" = "21b01d7f0288608a01dca632cf1df859df6fd6ffa885300fc275ce2ba6221953" "checksum sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" "checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" "checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" @@ -8791,7 +8791,7 @@ dependencies = [ "checksum slog-scope 4.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c44c89dd8b0ae4537d1ae318353eaf7840b4869c536e31c41e963d1ea523ee6" "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.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4" +"checksum smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc" "checksum snow 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "afb767eee7d257ba202f0b9b08673bc13b22281632ef45267b19f13100accd2f" "checksum soketto 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c9dab3f95c9ebdf3a88268c19af668f637a3c5039c2c56ff2d40b1b2d64a25b" "checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" @@ -8802,15 +8802,15 @@ 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.8 (registry+https://github.com/rust-lang/crates.io-index)" = "df136b42d76b1fbea72e2ab3057343977b04b4a2e00836c3c7c0673829572713" -"checksum structopt-derive 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd50a87d2f7b8958055f3e73a963d78feaccca3836767a9069844e34b5b03c0a" +"checksum structopt 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "a1bcbed7d48956fcbb5d80c6b95aedb553513de0a1b451ea92679d999c010e98" +"checksum structopt-derive 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "095064aa1f5b94d14e635d0a5684cf140c43ae40a0fd990708d38f5d669e5f64" "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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" "checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" -"checksum syn-mid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd3937748a7eccff61ba5b90af1a20dbf610858923a9192ea0ecb0cb77db1d0" +"checksum syn-mid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" "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" @@ -8909,7 +8909,7 @@ dependencies = [ "checksum wasmtime-jit 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ed7922689461a7b5bd0d9c7350cac526c8a520a23b3ffd7f5b446ac51dfc51f" "checksum wasmtime-runtime 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "781d6bb8b346efaa3dc39746386957cd79b8d841e8652ed9b02d77bcf64fb514" "checksum web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf97caf6aa8c2b1dac90faf0db529d9d63c93846cca4911856f78a83cebf53b" -"checksum webpki 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d7e664e770ac0110e2384769bcc59ed19e329d81f555916a6e072714957b81b4" +"checksum webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1f50e1972865d6b1adb54167d1c8ed48606004c2c9d0ea5f1eeb34d95e863ef" "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.24.0 (registry+https://github.com/rust-lang/crates.io-index)" = "413b37840b9e27b340ce91b319ede10731de8c72f5bc4cb0206ec1ca4ce581d0" diff --git a/primitives/arithmetic/fuzzer/Cargo.lock b/primitives/arithmetic/fuzzer/Cargo.lock index de8a764f1f..41bd9cc3ba 100644 --- a/primitives/arithmetic/fuzzer/Cargo.lock +++ b/primitives/arithmetic/fuzzer/Cargo.lock @@ -7,25 +7,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "arrayvec" -version = "0.4.12" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "autocfg" -version = "0.1.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitvec" -version = "0.14.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "byte-slice-cast" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -53,23 +50,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "fixed-hash" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (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)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "getrandom" -version = "0.1.13" +version = "0.1.14" 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)", - "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -87,12 +84,12 @@ name = "impl-codec" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "integer-sqrt" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -102,7 +99,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]] @@ -110,63 +107,58 @@ name = "memmap" version = "0.7.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)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "nodrop" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "num-bigint" -version = "0.2.3" +version = "0.2.6" 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.8 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-integer" -version = "0.1.41" +version = "0.1.42" 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.8 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parity-scale-codec" -version = "1.0.6" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "bitvec 0.14.0 (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.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitvec 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-slice-cast 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec-derive 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parity-scale-codec-derive" -version = "1.0.3" +version = "1.1.1" 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 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)", + "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -176,10 +168,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "primitive-types" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "fixed-hash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fixed-hash 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "impl-codec 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "uint 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -189,48 +181,32 @@ name = "proc-macro-crate" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "proc-macro2" -version = "0.4.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "proc-macro2" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "quote" -version = "0.6.13" -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)", -] - [[package]] name = "quote" version = "1.0.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)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand" -version = "0.7.2" +version = "0.7.3" 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)", + "getrandom 0.1.14 (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)", @@ -250,7 +226,7 @@ name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -263,35 +239,35 @@ dependencies = [ [[package]] name = "rustc-hex" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.102" +version = "1.0.104" 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.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "1.0.102" +version = "1.0.104" 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)", + "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] 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)", + "integer-sqrt 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "sp-debug-derive 2.0.0", "sp-std 2.0.0", ] @@ -301,9 +277,9 @@ 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)", + "num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "sp-arithmetic 2.0.0", ] @@ -311,9 +287,9 @@ dependencies = [ name = "sp-debug-derive" version = "2.0.0" dependencies = [ - "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -327,30 +303,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "syn" -version = "0.15.44" -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)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "syn" -version = "1.0.8" +version = "1.0.14" 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)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "toml" -version = "0.5.5" +version = "0.5.6" 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.104 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -360,15 +326,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "unicode-xid" version = "0.2.0" @@ -376,7 +337,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wasi" -version = "0.7.0" +version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -400,50 +361,45 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum arbitrary 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64cf76cb6e2222ed0ea86b2b0ee2f71c96ec6edd5af42e84d59160e91b836ec4" -"checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" -"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" -"checksum bitvec 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9633b74910e1870f50f5af189b08487195cdb83c0e27a71d6f64d5e09dd0538b" -"checksum byte-slice-cast 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f6209f3b2c1edea170002e016d5ead6903d3bb0a846477f53bbeb614967a52a9" +"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" +"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" +"checksum bitvec 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a993f74b4c99c1908d156b8d2e0fb6277736b0ecbd833982fd1241d39b2766a6" +"checksum byte-slice-cast 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" -"checksum fixed-hash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72fe7539e2c5692c6989f2f9c0457e42f1e5768f96b85c87d273574670ae459f" -"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407" +"checksum fixed-hash 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" +"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" "checksum honggfuzz 0.5.45 (registry+https://github.com/rust-lang/crates.io-index)" = "24c27b4aa3049d6d10d8e33d52c9d03ca9aec18f8a449b246f8c4a5b0c10fb34" "checksum impl-codec 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" -"checksum integer-sqrt 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ea155abb3ba6f382a75f1418988c05fe82959ed9ce727de427f9cfd425b0c903" +"checksum integer-sqrt 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f65877bf7d44897a473350b1046277941cee20b263397e90869c50b6e766088b" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"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 memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" -"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" -"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-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" -"checksum parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "001fbbb956d8593f321c7a784f64d16b2c99b2657823976eea729006ad2c3668" -"checksum parity-scale-codec-derive 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "42af752f59119656fa3cb31e8852ed24e895b968c0bdb41847da7f0cea6d155f" +"checksum num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +"checksum num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" +"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" +"checksum parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f747c06d9f3b2ad387ac881b9667298c81b1243aa9833f086e05996937c35507" +"checksum parity-scale-codec-derive 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34e513ff3e406f3ede6796dcdc83d0b32ffb86668cea1ccf7363118abeb00476" "checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" -"checksum primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a0253db64c26d8b4e7896dd2063b516d2a1b9e0a5da26b5b78335f236d1e9522" +"checksum primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e4336f4f5d5524fa60bcbd6fe626f9223d8142a50e7053e979acdf0da41ab975" "checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" -"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" -"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +"checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" -"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" +"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" "checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" "checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -"checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8" -"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 rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" +"checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" +"checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" "checksum static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -"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 toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "01d1404644c8b12b16bfcffa4322403a91a451584daaaa7c28d3152e6cbc98cf" +"checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" +"checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" "checksum uint 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e75a4cdd7b87b28840dba13c483b9a88ee6bbf16ba5c951ee1ecfcf723078e0d" -"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 wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" +"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -- GitLab From 9195fac755df57e18ed59fbd358ee528d2a52d0e Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 3 Feb 2020 09:55:09 +0100 Subject: [PATCH 073/180] block_import: switch to Box for intermediates representation (#4809) * block_import: switch to Box for intermediates representation * Use Cow and return Error instead of Option * Remove unused error * Distinguish NoIntermediate/InvalidIntermediate --- client/consensus/pow/src/lib.rs | 18 +++++----- .../consensus/common/src/block_import.rs | 34 ++++++++++++++++++- primitives/consensus/common/src/error.rs | 6 ++++ 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/client/consensus/pow/src/lib.rs b/client/consensus/pow/src/lib.rs index ca7285b7fe..87f51be216 100644 --- a/client/consensus/pow/src/lib.rs +++ b/client/consensus/pow/src/lib.rs @@ -30,6 +30,8 @@ //! clients. use std::sync::Arc; +use std::any::Any; +use std::borrow::Cow; use std::thread; use std::collections::HashMap; use std::marker::PhantomData; @@ -63,8 +65,6 @@ pub enum Error { InvalidSeal, #[display(fmt = "PoW validation error: invalid difficulty")] InvalidDifficulty, - #[display(fmt = "PoW block import expects an intermediate, but not found one")] - NoIntermediate, #[display(fmt = "Rejecting block too far in future")] TooFarInFuture, #[display(fmt = "Fetching best header failed using select chain: {:?}", _0)] @@ -257,6 +257,7 @@ impl BlockImport for PowBlockImport + Send + Sync + HeaderBackend + AuxStore + ProvideCache + BlockOf, C::Api: BlockBuilderApi, Algorithm: PowAlgorithm, + Algorithm::Difficulty: 'static, { type Error = ConsensusError; type Transaction = sp_api::TransactionFor; @@ -312,10 +313,9 @@ impl BlockImport for PowBlockImport return Err(Error::::HeaderUnsealed(block.header.hash()).into()), }; - let intermediate = PowIntermediate::::decode( - &mut &block.intermediates.remove(INTERMEDIATE_KEY) - .ok_or(Error::::NoIntermediate)?[..] - ).map_err(|_| Error::::NoIntermediate)?; + let intermediate = block.take_intermediate::>( + INTERMEDIATE_KEY + )?; let difficulty = match intermediate.difficulty { Some(difficulty) => difficulty, @@ -392,6 +392,7 @@ impl PowVerifier { impl Verifier for PowVerifier where Algorithm: PowAlgorithm + Send + Sync, + Algorithm::Difficulty: 'static, { fn verify( &mut self, @@ -418,7 +419,7 @@ impl Verifier for PowVerifier where justification, intermediates: { let mut ret = HashMap::new(); - ret.insert(INTERMEDIATE_KEY.to_vec(), intermediate.encode()); + ret.insert(Cow::from(INTERMEDIATE_KEY), Box::new(intermediate) as Box); ret }, auxiliary: vec![], @@ -553,6 +554,7 @@ fn mine_loop( ) -> Result<(), Error> where C: HeaderBackend + AuxStore + ProvideRuntimeApi, Algorithm: PowAlgorithm, + Algorithm::Difficulty: 'static, E: Environment, E::Proposer: Proposer>, E::Error: std::fmt::Debug, @@ -659,7 +661,7 @@ fn mine_loop( storage_changes: Some(proposal.storage_changes), intermediates: { let mut ret = HashMap::new(); - ret.insert(INTERMEDIATE_KEY.to_vec(), intermediate.encode()); + ret.insert(Cow::from(INTERMEDIATE_KEY), Box::new(intermediate) as Box); ret }, finalized: false, diff --git a/primitives/consensus/common/src/block_import.rs b/primitives/consensus/common/src/block_import.rs index af1b61a9fe..952a044e9b 100644 --- a/primitives/consensus/common/src/block_import.rs +++ b/primitives/consensus/common/src/block_import.rs @@ -22,7 +22,9 @@ use serde::{Serialize, Deserialize}; use std::borrow::Cow; use std::collections::HashMap; use std::sync::Arc; +use std::any::Any; +use crate::Error; use crate::import_queue::{Verifier, CacheKeyId}; /// Block import result. @@ -144,7 +146,7 @@ pub struct BlockImportParams { /// Intermediate values that are interpreted by block importers. Each block importer, /// upon handling a value, removes it from the intermediate list. The final block importer /// rejects block import if there are still intermediate values that remain unhandled. - pub intermediates: HashMap, Vec>, + pub intermediates: HashMap, Box>, /// Auxiliary consensus data produced by the block. /// Contains a list of key-value pairs. If values are `None`, the keys /// will be deleted. @@ -223,6 +225,36 @@ impl BlockImportParams { import_existing: self.import_existing, } } + + /// Take interemdiate by given key, and remove it from the processing list. + pub fn take_intermediate(&mut self, key: &[u8]) -> Result, Error> { + if self.intermediates.contains_key(key) { + self.intermediates.remove(key) + .ok_or(Error::NoIntermediate) + .and_then(|value| { + value.downcast::() + .map_err(|_| Error::InvalidIntermediate) + }) + } else { + Err(Error::NoIntermediate) + } + } + + /// Get a reference to a given intermediate. + pub fn intermediate(&self, key: &[u8]) -> Result<&T, Error> { + self.intermediates.get(key) + .ok_or(Error::NoIntermediate)? + .downcast_ref::() + .ok_or(Error::InvalidIntermediate) + } + + /// Get a mutable reference to a given intermediate. + pub fn intermediate_mut(&mut self, key: &[u8]) -> Result<&mut T, Error> { + self.intermediates.get_mut(key) + .ok_or(Error::NoIntermediate)? + .downcast_mut::() + .ok_or(Error::InvalidIntermediate) + } } /// Block import trait. diff --git a/primitives/consensus/common/src/error.rs b/primitives/consensus/common/src/error.rs index 972e4a2d48..c802831d65 100644 --- a/primitives/consensus/common/src/error.rs +++ b/primitives/consensus/common/src/error.rs @@ -31,6 +31,12 @@ pub enum Error { /// I/O terminated unexpectedly #[display(fmt="I/O terminated unexpectedly.")] IoTerminated, + /// Intermediate missing. + #[display(fmt="Missing intermediate.")] + NoIntermediate, + /// Intermediate is of wrong type. + #[display(fmt="Invalid intermediate.")] + InvalidIntermediate, /// Unable to schedule wakeup. #[display(fmt="Timer error: {}", _0)] FaultyTimer(std::io::Error), -- GitLab From 59947b9e55a4569432cc1dbf4660f045869356b9 Mon Sep 17 00:00:00 2001 From: Demi Obenour <48690212+DemiMarie-parity@users.noreply.github.com> Date: Mon, 3 Feb 2020 19:19:33 +0000 Subject: [PATCH 074/180] Switch to the new lockfile format (#4816) This will hopefully reduce merge conflicts in the future --- Cargo.lock | 8492 +++++++++++------------ primitives/arithmetic/fuzzer/Cargo.lock | 232 +- 2 files changed, 4356 insertions(+), 4368 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c468e3e7c8..d9fbff15de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,6743 +4,7175 @@ name = "Inflector" version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static", + "regex", ] [[package]] name = "adler32" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" [[package]] name = "aes-ctr" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2e5b0458ea3beae0d1d8c0f3946564f8e10f90646cf78c06b4351052058d1ee" dependencies = [ - "aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "aes-soft", + "aesni", + "ctr", + "stream-cipher", ] [[package]] name = "aes-soft" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "block-cipher-trait", + "byteorder 1.3.2", + "opaque-debug", ] [[package]] name = "aesni" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "block-cipher-trait", + "opaque-debug", + "stream-cipher", ] [[package]] name = "ahash" version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f33b5018f120946c1dcf279194f238a9f146725593ead1c08fa47ff22b0b5d3" dependencies = [ - "const-random 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "const-random", ] [[package]] name = "aho-corasick" version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f56c476256dc249def911d6f7580b5fc7e875895b5d7ee88f5d602208035744" dependencies = [ - "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr", ] [[package]] name = "ansi_term" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8", ] [[package]] name = "ansi_term" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8", ] [[package]] name = "anyhow" version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" [[package]] name = "app_dirs" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d" dependencies = [ - "ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ole32-sys", + "shell32-sys", + "winapi 0.2.8", + "xdg", ] [[package]] name = "arc-swap" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" [[package]] name = "arrayref" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" [[package]] name = "arrayvec" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" dependencies = [ - "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop", ] [[package]] name = "arrayvec" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" [[package]] name = "asn1_der" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fce6b6a0ffdafebd82c87e79e3f40e8d2c523e5fea5566ff6b90509bf98d638" dependencies = [ - "asn1_der_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "asn1_der_derive", ] [[package]] name = "asn1_der_derive" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d0864d84b8e07b145449be9a8537db86bf9de5ce03b913214694643b4743502" dependencies = [ - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2", + "syn", ] [[package]] name = "assert_matches" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7deb0a829ca7bcfaf5da70b073a8d128619259a7be8216a355e23f00763059e5" [[package]] name = "async-std" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "async-task 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "broadcaster 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io 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)", - "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.3.0 (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.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +checksum = "538ecb01eb64eecd772087e5b6f7540cbc917f047727339a472dafed2185b267" +dependencies = [ + "async-task", + "broadcaster", + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils 0.7.0", + "futures-core", + "futures-io", + "futures-timer 2.0.2", + "kv-log-macro", + "log 0.4.8", + "memchr", + "mio", + "mio-uds", + "num_cpus", + "once_cell 1.3.1", + "pin-project-lite", + "pin-utils", + "slab", ] [[package]] name = "async-task" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ac2c016b079e771204030951c366db398864f5026f84a44dafb0ff20f02085d" dependencies = [ - "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)", + "libc", + "winapi 0.3.8", ] [[package]] name = "async-tls" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce6977f57fa68da77ffe5542950d47e9c23d65f5bc7cb0a9f8700996913eec7" dependencies = [ - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki-roots 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1", + "rustls", + "webpki", + "webpki-roots 0.17.0", ] [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi 0.1.6 (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)", + "hermit-abi", + "libc", + "winapi 0.3.8", ] [[package]] name = "autocfg" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" [[package]] name = "autocfg" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "backtrace" version = "0.3.43" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f80256bc78f67e7df7e36d77366f636ed976895d91fe2ab9efa3973e8fe8c4f" 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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace-sys", + "cfg-if", + "libc", + "rustc-demangle", ] [[package]] name = "backtrace-sys" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" dependencies = [ - "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "libc", ] [[package]] name = "base58" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" [[package]] name = "base64" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", + "safemem", ] [[package]] name = "base64" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", ] [[package]] name = "base64" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" [[package]] name = "bincode" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5753e2a71534719bf3f4e57006c3a4f0d2c672a4b676eec84161f763eca87dbf" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", + "serde", ] [[package]] name = "bindgen" version = "0.49.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c07087f3d5731bf3fb375a81841b99597e25dc11bd3bc72d16d43adf6624a6e" 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.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)", - "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.4 (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)", + "bitflags", + "cexpr", + "cfg-if", + "clang-sys", + "clap", + "env_logger 0.6.2", + "fxhash", + "lazy_static", + "log 0.4.8", + "peeking_take_while", + "proc-macro2 0.4.30", + "quote 0.6.13", + "regex", + "shlex", + "which 2.0.1", ] [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bitmask" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5da9b3d9f6f585199287a473f4f8dfab6566cf827d15c00c219f53c645687ead" [[package]] name = "bitvec" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993f74b4c99c1908d156b8d2e0fb6277736b0ecbd833982fd1241d39b2766a6" [[package]] name = "blake2" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" dependencies = [ - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools", + "crypto-mac", + "digest", + "opaque-debug", ] [[package]] name = "blake2-rfc" version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" dependencies = [ - "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.12", + "constant_time_eq", ] [[package]] name = "blake2b_simd" version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" dependencies = [ - "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayref", + "arrayvec 0.5.1", + "constant_time_eq", ] [[package]] name = "block-buffer" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" dependencies = [ - "block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", + "block-padding", + "byte-tools", + "byteorder 1.3.2", + "generic-array", ] [[package]] name = "block-cipher-trait" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" dependencies = [ - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array", ] [[package]] name = "block-padding" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" dependencies = [ - "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools", ] [[package]] name = "broadcaster" -version = "0.2.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c972e21e0d055a36cf73e4daae870941fe7a8abcd5ac3396aab9e4c126bd87" dependencies = [ - "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-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)", - "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)", + "futures-channel", + "futures-core", + "futures-sink", + "futures-util", + "parking_lot 0.10.0", + "slab", ] [[package]] name = "browser-utils" version = "0.8.0" dependencies = [ - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "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)", - "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)", - "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb-web 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.15.0 (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 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-chain-spec 2.0.0", - "sc-network 0.8.0", - "sc-service 0.8.0", - "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "clear_on_drop", + "console_error_panic_hook", + "console_log", + "futures 0.1.29", + "futures 0.3.1", + "js-sys", + "kvdb-web", + "libp2p", + "log 0.4.8", + "rand 0.6.5", + "rand 0.7.3", + "sc-chain-spec", + "sc-network", + "sc-service", + "wasm-bindgen", + "wasm-bindgen-futures", ] [[package]] name = "bs58" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c95ee6bba9d950218b6cc910cf62bc9e0a171d0f4537e3627b0f54d08549b188" [[package]] name = "bs58" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b170cd256a3f9fa6b9edae3e44a7dfdfc77e8124dbc3e2612d75f9c3e2396dae" [[package]] name = "bstr" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe8a65814ca90dfc9705af76bb6ba3c6e2534489a72270e797e603783bb4990b" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.0 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static", + "memchr", + "regex-automata", + "serde", ] [[package]] name = "build-helper" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdce191bf3fa4995ce948c8c83b4640a1745457a149e73c6db75b4ffe36aad5f" dependencies = [ - "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.6.0", ] [[package]] name = "bumpalo" version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fb8038c1ddc0a5f73787b130f4cc75151e96ed33e417fde765eb5a81e3532f4" [[package]] name = "byte-slice-cast" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" [[package]] name = "byte-tools" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "byteorder" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" [[package]] name = "byteorder" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" [[package]] name = "bytes" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", + "either", + "iovec", ] [[package]] name = "bytes" version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" [[package]] name = "c2-chacha" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" dependencies = [ - "ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ppv-lite86", ] [[package]] name = "c_linked_list" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" [[package]] name = "cargo_metadata" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46e3374c604fb39d1a2f35ed5e4a4e30e60d01fab49446e08f1b3e9a90aef202" dependencies = [ - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.9.0", + "serde", + "serde_derive", + "serde_json", ] [[package]] name = "cast" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" dependencies = [ - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version", ] [[package]] name = "cc" version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" dependencies = [ - "jobserver 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver", ] [[package]] name = "cexpr" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fce5b5fb86b0c57c20c834c1b412fd09c77c8a59b9473f86272709e78874cd1d" dependencies = [ - "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "nom", ] [[package]] name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "chain-spec-builder" version = "2.0.0" dependencies = [ - "ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", - "node-cli 2.0.0", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-keystore 2.0.0", - "sp-core 2.0.0", - "structopt 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "ansi_term 0.12.1", + "node-cli", + "rand 0.7.3", + "sc-keystore", + "sp-core", + "structopt", ] [[package]] name = "chrono" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" dependencies = [ - "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer", + "num-traits", + "serde", + "time", ] [[package]] name = "clang-sys" version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853" dependencies = [ - "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)", + "glob 0.3.0", + "libc", + "libloading", ] [[package]] name = "clap" version = "2.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "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.7 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ansi_term 0.11.0", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", ] [[package]] name = "clear_on_drop" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" dependencies = [ - "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", ] [[package]] name = "cloudabi" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", ] [[package]] name = "cmake" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62" dependencies = [ - "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", ] [[package]] name = "console_error_panic_hook" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "wasm-bindgen", ] [[package]] name = "console_log" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7871d2947441b0fdd8e2bd1ce2a2f75304f896582c0d572162d48290683c48" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8", + "web-sys", ] [[package]] name = "const-random" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f1af9ac737b2dd2d577701e59fd09ba34822f6f2ebdb30a7647405d9e55e16a" dependencies = [ - "const-random-macro 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", + "const-random-macro", + "proc-macro-hack", ] [[package]] name = "const-random-macro" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25e4c606eb459dd29f7c57b2e0879f2b6f14ee130918c2b78ccb58a9624e6c7a" dependencies = [ - "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", + "proc-macro-hack", ] [[package]] name = "constant_time_eq" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "core-foundation" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" dependencies = [ - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys", + "libc", ] [[package]] name = "core-foundation-sys" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" [[package]] name = "cranelift-bforest" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd05aac8cefcde54ce26178df8f36cb1f518ac691db650e7d2440c2b6b41c4dc" dependencies = [ - "cranelift-entity 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-entity", ] [[package]] name = "cranelift-codegen" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c63d9b6ff8a94f98deabab21880d7fd54996e0e16be687b6f80a3b6bdd9c188d" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cranelift-bforest 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cranelift-codegen-meta 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", - "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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.2.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.10 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", + "cranelift-bforest", + "cranelift-codegen-meta", + "cranelift-codegen-shared", + "cranelift-entity", + "log 0.4.8", + "serde", + "smallvec 1.2.0", + "target-lexicon", + "thiserror", ] [[package]] name = "cranelift-codegen-meta" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cb3df51c2c07d719d02869bfac6cabd8d82ee308d5b29ca62e6528723cc33a4" 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)", + "cranelift-codegen-shared", + "cranelift-entity", ] [[package]] name = "cranelift-codegen-shared" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "758f9426b2e22bf83fc1a6b231a9d53cd4830751883c7f0e196ebb3c210467b3" [[package]] name = "cranelift-entity" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff064733df8b98f453060264a8790393d1e807aca6942706b42f79a4f7aae9ed" dependencies = [ - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", ] [[package]] name = "cranelift-frontend" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1eaafb5fa623dcbe19a28084a8226d7a1b17184a949c1a1f29a46b479867998d" dependencies = [ - "cranelift-codegen 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)", - "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "target-lexicon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-codegen", + "log 0.4.8", + "smallvec 1.2.0", + "target-lexicon", ] [[package]] name = "cranelift-native" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90033dbd7293f6fad4cf9dcd769cd621d60df22b1c5a11799e86359b7447a51d" dependencies = [ - "cranelift-codegen 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)", - "raw-cpuid 7.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "target-lexicon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-codegen", + "raw-cpuid", + "target-lexicon", ] [[package]] name = "cranelift-wasm" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54cb82a1071f88822763a583ec1a8688ffe5e2cda02c111d4483dd4376ed14d8" dependencies = [ - "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)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmparser 0.39.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "log 0.4.8", + "serde", + "thiserror", + "wasmparser", ] [[package]] name = "crc32fast" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", ] [[package]] name = "criterion" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "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.3 (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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (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.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "tinytemplate 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +checksum = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394" +dependencies = [ + "atty", + "cast", + "clap", + "criterion-plot 0.3.1", + "csv", + "itertools", + "lazy_static", + "libc", + "num-traits", + "rand_core 0.3.1", + "rand_os", + "rand_xoshiro", + "rayon", + "rayon-core", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", ] [[package]] name = "criterion" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc755679c12bda8e5523a71e4d654b6bf2e14bd838dfc48cde6559a05caf7d1" dependencies = [ - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "criterion-plot 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "csv 1.1.3 (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.11 (registry+https://github.com/rust-lang/crates.io-index)", - "oorandom 11.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "plotters 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "tinytemplate 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "atty", + "cast", + "clap", + "criterion-plot 0.4.1", + "csv", + "itertools", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", ] [[package]] name = "criterion-plot" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f9212ddf2f4a9eb2d401635190600656a1f88a932ef53d06e7fa4c7e02fb8e" 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.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", + "cast", + "itertools", ] [[package]] name = "criterion-plot" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01e15e0ea58e8234f96146b1f91fa9d0e4dd7a38da93ff7a75d42c0b9d3a545" dependencies = [ - "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cast", + "itertools", ] [[package]] name = "crossbeam-channel" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c" dependencies = [ - "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.0", ] [[package]] name = "crossbeam-deque" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca" dependencies = [ - "crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch", + "crossbeam-utils 0.7.0", ] [[package]] name = "crossbeam-epoch" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.7", + "cfg-if", + "crossbeam-utils 0.7.0", + "lazy_static", + "memoffset", + "scopeguard 1.0.0", ] [[package]] name = "crossbeam-queue" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" dependencies = [ - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6", ] [[package]] name = "crossbeam-queue" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "crossbeam-utils 0.7.0", ] [[package]] name = "crossbeam-utils" version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "lazy_static", ] [[package]] name = "crossbeam-utils" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.7", + "cfg-if", + "lazy_static", ] [[package]] name = "crunchy" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-mac" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" dependencies = [ - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array", + "subtle 1.0.0", ] [[package]] name = "csv" version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00affe7f6ab566df61b4be3ce8cf16bc2576bca0963ceb0955e45d514bf9a279" dependencies = [ - "bstr 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.5 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", + "bstr", + "csv-core", + "itoa", + "ryu", + "serde", ] [[package]] name = "csv-core" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c" dependencies = [ - "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr", ] [[package]] name = "ct-logs" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d3686f5fa27dbc1d76c751300376e167c5a43387f44bb451fd1c24776e49113" dependencies = [ - "sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sct", ] [[package]] name = "ctor" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd8ce37ad4184ab2ce004c33bf6379185d3b1c95801cab51026bd271bf68eedc" dependencies = [ - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2", + "syn", ] [[package]] name = "ctr" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "022cd691704491df67d25d006fe8eca083098253c4d43516c2206479c58c6736" dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "block-cipher-trait", + "stream-cipher", ] [[package]] name = "cuckoofilter" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dd43f7cfaffe0a386636a10baea2ee05cc50df3b77bea4a456c9572a939bf1f" dependencies = [ - "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 0.5.3", + "rand 0.3.23", ] [[package]] name = "curve25519-dalek" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b7dcd30ba50cdf88b55b033456138b7c0ac4afdc436d82e1b79f370f24cc66d" 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)", - "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.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", + "clear_on_drop", + "digest", + "rand_core 0.3.1", + "subtle 2.2.2", ] [[package]] name = "curve25519-dalek" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26778518a7f6cffa1d25a44b602b62b979bd88adb9e99ffec546998cf3404839" 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)", + "byteorder 1.3.2", + "digest", + "rand_core 0.5.1", + "subtle 2.2.2", + "zeroize 1.1.0", ] [[package]] name = "data-encoding" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97" [[package]] name = "derive_more" version = "0.99.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2159be042979966de68315bce7034bb000c775f22e3e834e1c52ff78f041cae8" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "difference" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" [[package]] name = "digest" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" dependencies = [ - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array", ] [[package]] name = "directories" version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "dirs-sys", ] [[package]] name = "dirs-sys" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" dependencies = [ - "cfg-if 0.1.10 (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.4 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "libc", + "redox_users", + "winapi 0.3.8", ] [[package]] name = "dns-parser" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", + "quick-error", ] [[package]] name = "doc-comment" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97" [[package]] name = "ed25519-dalek" version = "1.0.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978710b352437433c97b2bff193f2fb1dfd58a093f863dd95e225a19baa599a2" dependencies = [ - "clear_on_drop 0.2.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.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clear_on_drop", + "curve25519-dalek 2.0.0", + "rand 0.7.3", + "sha2", ] [[package]] name = "either" version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" [[package]] name = "enumflags2" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33121c8782ba948ba332dab29311b026a8716dc65a1599e5b88f392d38496af8" dependencies = [ - "enumflags2_derive 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "enumflags2_derive", ] [[package]] name = "enumflags2_derive" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecf634c5213044b8d54a46dd282cf5dd1f86bb5cb53e92c409cb4680a7fb9894" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "env_logger" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" dependencies = [ - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "humantime 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)", - "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty", + "humantime", + "log 0.4.8", + "regex", + "termcolor", ] [[package]] name = "env_logger" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" dependencies = [ - "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "humantime 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)", - "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty", + "humantime", + "log 0.4.8", + "regex", + "termcolor", ] [[package]] name = "environmental" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516aa8d7a71cb00a1c4146f0798549b93d083d4f189b3ced8f3de6b8f11ee6c4" [[package]] name = "erased-serde" version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd7d80305c9bd8cd78e3c753eb9fb110f83621e5211f1a3afffcc812b104daf9" dependencies = [ - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", ] [[package]] name = "errno" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e" dependencies = [ - "errno-dragonfly 0.1.1 (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)", + "errno-dragonfly", + "libc", + "winapi 0.3.8", ] [[package]] name = "errno-dragonfly" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067" dependencies = [ - "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc", + "libc", ] [[package]] name = "evm" version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a2c6961fdc9952371fc5f0416f03a9d90378a9dfb6862f6a7a9a3b8986b8dd" dependencies = [ - "evm-core 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", - "evm-gasometer 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", - "evm-runtime 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.6.2 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "evm-core", + "evm-gasometer", + "evm-runtime", + "primitive-types", + "rlp", + "serde", + "sha3", ] [[package]] name = "evm-core" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bcde5af3d542874ddeb53de0919302d57586ea04b3f76f54d865f8a6cdc70ae" dependencies = [ - "primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "primitive-types", ] [[package]] name = "evm-gasometer" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b82bc9f275cb59d2bcc05d85c98736ddfaba003a7ef7b73893fa7c1c1fab29dc" dependencies = [ - "evm-core 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", - "evm-runtime 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "evm-core", + "evm-runtime", + "primitive-types", ] [[package]] name = "evm-runtime" version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dbbc89d29618c3722c17ba78ddf432d40ace8ee27e3f8b28b52a85921112e4b" dependencies = [ - "evm-core 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "evm-core", + "primitive-types", + "sha3", ] [[package]] name = "exit-future" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5" dependencies = [ - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1", ] [[package]] name = "faerie" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f902f2af041f6c7177a2a04f805687cdc71e69c7cbef059a2755d8923f4cd7a8" dependencies = [ - "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "goblin 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.1 (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.10 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow", + "goblin", + "indexmap", + "log 0.4.8", + "scroll", + "string-interner", + "target-lexicon", + "thiserror", ] [[package]] name = "failure" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" dependencies = [ - "backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace", + "failure_derive", ] [[package]] name = "failure_derive" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", + "synstructure", ] [[package]] name = "fake-simd" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] name = "fallible-iterator" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fdlimit" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9084c55bb76efb1496328976db88320fe7d9ee86e649e83c4ecce3ba7a9a35d1" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "file-per-thread-logger" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8505b75b31ef7285168dd237c4a7db3c1f3e0927e7d314e670bc98e854272fe9" 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)", + "env_logger 0.6.2", + "log 0.4.8", ] [[package]] name = "finality-grandpa" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbb25bef9fcad97fb31e817da280b1c9174435b8769c770ee190a330dd181ea" 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)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.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.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1", + "futures-timer 2.0.2", + "log 0.4.8", + "num-traits", + "parity-scale-codec", + "parking_lot 0.9.0", + "rand 0.6.5", ] [[package]] name = "fixed-hash" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" dependencies = [ - "byteorder 1.3.2 (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.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", + "libc", + "rand 0.7.3", + "rustc-hex", + "static_assertions", ] [[package]] name = "fixedbitset" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" [[package]] name = "flate2" version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" 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)", - "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)", + "cfg-if", + "crc32fast", + "libc", + "libz-sys", + "miniz_oxide", ] [[package]] name = "fnv" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" [[package]] name = "foreign-types" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "foreign-types-shared", ] [[package]] name = "foreign-types-shared" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fork-tree" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec", ] [[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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "hex-literal", + "pallet-balances", + "pallet-indices", + "pallet-transaction-payment", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "frame-metadata" version = "11.0.0" dependencies = [ - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-core 2.0.0", - "sp-std 2.0.0", + "parity-scale-codec", + "serde", + "sp-core", + "sp-std", ] [[package]] name = "frame-support" version = "2.0.0" dependencies = [ - "bitmask 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "frame-metadata 11.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.2 (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.104 (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 0.8.0", - "sp-std 2.0.0", - "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "bitmask", + "frame-metadata", + "frame-support-procedural", + "frame-system", + "impl-trait-for-tuples", + "log 0.4.8", + "once_cell 0.2.4", + "parity-scale-codec", + "paste", + "pretty_assertions", + "serde", + "sp-arithmetic", + "sp-core", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-state-machine", + "sp-std", + "tracing", ] [[package]] name = "frame-support-procedural" version = "2.0.0" dependencies = [ - "frame-support-procedural-tools 2.0.0", - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "frame-support-procedural-tools", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[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.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "frame-support-procedural-tools-derive", + "proc-macro-crate", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "frame-support-procedural-tools-derive" version = "2.0.0" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "frame-support-test" version = "2.0.0" dependencies = [ - "frame-support 2.0.0", - "parity-scale-codec 1.1.2 (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.104 (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 0.8.0", - "trybuild 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "frame-support", + "parity-scale-codec", + "pretty_assertions", + "serde", + "sp-core", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-state-machine", + "trybuild", ] [[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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-core 2.0.0", - "sp-externalities 0.8.0", - "sp-io 2.0.0", - "sp-runtime 2.0.0", - "sp-std 2.0.0", - "sp-version 2.0.0", - "substrate-test-runtime-client 2.0.0", + "criterion 0.2.11", + "frame-support", + "impl-trait-for-tuples", + "parity-scale-codec", + "serde", + "sp-core", + "sp-externalities", + "sp-io", + "sp-runtime", + "sp-std", + "sp-version", + "substrate-test-runtime-client", ] [[package]] name = "frame-system-rpc-runtime-api" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-api 2.0.0", + "parity-scale-codec", + "sp-api", ] [[package]] name = "fs-swap" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "921d332c89b3b61a826de38c61ee5b6e02c56806cade1b0e5d81bd71f57a71bb" dependencies = [ - "lazy_static 1.4.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)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static", + "libc", + "libloading", + "winapi 0.3.8", ] [[package]] name = "fs2" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" dependencies = [ - "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)", + "libc", + "winapi 0.3.8", ] [[package]] name = "fuchsia-cprng" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] name = "fuchsia-zircon" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "fuchsia-zircon-sys", ] [[package]] name = "fuchsia-zircon-sys" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[package]] name = "futures" version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" [[package]] name = "futures" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f16056ecbb57525ff698bb955162d0cd03bee84e6241c27ff75c08d8ca5987" dependencies = [ - "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-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io 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-task 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)", + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", ] [[package]] name = "futures-channel" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcae98ca17d102fd8a3603727b9259fcf7fa4239b603d2142926189bc8999b86" dependencies = [ - "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-core", + "futures-sink", ] [[package]] name = "futures-channel-preview" version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5e5f4df964fa9c1c2f8bddeb5c3611631cacd93baf810fc8bb2fb4b495c263a" dependencies = [ - "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-core-preview", ] [[package]] name = "futures-core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79564c427afefab1dfb3298535b21eda083ef7935b4f0ecbfcb121f0aec10866" [[package]] name = "futures-core-preview" version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b35b6263fb1ef523c3056565fa67b1d16f0a8604ff12b11b08c25f28a734c60a" [[package]] name = "futures-cpupool" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29", + "num_cpus", ] [[package]] name = "futures-diagnose" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebbb8371dd6ee87aa2aeaa8458a372fd82fe216032387b766255754c92dd7271" 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)", - "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)", - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29", + "futures 0.3.1", + "lazy_static", + "log 0.4.8", + "parking_lot 0.9.0", + "pin-project", + "serde", + "serde_json", ] [[package]] name = "futures-executor" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e274736563f686a837a0568b478bdabfeaec2dca794b5649b04e2fe1627c231" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 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)", - "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core", + "futures-task", + "futures-util", + "num_cpus", ] [[package]] name = "futures-io" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e676577d229e70952ab25f3945795ba5b16d63ca794ca9d2c860e5595d20b5ff" [[package]] name = "futures-macro" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e7c56c15537adb4f76d0b7a76ad131cb4d2f4f32d3b0bcabcbe1c7c5e87764" dependencies = [ - "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "futures-sink" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "futures-sink-preview" -version = "0.3.0-alpha.19" -source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171be33efae63c2d59e6dbba34186fe0d6394fb378069a76dfd80fdcffd43c16" [[package]] name = "futures-task" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bae52d6b29cf440e298856fec3965ee6fa71b06aa7495178615953fd669e5f9" [[package]] name = "futures-timer" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "878f1d2fc31355fa02ed2372e741b0c17e58373341e6a122569b4623a14a7d33" dependencies = [ - "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)", - "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core-preview", + "futures-util-preview", + "pin-utils", ] [[package]] name = "futures-timer" version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6" [[package]] name = "futures-util" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76" dependencies = [ - "futures 0.1.29 (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-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-macro 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-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", + "tokio-io", ] [[package]] name = "futures-util-preview" version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce968633c17e5f97936bd2797b6e38fb56cf16a7422319f7ec2e30d3c470e8d" dependencies = [ - "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-sink-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel-preview", + "futures-core-preview", + "pin-utils", + "slab", ] [[package]] name = "futures_codec" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0a73299e4718f5452e45980fc1d6957a070abe308d3700b63b8673f47e1c2b3" dependencies = [ - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4", + "futures 0.3.1", + "memchr", + "pin-project", ] [[package]] name = "fxhash" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", ] [[package]] name = "gcc" version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" [[package]] name = "generic-array" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" dependencies = [ - "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum", ] [[package]] name = "get_if_addrs" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abddb55a898d32925f3148bd281174a68eeb68bbfd9a5938a57b18f506ee4ef7" 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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "c_linked_list", + "get_if_addrs-sys", + "libc", + "winapi 0.2.8", ] [[package]] name = "get_if_addrs-sys" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d04f9fb746cf36b191c00f3ede8bde9c8e64f9f4b05ae2694a9ccf5e3f5ab48" dependencies = [ - "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc", + "libc", ] [[package]] name = "getrandom" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "libc", + "wasi", + "wasm-bindgen", ] [[package]] name = "gimli" version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162d18ae5f2e3b90a993d202f1ba17a5633c2484426f8bcae201f86194bacd00" dependencies = [ - "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fallible-iterator 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.12", + "byteorder 1.3.2", + "fallible-iterator", + "indexmap", + "stable_deref_trait", ] [[package]] name = "glob" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" [[package]] name = "glob" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "globset" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2" dependencies = [ - "aho-corasick 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", - "bstr 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick", + "bstr", + "fnv", + "log 0.4.8", + "regex", ] [[package]] name = "goblin" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3081214398d39e4bd7f2c1975f0488ed04614ffdd976c6fc7a0708278552c0da" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "scroll 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8", + "plain", + "scroll", ] [[package]] name = "grafana-data-source" version = "0.8.0" dependencies = [ - "async-std 1.4.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)", - "hyper 0.13.2 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "async-std", + "chrono", + "derive_more", + "futures-timer 2.0.2", + "futures-util", + "hyper 0.13.2", + "lazy_static", + "log 0.4.8", + "parking_lot 0.9.0", + "serde", + "serde_json", + "tokio 0.2.11", ] [[package]] name = "grafana-data-source-test" 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)", - "grafana-data-source 0.8.0", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1", + "futures-timer 2.0.2", + "grafana-data-source", + "rand 0.7.3", ] [[package]] name = "h2" version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" 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)", - "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.21 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.1 (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-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", + "bytes 0.4.12", + "fnv", + "futures 0.1.29", + "http 0.1.21", + "indexmap", + "log 0.4.8", + "slab", + "string", + "tokio-io", ] [[package]] name = "h2" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9433d71e471c1736fd5a61b671fc0b148d7a2992f666c958d03cd8feb3b88d1" dependencies = [ - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (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.1 (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)", - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.0", + "indexmap", + "log 0.4.8", + "slab", + "tokio 0.2.11", + "tokio-util", ] [[package]] name = "hash-db" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" [[package]] name = "hash256-std-hasher" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" dependencies = [ - "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crunchy", ] [[package]] name = "hashbrown" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", + "scopeguard 0.3.3", ] [[package]] name = "hashbrown" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1de41fb8dba9714efd92241565cdff73f78508c95697dd56787d3cba27e2353" [[package]] name = "hashbrown" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead" dependencies = [ - "ahash 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "ahash", + "autocfg 0.1.7", ] [[package]] name = "heck" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" dependencies = [ - "unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-segmentation", ] [[package]] name = "hermit-abi" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "hex" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e" [[package]] name = "hex-literal" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0" dependencies = [ - "hex-literal-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", + "hex-literal-impl", + "proc-macro-hack", ] [[package]] name = "hex-literal-impl" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d4c5c844e2fee0bf673d54c2c177f1713b3d2af2ff6e666b49cb7572e6cf42d" dependencies = [ - "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack", ] [[package]] name = "hmac" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" dependencies = [ - "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-mac", + "digest", ] [[package]] name = "hmac-drbg" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" dependencies = [ - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "digest", + "generic-array", + "hmac", ] [[package]] name = "http" version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" 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)", - "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12", + "fnv", + "itoa", ] [[package]] name = "http" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b" dependencies = [ - "bytes 0.5.4 (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.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4", + "fnv", + "itoa", ] [[package]] name = "http-body" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" 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.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12", + "futures 0.1.29", + "http 0.1.21", + "tokio-buf", ] [[package]] name = "http-body" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" dependencies = [ - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4", + "http 0.2.0", ] [[package]] name = "httparse" version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" [[package]] name = "humantime" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" dependencies = [ - "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error", ] [[package]] name = "hyper" version = "0.10.16" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273" dependencies = [ - "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "typeable 0.1.2 (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)", + "base64 0.9.3", + "httparse", + "language-tags", + "log 0.3.9", + "mime", + "num_cpus", + "time", + "traitobject", + "typeable", + "unicase 1.4.2", + "url 1.7.2", ] [[package]] name = "hyper" version = "0.12.35" 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)", - "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.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)", - "itoa 0.4.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)", - "rustc_version 0.2.3 (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)", - "tokio-buf 0.1.1 (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.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.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)", +checksum = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6" +dependencies = [ + "bytes 0.4.12", + "futures 0.1.29", + "futures-cpupool", + "h2 0.1.26", + "http 0.1.21", + "http-body 0.1.0", + "httparse", + "iovec", + "itoa", + "log 0.4.8", + "net2", + "rustc_version", + "time", + "tokio 0.1.22", + "tokio-buf", + "tokio-executor 0.1.9", + "tokio-io", + "tokio-reactor", + "tokio-tcp", + "tokio-threadpool", + "tokio-timer", + "want 0.2.0", ] [[package]] name = "hyper" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa1c527bbc634be72aa7ba31e4e4def9bbb020f5416916279b7c705cd838893e" dependencies = [ - "bytes 0.5.4 (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)", - "itoa 0.4.5 (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.8 (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.11 (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)", + "bytes 0.5.4", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.2.1", + "http 0.2.0", + "http-body 0.3.1", + "httparse", + "itoa", + "log 0.4.8", + "pin-project", + "time", + "tokio 0.2.11", + "tower-service", + "want 0.3.0", ] [[package]] name = "hyper-rustls" version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719d85c7df4a7f309a77d145340a063ea929dcb2e025bae46a80345cffec2952" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "ct-logs 0.6.0 (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)", - "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-rustls 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki-roots 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12", + "ct-logs", + "futures 0.1.29", + "hyper 0.12.35", + "rustls", + "tokio-io", + "tokio-rustls", + "webpki", + "webpki-roots 0.17.0", ] [[package]] name = "hyper-tls" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" 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.12.35 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12", + "futures 0.1.29", + "hyper 0.12.35", + "native-tls", + "tokio-io", ] [[package]] name = "idna" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" 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.12 (registry+https://github.com/rust-lang/crates.io-index)", + "matches", + "unicode-bidi", + "unicode-normalization", ] [[package]] name = "idna" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" 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.12 (registry+https://github.com/rust-lang/crates.io-index)", + "matches", + "unicode-bidi", + "unicode-normalization", ] [[package]] name = "impl-codec" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" dependencies = [ - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec", ] [[package]] name = "impl-rlp" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f7a72f11830b52333f36e3b09a288333888bf54380fd0ac0790a3c31ab0f3c5" dependencies = [ - "rlp 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rlp", ] [[package]] name = "impl-serde" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58e3cae7e99c7ff5a995da2cf78dd0a5383740eda71d98cf7b1910c301ac69b8" dependencies = [ - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", ] [[package]] name = "impl-serde" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bbe9ea9b182f0fb1cabbd61f4ff9b7b7b9197955e95a7e4c27de5055eb29ff8" dependencies = [ - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", ] [[package]] name = "impl-trait-for-tuples" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "indexmap" version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b54058f0a6ff80b6803da8faf8997cde53872b38f4023728f6830b06cd3c0dc" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0", ] [[package]] name = "integer-sqrt" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f65877bf7d44897a473350b1046277941cee20b263397e90869c50b6e766088b" [[package]] name = "interleaved-ordered" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" [[package]] name = "iovec" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "ipnet" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a859057dc563d1388c1e816f98a1892629075fc046ed06e845b883bb8b2916fb" [[package]] name = "itertools" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" dependencies = [ - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "either", ] [[package]] name = "itoa" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" [[package]] name = "jobserver" version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "js-sys" version = "0.3.35" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7889c7c36282151f6bf465be4700359318aef36baa951462382eae49e9577cf9" dependencies = [ - "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen", ] [[package]] name = "jsonrpc-client-transports" version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a9ae166c4d1f702d297cd76d4b55758ace80272ffc6dbb139fdc1bf810de40b" 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.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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (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.24.0 (registry+https://github.com/rust-lang/crates.io-index)", + "failure", + "futures 0.1.29", + "hyper 0.12.35", + "hyper-tls", + "jsonrpc-core", + "jsonrpc-pubsub", + "log 0.4.8", + "serde", + "serde_json", + "tokio 0.1.22", + "url 1.7.2", + "websocket", ] [[package]] name = "jsonrpc-core" version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe3b688648f1ef5d5072229e2d672ecb92cbff7d1c79bcf3fd5898f3f3df0970" 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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29", + "log 0.4.8", + "serde", + "serde_derive", + "serde_json", ] [[package]] name = "jsonrpc-core-client" version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "080dc110be17701097df238fad3c816d4a478a1899dfbcf8ec8957dd40ec7304" dependencies = [ - "jsonrpc-client-transports 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-client-transports", ] [[package]] name = "jsonrpc-derive" version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8609af8f63b626e8e211f52441fcdb6ec54f1a446606b10d5c89ae9bf8a20058" dependencies = [ - "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-crate", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "jsonrpc-http-server" version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d83d348120edee487c560b7cdd2565055d61cda053aa0d0ef0f8b6a18429048" dependencies = [ - "hyper 0.12.35 (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)", - "unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.35", + "jsonrpc-core", + "jsonrpc-server-utils", + "log 0.4.8", + "net2", + "parking_lot 0.9.0", + "unicase 2.6.0", ] [[package]] name = "jsonrpc-pubsub" version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3453625f0f0f5cd6d6776d389d73b7d70fcc98620b7cbb1cbbb1f6a36e95f39a" dependencies = [ - "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.104 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core", + "log 0.4.8", + "parking_lot 0.9.0", + "serde", ] [[package]] name = "jsonrpc-server-utils" version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b7635e618a0edbbe0d2a2bbbc69874277c49383fcf6c3c0414491cfb517d22" 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.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)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12", + "globset", + "jsonrpc-core", + "lazy_static", + "log 0.4.8", + "tokio 0.1.22", + "tokio-codec", + "unicase 2.6.0", ] [[package]] name = "jsonrpc-ws-server" version = "14.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b34faa167c3ac9705aeecb986c0da6056529f348425dbe0441db60a2c4cc41d1" dependencies = [ - "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)", - "ws 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core", + "jsonrpc-server-utils", + "log 0.4.8", + "parking_lot 0.9.0", + "slab", + "ws", ] [[package]] name = "keccak" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" [[package]] name = "keccak-hasher" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3468207deea1359a0e921591ae9b4c928733d94eb9d6a2eeda994cfd59f42cf8" dependencies = [ - "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)", - "tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db", + "hash256-std-hasher", + "tiny-keccak 1.5.0", ] [[package]] name = "kernel32-sys" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 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)", + "winapi 0.2.8", + "winapi-build", ] [[package]] name = "kv-log-macro" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c54d9f465d530a752e6ebdc217e081a7a614b48cb200f6f0aee21ba6bc9aabb" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8", ] [[package]] name = "kvdb" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8396be0e5561ccd1bf7ff0b2007487cdd7a87a056873fe6ea906b35d4dbf7ed8" dependencies = [ - "parity-bytes 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-util-mem 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-bytes", + "parity-util-mem 0.4.1", + "smallvec 1.2.0", ] [[package]] name = "kvdb-memorydb" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d25ef14155e418515c4839e9144c839de3506e68946f255a32b7f166095493d" dependencies = [ - "kvdb 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-util-mem 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "kvdb", + "parity-util-mem 0.4.1", + "parking_lot 0.9.0", ] [[package]] name = "kvdb-rocksdb" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af488cc16c3801705c8d681c3a32c8faa8fafc7fb5309dee0f573f3c6a19d395" dependencies = [ - "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.3.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.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-util-mem 0.4.1 (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.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rocksdb 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "fs-swap", + "interleaved-ordered", + "kvdb", + "log 0.4.8", + "num_cpus", + "owning_ref", + "parity-util-mem 0.4.1", + "parking_lot 0.9.0", + "regex", + "rocksdb", + "smallvec 1.2.0", ] [[package]] name = "kvdb-web" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37a0e36637fb86454de401e7cb88f40eb0ad1b9bcee837d46785e7c451f1ebf4" dependencies = [ - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb-memorydb 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-util-mem 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "send_wrapper 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1", + "js-sys", + "kvdb", + "kvdb-memorydb", + "log 0.4.8", + "parity-util-mem 0.4.1", + "send_wrapper 0.3.0", + "wasm-bindgen", + "web-sys", ] [[package]] name = "language-tags" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "lazycell" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" [[package]] name = "libc" version = "0.2.66" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" [[package]] name = "libloading" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" dependencies = [ - "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "winapi 0.3.8", ] [[package]] name = "libp2p" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.5.4 (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)", - "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core-derive 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-deflate 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-dns 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-floodsub 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-gossipsub 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-identify 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-kad 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-mdns 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-mplex 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-noise 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-ping 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-plaintext 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-secio 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-tcp 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-uds 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-wasm-ext 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-websocket 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-yamux 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multihash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", +checksum = "f84847789ab24b3fc5971a68656ac85886df640986d9ce3264c0327694eae471" +dependencies = [ + "bytes 0.5.4", + "futures 0.3.1", + "lazy_static", + "libp2p-core", + "libp2p-core-derive", + "libp2p-deflate", + "libp2p-dns", + "libp2p-floodsub", + "libp2p-gossipsub", + "libp2p-identify", + "libp2p-kad", + "libp2p-mdns", + "libp2p-mplex", + "libp2p-noise", + "libp2p-ping", + "libp2p-plaintext", + "libp2p-secio", + "libp2p-swarm", + "libp2p-tcp", + "libp2p-uds", + "libp2p-wasm-ext", + "libp2p-websocket", + "libp2p-yamux", + "parity-multiaddr 0.7.1", + "parity-multihash 0.2.1", + "parking_lot 0.10.0", + "pin-project", + "smallvec 1.2.0", + "wasm-timer", ] [[package]] name = "libp2p-core" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -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)", - "ed25519-dalek 1.0.0-pre.3 (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)", - "futures-timer 2.0.2 (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.4 (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.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multiaddr 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multihash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.16.10 (registry+https://github.com/rust-lang/crates.io-index)", - "rw-stream-sink 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.3.0 (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)", - "zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +checksum = "dbafb2706b8082233f66dc13e196f9cf9b4c229f2cd7c96b2b16617ad6ee330b" +dependencies = [ + "asn1_der", + "bs58 0.3.0", + "ed25519-dalek", + "fnv", + "futures 0.3.1", + "futures-timer 2.0.2", + "lazy_static", + "libsecp256k1", + "log 0.4.8", + "multistream-select", + "parity-multiaddr 0.7.1", + "parity-multihash 0.2.1", + "parking_lot 0.10.0", + "pin-project", + "prost", + "prost-build", + "rand 0.7.3", + "ring", + "rw-stream-sink", + "sha2", + "smallvec 1.2.0", + "thiserror", + "unsigned-varint 0.3.0", + "untrusted", + "void", + "zeroize 1.1.0", ] [[package]] name = "libp2p-core-derive" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c320266be0a7760e23484d635acdb83844b2d74d3612d93b41c393c9bcf004e" dependencies = [ - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2", + "syn", ] [[package]] name = "libp2p-deflate" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be32697b42d040b325c3737f827ea04ede569ec956b7807700dd8d89d8210f9" dependencies = [ - "flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2", + "futures 0.3.1", + "libp2p-core", ] [[package]] name = "libp2p-dns" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f11c979b882f25d85726b15637d5bbc722dfa1be576605c54e99b8cf56906be3" dependencies = [ - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1", + "libp2p-core", + "log 0.4.8", ] [[package]] name = "libp2p-floodsub" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bdf6fba9272ad47dde94bade89540fdb16e24ae9ff7fb714c1c80a035165f28" dependencies = [ - "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cuckoofilter 0.3.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)", - "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bs58 0.3.0", + "cuckoofilter", + "fnv", + "futures 0.3.1", + "libp2p-core", + "libp2p-swarm", + "prost", + "prost-build", + "rand 0.7.3", + "smallvec 1.2.0", ] [[package]] name = "libp2p-gossipsub" version = "0.15.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)", - "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.4 (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)", - "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.5.0 (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)", - "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", +checksum = "6e6ecd058bf769d27ebec530544b081e08b0a1088e3186da8cc58d59915784d0" +dependencies = [ + "base64 0.11.0", + "bs58 0.3.0", + "byteorder 1.3.2", + "bytes 0.5.4", + "fnv", + "futures 0.3.1", + "futures_codec", + "libp2p-core", + "libp2p-swarm", + "log 0.4.8", + "lru 0.4.3", + "prost", + "prost-build", + "rand 0.7.3", + "sha2", + "smallvec 1.2.0", + "unsigned-varint 0.3.0", + "wasm-timer", ] [[package]] name = "libp2p-identify" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1a6261b804111c2dbf53f8ca03f66edc5ad1c29b78a61cf0cc5354052e28e9" dependencies = [ - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1", + "libp2p-core", + "libp2p-swarm", + "log 0.4.8", + "prost", + "prost-build", + "smallvec 1.2.0", + "wasm-timer", ] [[package]] name = "libp2p-kad" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.3 (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)", - "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multihash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uint 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.3.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.2.4 (registry+https://github.com/rust-lang/crates.io-index)", +checksum = "0c6ea6fece0d99599afb1b2082ca8937944cdd6b0946a88d54cb3ae7a38d1253" +dependencies = [ + "arrayvec 0.5.1", + "bytes 0.5.4", + "either", + "fnv", + "futures 0.3.1", + "futures_codec", + "libp2p-core", + "libp2p-swarm", + "log 0.4.8", + "parity-multihash 0.2.1", + "prost", + "prost-build", + "rand 0.7.3", + "sha2", + "smallvec 1.2.0", + "uint", + "unsigned-varint 0.3.0", + "void", + "wasm-timer", ] [[package]] name = "libp2p-mdns" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "074312353355df310affa105ec71b16fd7e52f5c6ae61d3dcbb3e79e8fdc9e5f" dependencies = [ - "async-std 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "dns-parser 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.3 (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)", - "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.5.0 (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)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.2.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.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "async-std", + "data-encoding", + "dns-parser", + "either", + "futures 0.3.1", + "lazy_static", + "libp2p-core", + "libp2p-swarm", + "log 0.4.8", + "net2", + "rand 0.7.3", + "smallvec 1.2.0", + "void", + "wasm-timer", ] [[package]] name = "libp2p-mplex" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d0b44dfdef80cc2be4b42d127de1c793905eca2459415a5c57d6b4fbd8ec30" dependencies = [ - "bytes 0.5.4 (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)", - "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.15.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.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4", + "fnv", + "futures 0.3.1", + "futures_codec", + "libp2p-core", + "log 0.4.8", + "parking_lot 0.10.0", + "unsigned-varint 0.3.0", ] [[package]] name = "libp2p-noise" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0845e8208d814cd41c26c90a6a2f2b720c31b588209cecc49a44c881a09f417f" dependencies = [ - "curve25519-dalek 1.2.3 (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)", - "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.16.10 (registry+https://github.com/rust-lang/crates.io-index)", - "snow 0.6.2 (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.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "curve25519-dalek 1.2.3", + "futures 0.3.1", + "lazy_static", + "libp2p-core", + "log 0.4.8", + "prost", + "prost-build", + "rand 0.7.3", + "ring", + "snow", + "x25519-dalek", + "zeroize 1.1.0", ] [[package]] name = "libp2p-ping" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16ecced2949ae93b6ff29565303ecd1bef15c4e4efb689033ee744922561a36b" dependencies = [ - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-swarm 0.5.0 (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.3 (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.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1", + "libp2p-core", + "libp2p-swarm", + "log 0.4.8", + "rand 0.7.3", + "void", + "wasm-timer", ] [[package]] name = "libp2p-plaintext" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "195fda6b6a948a242fd30570e0e3418ae8e0a20055ea75d45458e1079a8efb05" dependencies = [ - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rw-stream-sink 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4", + "futures 0.3.1", + "futures_codec", + "libp2p-core", + "log 0.4.8", + "prost", + "prost-build", + "rw-stream-sink", + "unsigned-varint 0.3.0", + "void", ] [[package]] name = "libp2p-secio" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "quicksink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.16.10 (registry+https://github.com/rust-lang/crates.io-index)", - "rw-stream-sink 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "twofish 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", +checksum = "ceef68ca377b264f84d64c88739a8fa118b5db1e8f18297351dff75314504a5f" +dependencies = [ + "aes-ctr", + "ctr", + "futures 0.3.1", + "hmac", + "js-sys", + "lazy_static", + "libp2p-core", + "log 0.4.8", + "parity-send-wrapper", + "pin-project", + "prost", + "prost-build", + "quicksink", + "rand 0.7.3", + "ring", + "rw-stream-sink", + "sha2", + "static_assertions", + "twofish", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", ] [[package]] name = "libp2p-swarm" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14ea00be81bc3985e36abad263ce2ad1b6aeb862aa743563eb70ad42880c05ae" dependencies = [ - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.2.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.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1", + "libp2p-core", + "log 0.4.8", + "smallvec 1.2.0", + "void", + "wasm-timer", ] [[package]] name = "libp2p-tcp" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e65ef381570df31cb047dfbc11483ab0fe7e6abbdcf2bdc2c60b5d11133d241" dependencies = [ - "async-std 1.4.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)", - "get_if_addrs 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ipnet 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "async-std", + "futures 0.3.1", + "futures-timer 2.0.2", + "get_if_addrs", + "ipnet", + "libp2p-core", + "log 0.4.8", ] [[package]] name = "libp2p-uds" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e4f4f7989b35f33d4b9738aab2f031310eb20fec513cab44d12b1bc985a8074" dependencies = [ - "async-std 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "async-std", + "futures 0.3.1", + "libp2p-core", + "log 0.4.8", ] [[package]] name = "libp2p-wasm-ext" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b4d457adb91a5e2212343218a554394cd8ced64a79fb8e36e7aed2a16d49495" dependencies = [ - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1", + "js-sys", + "libp2p-core", + "parity-send-wrapper", + "wasm-bindgen", + "wasm-bindgen-futures", ] [[package]] name = "libp2p-websocket" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bba425f2af1fdb7dece88b9ae05ca9430dfb0b72b2c078e73ded6f1556084509" dependencies = [ - "async-tls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quicksink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rw-stream-sink 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "soketto 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki-roots 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-tls", + "bytes 0.5.4", + "either", + "futures 0.3.1", + "libp2p-core", + "log 0.4.8", + "quicksink", + "rustls", + "rw-stream-sink", + "soketto", + "url 2.1.1", + "webpki", + "webpki-roots 0.18.0", ] [[package]] name = "libp2p-yamux" version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca25b3aac78a3c93c2a567622abd3cfc16f96f26ae1bf6134f0056203d62d86" dependencies = [ - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-core 0.15.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.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", - "yamux 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1", + "libp2p-core", + "log 0.4.8", + "parking_lot 0.10.0", + "thiserror", + "yamux", ] [[package]] name = "librocksdb-sys" version = "6.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a0785e816e1e11e7599388a492c61ef80ddc2afc91e313e61662cce537809be" dependencies = [ - "bindgen 0.49.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.50 (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)", + "bindgen", + "cc", + "glob 0.3.0", + "libc", ] [[package]] name = "libsecp256k1" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df6edf84fd62aad1c93932b39324eaeda3912c1d26bc18dfaee6293848e49a50" dependencies = [ - "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac-drbg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.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)", + "arrayref", + "crunchy", + "digest", + "hmac-drbg", + "rand 0.7.3", + "sha2", + "subtle 2.2.2", + "typenum", ] [[package]] name = "libz-sys" version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" dependencies = [ - "cc 1.0.50 (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.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "libc", + "pkg-config", + "vcpkg", ] [[package]] name = "linked-hash-map" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" [[package]] name = "linked_hash_set" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c7c91c4c7bbeb4f2f7c4e5be11e6a05bd6830bc37249c47ce1ad86ad453ff9c" dependencies = [ - "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "linked-hash-map", ] [[package]] name = "lock_api" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" dependencies = [ - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3", ] [[package]] name = "lock_api" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b" dependencies = [ - "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 1.0.0", ] [[package]] name = "log" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8", ] [[package]] name = "log" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", ] [[package]] name = "lru" version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8f669d42c72d18514dfca8115689c5f6370a17d980cb5bd777a67f404594c8" dependencies = [ - "hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hashbrown 0.5.0", ] [[package]] name = "lru" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0609345ddee5badacf857d4f547e0e5a2e987db77085c24cd887f73573a04237" dependencies = [ - "hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "hashbrown 0.6.3", ] [[package]] name = "mach" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86dd2487cdfea56def77b88438a2c915fb45113c5319bfe7e14306ca4cd0b0e1" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "malloc_size_of_derive" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37c5d4cd9473c5f4c9c111f033f15d4df9bd378fdf615944e360a4f55a05f0b" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "syn", + "synstructure", ] [[package]] name = "matches" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" [[package]] name = "maybe-uninit" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" [[package]] name = "memchr" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3197e20c7edb283f87c071ddfc7a2cca8f8e0b888c242959846a6fce03c72223" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "memoffset" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" dependencies = [ - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version", ] [[package]] name = "memory-db" version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881736a0f68a6fae1b596bb066c5bd16d7b3ed645a4dd8ffaefd02f585abaf71" 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.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ahash", + "hash-db", + "hashbrown 0.6.3", + "parity-util-mem 0.3.0", ] [[package]] name = "memory_units" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" [[package]] name = "merlin" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b0942b357c1b4d0dc43ba724674ec89c3218e6ca2b3e8269e7cb53bcecd2f6e" dependencies = [ - "byteorder 1.3.2 (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)", + "byteorder 1.3.2", + "keccak", + "rand_core 0.4.2", + "zeroize 1.1.0", ] [[package]] name = "mime" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" dependencies = [ - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9", ] [[package]] name = "miniz_oxide" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5" dependencies = [ - "adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "adler32", ] [[package]] name = "mio" version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" 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.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)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log 0.4.8", + "miow", + "net2", + "slab", + "winapi 0.2.8", ] [[package]] name = "mio-extras" version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" 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.21 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazycell", + "log 0.4.8", + "mio", + "slab", ] [[package]] name = "mio-uds" version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" dependencies = [ - "iovec 0.1.4 (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)", + "iovec", + "libc", + "mio", ] [[package]] name = "miow" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", ] [[package]] name = "more-asserts" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238" [[package]] name = "multimap" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97fbd5d00e0e37bfb10f433af8f5aaf631e739368dc9fc28286ca81ca4948dc" [[package]] name = "multistream-select" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f938ffe420493e77c8b6cbcc3f282283f68fc889c5dcbc8e51668d5f3a01ad94" dependencies = [ - "bytes 0.5.4 (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)", - "smallvec 1.2.0 (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.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4", + "futures 0.1.29", + "log 0.4.8", + "smallvec 1.2.0", + "tokio-io", + "unsigned-varint 0.3.0", ] [[package]] name = "names" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef320dab323286b50fb5cdda23f61c796a72a89998ab565ca32525c5c556f2da" dependencies = [ - "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.23", ] [[package]] name = "native-tls" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" dependencies = [ - "lazy_static 1.4.0 (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.27 (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.54 (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)", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static", + "libc", + "log 0.4.8", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", ] [[package]] name = "net2" version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" dependencies = [ - "cfg-if 0.1.10 (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)", + "cfg-if", + "libc", + "winapi 0.3.8", ] [[package]] name = "node-cli" version = "2.0.0" dependencies = [ - "browser-utils 0.8.0", - "frame-support 2.0.0", - "frame-system 2.0.0", - "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)", - "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)", - "node-executor 2.0.0", - "node-primitives 2.0.0", - "node-rpc 2.0.0", - "node-runtime 2.0.0", - "node-transaction-factory 0.8.0", - "pallet-authority-discovery 2.0.0", - "pallet-balances 2.0.0", - "pallet-contracts 2.0.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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-authority-discovery 0.8.0", - "sc-basic-authorship 0.8.0", - "sc-chain-spec 2.0.0", - "sc-cli 0.8.0", - "sc-client 0.8.0", - "sc-client-api 2.0.0", - "sc-client-db 0.8.0", - "sc-consensus-babe 0.8.0", - "sc-finality-grandpa 0.8.0", - "sc-keystore 2.0.0", - "sc-network 0.8.0", - "sc-offchain 2.0.0", - "sc-rpc 2.0.0", - "sc-service 0.8.0", - "sc-service-test 2.0.0", - "sc-telemetry 2.0.0", - "sc-transaction-pool 2.0.0", - "serde 1.0.104 (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", - "sp-transaction-pool 2.0.0", - "structopt 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-build-script-utils 2.0.0", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "browser-utils", + "frame-support", + "frame-system", + "futures 0.3.1", + "hex-literal", + "jsonrpc-core", + "log 0.4.8", + "node-executor", + "node-primitives", + "node-rpc", + "node-runtime", + "node-transaction-factory", + "pallet-authority-discovery", + "pallet-balances", + "pallet-contracts", + "pallet-im-online", + "pallet-indices", + "pallet-timestamp", + "pallet-transaction-payment", + "parity-scale-codec", + "rand 0.7.3", + "sc-authority-discovery", + "sc-basic-authorship", + "sc-chain-spec", + "sc-cli", + "sc-client", + "sc-client-api", + "sc-client-db", + "sc-consensus-babe", + "sc-finality-grandpa", + "sc-keystore", + "sc-network", + "sc-offchain", + "sc-rpc", + "sc-service", + "sc-service-test", + "sc-telemetry", + "sc-transaction-pool", + "serde", + "sp-authority-discovery", + "sp-consensus", + "sp-consensus-babe", + "sp-core", + "sp-finality-grandpa", + "sp-finality-tracker", + "sp-inherents", + "sp-io", + "sp-keyring", + "sp-runtime", + "sp-timestamp", + "sp-transaction-pool", + "structopt", + "substrate-build-script-utils", + "tempfile", + "vergen", + "wasm-bindgen", + "wasm-bindgen-futures", ] [[package]] name = "node-executor" version = "2.0.0" dependencies = [ - "criterion 0.3.1 (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", - "pallet-balances 2.0.0", - "pallet-contracts 2.0.0", - "pallet-grandpa 2.0.0", - "pallet-im-online 2.0.0", - "pallet-indices 2.0.0", - "pallet-session 2.0.0", - "pallet-timestamp 2.0.0", - "pallet-transaction-payment 2.0.0", - "pallet-treasury 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-executor 0.8.0", - "sp-application-crypto 2.0.0", - "sp-core 2.0.0", - "sp-io 2.0.0", - "sp-runtime 2.0.0", - "sp-state-machine 0.8.0", - "sp-trie 2.0.0", - "substrate-test-client 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)", + "criterion 0.3.1", + "frame-support", + "frame-system", + "node-primitives", + "node-runtime", + "node-testing", + "pallet-balances", + "pallet-contracts", + "pallet-grandpa", + "pallet-im-online", + "pallet-indices", + "pallet-session", + "pallet-timestamp", + "pallet-transaction-payment", + "pallet-treasury", + "parity-scale-codec", + "sc-executor", + "sp-application-crypto", + "sp-core", + "sp-io", + "sp-runtime", + "sp-state-machine", + "sp-trie", + "substrate-test-client", + "trie-root", + "wabt", ] [[package]] name = "node-primitives" version = "2.0.0" dependencies = [ - "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-core 2.0.0", - "sp-runtime 2.0.0", - "sp-serializer 2.0.0", + "pretty_assertions", + "sp-core", + "sp-runtime", + "sp-serializer", ] [[package]] name = "node-rpc" version = "2.0.0" dependencies = [ - "jsonrpc-core 14.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "node-primitives 2.0.0", - "node-runtime 2.0.0", - "pallet-contracts-rpc 0.8.0", - "pallet-transaction-payment-rpc 2.0.0", - "sc-client 0.8.0", - "sp-api 2.0.0", - "sp-runtime 2.0.0", - "sp-transaction-pool 2.0.0", - "substrate-frame-rpc-system 2.0.0", + "jsonrpc-core", + "node-primitives", + "node-runtime", + "pallet-contracts-rpc", + "pallet-transaction-payment-rpc", + "sc-client", + "sp-api", + "sp-runtime", + "sp-transaction-pool", + "substrate-frame-rpc-system", ] [[package]] name = "node-rpc-client" 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)", - "hyper 0.12.35 (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", - "sc-rpc 2.0.0", + "env_logger 0.7.1", + "futures 0.1.29", + "hyper 0.12.35", + "jsonrpc-core-client", + "log 0.4.8", + "node-primitives", + "sc-rpc", ] [[package]] name = "node-runtime" version = "2.0.0" dependencies = [ - "frame-executive 2.0.0", - "frame-support 2.0.0", - "frame-system 2.0.0", - "frame-system-rpc-runtime-api 2.0.0", - "integer-sqrt 0.1.3 (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", - "pallet-contracts 2.0.0", - "pallet-contracts-primitives 2.0.0", - "pallet-contracts-rpc-runtime-api 0.8.0", - "pallet-democracy 2.0.0", - "pallet-elections-phragmen 2.0.0", - "pallet-finality-tracker 2.0.0", - "pallet-grandpa 2.0.0", - "pallet-identity 2.0.0", - "pallet-im-online 2.0.0", - "pallet-indices 2.0.0", - "pallet-membership 2.0.0", - "pallet-offences 2.0.0", - "pallet-randomness-collective-flip 2.0.0", - "pallet-recovery 2.0.0", - "pallet-session 2.0.0", - "pallet-society 2.0.0", - "pallet-staking 2.0.0", - "pallet-staking-reward-curve 2.0.0", - "pallet-sudo 2.0.0", - "pallet-timestamp 2.0.0", - "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", - "pallet-vesting 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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.5", + "frame-executive", + "frame-support", + "frame-system", + "frame-system-rpc-runtime-api", + "integer-sqrt", + "node-primitives", + "pallet-authority-discovery", + "pallet-authorship", + "pallet-babe", + "pallet-balances", + "pallet-collective", + "pallet-contracts", + "pallet-contracts-primitives", + "pallet-contracts-rpc-runtime-api", + "pallet-democracy", + "pallet-elections-phragmen", + "pallet-finality-tracker", + "pallet-grandpa", + "pallet-identity", + "pallet-im-online", + "pallet-indices", + "pallet-membership", + "pallet-offences", + "pallet-randomness-collective-flip", + "pallet-recovery", + "pallet-session", + "pallet-society", + "pallet-staking", + "pallet-staking-reward-curve", + "pallet-sudo", + "pallet-timestamp", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "pallet-treasury", + "pallet-utility", + "pallet-vesting", + "parity-scale-codec", + "rustc-hex", + "serde", + "sp-api", + "sp-authority-discovery", + "sp-block-builder", + "sp-consensus-babe", + "sp-core", + "sp-inherents", + "sp-io", + "sp-keyring", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-staking", + "sp-std", + "sp-transaction-pool", + "sp-version", + "substrate-wasm-builder-runner", ] [[package]] name = "node-template" 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)", - "node-template-runtime 2.0.0", - "sc-basic-authorship 0.8.0", - "sc-cli 0.8.0", - "sc-client 0.8.0", - "sc-consensus-aura 0.8.0", - "sc-executor 0.8.0", - "sc-finality-grandpa 0.8.0", - "sc-network 0.8.0", - "sc-service 0.8.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-runtime 2.0.0", - "sp-transaction-pool 2.0.0", - "structopt 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "substrate-build-script-utils 2.0.0", - "vergen 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1", + "log 0.4.8", + "node-template-runtime", + "sc-basic-authorship", + "sc-cli", + "sc-client", + "sc-consensus-aura", + "sc-executor", + "sc-finality-grandpa", + "sc-network", + "sc-service", + "sc-transaction-pool", + "sp-consensus", + "sp-consensus-aura", + "sp-core", + "sp-finality-grandpa", + "sp-inherents", + "sp-runtime", + "sp-transaction-pool", + "structopt", + "substrate-build-script-utils", + "vergen", ] [[package]] name = "node-template-runtime" version = "2.0.0" dependencies = [ - "frame-executive 2.0.0", - "frame-support 2.0.0", - "frame-system 2.0.0", - "pallet-aura 2.0.0", - "pallet-balances 2.0.0", - "pallet-grandpa 2.0.0", - "pallet-indices 2.0.0", - "pallet-randomness-collective-flip 2.0.0", - "pallet-sudo 2.0.0", - "pallet-timestamp 2.0.0", - "pallet-transaction-payment 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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.5", + "frame-executive", + "frame-support", + "frame-system", + "pallet-aura", + "pallet-balances", + "pallet-grandpa", + "pallet-indices", + "pallet-randomness-collective-flip", + "pallet-sudo", + "pallet-timestamp", + "pallet-transaction-payment", + "parity-scale-codec", + "serde", + "sp-api", + "sp-block-builder", + "sp-consensus-aura", + "sp-core", + "sp-inherents", + "sp-io", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-std", + "sp-transaction-pool", + "sp-version", + "substrate-wasm-builder-runner", ] [[package]] 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", - "pallet-balances 2.0.0", - "pallet-contracts 2.0.0", - "pallet-grandpa 2.0.0", - "pallet-indices 2.0.0", - "pallet-session 2.0.0", - "pallet-society 2.0.0", - "pallet-staking 2.0.0", - "pallet-timestamp 2.0.0", - "pallet-transaction-payment 2.0.0", - "pallet-treasury 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-client 0.8.0", - "sc-executor 0.8.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)", + "frame-support", + "frame-system", + "node-executor", + "node-primitives", + "node-runtime", + "pallet-balances", + "pallet-contracts", + "pallet-grandpa", + "pallet-indices", + "pallet-session", + "pallet-society", + "pallet-staking", + "pallet-timestamp", + "pallet-transaction-payment", + "pallet-treasury", + "parity-scale-codec", + "sc-client", + "sc-executor", + "sp-core", + "sp-io", + "sp-keyring", + "sp-runtime", + "substrate-test-client", + "wabt", ] [[package]] name = "node-transaction-factory" version = "0.8.0" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-cli 0.8.0", - "sc-client 0.8.0", - "sc-client-api 2.0.0", - "sc-service 0.8.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", + "log 0.4.8", + "parity-scale-codec", + "sc-cli", + "sc-client", + "sc-client-api", + "sc-service", + "sp-api", + "sp-block-builder", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-runtime", ] [[package]] name = "nodrop" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" [[package]] name = "nohash-hasher" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721a2bf1c26159ebf17e0a980bc4ce61f4b2fec5ec3b42d42fddd7a84a9e538f" [[package]] name = "nom" version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" dependencies = [ - "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr", + "version_check 0.1.5", ] [[package]] name = "num-bigint" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0", + "num-integer", + "num-traits", ] [[package]] name = "num-integer" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0", + "num-traits", ] [[package]] name = "num-rational" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da4dc79f9e6c81bef96148c8f6b8e72ad4541caa4a24373e900a36da07de03a3" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0", + "num-bigint", + "num-integer", + "num-traits", ] [[package]] name = "num-traits" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0", ] [[package]] name = "num_cpus" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" dependencies = [ - "hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "hermit-abi", + "libc", ] [[package]] name = "ole32-sys" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" 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)", + "winapi 0.2.8", + "winapi-build", ] [[package]] name = "once_cell" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37" dependencies = [ - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1", ] [[package]] name = "once_cell" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d584f08c2d717d5c23a6414fc2822b71c651560713e54fa7eace675f758a355e" [[package]] name = "once_cell" version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b" [[package]] name = "oorandom" version = "11.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcec7c9c2a95cacc7cd0ecb89d8a8454eca13906f6deb55258ffff0adeb9405" [[package]] name = "opaque-debug" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" [[package]] name = "openssl" version = "0.10.27" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e176a45fedd4c990e26580847a525e39e16ec32ac78957dbf62ded31b3abfd6f" 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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.54 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "cfg-if", + "foreign-types", + "lazy_static", + "libc", + "openssl-sys", ] [[package]] name = "openssl-probe" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" [[package]] name = "openssl-sys" version = "0.9.54" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1024c0a59774200a555087a6da3f253a9095a5f344e353b212ac4c8b8e450986" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.50 (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.8 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0", + "cc", + "libc", + "pkg-config", + "vcpkg", ] [[package]] name = "output_vt100" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9" dependencies = [ - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8", ] [[package]] name = "owning_ref" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" dependencies = [ - "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "stable_deref_trait", ] [[package]] name = "pallet-assets" version = "2.0.0" dependencies = [ - "frame-support 2.0.0", - "frame-system 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-aura" version = "2.0.0" dependencies = [ - "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.2 (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.104 (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", + "frame-support", + "frame-system", + "lazy_static", + "pallet-session", + "pallet-timestamp", + "parity-scale-codec", + "parking_lot 0.9.0", + "serde", + "sp-application-crypto", + "sp-consensus-aura", + "sp-core", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-std", + "sp-timestamp", ] [[package]] name = "pallet-authority-discovery" 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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "pallet-session", + "parity-scale-codec", + "serde", + "sp-application-crypto", + "sp-authority-discovery", + "sp-core", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", ] [[package]] name = "pallet-authorship" version = "2.0.0" dependencies = [ - "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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-authorship 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", + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "parity-scale-codec", + "sp-authorship", + "sp-core", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-babe" 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)", - "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.2 (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.104 (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", - "sp-version 2.0.0", - "substrate-test-runtime 2.0.0", + "frame-support", + "frame-system", + "hex-literal", + "lazy_static", + "pallet-session", + "pallet-timestamp", + "parity-scale-codec", + "parking_lot 0.9.0", + "serde", + "sp-consensus-babe", + "sp-core", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", + "sp-timestamp", + "sp-version", + "substrate-test-runtime", ] [[package]] name = "pallet-balances" version = "2.0.0" dependencies = [ - "frame-support 2.0.0", - "frame-system 2.0.0", - "pallet-transaction-payment 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "pallet-transaction-payment", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-collective" 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", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "hex-literal", + "pallet-balances", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-contracts" version = "2.0.0" dependencies = [ - "assert_matches 1.3.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)", - "pallet-balances 2.0.0", - "pallet-contracts-primitives 2.0.0", - "pallet-randomness-collective-flip 2.0.0", - "pallet-timestamp 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "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.104 (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 0.8.0", - "sp-std 2.0.0", - "wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasmi-validation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "assert_matches", + "frame-support", + "frame-system", + "hex-literal", + "pallet-balances", + "pallet-contracts-primitives", + "pallet-randomness-collective-flip", + "pallet-timestamp", + "parity-scale-codec", + "parity-wasm 0.41.0", + "pwasm-utils", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-sandbox", + "sp-std", + "wabt", + "wasmi-validation", ] [[package]] name = "pallet-contracts-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-runtime 2.0.0", - "sp-std 2.0.0", + "parity-scale-codec", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-contracts-rpc" version = "0.8.0" dependencies = [ - "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-primitives 2.0.0", - "pallet-contracts-rpc-runtime-api 0.8.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (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-rpc 2.0.0", - "sp-runtime 2.0.0", + "jsonrpc-core", + "jsonrpc-core-client", + "jsonrpc-derive", + "pallet-contracts-primitives", + "pallet-contracts-rpc-runtime-api", + "parity-scale-codec", + "serde", + "serde_json", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-rpc", + "sp-runtime", ] [[package]] name = "pallet-contracts-rpc-runtime-api" version = "0.8.0" dependencies = [ - "pallet-contracts-primitives 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-api 2.0.0", - "sp-runtime 2.0.0", - "sp-std 2.0.0", + "pallet-contracts-primitives", + "parity-scale-codec", + "sp-api", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-democracy" 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", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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-storage 2.0.0", + "frame-support", + "frame-system", + "hex-literal", + "pallet-balances", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-storage", ] [[package]] name = "pallet-elections" 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", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "hex-literal", + "pallet-balances", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-elections-phragmen" 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", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "hex-literal", + "pallet-balances", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-phragmen", + "sp-runtime", + "sp-std", + "substrate-test-utils", ] [[package]] name = "pallet-evm" version = "2.0.0" dependencies = [ - "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", - "pallet-timestamp 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.6.2 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "sha3 0.8.2 (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", + "evm", + "frame-support", + "frame-system", + "pallet-balances", + "pallet-timestamp", + "parity-scale-codec", + "primitive-types", + "rlp", + "serde", + "sha3", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-example" 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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "pallet-balances", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-finality-tracker" version = "2.0.0" dependencies = [ - "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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-core 2.0.0", - "sp-finality-tracker 2.0.0", - "sp-inherents 2.0.0", - "sp-io 2.0.0", - "sp-runtime 2.0.0", - "sp-std 2.0.0", + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "parity-scale-codec", + "serde", + "sp-core", + "sp-finality-tracker", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-generic-asset" version = "2.0.0" dependencies = [ - "frame-support 2.0.0", - "frame-system 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-grandpa" version = "2.0.0" dependencies = [ - "frame-support 2.0.0", - "frame-system 2.0.0", - "pallet-finality-tracker 2.0.0", - "pallet-session 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "pallet-finality-tracker", + "pallet-session", + "parity-scale-codec", + "serde", + "sp-core", + "sp-finality-grandpa", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", ] [[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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "enumflags2", + "frame-support", + "frame-system", + "pallet-balances", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-im-online" version = "2.0.0" dependencies = [ - "frame-support 2.0.0", - "frame-system 2.0.0", - "pallet-authorship 2.0.0", - "pallet-session 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "pallet-authorship", + "pallet-session", + "parity-scale-codec", + "serde", + "sp-application-crypto", + "sp-core", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", ] [[package]] name = "pallet-indices" version = "2.0.0" dependencies = [ - "frame-support 2.0.0", - "frame-system 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-keyring", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-membership" version = "2.0.0" dependencies = [ - "frame-support 2.0.0", - "frame-system 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-nicks" 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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "pallet-balances", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-offences" 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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "pallet-balances", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", ] [[package]] name = "pallet-randomness-collective-flip" version = "2.0.0" dependencies = [ - "frame-support 2.0.0", - "frame-system 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "safe-mix 1.0.0 (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", + "frame-support", + "frame-system", + "parity-scale-codec", + "safe-mix", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-recovery" 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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "enumflags2", + "frame-support", + "frame-system", + "pallet-balances", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-scored-pool" 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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "pallet-balances", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-session" version = "2.0.0" dependencies = [ - "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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "lazy_static", + "pallet-timestamp", + "parity-scale-codec", + "serde", + "sp-application-crypto", + "sp-core", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", + "sp-trie", ] [[package]] name = "pallet-society" 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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "pallet-balances", + "parity-scale-codec", + "rand_chacha 0.2.1", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-staking" version = "2.0.0" dependencies = [ - "frame-support 2.0.0", - "frame-system 2.0.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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "pallet-authorship", + "pallet-balances", + "pallet-session", + "pallet-staking-reward-curve", + "pallet-timestamp", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-keyring", + "sp-phragmen", + "sp-runtime", + "sp-staking", + "sp-std", + "substrate-test-utils", ] [[package]] name = "pallet-staking-reward-curve" version = "2.0.0" dependencies = [ - "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-runtime 2.0.0", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-crate", + "proc-macro2 1.0.8", + "quote 1.0.2", + "sp-runtime", + "syn", ] [[package]] name = "pallet-sudo" version = "2.0.0" dependencies = [ - "frame-support 2.0.0", - "frame-system 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-timestamp" version = "2.0.0" dependencies = [ - "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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "impl-trait-for-tuples", + "parity-scale-codec", + "serde", + "sp-core", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-std", + "sp-timestamp", ] [[package]] name = "pallet-transaction-payment" version = "2.0.0" dependencies = [ - "frame-support 2.0.0", - "frame-system 2.0.0", - "pallet-balances 2.0.0", - "pallet-transaction-payment-rpc-runtime-api 2.0.0", - "parity-scale-codec 1.1.2 (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", + "frame-support", + "frame-system", + "pallet-balances", + "pallet-transaction-payment-rpc-runtime-api", + "parity-scale-codec", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-transaction-payment-rpc" version = "2.0.0" dependencies = [ - "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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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-rpc 2.0.0", - "sp-runtime 2.0.0", + "jsonrpc-core", + "jsonrpc-core-client", + "jsonrpc-derive", + "pallet-transaction-payment-rpc-runtime-api", + "parity-scale-codec", + "serde", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-rpc", + "sp-runtime", ] [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "2.0.0" dependencies = [ - "frame-support 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-api 2.0.0", - "sp-runtime 2.0.0", - "sp-std 2.0.0", + "frame-support", + "parity-scale-codec", + "serde", + "serde_json", + "sp-api", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-treasury" 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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "pallet-balances", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "frame-support", + "frame-system", + "pallet-balances", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-vesting" 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", - "hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pallet-balances 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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-storage 2.0.0", + "enumflags2", + "frame-support", + "frame-system", + "hex-literal", + "pallet-balances", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-storage", ] [[package]] name = "parity-bytes" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c276d76c5333b8c2579e02d49a06733a55b8282d2d9b13e8d53b6406bd7e30a" [[package]] name = "parity-multiaddr" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "045b3c7af871285146300da35b1932bb6e4639b66c7c98e85d06a32cbc4e8fa7" dependencies = [ - "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "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)", - "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.104 (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)", + "arrayref", + "bs58 0.2.5", + "byteorder 1.3.2", + "bytes 0.4.12", + "data-encoding", + "parity-multihash 0.1.3", + "percent-encoding 1.0.1", + "serde", + "unsigned-varint 0.2.3", + "url 1.7.2", ] [[package]] name = "parity-multiaddr" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80878c27f90dd162d3143333d672e80b194d6b080f05c83440e3dfda42e409f2" dependencies = [ - "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-multihash 0.2.1 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayref", + "bs58 0.3.0", + "byteorder 1.3.2", + "data-encoding", + "parity-multihash 0.2.1", + "percent-encoding 2.1.0", + "serde", + "static_assertions", + "unsigned-varint 0.3.0", + "url 2.1.1", ] [[package]] name = "parity-multihash" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3a17dc27848fd99e4f87eb0f8c9baba6ede0a6d555400c850ca45254ef4ce3" dependencies = [ - "blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2", + "bytes 0.4.12", + "rand 0.6.5", + "sha-1", + "sha2", + "sha3", + "unsigned-varint 0.2.3", ] [[package]] name = "parity-multihash" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a4d7b05e51bff5ae2c29c7b8c3d889985bbd8f4e15b3542fcc1f6f9666d292" dependencies = [ - "blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2", + "bytes 0.5.4", + "rand 0.7.3", + "sha-1", + "sha2", + "sha3", + "unsigned-varint 0.3.0", ] [[package]] name = "parity-scale-codec" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f747c06d9f3b2ad387ac881b9667298c81b1243aa9833f086e05996937c35507" dependencies = [ - "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bitvec 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-slice-cast 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec-derive 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.5.1", + "bitvec", + "byte-slice-cast", + "parity-scale-codec-derive", + "serde", ] [[package]] name = "parity-scale-codec-derive" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34e513ff3e406f3ede6796dcdc83d0b32ffb86668cea1ccf7363118abeb00476" dependencies = [ - "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-crate", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "parity-send-wrapper" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" [[package]] name = "parity-util-mem" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8174d85e62c4d615fddd1ef67966bdc5757528891d0742f15b131ad04667b3f9" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "malloc_size_of_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "malloc_size_of_derive", + "winapi 0.3.8", ] [[package]] name = "parity-util-mem" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900dd84654b048e5bad420bb341658fc2c4d7fea628c22bcf4621733e54859b4" dependencies = [ - "cfg-if 0.1.10 (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)", - "parity-util-mem-derive 0.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)", - "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "impl-trait-for-tuples", + "parity-util-mem-derive", + "parking_lot 0.9.0", + "smallvec 1.2.0", + "winapi 0.3.8", ] [[package]] name = "parity-util-mem-derive" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "syn", + "synstructure", ] [[package]] name = "parity-wasm" version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16ad52817c4d343339b3bc2e26861bd21478eda0b7509acf83505727000512ac" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", ] [[package]] name = "parity-wasm" version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" [[package]] name = "parking_lot" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" dependencies = [ - "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api 0.1.5", + "parking_lot_core 0.4.0", ] [[package]] name = "parking_lot" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" dependencies = [ - "lock_api 0.3.3 (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)", + "lock_api 0.3.3", + "parking_lot_core 0.6.2", + "rustc_version", ] [[package]] name = "parking_lot" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" dependencies = [ - "lock_api 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api 0.3.3", + "parking_lot_core 0.7.0", ] [[package]] name = "parking_lot_core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" dependencies = [ - "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)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "rand 0.6.5", + "rustc_version", + "smallvec 0.6.13", + "winapi 0.3.8", ] [[package]] name = "parking_lot_core" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" 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.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)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "cloudabi", + "libc", + "redox_syscall", + "rustc_version", + "smallvec 0.6.13", + "winapi 0.3.8", ] [[package]] name = "parking_lot_core" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" 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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "cloudabi", + "libc", + "redox_syscall", + "smallvec 1.2.0", + "winapi 0.3.8", ] [[package]] name = "paste" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "423a519e1c6e828f1e73b720f9d9ed2fa643dce8a7737fb43235ce0b41eeaa49" dependencies = [ - "paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", + "paste-impl", + "proc-macro-hack", ] [[package]] name = "paste-impl" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5" dependencies = [ - "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-hack", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "pbkdf2" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", + "crypto-mac", ] [[package]] name = "pdqselect" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec91767ecc0a0bbe558ce8c9da33c068066c57ecc8bb8477ef8c1ad3ef77c27" [[package]] name = "peeking_take_while" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "percent-encoding" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" [[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "petgraph" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c127eea4a29ec6c85d153c59dc1213f33ec74cead30fe4730aecc88cc1fd92" dependencies = [ - "fixedbitset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fixedbitset", + "indexmap", ] [[package]] name = "pin-project" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7804a463a8d9572f13453c516a5faea534a2403d7ced2f0c7e100eeff072772c" dependencies = [ - "pin-project-internal 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-internal", ] [[package]] name = "pin-project-internal" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "pin-project-lite" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae" [[package]] name = "pin-utils" version = "0.1.0-alpha.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" [[package]] name = "pkg-config" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" [[package]] name = "plain" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" [[package]] name = "plotters" version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e3bb8da247d27ae212529352020f3e5ee16e83c0c258061d27b08ab92675eeb" dependencies = [ - "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys", + "num-traits", + "wasm-bindgen", + "web-sys", ] [[package]] name = "ppv-lite86" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" [[package]] name = "pretty_assertions" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ctor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ansi_term 0.11.0", + "ctor", + "difference", + "output_vt100", ] [[package]] name = "primitive-types" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4336f4f5d5524fa60bcbd6fe626f9223d8142a50e7053e979acdf0da41ab975" dependencies = [ - "fixed-hash 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-codec 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-serde 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uint 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde 0.3.0", + "uint", ] [[package]] name = "proc-macro-crate" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" dependencies = [ - "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "toml", ] [[package]] name = "proc-macro-error" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875077759af22fa20b610ad4471d8155b321c89c3f2785526c9839b099be4e0a" dependencies = [ - "proc-macro-error-attr 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.8 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-error-attr", + "proc-macro2 1.0.8", + "quote 1.0.2", + "rustversion", + "syn", ] [[package]] name = "proc-macro-error-attr" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5717d9fa2664351a01ed73ba5ef6df09c01a521cb42cb65a061432a826f3c7a" dependencies = [ - "proc-macro2 1.0.8 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", - "syn-mid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "rustversion", + "syn", + "syn-mid", ] [[package]] name = "proc-macro-hack" version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "proc-macro-nested" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" [[package]] name = "proc-macro2" version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" dependencies = [ - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0", ] [[package]] name = "proc-macro2" version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" dependencies = [ - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0", ] [[package]] name = "prost" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212" dependencies = [ - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-derive 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4", + "prost-derive", ] [[package]] name = "prost-build" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b10678c913ecbd69350e8535c3aef91a8676c0773fc1d7b95cdd196d7f2f26" dependencies = [ - "bytes 0.5.4 (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.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.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "petgraph 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "which 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4", + "heck", + "itertools", + "log 0.4.8", + "multimap", + "petgraph", + "prost", + "prost-types", + "tempfile", + "which 3.1.0", ] [[package]] name = "prost-derive" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72" dependencies = [ - "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow", + "itertools", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "prost-types" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1834f67c0697c001304b75be76f67add9c89742eda3a085ad8ee0bb38c3417aa" dependencies = [ - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4", + "prost", ] [[package]] name = "pwasm-utils" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f7a12f176deee919f4ba55326ee17491c8b707d0987aed822682c821b660192" 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.41.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", + "log 0.4.8", + "parity-wasm 0.41.0", ] [[package]] name = "quick-error" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quickcheck" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f" 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)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.1", + "log 0.4.8", + "rand 0.7.3", + "rand_core 0.5.1", ] [[package]] name = "quicksink" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8461ef7445f61fd72d8dcd0629ce724b9131b3c2eb36e83a5d3d4161c127530" dependencies = [ - "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)", - "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core", + "futures-sink", + "pin-project-lite", ] [[package]] name = "quote" version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30", ] [[package]] name = "quote" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", ] [[package]] name = "rand" version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" dependencies = [ - "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)", + "libc", + "rand 0.4.6", ] [[package]] name = "rand" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" dependencies = [ - "fuchsia-cprng 0.1.1 (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)", + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi 0.3.8", ] [[package]] name = "rand" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" dependencies = [ - "autocfg 0.1.7 (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)", - "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.7", + "libc", + "rand_chacha 0.1.1", + "rand_core 0.4.2", + "rand_hc 0.1.0", + "rand_isaac", + "rand_jitter", + "rand_os", + "rand_pcg", + "rand_xorshift", + "winapi 0.3.8", ] [[package]] name = "rand" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom 0.1.14 (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)", + "getrandom", + "libc", + "rand_chacha 0.2.1", + "rand_core 0.5.1", + "rand_hc 0.2.0", ] [[package]] name = "rand_chacha" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.7", + "rand_core 0.3.1", ] [[package]] name = "rand_chacha" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" dependencies = [ - "c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "c2-chacha", + "rand_core 0.5.1", ] [[package]] name = "rand_core" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" dependencies = [ - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.2", ] [[package]] name = "rand_core" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" [[package]] name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", ] [[package]] name = "rand_hc" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1", ] [[package]] name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1", ] [[package]] name = "rand_isaac" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1", ] [[package]] name = "rand_jitter" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" dependencies = [ - "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)", + "libc", + "rand_core 0.4.2", + "winapi 0.3.8", ] [[package]] name = "rand_os" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" 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.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.58 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "wasm-bindgen", + "winapi 0.3.8", ] [[package]] name = "rand_pcg" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.7", + "rand_core 0.4.2", ] [[package]] name = "rand_xorshift" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1", ] [[package]] name = "rand_xoshiro" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b418169fb9c46533f326efd6eed2576699c44ca92d3052a066214a8d828929" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", + "rand_core 0.3.1", ] [[package]] name = "raw-cpuid" version = "7.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4a349ca83373cfa5d6dbb66fd76e58b2cca08da71a5f6400de0a0a6a9bceeaf" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "cc", + "rustc_version", ] [[package]] name = "rayon" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098" dependencies = [ - "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque", + "either", + "rayon-core", ] [[package]] name = "rayon-core" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9" dependencies = [ - "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque", + "crossbeam-queue 0.2.1", + "crossbeam-utils 0.7.0", + "lazy_static", + "num_cpus", ] [[package]] name = "rdrand" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1", ] [[package]] name = "redox_syscall" version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" [[package]] name = "redox_users" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" dependencies = [ - "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", + "redox_syscall", + "rust-argon2", ] [[package]] name = "regex" version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" dependencies = [ - "aho-corasick 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", ] [[package]] name = "regex-automata" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", ] [[package]] name = "regex-syntax" version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06" [[package]] name = "region" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "448e868c6e4cfddfa49b6a72c95906c04e8547465e9536575b95c70a4044f856" dependencies = [ - "bitflags 1.2.1 (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)", + "bitflags", + "libc", + "mach", + "winapi 0.3.8", ] [[package]] name = "remove_dir_all" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" dependencies = [ - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8", ] [[package]] name = "ring" version = "0.16.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "113f53b644c5442e20ff3a299be3d6c61ba143737af5bd2ab298e248a7575b2d" dependencies = [ - "cc 1.0.50 (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.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.35 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cc", + "lazy_static", + "libc", + "spin", + "untrusted", + "web-sys", + "winapi 0.3.8", ] [[package]] name = "rlp" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a44d5ae8afcb238af8b75640907edc6c931efcfab2c854e81ed35fa080f84cd" dependencies = [ - "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hex", ] [[package]] name = "rocksdb" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12069b106981c6103d3eab7dd1c86751482d0779a520b7c14954c8b586c1e643" dependencies = [ - "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)", + "libc", + "librocksdb-sys", ] [[package]] name = "rpassword" version = "4.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99371657d3c8e4d816fb6221db98fa408242b0b53bac08f8676a41f8554fe99f" dependencies = [ - "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)", + "libc", + "winapi 0.3.8", ] [[package]] name = "rust-argon2" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" dependencies = [ - "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", - "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.11.0", + "blake2b_simd", + "constant_time_eq", + "crossbeam-utils 0.7.0", ] [[package]] name = "rustc-demangle" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" [[package]] name = "rustc-hex" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" [[package]] name = "rustc_version" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" dependencies = [ - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.9.0", ] [[package]] name = "rustls" version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b25a18b1bf7387f0145e7f8324e700805aade3842dd3db2e74e4cdeb4677c09e" dependencies = [ - "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.16.10 (registry+https://github.com/rust-lang/crates.io-index)", - "sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.10.1", + "log 0.4.8", + "ring", + "sct", + "webpki", ] [[package]] name = "rustversion" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "rw-stream-sink" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020" dependencies = [ - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1", + "pin-project", + "static_assertions", ] [[package]] name = "ryu" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" [[package]] name = "safe-mix" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347" dependencies = [ - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version", ] [[package]] name = "safemem" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" [[package]] name = "same-file" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ - "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util", ] [[package]] name = "sc-authority-discovery" version = "0.8.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.15.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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "quickcheck 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (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.46 (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", - "substrate-test-runtime-client 2.0.0", + "bytes 0.4.12", + "derive_more", + "env_logger 0.7.1", + "futures 0.3.1", + "futures-timer 2.0.2", + "libp2p", + "log 0.4.8", + "parity-scale-codec", + "prost", + "prost-build", + "quickcheck", + "rand 0.7.3", + "sc-client-api", + "sc-keystore", + "sc-network", + "sc-peerset", + "serde_json", + "sp-api", + "sp-authority-discovery", + "sp-blockchain", + "sp-core", + "sp-runtime", + "substrate-test-runtime-client", ] [[package]] name = "sc-basic-authorship" version = "0.8.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.2 (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 0.8.0", - "sc-client 0.8.0", - "sc-client-api 2.0.0", - "sc-telemetry 2.0.0", - "sc-transaction-pool 2.0.0", - "sp-api 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)", + "futures 0.3.1", + "log 0.4.8", + "parity-scale-codec", + "parking_lot 0.9.0", + "sc-block-builder", + "sc-client", + "sc-client-api", + "sc-telemetry", + "sc-transaction-pool", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-transaction-pool", + "substrate-test-runtime-client", + "tokio-executor 0.2.0-alpha.6", ] [[package]] name = "sc-block-builder" version = "0.8.0" dependencies = [ - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-client-api 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", - "sp-state-machine 0.8.0", + "parity-scale-codec", + "sc-client-api", + "sp-api", + "sp-block-builder", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-runtime", + "sp-state-machine", ] [[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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-core 2.0.0", - "sp-runtime 2.0.0", + "impl-trait-for-tuples", + "sc-chain-spec-derive", + "sc-network", + "sc-telemetry", + "serde", + "serde_json", + "sp-core", + "sp-runtime", ] [[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.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-crate", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "sc-cli" version = "0.8.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.14 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.10 (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.2 (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.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rpassword 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-client-api 2.0.0", - "sc-network 0.8.0", - "sc-service 0.8.0", - "sc-telemetry 2.0.0", - "sc-tracing 2.0.0", - "serde_json 1.0.46 (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 0.8.0", - "structopt 0.3.9 (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.11 (registry+https://github.com/rust-lang/crates.io-index)", + "ansi_term 0.12.1", + "app_dirs", + "atty", + "chrono", + "clap", + "derive_more", + "env_logger 0.7.1", + "fdlimit", + "futures 0.3.1", + "lazy_static", + "log 0.4.8", + "names", + "regex", + "rpassword", + "sc-client-api", + "sc-network", + "sc-service", + "sc-telemetry", + "sc-tracing", + "serde_json", + "sp-blockchain", + "sp-core", + "sp-keyring", + "sp-panic-handler", + "sp-runtime", + "sp-state-machine", + "structopt", + "tempfile", + "time", + "tokio 0.2.11", ] [[package]] name = "sc-client" 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)", - "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.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb-memorydb 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.2 (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 0.8.0", - "sc-client-api 2.0.0", - "sc-executor 0.8.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 0.8.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 0.8.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.12 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more", + "env_logger 0.7.1", + "fnv", + "futures 0.3.1", + "hash-db", + "hex-literal", + "kvdb", + "kvdb-memorydb", + "log 0.4.8", + "parity-scale-codec", + "parking_lot 0.9.0", + "sc-block-builder", + "sc-client-api", + "sc-executor", + "sc-telemetry", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-externalities", + "sp-inherents", + "sp-keyring", + "sp-panic-handler", + "sp-runtime", + "sp-state-machine", + "sp-std", + "sp-trie", + "sp-version", + "substrate-test-runtime-client", + "tempfile", + "tracing", ] [[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.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.2 (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 0.8.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 0.8.0", - "sp-inherents 2.0.0", - "sp-keyring 2.0.0", - "sp-runtime 2.0.0", - "sp-state-machine 0.8.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", + "derive_more", + "fnv", + "futures 0.3.1", + "hash-db", + "hex-literal", + "kvdb", + "log 0.4.8", + "parity-scale-codec", + "parking_lot 0.9.0", + "sc-executor", + "sc-telemetry", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-externalities", + "sp-inherents", + "sp-keyring", + "sp-runtime", + "sp-state-machine", + "sp-std", + "sp-test-primitives", + "sp-transaction-pool", + "sp-trie", + "sp-version", ] [[package]] name = "sc-client-db" 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.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb-memorydb 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "kvdb-rocksdb 0.4.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)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-util-mem 0.4.1 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-client 0.8.0", - "sc-client-api 2.0.0", - "sc-executor 0.8.0", - "sc-state-db 0.8.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 0.8.0", - "sp-trie 2.0.0", - "substrate-test-runtime-client 2.0.0", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.7.1", + "hash-db", + "kvdb", + "kvdb-memorydb", + "kvdb-rocksdb", + "linked-hash-map", + "log 0.4.8", + "parity-scale-codec", + "parity-util-mem 0.4.1", + "parking_lot 0.9.0", + "quickcheck", + "sc-client", + "sc-client-api", + "sc-executor", + "sc-state-db", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-keyring", + "sp-runtime", + "sp-state-machine", + "sp-trie", + "substrate-test-runtime-client", + "tempfile", ] [[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.2 (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 0.8.0", - "sc-client-api 2.0.0", - "sc-consensus-slots 0.8.0", - "sc-executor 0.8.0", - "sc-keystore 2.0.0", - "sc-network 0.8.0", - "sc-network-test 0.8.0", - "sc-service 0.8.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)", + "derive_more", + "env_logger 0.7.1", + "futures 0.1.29", + "futures 0.3.1", + "futures-timer 0.4.0", + "log 0.4.8", + "parity-scale-codec", + "parking_lot 0.9.0", + "sc-client", + "sc-client-api", + "sc-consensus-slots", + "sc-executor", + "sc-keystore", + "sc-network", + "sc-network-test", + "sc-service", + "sc-telemetry", + "sp-api", + "sp-application-crypto", + "sp-block-builder", + "sp-blockchain", + "sp-consensus", + "sp-consensus-aura", + "sp-core", + "sp-inherents", + "sp-io", + "sp-keyring", + "sp-runtime", + "sp-timestamp", + "sp-version", + "substrate-test-runtime-client", + "tempfile", + "tokio 0.1.22", ] [[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.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num-rational 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.2 (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.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-block-builder 0.8.0", - "sc-client 0.8.0", - "sc-client-api 2.0.0", - "sc-consensus-slots 0.8.0", - "sc-consensus-uncles 0.8.0", - "sc-executor 0.8.0", - "sc-keystore 2.0.0", - "sc-network 0.8.0", - "sc-network-test 0.8.0", - "sc-service 0.8.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)", + "derive_more", + "env_logger 0.7.1", + "fork-tree", + "futures 0.1.29", + "futures 0.3.1", + "futures-timer 0.4.0", + "log 0.4.8", + "merlin", + "num-bigint", + "num-rational", + "num-traits", + "parity-scale-codec", + "parking_lot 0.9.0", + "pdqselect", + "rand 0.7.3", + "sc-block-builder", + "sc-client", + "sc-client-api", + "sc-consensus-slots", + "sc-consensus-uncles", + "sc-executor", + "sc-keystore", + "sc-network", + "sc-network-test", + "sc-service", + "sc-telemetry", + "schnorrkel", + "sp-api", + "sp-application-crypto", + "sp-block-builder", + "sp-blockchain", + "sp-consensus", + "sp-consensus-babe", + "sp-core", + "sp-inherents", + "sp-io", + "sp-keyring", + "sp-runtime", + "sp-timestamp", + "sp-version", + "substrate-test-runtime-client", + "tempfile", + "tokio 0.1.22", ] [[package]] name = "sc-consensus-manual-seal" 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.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)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-basic-authorship 0.8.0", - "sc-client 0.8.0", - "sc-client-api 2.0.0", - "sc-transaction-pool 2.0.0", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-blockchain 2.0.0", - "sp-consensus 0.8.0", - "sp-inherents 2.0.0", - "sp-runtime 2.0.0", - "sp-transaction-pool 2.0.0", - "substrate-test-runtime-client 2.0.0", - "substrate-test-runtime-transaction-pool 2.0.0", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more", + "env_logger 0.7.1", + "futures 0.3.1", + "jsonrpc-core", + "jsonrpc-core-client", + "jsonrpc-derive", + "log 0.4.8", + "parking_lot 0.10.0", + "sc-basic-authorship", + "sc-client", + "sc-client-api", + "sc-transaction-pool", + "serde", + "sp-blockchain", + "sp-consensus", + "sp-inherents", + "sp-runtime", + "sp-transaction-pool", + "substrate-test-runtime-client", + "substrate-test-runtime-transaction-pool", + "tempfile", + "tokio 0.2.11", ] [[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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-client-api 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-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", + "derive_more", + "futures 0.3.1", + "log 0.4.8", + "parity-scale-codec", + "sc-client-api", + "sp-api", + "sp-block-builder", + "sp-blockchain", + "sp-consensus", + "sp-consensus-pow", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-timestamp", ] [[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.2 (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-api 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-state-machine 0.8.0", - "substrate-test-runtime-client 2.0.0", + "futures 0.3.1", + "futures-timer 2.0.2", + "log 0.4.8", + "parity-scale-codec", + "parking_lot 0.9.0", + "sc-client-api", + "sc-telemetry", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-state-machine", + "substrate-test-runtime-client", ] [[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", + "log 0.4.8", + "sc-client-api", + "sp-authorship", + "sp-consensus", + "sp-core", + "sp-inherents", + "sp-runtime", ] [[package]] name = "sc-executor" version = "0.8.0" dependencies = [ - "assert_matches 1.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)", - "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.4 (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.2 (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-executor-common 0.8.0", - "sc-executor-wasmi 0.8.0", - "sc-executor-wasmtime 0.8.0", - "sc-runtime-test 2.0.0", - "sp-core 2.0.0", - "sp-externalities 0.8.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 0.8.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)", + "assert_matches", + "derive_more", + "hex-literal", + "lazy_static", + "libsecp256k1", + "log 0.4.8", + "parity-scale-codec", + "parity-wasm 0.41.0", + "parking_lot 0.9.0", + "sc-executor-common", + "sc-executor-wasmi", + "sc-executor-wasmtime", + "sc-runtime-test", + "sp-core", + "sp-externalities", + "sp-io", + "sp-panic-handler", + "sp-runtime-interface", + "sp-serializer", + "sp-state-machine", + "sp-trie", + "sp-version", + "sp-wasm-interface", + "substrate-test-runtime", + "test-case", + "wabt", + "wasmi", ] [[package]] name = "sc-executor-common" version = "0.8.0" dependencies = [ - "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)", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-allocator 2.0.0", - "sp-core 2.0.0", - "sp-runtime-interface 2.0.0", - "sp-serializer 2.0.0", - "sp-wasm-interface 2.0.0", - "wasmi 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more", + "log 0.4.8", + "parity-scale-codec", + "sp-allocator", + "sp-core", + "sp-runtime-interface", + "sp-serializer", + "sp-wasm-interface", + "wasmi", ] [[package]] name = "sc-executor-wasmi" version = "0.8.0" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-executor-common 0.8.0", - "sp-allocator 2.0.0", - "sp-core 2.0.0", - "sp-runtime-interface 2.0.0", - "sp-wasm-interface 2.0.0", - "wasmi 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8", + "parity-scale-codec", + "parity-wasm 0.41.0", + "sc-executor-common", + "sp-allocator", + "sp-core", + "sp-runtime-interface", + "sp-wasm-interface", + "wasmi", ] [[package]] name = "sc-executor-wasmtime" version = "0.8.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)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-executor-common 0.8.0", - "sp-allocator 2.0.0", - "sp-core 2.0.0", - "sp-runtime-interface 2.0.0", - "sp-wasm-interface 2.0.0", - "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)", + "assert_matches", + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "cranelift-native", + "cranelift-wasm", + "log 0.4.8", + "parity-scale-codec", + "parity-wasm 0.41.0", + "sc-executor-common", + "sp-allocator", + "sp-core", + "sp-runtime-interface", + "sp-wasm-interface", + "wasmi", + "wasmtime-environ", + "wasmtime-jit", + "wasmtime-runtime", ] [[package]] name = "sc-finality-grandpa" version = "0.8.0" dependencies = [ - "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "finality-grandpa 0.11.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)", - "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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-client 0.8.0", - "sc-client-api 2.0.0", - "sc-keystore 2.0.0", - "sc-network 0.8.0", - "sc-network-gossip 0.8.0", - "sc-network-test 0.8.0", - "sc-telemetry 2.0.0", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-api 2.0.0", - "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-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 0.8.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)", + "assert_matches", + "env_logger 0.7.1", + "finality-grandpa", + "fork-tree", + "futures 0.1.29", + "futures 0.3.1", + "futures-timer 2.0.2", + "log 0.4.8", + "parity-scale-codec", + "parking_lot 0.9.0", + "pin-project", + "rand 0.7.3", + "sc-client", + "sc-client-api", + "sc-keystore", + "sc-network", + "sc-network-gossip", + "sc-network-test", + "sc-telemetry", + "serde_json", + "sp-api", + "sp-arithmetic", + "sp-blockchain", + "sp-consensus", + "sp-consensus-babe", + "sp-core", + "sp-finality-grandpa", + "sp-finality-tracker", + "sp-inherents", + "sp-keyring", + "sp-runtime", + "sp-state-machine", + "substrate-test-runtime-client", + "tempfile", + "tokio 0.1.22", ] [[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.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (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)", + "derive_more", + "hex", + "parking_lot 0.9.0", + "rand 0.7.3", + "serde_json", + "sp-application-crypto", + "sp-core", + "subtle 2.2.2", + "tempfile", ] [[package]] name = "sc-network" version = "0.8.0" dependencies = [ - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.4 (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.10 (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.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)", - "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.15.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)", - "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.2 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-block-builder 0.8.0", - "sc-client 0.8.0", - "sc-client-api 2.0.0", - "sc-peerset 2.0.0", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (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)", - "unsigned-varint 0.3.0 (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)", + "bitflags", + "bytes 0.5.4", + "derive_more", + "either", + "env_logger 0.7.1", + "erased-serde", + "fnv", + "fork-tree", + "futures 0.3.1", + "futures-timer 0.4.0", + "futures_codec", + "libp2p", + "linked-hash-map", + "linked_hash_set", + "log 0.4.8", + "lru 0.4.3", + "parity-scale-codec", + "parking_lot 0.9.0", + "quickcheck", + "rand 0.7.3", + "rustc-hex", + "sc-block-builder", + "sc-client", + "sc-client-api", + "sc-peerset", + "serde", + "serde_json", + "slog", + "slog_derive", + "smallvec 0.6.13", + "sp-arithmetic", + "sp-blockchain", + "sp-consensus", + "sp-consensus-babe", + "sp-core", + "sp-keyring", + "sp-runtime", + "sp-test-primitives", + "substrate-test-client", + "substrate-test-runtime-client", + "tempfile", + "unsigned-varint 0.3.0", + "void", + "zeroize 1.1.0", ] [[package]] name = "sc-network-gossip" version = "0.8.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.15.0 (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", + "futures 0.1.29", + "futures 0.3.1", + "futures-timer 0.4.0", + "libp2p", + "log 0.4.8", + "lru 0.1.17", + "parking_lot 0.9.0", + "sc-network", + "sp-runtime", ] [[package]] name = "sc-network-test" version = "0.8.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.15.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)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-block-builder 0.8.0", - "sc-client 0.8.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)", + "env_logger 0.7.1", + "futures 0.1.29", + "futures 0.3.1", + "futures-timer 0.4.0", + "libp2p", + "log 0.4.8", + "parking_lot 0.9.0", + "rand 0.7.3", + "sc-block-builder", + "sc-client", + "sc-client-api", + "sc-network", + "sp-blockchain", + "sp-consensus", + "sp-consensus-babe", + "sp-core", + "sp-runtime", + "substrate-test-runtime", + "substrate-test-runtime-client", + "tempfile", + "tokio 0.1.22", ] [[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.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.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.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-client-api 2.0.0", - "sc-client-db 0.8.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)", + "bytes 0.4.12", + "env_logger 0.7.1", + "fnv", + "futures 0.1.29", + "futures 0.3.1", + "futures-timer 2.0.2", + "hyper 0.12.35", + "hyper-rustls", + "log 0.4.8", + "num_cpus", + "parity-scale-codec", + "parking_lot 0.9.0", + "rand 0.7.3", + "sc-client-api", + "sc-client-db", + "sc-keystore", + "sc-network", + "sc-transaction-pool", + "sp-api", + "sp-core", + "sp-offchain", + "sp-runtime", + "sp-transaction-pool", + "substrate-test-runtime-client", + "threadpool", + "tokio 0.1.22", ] [[package]] name = "sc-peerset" version = "2.0.0" dependencies = [ - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p 0.15.0 (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.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1", + "libp2p", + "log 0.4.8", + "rand 0.7.3", + "serde_json", ] [[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.2 (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.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-client 0.8.0", - "sc-client-api 2.0.0", - "sc-executor 0.8.0", - "sc-keystore 2.0.0", - "sc-network 0.8.0", - "sc-rpc-api 0.8.0", - "sc-transaction-pool 2.0.0", - "serde_json 1.0.46 (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-offchain 2.0.0", - "sp-rpc 2.0.0", - "sp-runtime 2.0.0", - "sp-session 2.0.0", - "sp-state-machine 0.8.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)", + "assert_matches", + "futures 0.1.29", + "futures 0.3.1", + "hash-db", + "jsonrpc-core", + "jsonrpc-pubsub", + "log 0.4.8", + "parity-scale-codec", + "parking_lot 0.9.0", + "rustc-hex", + "sc-client", + "sc-client-api", + "sc-executor", + "sc-keystore", + "sc-network", + "sc-rpc-api", + "sc-transaction-pool", + "serde_json", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-io", + "sp-offchain", + "sp-rpc", + "sp-runtime", + "sp-session", + "sp-state-machine", + "sp-transaction-pool", + "sp-version", + "substrate-test-runtime-client", + "tokio 0.1.22", ] [[package]] name = "sc-rpc-api" 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)", - "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.2 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (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", + "derive_more", + "futures 0.3.1", + "jsonrpc-core", + "jsonrpc-core-client", + "jsonrpc-derive", + "jsonrpc-pubsub", + "log 0.4.8", + "parity-scale-codec", + "parking_lot 0.9.0", + "serde", + "serde_json", + "sp-core", + "sp-rpc", + "sp-transaction-pool", + "sp-version", ] [[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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-runtime 2.0.0", + "jsonrpc-core", + "jsonrpc-http-server", + "jsonrpc-pubsub", + "jsonrpc-ws-server", + "log 0.4.8", + "serde", + "serde_json", + "sp-runtime", ] [[package]] name = "sc-runtime-test" version = "2.0.0" dependencies = [ - "sp-allocator 2.0.0", - "sp-core 2.0.0", - "sp-io 2.0.0", - "sp-runtime 2.0.0", - "sp-sandbox 0.8.0", - "sp-std 2.0.0", - "substrate-wasm-builder-runner 1.0.5", + "sp-allocator", + "sp-core", + "sp-io", + "sp-runtime", + "sp-sandbox", + "sp-std", + "substrate-wasm-builder-runner", ] [[package]] name = "sc-service" version = "0.8.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)", - "futures-diagnose 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "grafana-data-source 0.8.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.2 (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 0.8.0", - "sc-client-api 2.0.0", - "sc-client-db 0.8.0", - "sc-executor 0.8.0", - "sc-finality-grandpa 0.8.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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (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.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more", + "exit-future", + "futures 0.1.29", + "futures 0.3.1", + "futures-diagnose", + "futures-timer 2.0.2", + "grafana-data-source", + "lazy_static", + "log 0.4.8", + "parity-multiaddr 0.5.0", + "parity-scale-codec", + "parking_lot 0.9.0", + "sc-chain-spec", + "sc-client", + "sc-client-api", + "sc-client-db", + "sc-executor", + "sc-finality-grandpa", + "sc-keystore", + "sc-network", + "sc-offchain", + "sc-rpc", + "sc-rpc-server", + "sc-telemetry", + "sc-tracing", + "sc-transaction-pool", + "serde", + "serde_json", + "slog", + "sp-api", + "sp-application-crypto", + "sp-blockchain", + "sp-consensus", + "sp-consensus-babe", + "sp-core", + "sp-finality-grandpa", + "sp-io", + "sp-runtime", + "sp-session", + "sp-transaction-pool", + "substrate-test-runtime-client", + "sysinfo", + "target_info", + "tokio 0.2.11", + "tokio-executor 0.1.9", + "tracing", ] [[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.2 (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 0.8.0", - "sc-network 0.8.0", - "sc-service 0.8.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)", + "env_logger 0.7.1", + "fdlimit", + "futures 0.1.29", + "futures 0.3.1", + "log 0.4.8", + "sc-client", + "sc-network", + "sc-service", + "sp-consensus", + "sp-core", + "sp-runtime", + "sp-transaction-pool", + "tempfile", + "tokio 0.1.22", ] [[package]] name = "sc-state-db" version = "0.8.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.2 (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", + "env_logger 0.7.1", + "log 0.4.8", + "parity-scale-codec", + "parking_lot 0.9.0", + "sp-core", ] [[package]] name = "sc-telemetry" version = "2.0.0" dependencies = [ - "bytes 0.5.4 (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.15.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)", - "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4", + "futures 0.3.1", + "futures-timer 2.0.2", + "libp2p", + "log 0.4.8", + "parking_lot 0.9.0", + "pin-project", + "rand 0.7.3", + "serde", + "slog", + "slog-json", + "slog-scope", + "take_mut", + "void", ] [[package]] name = "sc-tracing" version = "2.0.0" dependencies = [ - "erased-serde 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", - "grafana-data-source 0.8.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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (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.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "erased-serde", + "grafana-data-source", + "log 0.4.8", + "parking_lot 0.9.0", + "sc-telemetry", + "serde", + "serde_json", + "slog", + "tracing", + "tracing-core", ] [[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.1 (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.2 (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.104 (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", + "assert_matches", + "criterion 0.3.1", + "derive_more", + "futures 0.3.1", + "log 0.4.8", + "parity-scale-codec", + "parking_lot 0.9.0", + "serde", + "sp-core", + "sp-runtime", + "sp-transaction-pool", + "substrate-test-runtime", ] [[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)", - "futures-diagnose 1.0.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.2 (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", - "substrate-test-runtime-transaction-pool 2.0.0", + "derive_more", + "futures 0.3.1", + "futures-diagnose", + "log 0.4.8", + "parity-scale-codec", + "parking_lot 0.9.0", + "sc-client-api", + "sc-transaction-graph", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-keyring", + "sp-runtime", + "sp-transaction-pool", + "substrate-test-runtime-client", + "substrate-test-runtime-transaction-pool", ] [[package]] name = "schannel" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" 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)", + "lazy_static", + "winapi 0.3.8", ] [[package]] name = "schnorrkel" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eacd8381b3c37840c9c9f40472af529e49975bdcbc24f83c31059fd6539023d3" 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.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.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)", + "curve25519-dalek 1.2.3", + "failure", + "merlin", + "rand 0.6.5", + "rand_core 0.4.2", + "rand_os", + "sha2", + "subtle 2.2.2", + "zeroize 0.9.3", ] [[package]] name = "scopeguard" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" [[package]] name = "scopeguard" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" [[package]] name = "scroll" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb2332cb595d33f7edd5700f4cbf94892e680c7f0ae56adab58a35190b66cb1" dependencies = [ - "scroll_derive 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "scroll_derive", ] [[package]] name = "scroll_derive" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8584eea9b9ff42825b46faf46a8c24d2cff13ec152fa2a50df788b87c07ee28" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "sct" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c" dependencies = [ - "ring 0.16.10 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ring", + "untrusted", ] [[package]] name = "security-framework" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ef2429d7cefe5fd28bd1d2ed41c944547d4ff84776f5935b456da44593a16df" 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.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)", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", ] [[package]] name = "security-framework-sys" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31493fc37615debb8c5090a7aeb4a9730bc61e77ab10b9af59f1a202284f895" dependencies = [ - "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys", ] [[package]] name = "semver" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" dependencies = [ - "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "semver-parser", ] [[package]] name = "semver" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "semver-parser", + "serde", ] [[package]] name = "semver-parser" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "send_wrapper" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0eddf2e8f50ced781f288c19f18621fa72a3779e3cb58dbf23b07469b0abeb4" [[package]] name = "send_wrapper" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686ef91cf020ad8d4aca9a7047641fd6add626b7b89e14546c2b6a76781cf822" [[package]] name = "serde" version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" dependencies = [ - "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "serde_json" version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b01d7f0288608a01dca632cf1df859df6fd6ffa885300fc275ce2ba6221953" dependencies = [ - "itoa 0.4.5 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa", + "ryu", + "serde", ] [[package]] name = "sha-1" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" dependencies = [ - "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "block-buffer", + "digest", + "fake-simd", + "opaque-debug", ] [[package]] name = "sha1" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" [[package]] name = "sha2" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" dependencies = [ - "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "block-buffer", + "digest", + "fake-simd", + "opaque-debug", ] [[package]] name = "sha3" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf" 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)", + "block-buffer", + "byte-tools", + "digest", + "keccak", + "opaque-debug", ] [[package]] name = "shell32-sys" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c" 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)", + "winapi 0.2.8", + "winapi-build", ] [[package]] name = "shlex" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" [[package]] name = "signal-hook-registry" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" dependencies = [ - "arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "arc-swap", + "libc", ] [[package]] name = "slab" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" [[package]] name = "slog" version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cc9c640a4adbfbcc11ffb95efe5aa7af7309e002adab54b185507dbf2377b99" dependencies = [ - "erased-serde 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", + "erased-serde", ] [[package]] name = "slog-json" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddc0d2aff1f8f325ef660d9a0eb6e6dcd20b30b3f581a5897f58bf42d061c37a" dependencies = [ - "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "erased-serde 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono", + "erased-serde", + "serde", + "serde_json", + "slog", ] [[package]] name = "slog-scope" version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c44c89dd8b0ae4537d1ae318353eaf7840b4869c536e31c41e963d1ea523ee6" 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)", + "arc-swap", + "lazy_static", + "slog", ] [[package]] name = "slog_derive" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a945ec7f7ce853e89ffa36be1e27dce9a43e82ff9093bf3461c30d5da74ed11b" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "smallvec" version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" dependencies = [ - "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "maybe-uninit", ] [[package]] name = "smallvec" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc" [[package]] name = "snow" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afb767eee7d257ba202f0b9b08673bc13b22281632ef45267b19f13100accd2f" dependencies = [ - "arrayref 0.3.6 (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.10 (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)", + "arrayref", + "rand_core 0.5.1", + "ring", + "rustc_version", + "subtle 2.2.2", ] [[package]] name = "soketto" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c9dab3f95c9ebdf3a88268c19af668f637a3c5039c2c56ff2d40b1b2d64a25b" dependencies = [ - "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 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)", - "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.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.11.0", + "bytes 0.5.4", + "flate2", + "futures 0.3.1", + "http 0.2.0", + "httparse", + "log 0.4.8", + "rand 0.7.3", + "sha1", + "smallvec 1.2.0", + "static_assertions", + "thiserror", ] [[package]] name = "sourcefile" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" [[package]] name = "sp-allocator" version = "2.0.0" dependencies = [ - "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)", - "sp-core 2.0.0", - "sp-std 2.0.0", - "sp-wasm-interface 2.0.0", + "derive_more", + "log 0.4.8", + "sp-core", + "sp-std", + "sp-wasm-interface", ] [[package]] name = "sp-api" version = "2.0.0" dependencies = [ - "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-api-proc-macro 2.0.0", - "sp-core 2.0.0", - "sp-runtime 2.0.0", - "sp-state-machine 0.8.0", - "sp-std 2.0.0", - "sp-test-primitives 2.0.0", - "sp-version 2.0.0", + "hash-db", + "parity-scale-codec", + "sp-api-proc-macro", + "sp-core", + "sp-runtime", + "sp-state-machine", + "sp-std", + "sp-test-primitives", + "sp-version", ] [[package]] name = "sp-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.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2-rfc", + "proc-macro-crate", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "sp-api-test" version = "2.0.0" dependencies = [ - "criterion 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustversion 1.0.2 (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 0.8.0", - "sp-version 2.0.0", - "substrate-test-runtime-client 2.0.0", - "trybuild 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "criterion 0.3.1", + "parity-scale-codec", + "rustversion", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-runtime", + "sp-state-machine", + "sp-version", + "substrate-test-runtime-client", + "trybuild", ] [[package]] name = "sp-application-crypto" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-core 2.0.0", - "sp-io 2.0.0", - "sp-std 2.0.0", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-std", ] [[package]] name = "sp-application-crypto-test" version = "2.0.0" dependencies = [ - "sp-api 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", + "sp-api", + "sp-application-crypto", + "sp-core", + "sp-runtime", + "substrate-test-runtime-client", ] [[package]] name = "sp-arithmetic" version = "2.0.0" dependencies = [ - "criterion 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "integer-sqrt 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-debug-derive 2.0.0", - "sp-std 2.0.0", + "criterion 0.3.1", + "integer-sqrt", + "num-traits", + "parity-scale-codec", + "primitive-types", + "rand 0.7.3", + "serde", + "sp-debug-derive", + "sp-std", ] [[package]] name = "sp-authority-discovery" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.1.2 (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", + "parity-scale-codec", + "sp-api", + "sp-application-crypto", + "sp-runtime", + "sp-std", ] [[package]] name = "sp-authorship" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-inherents 2.0.0", - "sp-runtime 2.0.0", - "sp-std 2.0.0", + "parity-scale-codec", + "sp-inherents", + "sp-runtime", + "sp-std", ] [[package]] name = "sp-block-builder" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.1.2 (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", + "parity-scale-codec", + "sp-api", + "sp-inherents", + "sp-runtime", + "sp-std", ] [[package]] name = "sp-blockchain" version = "2.0.0" dependencies = [ - "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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.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 0.8.0", + "derive_more", + "log 0.4.8", + "lru 0.4.3", + "parity-scale-codec", + "parking_lot 0.9.0", + "sp-block-builder", + "sp-consensus", + "sp-runtime", + "sp-state-machine", ] [[package]] name = "sp-consensus" 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)", - "futures-diagnose 1.0.0 (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.15.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.2 (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.104 (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-state-machine 0.8.0", - "sp-std 2.0.0", - "sp-test-primitives 2.0.0", - "sp-version 2.0.0", + "derive_more", + "futures 0.3.1", + "futures-diagnose", + "futures-timer 0.4.0", + "libp2p", + "log 0.4.8", + "parity-scale-codec", + "parking_lot 0.9.0", + "serde", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-state-machine", + "sp-std", + "sp-test-primitives", + "sp-version", ] [[package]] name = "sp-consensus-aura" version = "0.8.0" dependencies = [ - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "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", + "parity-scale-codec", + "sp-api", + "sp-application-crypto", + "sp-inherents", + "sp-runtime", + "sp-std", + "sp-timestamp", ] [[package]] name = "sp-consensus-babe" version = "0.8.0" dependencies = [ - "parity-scale-codec 1.1.2 (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", + "parity-scale-codec", + "schnorrkel", + "sp-api", + "sp-application-crypto", + "sp-consensus", + "sp-inherents", + "sp-runtime", + "sp-std", + "sp-timestamp", ] [[package]] name = "sp-consensus-pow" version = "0.8.0" dependencies = [ - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-api 2.0.0", - "sp-core 2.0.0", - "sp-runtime 2.0.0", - "sp-std 2.0.0", + "parity-scale-codec", + "sp-api", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] name = "sp-core" 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 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.4 (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.11 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.2 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.1.0 (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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-debug-derive 2.0.0", - "sp-externalities 0.8.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)", + "base58", + "blake2-rfc", + "byteorder 1.3.2", + "criterion 0.2.11", + "ed25519-dalek", + "hash-db", + "hash256-std-hasher", + "hex", + "hex-literal", + "impl-serde 0.2.3", + "lazy_static", + "libsecp256k1", + "log 0.4.8", + "num-traits", + "parity-scale-codec", + "parking_lot 0.9.0", + "pretty_assertions", + "primitive-types", + "rand 0.7.3", + "regex", + "rustc-hex", + "schnorrkel", + "serde", + "serde_json", + "sha2", + "sp-debug-derive", + "sp-externalities", + "sp-runtime-interface", + "sp-serializer", + "sp-std", + "sp-storage", + "substrate-bip39", + "tiny-bip39", + "tiny-keccak 2.0.1", + "twox-hash", + "wasmi", + "zeroize 1.1.0", ] [[package]] name = "sp-debug-derive" version = "2.0.0" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "sp-externalities" version = "0.8.0" dependencies = [ - "environmental 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-std 2.0.0", - "sp-storage 2.0.0", + "environmental", + "sp-std", + "sp-storage", ] [[package]] name = "sp-finality-grandpa" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "parity-scale-codec", + "serde", + "sp-api", + "sp-application-crypto", + "sp-runtime", + "sp-std", ] [[package]] name = "sp-finality-tracker" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-inherents 2.0.0", - "sp-std 2.0.0", + "parity-scale-codec", + "sp-inherents", + "sp-std", ] [[package]] name = "sp-inherents" version = "2.0.0" dependencies = [ - "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.2 (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", - "sp-std 2.0.0", + "derive_more", + "parity-scale-codec", + "parking_lot 0.9.0", + "sp-core", + "sp-std", ] [[package]] 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.4 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-core 2.0.0", - "sp-externalities 0.8.0", - "sp-runtime-interface 2.0.0", - "sp-state-machine 0.8.0", - "sp-std 2.0.0", - "sp-trie 2.0.0", - "sp-wasm-interface 2.0.0", + "hash-db", + "libsecp256k1", + "log 0.4.8", + "parity-scale-codec", + "sp-core", + "sp-externalities", + "sp-runtime-interface", + "sp-state-machine", + "sp-std", + "sp-trie", + "sp-wasm-interface", ] [[package]] name = "sp-keyring" version = "2.0.0" dependencies = [ - "lazy_static 1.4.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)", + "lazy_static", + "sp-core", + "sp-runtime", + "strum", ] [[package]] name = "sp-offchain" version = "2.0.0" dependencies = [ - "sp-api 2.0.0", - "sp-runtime 2.0.0", + "sp-api", + "sp-runtime", ] [[package]] name = "sp-panic-handler" version = "2.0.0" dependencies = [ - "backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace", + "log 0.4.8", ] [[package]] name = "sp-phragmen" version = "2.0.0" dependencies = [ - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "rand 0.7.3", + "serde", + "sp-io", + "sp-runtime", + "sp-std", + "substrate-test-utils", ] [[package]] name = "sp-rpc" version = "2.0.0" dependencies = [ - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-core 2.0.0", + "serde", + "serde_json", + "sp-core", ] [[package]] name = "sp-runtime" 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.2 (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.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (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", + "impl-trait-for-tuples", + "log 0.4.8", + "parity-scale-codec", + "paste", + "rand 0.7.3", + "serde", + "serde_json", + "sp-application-crypto", + "sp-arithmetic", + "sp-core", + "sp-inherents", + "sp-io", + "sp-std", ] [[package]] name = "sp-runtime-interface" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-core 2.0.0", - "sp-externalities 0.8.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 0.8.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.21 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec", + "primitive-types", + "rustversion", + "sp-core", + "sp-externalities", + "sp-io", + "sp-runtime-interface-proc-macro", + "sp-runtime-interface-test-wasm", + "sp-state-machine", + "sp-std", + "sp-wasm-interface", + "static_assertions", + "trybuild", ] [[package]] name = "sp-runtime-interface-proc-macro" version = "2.0.0" dependencies = [ - "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.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "Inflector", + "proc-macro-crate", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "sp-runtime-interface-test" version = "2.0.0" dependencies = [ - "sc-executor 0.8.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 0.8.0", + "sc-executor", + "sp-core", + "sp-io", + "sp-runtime-interface", + "sp-runtime-interface-test-wasm", + "sp-state-machine", ] [[package]] name = "sp-runtime-interface-test-wasm" version = "2.0.0" dependencies = [ - "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.5", + "sp-core", + "sp-io", + "sp-runtime-interface", + "sp-std", + "substrate-wasm-builder-runner", ] [[package]] name = "sp-sandbox" version = "0.8.0" dependencies = [ - "assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-core 2.0.0", - "sp-io 2.0.0", - "sp-std 2.0.0", - "sp-wasm-interface 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)", + "assert_matches", + "parity-scale-codec", + "sp-core", + "sp-io", + "sp-std", + "sp-wasm-interface", + "wabt", + "wasmi", ] [[package]] name = "sp-serializer" version = "2.0.0" dependencies = [ - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", + "serde_json", ] [[package]] name = "sp-session" version = "2.0.0" dependencies = [ - "sp-api 2.0.0", - "sp-core 2.0.0", - "sp-runtime 2.0.0", - "sp-std 2.0.0", + "sp-api", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] name = "sp-staking" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-runtime 2.0.0", - "sp-std 2.0.0", + "parity-scale-codec", + "sp-runtime", + "sp-std", ] [[package]] name = "sp-state-machine" version = "0.8.0" dependencies = [ - "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)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.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.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-core 2.0.0", - "sp-externalities 0.8.0", - "sp-panic-handler 2.0.0", - "sp-trie 2.0.0", - "trie-db 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db", + "hex-literal", + "log 0.4.8", + "num-traits", + "parity-scale-codec", + "parking_lot 0.9.0", + "rand 0.7.3", + "sp-core", + "sp-externalities", + "sp-panic-handler", + "sp-trie", + "trie-db", + "trie-root", ] [[package]] @@ -6751,208 +7183,220 @@ version = "2.0.0" name = "sp-storage" version = "2.0.0" dependencies = [ - "impl-serde 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-debug-derive 2.0.0", - "sp-std 2.0.0", + "impl-serde 0.2.3", + "serde", + "sp-debug-derive", + "sp-std", ] [[package]] name = "sp-test-primitives" version = "2.0.0" dependencies = [ - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (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", + "parity-scale-codec", + "serde", + "sp-application-crypto", + "sp-core", + "sp-runtime", ] [[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.2 (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", + "impl-trait-for-tuples", + "parity-scale-codec", + "sp-api", + "sp-inherents", + "sp-runtime", + "sp-std", ] [[package]] name = "sp-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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-api 2.0.0", - "sp-runtime 2.0.0", + "derive_more", + "futures 0.3.1", + "log 0.4.8", + "parity-scale-codec", + "serde", + "sp-api", + "sp-runtime", ] [[package]] name = "sp-trie" 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.18.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-core 2.0.0", - "sp-std 2.0.0", - "trie-bench 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-db 0.19.2 (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)", + "criterion 0.2.11", + "hash-db", + "hex-literal", + "memory-db", + "parity-scale-codec", + "sp-core", + "sp-std", + "trie-bench", + "trie-db", + "trie-root", + "trie-standardmap", ] [[package]] name = "sp-version" version = "2.0.0" dependencies = [ - "impl-serde 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-runtime 2.0.0", - "sp-std 2.0.0", + "impl-serde 0.2.3", + "parity-scale-codec", + "serde", + "sp-runtime", + "sp-std", ] [[package]] name = "sp-wasm-interface" 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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-std 2.0.0", - "wasmi 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "impl-trait-for-tuples", + "parity-scale-codec", + "sp-std", + "wasmi", ] [[package]] name = "spin" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "stable_deref_trait" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "stream-cipher" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8131256a5896cabcf5eb04f4d6dacbe1aefda854b0d9896e09cb58829ec5638c" dependencies = [ - "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array", ] [[package]] name = "string" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12", ] [[package]] name = "string-interner" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd710eadff449a1531351b0e43eb81ea404336fa2f56c777427ab0e32a4cf183" dependencies = [ - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", ] [[package]] name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1bcbed7d48956fcbb5d80c6b95aedb553513de0a1b451ea92679d999c010e98" dependencies = [ - "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "structopt-derive 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "lazy_static", + "structopt-derive", ] [[package]] name = "structopt-derive" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "095064aa1f5b94d14e635d0a5684cf140c43ae40a0fd990708d38f5d669e5f64" dependencies = [ - "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-error 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "heck", + "proc-macro-error", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "strum" version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6138f8f88a16d90134763314e3fc76fa3ed6a7db4725d6acf9a3ef95a3188d22" dependencies = [ - "strum_macros 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "strum_macros", ] [[package]] name = "strum_macros" version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0054a7df764039a6cd8592b9de84be4bec368ff081d203a7d5371cbfa8e65c81" dependencies = [ - "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "heck", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "subkey" version = "2.0.0" dependencies = [ - "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)", - "frame-system 2.0.0", - "futures 0.1.29 (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)", - "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core-client 14.0.5 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rpassword 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-rpc 2.0.0", - "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)", + "clap", + "derive_more", + "frame-system", + "futures 0.1.29", + "hex", + "hex-literal", + "hyper 0.12.35", + "itertools", + "jsonrpc-core-client", + "node-primitives", + "node-runtime", + "pallet-balances", + "pallet-transaction-payment", + "parity-scale-codec", + "rand 0.7.3", + "rpassword", + "rustc-hex", + "sc-rpc", + "sp-core", + "sp-runtime", + "substrate-bip39", + "tiny-bip39", ] [[package]] name = "substrate-bip39" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be511be555a3633e71739a79e4ddff6a6aaa6579fa6114182a51d72c3eb93c5" 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.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hmac", + "pbkdf2", + "schnorrkel", + "sha2", ] [[package]] @@ -6963,129 +7407,129 @@ version = "2.0.0" name = "substrate-frame-rpc-support" version = "2.0.0" dependencies = [ - "frame-support 2.0.0", - "frame-system 2.0.0", - "futures 0.3.1 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-rpc-api 0.8.0", - "serde 1.0.104 (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)", + "frame-support", + "frame-system", + "futures 0.3.1", + "jsonrpc-client-transports", + "jsonrpc-core", + "parity-scale-codec", + "sc-rpc-api", + "serde", + "sp-storage", + "tokio 0.1.22", ] [[package]] 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)", - "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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-client 0.8.0", - "sc-transaction-pool 2.0.0", - "serde 1.0.104 (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-runtime 2.0.0", - "sp-transaction-pool 2.0.0", - "substrate-test-runtime-client 2.0.0", + "env_logger 0.7.1", + "frame-system-rpc-runtime-api", + "futures 0.3.1", + "jsonrpc-core", + "jsonrpc-core-client", + "jsonrpc-derive", + "log 0.4.8", + "parity-scale-codec", + "sc-client", + "sc-transaction-pool", + "serde", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-runtime", + "sp-transaction-pool", + "substrate-test-runtime-client", ] [[package]] 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.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-client 0.8.0", - "sc-client-api 2.0.0", - "sc-client-db 0.8.0", - "sc-executor 0.8.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 0.8.0", + "futures 0.3.1", + "hash-db", + "parity-scale-codec", + "sc-client", + "sc-client-api", + "sc-client-db", + "sc-executor", + "sp-blockchain", + "sp-consensus", + "sp-core", + "sp-keyring", + "sp-runtime", + "sp-state-machine", ] [[package]] name = "substrate-test-runtime" version = "2.0.0" dependencies = [ - "cfg-if 0.1.10 (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.18.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pallet-babe 2.0.0", - "pallet-timestamp 2.0.0", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-client 0.8.0", - "sc-executor 0.8.0", - "serde 1.0.104 (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 0.8.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-wasm-builder-runner 1.0.5", - "trie-db 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "frame-executive", + "frame-support", + "frame-system", + "frame-system-rpc-runtime-api", + "log 0.4.8", + "memory-db", + "pallet-babe", + "pallet-timestamp", + "parity-scale-codec", + "sc-client", + "sc-executor", + "serde", + "sp-api", + "sp-application-crypto", + "sp-block-builder", + "sp-consensus-aura", + "sp-consensus-babe", + "sp-core", + "sp-inherents", + "sp-io", + "sp-keyring", + "sp-offchain", + "sp-runtime", + "sp-runtime-interface", + "sp-session", + "sp-state-machine", + "sp-std", + "sp-transaction-pool", + "sp-trie", + "sp-version", + "substrate-test-runtime-client", + "substrate-wasm-builder-runner", + "trie-db", ] [[package]] name = "substrate-test-runtime-client" version = "2.0.0" dependencies = [ - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-block-builder 0.8.0", - "sc-client 0.8.0", - "sc-client-api 2.0.0", - "sp-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", + "futures 0.3.1", + "parity-scale-codec", + "sc-block-builder", + "sc-client", + "sc-client-api", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-runtime", + "substrate-test-client", + "substrate-test-runtime", ] [[package]] name = "substrate-test-runtime-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)", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sc-transaction-graph 2.0.0", - "sp-runtime 2.0.0", - "sp-transaction-pool 2.0.0", - "substrate-test-runtime-client 2.0.0", + "derive_more", + "futures 0.3.1", + "parity-scale-codec", + "parking_lot 0.9.0", + "sc-transaction-graph", + "sp-runtime", + "sp-transaction-pool", + "substrate-test-runtime-client", ] [[package]] @@ -7096,14 +7540,14 @@ version = "2.0.0" name = "substrate-wasm-builder" version = "1.0.9" dependencies = [ - "atty 0.2.14 (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.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.6 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-gc-api 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "atty", + "build-helper", + "cargo_metadata", + "fs2", + "tempfile", + "toml", + "walkdir", + "wasm-gc-api", ] [[package]] @@ -7114,1823 +7558,1369 @@ version = "1.0.5" name = "subtle" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" [[package]] name = "subtle" version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" [[package]] name = "syn" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "unicode-xid 0.2.0", ] [[package]] name = "syn-mid" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "synstructure" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", + "unicode-xid 0.2.0", ] [[package]] name = "sysinfo" version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f4b2468c629cffba39c0a4425849ab3cdb03d9dfacba69684609aea04d08ff9" 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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "doc-comment", + "libc", + "rayon", + "winapi 0.3.8", ] [[package]] name = "take_mut" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" [[package]] name = "target-lexicon" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f4c118a7a38378f305a9e111fcb2f7f838c0be324bfb31a77ea04f7f6e684b4" [[package]] name = "target_info" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" [[package]] name = "tempfile" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ - "cfg-if 0.1.10 (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.3 (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)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "libc", + "rand 0.7.3", + "redox_syscall", + "remove_dir_all", + "winapi 0.3.8", ] [[package]] name = "termcolor" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" dependencies = [ - "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util", ] [[package]] name = "test-case" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a605baa797821796a751f4a959e1206079b24a4b7e1ed302b7d785d81a9276c9" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", + "version_check 0.9.1", ] [[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width", ] [[package]] name = "thiserror" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "205684fd018ca14432b12cce6ea3d46763311a571c3d294e71ba3f01adcf1aad" dependencies = [ - "thiserror-impl 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror-impl", ] [[package]] name = "thiserror-impl" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e4d2e50ca050ed44fb58309bdce3efa79948f84f9993ad1978de5eebdce5a7" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "thread_local" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static", ] [[package]] name = "threadpool" version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" dependencies = [ - "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus", ] [[package]] name = "time" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" dependencies = [ - "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)", + "libc", + "redox_syscall", + "winapi 0.3.8", ] [[package]] name = "tiny-bip39" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1c5676413eaeb1ea35300a0224416f57abc3bd251657e0fafc12c47ff98c060" dependencies = [ - "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pbkdf2 0.3.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.1 (registry+https://github.com/rust-lang/crates.io-index)", + "failure", + "hashbrown 0.1.8", + "hmac", + "once_cell 0.1.8", + "pbkdf2", + "rand 0.6.5", + "sha2", ] [[package]] name = "tiny-keccak" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2" dependencies = [ - "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crunchy", ] [[package]] name = "tiny-keccak" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2953ca5148619bc99695c1274cb54c5275bbb913c6adad87e72eaf8db9787f69" dependencies = [ - "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crunchy", ] [[package]] name = "tinytemplate" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a3c6667d3e65eb1bc3aed6fd14011c6cbc3a0665218ab7f5daf040b9ec371a" dependencies = [ - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", + "serde_json", ] [[package]] name = "tokio" version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" 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.21 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.12.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-current-thread 0.1.6 (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.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.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)", + "bytes 0.4.12", + "futures 0.1.29", + "mio", + "num_cpus", + "tokio-codec", + "tokio-current-thread", + "tokio-executor 0.1.9", + "tokio-fs", + "tokio-io", + "tokio-reactor", + "tokio-sync 0.1.7", + "tokio-tcp", + "tokio-threadpool", + "tokio-timer", + "tokio-udp", + "tokio-uds", ] [[package]] name = "tokio" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fdd17989496f49cdc57978c96f0c9fe5e4a58a8bddc6813c449a4624f6a030b" dependencies = [ - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (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.66 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.3.0 (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.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-macros 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4", + "fnv", + "lazy_static", + "libc", + "memchr", + "mio", + "mio-uds", + "num_cpus", + "pin-project-lite", + "signal-hook-registry", + "tokio-macros", + "winapi 0.3.8", ] [[package]] name = "tokio-buf" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" 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.4.12", + "either", + "futures 0.1.29", ] [[package]] name = "tokio-codec" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" 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)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12", + "futures 0.1.29", + "tokio-io", ] [[package]] name = "tokio-current-thread" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29", + "tokio-executor 0.1.9", ] [[package]] name = "tokio-executor" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6df436c42b0c3330a82d855d2ef017cd793090ad550a6bc2184f4b933532ab" 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)", + "crossbeam-utils 0.6.6", + "futures 0.1.29", ] [[package]] name = "tokio-executor" version = "0.2.0-alpha.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ee9ceecf69145923834ea73f32ba40c790fd877b74a7817dd0b089f1eb9c7c8" 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)", + "futures-util-preview", + "lazy_static", + "tokio-sync 0.2.0-alpha.6", ] [[package]] name = "tokio-fs" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af" 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.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29", + "tokio-io", + "tokio-threadpool", ] [[package]] name = "tokio-io" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" 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)", + "bytes 0.4.12", + "futures 0.1.29", + "log 0.4.8", ] [[package]] name = "tokio-macros" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4b1e7ed7d5d4c2af3d999904b0eebe76544897cdbfb2b9684bed2174ab20f7c" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", ] [[package]] name = "tokio-reactor" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6732fe6b53c8d11178dcb77ac6d9682af27fc6d4cb87789449152e5377377146" 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.21 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.12.0 (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.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)", + "crossbeam-utils 0.6.6", + "futures 0.1.29", + "lazy_static", + "log 0.4.8", + "mio", + "num_cpus", + "parking_lot 0.9.0", + "slab", + "tokio-executor 0.1.9", + "tokio-io", + "tokio-sync 0.1.7", ] [[package]] name = "tokio-rustls" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d7cf08f990090abd6c6a73cab46fed62f85e8aef8b99e4b918a9f4a637f0676" 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)", - "rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12", + "futures 0.1.29", + "iovec", + "rustls", + "tokio-io", + "webpki", ] [[package]] name = "tokio-sync" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76" dependencies = [ - "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)", + "fnv", + "futures 0.1.29", ] [[package]] name = "tokio-sync" version = "0.2.0-alpha.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f1aaeb685540f7407ea0e27f1c9757d258c7c6bf4e3eb19da6fc59b747239d2" dependencies = [ - "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-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv", + "futures-core-preview", + "futures-util-preview", ] [[package]] name = "tokio-tcp" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" 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.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.11 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12", + "futures 0.1.29", + "iovec", + "mio", + "tokio-io", + "tokio-reactor", ] [[package]] name = "tokio-threadpool" version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c32ffea4827978e9aa392d2f743d973c1dfa3730a2ed3f22ce1e6984da848c" dependencies = [ - "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "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)", - "num_cpus 1.12.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.9 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque", + "crossbeam-queue 0.1.2", + "crossbeam-utils 0.6.6", + "futures 0.1.29", + "lazy_static", + "log 0.4.8", + "num_cpus", + "slab", + "tokio-executor 0.1.9", ] [[package]] name = "tokio-timer" version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1739638e364e558128461fc1ad84d997702c8e31c2e6b18fb99842268199e827" 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.9 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6", + "futures 0.1.29", + "slab", + "tokio-executor 0.1.9", ] [[package]] name = "tokio-tls" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "354b8cd83825b3c20217a9dc174d6a0c67441a2fae5c41bcb1ea6679f6ae0f7c" dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29", + "native-tls", + "tokio-io", ] [[package]] name = "tokio-udp" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f02298505547f73e60f568359ef0d016d5acd6e830ab9bc7c4a5b3403440121b" 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.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.11 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12", + "futures 0.1.29", + "log 0.4.8", + "mio", + "tokio-codec", + "tokio-io", + "tokio-reactor", ] [[package]] name = "tokio-uds" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" 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.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.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.11 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12", + "futures 0.1.29", + "iovec", + "libc", + "log 0.4.8", + "mio", + "mio-uds", + "tokio-codec", + "tokio-io", + "tokio-reactor", ] [[package]] name = "tokio-util" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" dependencies = [ - "bytes 0.5.4 (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.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4", + "futures-core", + "futures-sink", + "log 0.4.8", + "pin-project-lite", + "tokio 0.2.11", ] [[package]] name = "toml" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" dependencies = [ - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", ] [[package]] name = "tower-service" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" [[package]] name = "tracing" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e213bd24252abeb86a0b7060e02df677d367ce6cb772cef17e9214b8390a8d3" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing-attributes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tracing-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "tracing-attributes", + "tracing-core", ] [[package]] name = "tracing-attributes" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cfd395def5a60236e187e1ff905cb55668a59f29928dec05e6e1b1fd2ac1f3" dependencies = [ - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2", + "syn", ] [[package]] name = "tracing-core" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13a46f11e372b8bd4b4398ea54353412fdd7fd42a8370c7e543e218cf7661978" dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static", ] [[package]] name = "traitobject" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" [[package]] name = "trie-bench" version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26fd042d57ee9c987c562811162a78db78b5340ab674ac76056c85dca49b26bc" 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.18.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "trie-db 0.19.2 (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)", + "criterion 0.2.11", + "hash-db", + "keccak-hasher", + "memory-db", + "parity-scale-codec", + "trie-db", + "trie-root", + "trie-standardmap", ] [[package]] name = "trie-db" version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d747ae5b6f078df7e46477fcc7df66df9eb4f27a031cf4a7c890a8dd03d8e6" dependencies = [ - "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)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db", + "hashbrown 0.6.3", + "log 0.4.8", + "rand 0.6.5", + "rustc-hex", + "smallvec 1.2.0", ] [[package]] name = "trie-root" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b779f7c1c8fe9276365d9d5be5c4b5adeacf545117bb3f64c974305789c5c0b" dependencies = [ - "hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hash-db", ] [[package]] name = "trie-standardmap" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3161ba520ab28cd8e6b68e1126f1009f6e335339d1a73b978139011703264c8" dependencies = [ - "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)", + "hash-db", + "keccak-hasher", ] [[package]] name = "try-lock" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" [[package]] name = "trybuild" version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f5b3f750c701725331ac78e389b5d143b7d25f6b6ffffd0d419759a9063ac5f" 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.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.3.0", + "lazy_static", + "serde", + "serde_json", + "termcolor", + "toml", ] [[package]] name = "twofish" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712d261e83e727c8e2dbb75dacac67c36e35db36a958ee504f2164fc052434e1" dependencies = [ - "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "block-cipher-trait", + "byteorder 1.3.2", + "opaque-debug", ] [[package]] name = "twox-hash" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" dependencies = [ - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3", ] [[package]] name = "typeable" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" [[package]] name = "typenum" version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" [[package]] name = "uint" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e75a4cdd7b87b28840dba13c483b9a88ee6bbf16ba5c951ee1ecfcf723078e0d" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", + "crunchy", + "rustc-hex", + "static_assertions", ] [[package]] name = "unicase" version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" dependencies = [ - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.1.5", ] [[package]] name = "unicase" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" dependencies = [ - "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.9.1", ] [[package]] name = "unicode-bidi" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" dependencies = [ - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "matches", ] [[package]] name = "unicode-normalization" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" dependencies = [ - "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0", ] [[package]] name = "unicode-segmentation" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" [[package]] name = "unicode-width" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" [[package]] name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" [[package]] name = "unicode-xid" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" [[package]] name = "unsigned-varint" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f0023a96687fe169081e8adce3f65e3874426b7886e9234d490af2dc077959" [[package]] name = "unsigned-varint" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c689459fbaeb50e56c6749275f084decfd02194ac5852e6617d95d0d3cf02eaf" dependencies = [ - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4", + "futures_codec", + "tokio-util", ] [[package]] name = "untrusted" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60369ef7a31de49bcb3f6ca728d4ba7300d9a1658f94c727d4cab8c8d9f4aece" [[package]] name = "url" version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" dependencies = [ - "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "idna 0.1.5", + "matches", + "percent-encoding 1.0.1", ] [[package]] name = "url" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" dependencies = [ - "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "idna 0.2.0", + "matches", + "percent-encoding 2.1.0", ] [[package]] name = "vcpkg" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" [[package]] name = "vec_map" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" [[package]] name = "vergen" version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aba5e34f93dc7051dfad05b98a18e9156f27e7b431fe1d2398cb6061c0a1dba" dependencies = [ - "bitflags 1.2.1 (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)", + "bitflags", + "chrono", + "failure", ] [[package]] name = "version_check" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" [[package]] name = "version_check" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" [[package]] name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] name = "wabt" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5c5c1286c6e578416982609f47594265f9d489f9b836157d403ad605a46693" dependencies = [ - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", - "wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", + "serde_derive", + "serde_json", + "wabt-sys", ] [[package]] name = "wabt-sys" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af5d153dc96aad7dc13ab90835b892c69867948112d95299e522d370c4e13a08" dependencies = [ - "cc 1.0.50 (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)", + "cc", + "cmake", + "glob 0.2.11", ] [[package]] name = "walkdir" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" dependencies = [ - "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "same-file", + "winapi 0.3.8", + "winapi-util", ] [[package]] name = "want" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" 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)", - "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29", + "log 0.4.8", + "try-lock", ] [[package]] name = "want" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8", + "try-lock", ] [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasm-bindgen" version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11cdb95816290b525b32587d76419facd99662a07e59d3cdb560488a819d9a45" dependencies = [ - "bumpalo 3.1.2 (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)", - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "bumpalo", + "lazy_static", + "log 0.4.8", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bbdd49e3e28b40dec6a9ba8d17798245ce32b019513a845369c641b275135d9" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", ] [[package]] name = "wasm-bindgen-macro" version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "574094772ce6921576fb6f2e3f7497b8a76273b6db092be18fc48a082de09dc3" dependencies = [ - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro-support 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2", + "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e7e61fc929f4c0dddb748b102ebf9f632e2b8d739f2016542b4de2965a9601" [[package]] name = "wasm-bindgen-webidl" version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef012a0d93fc0432df126a8eaf547b2dce25a8ce9212e1d3cbeef5c11157975d" dependencies = [ - "anyhow 1.0.26 (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.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow", + "heck", + "log 0.4.8", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", + "wasm-bindgen-backend", + "weedle", ] [[package]] name = "wasm-gc-api" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0c32691b6c7e6c14e7f8fd55361a9088b507aa49620fcd06c09b3a1082186b9" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-wasm 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8", + "parity-wasm 0.32.0", + "rustc-demangle", ] [[package]] name = "wasm-timer" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "324c5e65a08699c9c4334ba136597ab22b85dccd4b65dd1e36ccf8f723a95b54" dependencies = [ - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", - "send_wrapper 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1", + "js-sys", + "parking_lot 0.9.0", + "pin-utils", + "send_wrapper 0.2.0", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", ] [[package]] name = "wasmi" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf617d864d25af3587aa745529f7aaa541066c876d57e050c0d0c85c61c92aff" dependencies = [ - "errno 0.2.4 (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.3 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (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)", + "errno", + "libc", + "memory_units", + "num-rational", + "num-traits", + "parity-wasm 0.41.0", + "wasmi-validation", ] [[package]] name = "wasmi-validation" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea78c597064ba73596099281e2f4cfc019075122a65cdda3205af94f0b264d93" dependencies = [ - "parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-wasm 0.41.0", ] [[package]] name = "wasmparser" version = "0.39.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c702914acda5feeeffbc29e4d953e5b9ce79d8b98da4dbf18a77086e116c5470" [[package]] name = "wasmtime-debug" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5008729ad53f75020f28fa0d682269335d6f0eac0b3ffafe31f185b2f33aca74" dependencies = [ - "anyhow 1.0.26 (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)", - "faerie 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "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.10 (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)", + "anyhow", + "cranelift-codegen", + "cranelift-entity", + "cranelift-wasm", + "faerie", + "gimli", + "more-asserts", + "target-lexicon", + "thiserror", + "wasmparser", + "wasmtime-environ", ] [[package]] name = "wasmtime-environ" 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.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)", - "directories 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "file-per-thread-logger 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.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)", - "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.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.1 (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.10 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.5.6 (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)", - "zstd 0.5.1+zstd.1.4.4 (registry+https://github.com/rust-lang/crates.io-index)", +checksum = "a3947662a0b8e05b1418465e64f16de9114f9fec18cc3f56e0ed5aa7737b89d0" +dependencies = [ + "base64 0.11.0", + "bincode", + "cranelift-codegen", + "cranelift-entity", + "cranelift-wasm", + "directories", + "errno", + "file-per-thread-logger", + "indexmap", + "lazy_static", + "libc", + "log 0.4.8", + "more-asserts", + "rayon", + "serde", + "sha2", + "spin", + "thiserror", + "toml", + "wasmparser", + "winapi 0.3.8", + "zstd", ] [[package]] name = "wasmtime-jit" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed7922689461a7b5bd0d9c7350cac526c8a520a23b3ffd7f5b446ac51dfc51f" dependencies = [ - "anyhow 1.0.26 (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-wasm 0.50.0 (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)", - "target-lexicon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.10 (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)", - "wasmtime-runtime 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)", + "anyhow", + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "cranelift-wasm", + "more-asserts", + "region", + "target-lexicon", + "thiserror", + "wasmparser", + "wasmtime-debug", + "wasmtime-environ", + "wasmtime-runtime", + "winapi 0.3.8", ] [[package]] name = "wasmtime-runtime" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "781d6bb8b346efaa3dc39746386957cd79b8d841e8652ed9b02d77bcf64fb514" dependencies = [ - "cc 1.0.50 (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.1 (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.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.10 (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)", + "cc", + "cranelift-codegen", + "cranelift-entity", + "cranelift-wasm", + "indexmap", + "lazy_static", + "libc", + "memoffset", + "more-asserts", + "region", + "thiserror", + "wasmtime-environ", + "winapi 0.3.8", ] [[package]] name = "web-sys" version = "0.3.35" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf97caf6aa8c2b1dac90faf0db529d9d63c93846cca4911856f78a83cebf53b" dependencies = [ - "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.35 (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.58 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-webidl 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow", + "js-sys", + "sourcefile", + "wasm-bindgen", + "wasm-bindgen-webidl", ] [[package]] name = "webpki" version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f50e1972865d6b1adb54167d1c8ed48606004c2c9d0ea5f1eeb34d95e863ef" dependencies = [ - "ring 0.16.10 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ring", + "untrusted", ] [[package]] name = "webpki-roots" version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a262ae37dd9d60f60dd473d1158f9fbebf110ba7b6a5051c8160460f6043718b" dependencies = [ - "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki", ] [[package]] name = "webpki-roots" version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cd5736df7f12a964a5067a12c62fa38e1bd8080aff1f80bc29be7c80d19ab4" dependencies = [ - "webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "webpki", ] [[package]] name = "websocket" version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413b37840b9e27b340ce91b319ede10731de8c72f5bc4cb0206ec1ca4ce581d0" 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)", + "bytes 0.4.12", + "futures 0.1.29", + "hyper 0.10.16", + "native-tls", + "rand 0.6.5", + "tokio-codec", + "tokio-io", + "tokio-reactor", + "tokio-tcp", + "tokio-tls", + "unicase 1.4.2", + "url 1.7.2", + "websocket-base", ] [[package]] name = "websocket-base" version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e3810f0d00c4dccb54c30a4eee815e703232819dec7b007db115791c42aa374" dependencies = [ - "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "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)", - "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-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)", + "base64 0.10.1", + "bitflags", + "byteorder 1.3.2", + "bytes 0.4.12", + "futures 0.1.29", + "native-tls", + "rand 0.6.5", + "sha1", + "tokio-codec", + "tokio-io", + "tokio-tcp", + "tokio-tls", ] [[package]] name = "weedle" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" dependencies = [ - "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "nom", ] [[package]] name = "which" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" dependencies = [ - "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "failure", + "libc", ] [[package]] name = "which" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5475d47078209a02e60614f7ba5e645ef3ed60f771920ac1906d7c1cc65024c8" dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "winapi" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" [[package]] name = "winapi" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" dependencies = [ - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8", ] [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "ws" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c51a2c47b5798ccc774ffb93ff536aec7c4275d722fd9c740c83cdd1af1f2d94" 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)", - "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.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.3 (registry+https://github.com/rust-lang/crates.io-index)", - "sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2", + "bytes 0.4.12", + "httparse", + "log 0.4.8", + "mio", + "mio-extras", + "rand 0.7.3", + "sha-1", + "slab", + "url 2.1.1", ] [[package]] name = "ws2_32-sys" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" 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)", + "winapi 0.2.8", + "winapi-build", ] [[package]] name = "x25519-dalek" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee1585dc1484373cbc1cee7aafda26634665cf449436fd6e24bfd1fad230538" 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)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clear_on_drop", + "curve25519-dalek 1.2.3", + "rand_core 0.3.1", ] [[package]] name = "xdg" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" [[package]] name = "yamux" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f937668802a2e862a4fed05267e10b20c310bf771adc89687710706d55a9a65" dependencies = [ - "bytes 0.5.4 (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)", - "nohash-hasher 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4", + "futures 0.3.1", + "log 0.4.8", + "nohash-hasher", + "parking_lot 0.10.0", + "rand 0.7.3", + "thiserror", ] [[package]] name = "zeroize" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" [[package]] name = "zeroize" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8" dependencies = [ - "zeroize_derive 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "zeroize_derive", ] [[package]] name = "zeroize_derive" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8", + "quote 1.0.2", + "syn", + "synstructure", ] [[package]] name = "zstd" version = "0.5.1+zstd.1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5d978b793ae64375b80baf652919b148f6a496ac8802922d9999f5a553194f" dependencies = [ - "zstd-safe 2.0.3+zstd.1.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "zstd-safe", ] [[package]] name = "zstd-safe" version = "2.0.3+zstd.1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee25eac9753cfedd48133fa1736cbd23b774e253d89badbeac7d12b23848d3f" dependencies = [ - "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)", + "libc", + "zstd-sys", ] [[package]] name = "zstd-sys" version = "1.4.15+zstd.1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89719b034dc22d240d5b407fb0a3fe6d29952c181cff9a9f95c0bd40b4f8f7d8" dependencies = [ - "cc 1.0.50 (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)", -] - -[metadata] -"checksum Inflector 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -"checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" -"checksum aes-ctr 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2e5b0458ea3beae0d1d8c0f3946564f8e10f90646cf78c06b4351052058d1ee" -"checksum aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" -"checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" -"checksum ahash 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6f33b5018f120946c1dcf279194f238a9f146725593ead1c08fa47ff22b0b5d3" -"checksum aho-corasick 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5f56c476256dc249def911d6f7580b5fc7e875895b5d7ee88f5d602208035744" -"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.26 (registry+https://github.com/rust-lang/crates.io-index)" = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" -"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.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" -"checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" -"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" -"checksum asn1_der 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6fce6b6a0ffdafebd82c87e79e3f40e8d2c523e5fea5566ff6b90509bf98d638" -"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-std 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0bf6039b315300e057d198b9d3ab92ee029e31c759b7f1afae538145e6f18a3e" -"checksum async-task 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f20c6fda19d0fc02406779587ca4f9a4171cd32e4a5bda0bd016f0a1334c8d4a" -"checksum async-tls 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce6977f57fa68da77ffe5542950d47e9c23d65f5bc7cb0a9f8700996913eec7" -"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" -"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" -"checksum backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = "7f80256bc78f67e7df7e36d77366f636ed976895d91fe2ab9efa3973e8fe8c4f" -"checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" -"checksum base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" -"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.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" -"checksum blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" -"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" -"checksum blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" -"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -"checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" -"checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -"checksum broadcaster 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "07a1446420a56f1030271649ba0da46d23239b3a68c73591cea5247f15a788a0" -"checksum bs58 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c95ee6bba9d950218b6cc910cf62bc9e0a171d0f4537e3627b0f54d08549b188" -"checksum bs58 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b170cd256a3f9fa6b9edae3e44a7dfdfc77e8124dbc3e2612d75f9c3e2396dae" -"checksum bstr 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "fe8a65814ca90dfc9705af76bb6ba3c6e2534489a72270e797e603783bb4990b" -"checksum build-helper 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdce191bf3fa4995ce948c8c83b4640a1745457a149e73c6db75b4ffe36aad5f" -"checksum bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb8038c1ddc0a5f73787b130f4cc75151e96ed33e417fde765eb5a81e3532f4" -"checksum byte-slice-cast 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" -"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" -"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.4 (registry+https://github.com/rust-lang/crates.io-index)" = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" -"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.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.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" -"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.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" -"checksum cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62" -"checksum console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211" -"checksum console_log 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1e7871d2947441b0fdd8e2bd1ce2a2f75304f896582c0d572162d48290683c48" -"checksum const-random 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "2f1af9ac737b2dd2d577701e59fd09ba34822f6f2ebdb30a7647405d9e55e16a" -"checksum const-random-macro 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "25e4c606eb459dd29f7c57b2e0879f2b6f14ee130918c2b78ccb58a9624e6c7a" -"checksum constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" -"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" -"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" -"checksum cranelift-bforest 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd05aac8cefcde54ce26178df8f36cb1f518ac691db650e7d2440c2b6b41c4dc" -"checksum cranelift-codegen 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63d9b6ff8a94f98deabab21880d7fd54996e0e16be687b6f80a3b6bdd9c188d" -"checksum cranelift-codegen-meta 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7cb3df51c2c07d719d02869bfac6cabd8d82ee308d5b29ca62e6528723cc33a4" -"checksum cranelift-codegen-shared 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "758f9426b2e22bf83fc1a6b231a9d53cd4830751883c7f0e196ebb3c210467b3" -"checksum cranelift-entity 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff064733df8b98f453060264a8790393d1e807aca6942706b42f79a4f7aae9ed" -"checksum cranelift-frontend 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1eaafb5fa623dcbe19a28084a8226d7a1b17184a949c1a1f29a46b479867998d" -"checksum cranelift-native 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "90033dbd7293f6fad4cf9dcd769cd621d60df22b1c5a11799e86359b7447a51d" -"checksum cranelift-wasm 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)" = "54cb82a1071f88822763a583ec1a8688ffe5e2cda02c111d4483dd4376ed14d8" -"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" -"checksum criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394" -"checksum criterion 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc755679c12bda8e5523a71e4d654b6bf2e14bd838dfc48cde6559a05caf7d1" -"checksum criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76f9212ddf2f4a9eb2d401635190600656a1f88a932ef53d06e7fa4c7e02fb8e" -"checksum criterion-plot 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a01e15e0ea58e8234f96146b1f91fa9d0e4dd7a38da93ff7a75d42c0b9d3a545" -"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" -"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" -"checksum crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db" -"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" -"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" -"checksum crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" -"checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" -"checksum csv 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "00affe7f6ab566df61b4be3ce8cf16bc2576bca0963ceb0955e45d514bf9a279" -"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c" -"checksum ct-logs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4d3686f5fa27dbc1d76c751300376e167c5a43387f44bb451fd1c24776e49113" -"checksum ctor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8ce37ad4184ab2ce004c33bf6379185d3b1c95801cab51026bd271bf68eedc" -"checksum ctr 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "022cd691704491df67d25d006fe8eca083098253c4d43516c2206479c58c6736" -"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.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 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 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.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "516aa8d7a71cb00a1c4146f0798549b93d083d4f189b3ced8f3de6b8f11ee6c4" -"checksum erased-serde 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)" = "cd7d80305c9bd8cd78e3c753eb9fb110f83621e5211f1a3afffcc812b104daf9" -"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.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.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" -"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" -"checksum fallible-iterator 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" -"checksum fdlimit 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9084c55bb76efb1496328976db88320fe7d9ee86e649e83c4ecce3ba7a9a35d1" -"checksum file-per-thread-logger 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8505b75b31ef7285168dd237c4a7db3c1f3e0927e7d314e670bc98e854272fe9" -"checksum finality-grandpa 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "52c48f8a628193ba18639b2f727c32132d75f167a4b32f44b252ea8b937f154c" -"checksum fixed-hash 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" -"checksum fixedbitset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" -"checksum flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" -"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" -"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -"checksum fs-swap 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "921d332c89b3b61a826de38c61ee5b6e02c56806cade1b0e5d81bd71f57a71bb" -"checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" -"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" -"checksum futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6f16056ecbb57525ff698bb955162d0cd03bee84e6241c27ff75c08d8ca5987" -"checksum futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fcae98ca17d102fd8a3603727b9259fcf7fa4239b603d2142926189bc8999b86" -"checksum futures-channel-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "d5e5f4df964fa9c1c2f8bddeb5c3611631cacd93baf810fc8bb2fb4b495c263a" -"checksum futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "79564c427afefab1dfb3298535b21eda083ef7935b4f0ecbfcb121f0aec10866" -"checksum futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "b35b6263fb1ef523c3056565fa67b1d16f0a8604ff12b11b08c25f28a734c60a" -"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -"checksum futures-diagnose 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbb8371dd6ee87aa2aeaa8458a372fd82fe216032387b766255754c92dd7271" -"checksum futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e274736563f686a837a0568b478bdabfeaec2dca794b5649b04e2fe1627c231" -"checksum futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e676577d229e70952ab25f3945795ba5b16d63ca794ca9d2c860e5595d20b5ff" -"checksum futures-macro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "52e7c56c15537adb4f76d0b7a76ad131cb4d2f4f32d3b0bcabcbe1c7c5e87764" -"checksum futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "171be33efae63c2d59e6dbba34186fe0d6394fb378069a76dfd80fdcffd43c16" -"checksum futures-sink-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "86f148ef6b69f75bb610d4f9a2336d4fc88c4b5b67129d1a340dd0fd362efeec" -"checksum futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0bae52d6b29cf440e298856fec3965ee6fa71b06aa7495178615953fd669e5f9" -"checksum futures-timer 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "878f1d2fc31355fa02ed2372e741b0c17e58373341e6a122569b4623a14a7d33" -"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 futures_codec 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a0a73299e4718f5452e45980fc1d6957a070abe308d3700b63b8673f47e1c2b3" -"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" -"checksum get_if_addrs-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d04f9fb746cf36b191c00f3ede8bde9c8e64f9f4b05ae2694a9ccf5e3f5ab48" -"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" -"checksum gimli 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "162d18ae5f2e3b90a993d202f1ba17a5633c2484426f8bcae201f86194bacd00" -"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.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3081214398d39e4bd7f2c1975f0488ed04614ffdd976c6fc7a0708278552c0da" -"checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" -"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 heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" -"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" -"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.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.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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fa1c527bbc634be72aa7ba31e4e4def9bbb020f5416916279b7c705cd838893e" -"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" -"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" -"checksum impl-codec 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" -"checksum impl-rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8f7a72f11830b52333f36e3b09a288333888bf54380fd0ac0790a3c31ab0f3c5" -"checksum impl-serde 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "58e3cae7e99c7ff5a995da2cf78dd0a5383740eda71d98cf7b1910c301ac69b8" -"checksum impl-serde 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5bbe9ea9b182f0fb1cabbd61f4ff9b7b7b9197955e95a7e4c27de5055eb29ff8" -"checksum impl-trait-for-tuples 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" -"checksum indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b54058f0a6ff80b6803da8faf8997cde53872b38f4023728f6830b06cd3c0dc" -"checksum integer-sqrt 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f65877bf7d44897a473350b1046277941cee20b263397e90869c50b6e766088b" -"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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" -"checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" -"checksum jobserver 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2" -"checksum js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "7889c7c36282151f6bf465be4700359318aef36baa951462382eae49e9577cf9" -"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.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8396be0e5561ccd1bf7ff0b2007487cdd7a87a056873fe6ea906b35d4dbf7ed8" -"checksum kvdb-memorydb 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d25ef14155e418515c4839e9144c839de3506e68946f255a32b7f166095493d" -"checksum kvdb-rocksdb 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "af488cc16c3801705c8d681c3a32c8faa8fafc7fb5309dee0f573f3c6a19d395" -"checksum kvdb-web 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37a0e36637fb86454de401e7cb88f40eb0ad1b9bcee837d46785e7c451f1ebf4" -"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.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.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f84847789ab24b3fc5971a68656ac85886df640986d9ce3264c0327694eae471" -"checksum libp2p-core 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dbafb2706b8082233f66dc13e196f9cf9b4c229f2cd7c96b2b16617ad6ee330b" -"checksum libp2p-core-derive 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6c320266be0a7760e23484d635acdb83844b2d74d3612d93b41c393c9bcf004e" -"checksum libp2p-deflate 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be32697b42d040b325c3737f827ea04ede569ec956b7807700dd8d89d8210f9" -"checksum libp2p-dns 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f11c979b882f25d85726b15637d5bbc722dfa1be576605c54e99b8cf56906be3" -"checksum libp2p-floodsub 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4bdf6fba9272ad47dde94bade89540fdb16e24ae9ff7fb714c1c80a035165f28" -"checksum libp2p-gossipsub 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e6ecd058bf769d27ebec530544b081e08b0a1088e3186da8cc58d59915784d0" -"checksum libp2p-identify 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d1a6261b804111c2dbf53f8ca03f66edc5ad1c29b78a61cf0cc5354052e28e9" -"checksum libp2p-kad 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c6ea6fece0d99599afb1b2082ca8937944cdd6b0946a88d54cb3ae7a38d1253" -"checksum libp2p-mdns 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "074312353355df310affa105ec71b16fd7e52f5c6ae61d3dcbb3e79e8fdc9e5f" -"checksum libp2p-mplex 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "89d0b44dfdef80cc2be4b42d127de1c793905eca2459415a5c57d6b4fbd8ec30" -"checksum libp2p-noise 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0845e8208d814cd41c26c90a6a2f2b720c31b588209cecc49a44c881a09f417f" -"checksum libp2p-ping 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ecced2949ae93b6ff29565303ecd1bef15c4e4efb689033ee744922561a36b" -"checksum libp2p-plaintext 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "195fda6b6a948a242fd30570e0e3418ae8e0a20055ea75d45458e1079a8efb05" -"checksum libp2p-secio 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ceef68ca377b264f84d64c88739a8fa118b5db1e8f18297351dff75314504a5f" -"checksum libp2p-swarm 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "14ea00be81bc3985e36abad263ce2ad1b6aeb862aa743563eb70ad42880c05ae" -"checksum libp2p-tcp 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9e65ef381570df31cb047dfbc11483ab0fe7e6abbdcf2bdc2c60b5d11133d241" -"checksum libp2p-uds 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4f4f7989b35f33d4b9738aab2f031310eb20fec513cab44d12b1bc985a8074" -"checksum libp2p-wasm-ext 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0b4d457adb91a5e2212343218a554394cd8ced64a79fb8e36e7aed2a16d49495" -"checksum libp2p-websocket 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bba425f2af1fdb7dece88b9ae05ca9430dfb0b72b2c078e73ded6f1556084509" -"checksum libp2p-yamux 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ca25b3aac78a3c93c2a567622abd3cfc16f96f26ae1bf6134f0056203d62d86" -"checksum librocksdb-sys 6.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0785e816e1e11e7599388a492c61ef80ddc2afc91e313e61662cce537809be" -"checksum libsecp256k1 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "df6edf84fd62aad1c93932b39324eaeda3912c1d26bc18dfaee6293848e49a50" -"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.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b" -"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.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.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3197e20c7edb283f87c071ddfc7a2cca8f8e0b888c242959846a6fce03c72223" -"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" -"checksum memory-db 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "881736a0f68a6fae1b596bb066c5bd16d7b3ed645a4dd8ffaefd02f585abaf71" -"checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882" -"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.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.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a97fbd5d00e0e37bfb10f433af8f5aaf631e739368dc9fc28286ca81ca4948dc" -"checksum multistream-select 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f938ffe420493e77c8b6cbcc3f282283f68fc889c5dcbc8e51668d5f3a01ad94" -"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" -"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" -"checksum nohash-hasher 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "721a2bf1c26159ebf17e0a980bc4ce61f4b2fec5ec3b42d42fddd7a84a9e538f" -"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" -"checksum num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" -"checksum num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" -"checksum num-rational 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "da4dc79f9e6c81bef96148c8f6b8e72ad4541caa4a24373e900a36da07de03a3" -"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" -"checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" -"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.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b" -"checksum oorandom 11.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebcec7c9c2a95cacc7cd0ecb89d8a8454eca13906f6deb55258ffff0adeb9405" -"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" -"checksum openssl 0.10.27 (registry+https://github.com/rust-lang/crates.io-index)" = "e176a45fedd4c990e26580847a525e39e16ec32ac78957dbf62ded31b3abfd6f" -"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.54 (registry+https://github.com/rust-lang/crates.io-index)" = "1024c0a59774200a555087a6da3f253a9095a5f344e353b212ac4c8b8e450986" -"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.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.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80878c27f90dd162d3143333d672e80b194d6b080f05c83440e3dfda42e409f2" -"checksum parity-multihash 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "df3a17dc27848fd99e4f87eb0f8c9baba6ede0a6d555400c850ca45254ef4ce3" -"checksum parity-multihash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70a4d7b05e51bff5ae2c29c7b8c3d889985bbd8f4e15b3542fcc1f6f9666d292" -"checksum parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f747c06d9f3b2ad387ac881b9667298c81b1243aa9833f086e05996937c35507" -"checksum parity-scale-codec-derive 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34e513ff3e406f3ede6796dcdc83d0b32ffb86668cea1ccf7363118abeb00476" -"checksum parity-send-wrapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" -"checksum parity-util-mem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8174d85e62c4d615fddd1ef67966bdc5757528891d0742f15b131ad04667b3f9" -"checksum parity-util-mem 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "900dd84654b048e5bad420bb341658fc2c4d7fea628c22bcf4621733e54859b4" -"checksum parity-util-mem-derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" -"checksum parity-wasm 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16ad52817c4d343339b3bc2e26861bd21478eda0b7509acf83505727000512ac" -"checksum parity-wasm 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" -"checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" -"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" -"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" -"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" -"checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" -"checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" -"checksum paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "423a519e1c6e828f1e73b720f9d9ed2fa643dce8a7737fb43235ce0b41eeaa49" -"checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5" -"checksum pbkdf2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" -"checksum pdqselect 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ec91767ecc0a0bbe558ce8c9da33c068066c57ecc8bb8477ef8c1ad3ef77c27" -"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" -"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" -"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" -"checksum petgraph 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29c127eea4a29ec6c85d153c59dc1213f33ec74cead30fe4730aecc88cc1fd92" -"checksum pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7804a463a8d9572f13453c516a5faea534a2403d7ced2f0c7e100eeff072772c" -"checksum pin-project-internal 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" -"checksum pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae" -"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" -"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" -"checksum plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" -"checksum plotters 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "4e3bb8da247d27ae212529352020f3e5ee16e83c0c258061d27b08ab92675eeb" -"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" -"checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" -"checksum primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e4336f4f5d5524fa60bcbd6fe626f9223d8142a50e7053e979acdf0da41ab975" -"checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" -"checksum proc-macro-error 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "875077759af22fa20b610ad4471d8155b321c89c3f2785526c9839b099be4e0a" -"checksum proc-macro-error-attr 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c5717d9fa2664351a01ed73ba5ef6df09c01a521cb42cb65a061432a826f3c7a" -"checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" -"checksum proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" -"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -"checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" -"checksum prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212" -"checksum prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "02b10678c913ecbd69350e8535c3aef91a8676c0773fc1d7b95cdd196d7f2f26" -"checksum prost-derive 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72" -"checksum prost-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1834f67c0697c001304b75be76f67add9c89742eda3a085ad8ee0bb38c3417aa" -"checksum pwasm-utils 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f7a12f176deee919f4ba55326ee17491c8b707d0987aed822682c821b660192" -"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" -"checksum quickcheck 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f" -"checksum quicksink 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a8461ef7445f61fd72d8dcd0629ce724b9131b3c2eb36e83a5d3d4161c127530" -"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.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" -"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" -"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -"checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -"checksum rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03b418169fb9c46533f326efd6eed2576699c44ca92d3052a066214a8d828929" -"checksum raw-cpuid 7.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4a349ca83373cfa5d6dbb66fd76e58b2cca08da71a5f6400de0a0a6a9bceeaf" -"checksum rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098" -"checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9" -"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" -"checksum redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" -"checksum regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" -"checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9" -"checksum regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06" -"checksum region 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "448e868c6e4cfddfa49b6a72c95906c04e8547465e9536575b95c70a4044f856" -"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" -"checksum ring 0.16.10 (registry+https://github.com/rust-lang/crates.io-index)" = "113f53b644c5442e20ff3a299be3d6c61ba143737af5bd2ab298e248a7575b2d" -"checksum rlp 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3a44d5ae8afcb238af8b75640907edc6c931efcfab2c854e81ed35fa080f84cd" -"checksum rocksdb 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "12069b106981c6103d3eab7dd1c86751482d0779a520b7c14954c8b586c1e643" -"checksum rpassword 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "99371657d3c8e4d816fb6221db98fa408242b0b53bac08f8676a41f8554fe99f" -"checksum rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" -"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" -"checksum rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" -"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b25a18b1bf7387f0145e7f8324e700805aade3842dd3db2e74e4cdeb4677c09e" -"checksum rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" -"checksum rw-stream-sink 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020" -"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" -"checksum safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347" -"checksum safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" -"checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -"checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" -"checksum schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eacd8381b3c37840c9c9f40472af529e49975bdcbc24f83c31059fd6539023d3" -"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" -"checksum scroll 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "abb2332cb595d33f7edd5700f4cbf94892e680c7f0ae56adab58a35190b66cb1" -"checksum scroll_derive 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8584eea9b9ff42825b46faf46a8c24d2cff13ec152fa2a50df788b87c07ee28" -"checksum sct 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c" -"checksum security-framework 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8ef2429d7cefe5fd28bd1d2ed41c944547d4ff84776f5935b456da44593a16df" -"checksum security-framework-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e31493fc37615debb8c5090a7aeb4a9730bc61e77ab10b9af59f1a202284f895" -"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" -"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 send_wrapper 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "686ef91cf020ad8d4aca9a7047641fd6add626b7b89e14546c2b6a76781cf822" -"checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" -"checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" -"checksum serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)" = "21b01d7f0288608a01dca632cf1df859df6fd6ffa885300fc275ce2ba6221953" -"checksum sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" -"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" -"checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" -"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 signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" -"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-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.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.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc" -"checksum snow 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "afb767eee7d257ba202f0b9b08673bc13b22281632ef45267b19f13100accd2f" -"checksum soketto 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c9dab3f95c9ebdf3a88268c19af668f637a3c5039c2c56ff2d40b1b2d64a25b" -"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" -"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" -"checksum static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -"checksum stream-cipher 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8131256a5896cabcf5eb04f4d6dacbe1aefda854b0d9896e09cb58829ec5638c" -"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.9 (registry+https://github.com/rust-lang/crates.io-index)" = "a1bcbed7d48956fcbb5d80c6b95aedb553513de0a1b451ea92679d999c010e98" -"checksum structopt-derive 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "095064aa1f5b94d14e635d0a5684cf140c43ae40a0fd990708d38f5d669e5f64" -"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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" -"checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" -"checksum syn-mid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" -"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 tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" -"checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" -"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.10 (registry+https://github.com/rust-lang/crates.io-index)" = "205684fd018ca14432b12cce6ea3d46763311a571c3d294e71ba3f01adcf1aad" -"checksum thiserror-impl 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "57e4d2e50ca050ed44fb58309bdce3efa79948f84f9993ad1978de5eebdce5a7" -"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" -"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" -"checksum tiny-bip39 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c5676413eaeb1ea35300a0224416f57abc3bd251657e0fafc12c47ff98c060" -"checksum tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2" -"checksum tiny-keccak 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2953ca5148619bc99695c1274cb54c5275bbb913c6adad87e72eaf8db9787f69" -"checksum tinytemplate 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "57a3c6667d3e65eb1bc3aed6fd14011c6cbc3a0665218ab7f5daf040b9ec371a" -"checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" -"checksum tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8fdd17989496f49cdc57978c96f0c9fe5e4a58a8bddc6813c449a4624f6a030b" -"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-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" -"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-macros 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f4b1e7ed7d5d4c2af3d999904b0eebe76544897cdbfb2b9684bed2174ab20f7c" -"checksum tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6732fe6b53c8d11178dcb77ac6d9682af27fc6d4cb87789449152e5377377146" -"checksum tokio-rustls 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d7cf08f990090abd6c6a73cab46fed62f85e8aef8b99e4b918a9f4a637f0676" -"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.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.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" -"checksum tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" -"checksum tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1e213bd24252abeb86a0b7060e02df677d367ce6cb772cef17e9214b8390a8d3" -"checksum tracing-attributes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04cfd395def5a60236e187e1ff905cb55668a59f29928dec05e6e1b1fd2ac1f3" -"checksum tracing-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "13a46f11e372b8bd4b4398ea54353412fdd7fd42a8370c7e543e218cf7661978" -"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" -"checksum trie-bench 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26fd042d57ee9c987c562811162a78db78b5340ab674ac76056c85dca49b26bc" -"checksum trie-db 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a0d747ae5b6f078df7e46477fcc7df66df9eb4f27a031cf4a7c890a8dd03d8e6" -"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.21 (registry+https://github.com/rust-lang/crates.io-index)" = "3f5b3f750c701725331ac78e389b5d143b7d25f6b6ffffd0d419759a9063ac5f" -"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" -"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" -"checksum uint 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e75a4cdd7b87b28840dba13c483b9a88ee6bbf16ba5c951ee1ecfcf723078e0d" -"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.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" -"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" -"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 unsigned-varint 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c689459fbaeb50e56c6749275f084decfd02194ac5852e6617d95d0d3cf02eaf" -"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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" -"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" -"checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum wabt 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3c5c5c1286c6e578416982609f47594265f9d489f9b836157d403ad605a46693" -"checksum wabt-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "af5d153dc96aad7dc13ab90835b892c69867948112d95299e522d370c4e13a08" -"checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" -"checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" -"checksum want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -"checksum wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c" -"checksum wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "11cdb95816290b525b32587d76419facd99662a07e59d3cdb560488a819d9a45" -"checksum wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8bbdd49e3e28b40dec6a9ba8d17798245ce32b019513a845369c641b275135d9" -"checksum wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "574094772ce6921576fb6f2e3f7497b8a76273b6db092be18fc48a082de09dc3" -"checksum wasm-bindgen-macro-support 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" -"checksum wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e7e61fc929f4c0dddb748b102ebf9f632e2b8d739f2016542b4de2965a9601" -"checksum wasm-bindgen-webidl 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "ef012a0d93fc0432df126a8eaf547b2dce25a8ce9212e1d3cbeef5c11157975d" -"checksum wasm-gc-api 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c32691b6c7e6c14e7f8fd55361a9088b507aa49620fcd06c09b3a1082186b9" -"checksum wasm-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "324c5e65a08699c9c4334ba136597ab22b85dccd4b65dd1e36ccf8f723a95b54" -"checksum wasmi 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bf617d864d25af3587aa745529f7aaa541066c876d57e050c0d0c85c61c92aff" -"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" -"checksum wasmtime-environ 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a3947662a0b8e05b1418465e64f16de9114f9fec18cc3f56e0ed5aa7737b89d0" -"checksum wasmtime-jit 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ed7922689461a7b5bd0d9c7350cac526c8a520a23b3ffd7f5b446ac51dfc51f" -"checksum wasmtime-runtime 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "781d6bb8b346efaa3dc39746386957cd79b8d841e8652ed9b02d77bcf64fb514" -"checksum web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf97caf6aa8c2b1dac90faf0db529d9d63c93846cca4911856f78a83cebf53b" -"checksum webpki 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1f50e1972865d6b1adb54167d1c8ed48606004c2c9d0ea5f1eeb34d95e863ef" -"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.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 which 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5475d47078209a02e60614f7ba5e645ef3ed60f771920ac1906d7c1cc65024c8" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum ws 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a2c47b5798ccc774ffb93ff536aec7c4275d722fd9c740c83cdd1af1f2d94" -"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -"checksum x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ee1585dc1484373cbc1cee7aafda26634665cf449436fd6e24bfd1fad230538" -"checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" -"checksum yamux 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f937668802a2e862a4fed05267e10b20c310bf771adc89687710706d55a9a65" -"checksum zeroize 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "45af6a010d13e4cf5b54c94ba5a2b2eba5596b9e46bf5875612d332a1f2b3f86" -"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" + "cc", + "glob 0.3.0", + "libc", +] diff --git a/primitives/arithmetic/fuzzer/Cargo.lock b/primitives/arithmetic/fuzzer/Cargo.lock index 41bd9cc3ba..b196418375 100644 --- a/primitives/arithmetic/fuzzer/Cargo.lock +++ b/primitives/arithmetic/fuzzer/Cargo.lock @@ -4,292 +4,326 @@ name = "arbitrary" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64cf76cb6e2222ed0ea86b2b0ee2f71c96ec6edd5af42e84d59160e91b836ec4" [[package]] name = "arrayvec" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" [[package]] name = "autocfg" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "bitvec" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993f74b4c99c1908d156b8d2e0fb6277736b0ecbd833982fd1241d39b2766a6" [[package]] name = "byte-slice-cast" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" [[package]] name = "byteorder" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" [[package]] name = "c2-chacha" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" dependencies = [ - "ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ppv-lite86", ] [[package]] name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "crunchy" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "fixed-hash" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder", + "rand", + "rustc-hex", + "static_assertions", ] [[package]] name = "getrandom" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "libc", + "wasi", ] [[package]] name = "honggfuzz" version = "0.5.45" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24c27b4aa3049d6d10d8e33d52c9d03ca9aec18f8a449b246f8c4a5b0c10fb34" dependencies = [ - "arbitrary 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "arbitrary", + "lazy_static", + "memmap", ] [[package]] name = "impl-codec" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" dependencies = [ - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "parity-scale-codec", ] [[package]] name = "integer-sqrt" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f65877bf7d44897a473350b1046277941cee20b263397e90869c50b6e766088b" [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" version = "0.2.66" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" [[package]] name = "memmap" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" dependencies = [ - "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)", + "libc", + "winapi", ] [[package]] name = "num-bigint" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", + "num-integer", + "num-traits", ] [[package]] name = "num-integer" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", + "num-traits", ] [[package]] name = "num-traits" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" dependencies = [ - "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", ] [[package]] name = "parity-scale-codec" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f747c06d9f3b2ad387ac881b9667298c81b1243aa9833f086e05996937c35507" dependencies = [ - "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bitvec 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byte-slice-cast 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec-derive 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec", + "bitvec", + "byte-slice-cast", + "parity-scale-codec-derive", + "serde", ] [[package]] name = "parity-scale-codec-derive" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34e513ff3e406f3ede6796dcdc83d0b32ffb86668cea1ccf7363118abeb00476" dependencies = [ - "proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "ppv-lite86" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" [[package]] name = "primitive-types" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4336f4f5d5524fa60bcbd6fe626f9223d8142a50e7053e979acdf0da41ab975" dependencies = [ - "fixed-hash 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "impl-codec 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "uint 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fixed-hash", + "impl-codec", + "uint", ] [[package]] name = "proc-macro-crate" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" dependencies = [ - "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "toml", ] [[package]] name = "proc-macro2" version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" dependencies = [ - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid", ] [[package]] name = "quote" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", ] [[package]] name = "rand" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom 0.1.14 (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)", + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", ] [[package]] name = "rand_chacha" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" dependencies = [ - "c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "c2-chacha", + "rand_core", ] [[package]] name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom", ] [[package]] name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core", ] [[package]] name = "rustc-hex" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" [[package]] name = "serde" version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" dependencies = [ - "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "sp-arithmetic" version = "2.0.0" dependencies = [ - "integer-sqrt 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-debug-derive 2.0.0", - "sp-std 2.0.0", + "integer-sqrt", + "num-traits", + "parity-scale-codec", + "serde", + "sp-debug-derive", + "sp-std", ] [[package]] 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.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "sp-arithmetic 2.0.0", + "honggfuzz", + "num-bigint", + "num-traits", + "primitive-types", + "sp-arithmetic", ] [[package]] name = "sp-debug-derive" version = "2.0.0" dependencies = [ - "proc-macro2 1.0.8 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -300,106 +334,70 @@ version = "2.0.0" name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "syn" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "unicode-xid", ] [[package]] name = "toml" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" dependencies = [ - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", ] [[package]] name = "uint" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e75a4cdd7b87b28840dba13c483b9a88ee6bbf16ba5c951ee1ecfcf723078e0d" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder", + "crunchy", + "rustc-hex", + "static_assertions", ] [[package]] name = "unicode-xid" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "winapi" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum arbitrary 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64cf76cb6e2222ed0ea86b2b0ee2f71c96ec6edd5af42e84d59160e91b836ec4" -"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" -"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" -"checksum bitvec 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a993f74b4c99c1908d156b8d2e0fb6277736b0ecbd833982fd1241d39b2766a6" -"checksum byte-slice-cast 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" -"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" -"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" -"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" -"checksum crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" -"checksum fixed-hash 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" -"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" -"checksum honggfuzz 0.5.45 (registry+https://github.com/rust-lang/crates.io-index)" = "24c27b4aa3049d6d10d8e33d52c9d03ca9aec18f8a449b246f8c4a5b0c10fb34" -"checksum impl-codec 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" -"checksum integer-sqrt 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f65877bf7d44897a473350b1046277941cee20b263397e90869c50b6e766088b" -"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" -"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" -"checksum num-bigint 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" -"checksum num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" -"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" -"checksum parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f747c06d9f3b2ad387ac881b9667298c81b1243aa9833f086e05996937c35507" -"checksum parity-scale-codec-derive 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34e513ff3e406f3ede6796dcdc83d0b32ffb86668cea1ccf7363118abeb00476" -"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" -"checksum primitive-types 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e4336f4f5d5524fa60bcbd6fe626f9223d8142a50e7053e979acdf0da41ab975" -"checksum proc-macro-crate 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" -"checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" -"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" -"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" -"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -"checksum rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" -"checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" -"checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" -"checksum static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -"checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" -"checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" -"checksum uint 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e75a4cdd7b87b28840dba13c483b9a88ee6bbf16ba5c951ee1ecfcf723078e0d" -"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" -"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -- GitLab From bf250d1ca3df4d508c83a73b507ad79cf217ad44 Mon Sep 17 00:00:00 2001 From: cheme Date: Mon, 3 Feb 2020 20:28:10 +0100 Subject: [PATCH 075/180] Fix call to backend in child_storage_hash (#4815) * Fix call to backend in child_storage_hash * child storage test. --- primitives/state-machine/src/ext.rs | 57 ++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/primitives/state-machine/src/ext.rs b/primitives/state-machine/src/ext.rs index f293ae9f51..38a2e70262 100644 --- a/primitives/state-machine/src/ext.rs +++ b/primitives/state-machine/src/ext.rs @@ -231,7 +231,7 @@ where fn child_storage_hash( &self, storage_key: ChildStorageKey, - _child_info: ChildInfo, + child_info: ChildInfo, key: &[u8], ) -> Option> { let _guard = sp_panic_handler::AbortGuard::force_abort(); @@ -239,7 +239,8 @@ where .child_storage(storage_key.as_ref(), key) .map(|x| x.map(|x| H::hash(x))) .unwrap_or_else(|| - self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL) + self.backend.child_storage_hash(storage_key.as_ref(), child_info, key) + .expect(EXT_NOT_ALLOWED_TO_FAIL) ); trace!(target: "state-trace", "{:04x}: ChildHash({}) {}={:?}", @@ -613,6 +614,12 @@ mod tests { type TestBackend = InMemoryBackend; type TestExt<'a> = Ext<'a, Blake2Hasher, u64, TestBackend>; + 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); + + fn prepare_overlay_with_changes() -> OverlayedChanges { OverlayedChanges { prospective: vec![ @@ -769,4 +776,50 @@ mod tests { // next_overlay exist but next_backend doesn't exist assert_eq!(ext.next_child_storage_key(child(), CHILD_INFO_1, &[40]), Some(vec![50])); } + + #[test] + fn child_storage_works() { + let mut cache = StorageTransactionCache::default(); + 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![30] => vec![40] + ], + child_info: CHILD_INFO_1.to_owned(), + } + ], + }.into(); + + let ext = TestExt::new(&mut overlay, &mut cache, &backend, None, None); + + assert_eq!(ext.child_storage(child(), CHILD_INFO_1, &[10]), Some(vec![10])); + assert_eq!(ext.original_child_storage(child(), CHILD_INFO_1, &[10]), Some(vec![10])); + assert_eq!( + ext.child_storage_hash(child(), CHILD_INFO_1, &[10]), + Some(Blake2Hasher::hash(&[10]).as_ref().to_vec()), + ); + + assert_eq!(ext.child_storage(child(), CHILD_INFO_1, &[20]), None); + assert_eq!(ext.original_child_storage(child(), CHILD_INFO_1, &[20]), Some(vec![20])); + assert_eq!( + ext.child_storage_hash(child(), CHILD_INFO_1, &[20]), + None, + ); + + assert_eq!(ext.child_storage(child(), CHILD_INFO_1, &[30]), Some(vec![31])); + assert_eq!(ext.original_child_storage(child(), CHILD_INFO_1, &[30]), Some(vec![40])); + assert_eq!( + ext.child_storage_hash(child(), CHILD_INFO_1, &[30]), + Some(Blake2Hasher::hash(&[31]).as_ref().to_vec()), + ); + + } } -- GitLab From eeebfc8fe54f3a288d909ebfea5ec89eed5ebb5f Mon Sep 17 00:00:00 2001 From: Xiliang Chen Date: Tue, 4 Feb 2020 22:44:40 +1300 Subject: [PATCH 076/180] add state_getKeysPaged (#4718) * add storage_getNextKey * RPC storage_getKeysPages * respect count * use iterator * improve * add tests * improve * add doc comments * Make prefix optional * update error * improve --- client/rpc-api/src/state/error.rs | 13 ++++ client/rpc-api/src/state/mod.rs | 15 +++- client/rpc/src/state/mod.rs | 31 +++++++- client/rpc/src/state/state_full.rs | 18 +++++ client/rpc/src/state/state_light.rs | 10 +++ client/src/client.rs | 115 +++++++++++++++++++++++++++- 6 files changed, 199 insertions(+), 3 deletions(-) diff --git a/client/rpc-api/src/state/error.rs b/client/rpc-api/src/state/error.rs index 4997a728fc..c9c2cf4e45 100644 --- a/client/rpc-api/src/state/error.rs +++ b/client/rpc-api/src/state/error.rs @@ -41,6 +41,14 @@ pub enum Error { /// Details of the error message. details: String, }, + /// Provided count exceeds maximum value. + #[display(fmt = "count exceeds maximum value. value: {}, max: {}", value, max)] + InvalidCount { + /// Provided value + value: u32, + /// Maximum allowed value + max: u32, + }, } impl std::error::Error for Error { @@ -63,6 +71,11 @@ impl From for rpc::Error { message: format!("{}", e), data: None, }, + Error::InvalidCount { .. } => rpc::Error { + code: rpc::ErrorCode::ServerError(BASE_ERROR + 2), + message: format!("{}", e), + data: None, + }, e => errors::internal(e), } } diff --git a/client/rpc-api/src/state/mod.rs b/client/rpc-api/src/state/mod.rs index b22bacbe87..6901738efe 100644 --- a/client/rpc-api/src/state/mod.rs +++ b/client/rpc-api/src/state/mod.rs @@ -39,10 +39,23 @@ pub trait StateApi { #[rpc(name = "state_call", alias("state_callAt"))] fn call(&self, name: String, bytes: Bytes, hash: Option) -> FutureResult; - /// Returns the keys with prefix, leave empty to get all the keys + /// DEPRECATED: Please use `state_getKeysPaged` with proper paging support. + /// Returns the keys with prefix, leave empty to get all the keys. #[rpc(name = "state_getKeys")] fn storage_keys(&self, prefix: StorageKey, hash: Option) -> FutureResult>; + /// Returns the keys with prefix with pagination support. + /// Up to `count` keys will be returned. + /// If `start_key` is passed, return next keys in storage in lexicographic order. + #[rpc(name = "state_getKeysPaged", alias("state_getKeysPagedAt"))] + fn storage_keys_paged( + &self, + prefix: Option, + count: u32, + start_key: Option, + hash: Option, + ) -> FutureResult>; + /// Returns a storage entry at a specific block's state. #[rpc(name = "state_getStorage", alias("state_getStorageAt"))] fn storage(&self, key: StorageKey, hash: Option) -> FutureResult>; diff --git a/client/rpc/src/state/mod.rs b/client/rpc/src/state/mod.rs index f8f8fe4223..df26daa929 100644 --- a/client/rpc/src/state/mod.rs +++ b/client/rpc/src/state/mod.rs @@ -24,7 +24,7 @@ mod tests; use std::sync::Arc; use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; -use rpc::{Result as RpcResult, futures::Future}; +use rpc::{Result as RpcResult, futures::{Future, future::result}}; use sc_rpc_api::Subscriptions; use sc_client::{Client, CallExecutor, light::{blockchain::RemoteBlockchain, fetcher::Fetcher}}; @@ -38,6 +38,8 @@ use self::error::{Error, FutureResult}; pub use sc_rpc_api::state::*; +const STORAGE_KEYS_PAGED_MAX_COUNT: u32 = 1000; + /// State backend API. pub trait StateBackend: Send + Sync + 'static where @@ -61,6 +63,15 @@ pub trait StateBackend: Send + Sync + 'static prefix: StorageKey, ) -> FutureResult>; + /// Returns the keys with prefix with pagination support. + fn storage_keys_paged( + &self, + block: Option, + prefix: Option, + count: u32, + start_key: Option, + ) -> FutureResult>; + /// Returns a storage entry at a specific block's state. fn storage( &self, @@ -244,6 +255,24 @@ impl StateApi for State self.backend.storage_keys(block, key_prefix) } + fn storage_keys_paged( + &self, + prefix: Option, + count: u32, + start_key: Option, + block: Option, + ) -> FutureResult> { + if count > STORAGE_KEYS_PAGED_MAX_COUNT { + return Box::new(result(Err( + Error::InvalidCount { + value: count, + max: STORAGE_KEYS_PAGED_MAX_COUNT, + } + ))); + } + self.backend.storage_keys_paged(block, prefix, count, start_key) + } + fn storage(&self, key: StorageKey, block: Option) -> FutureResult> { self.backend.storage(block, key) } diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index 3f7470ae4e..87c75e77a6 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -254,6 +254,24 @@ impl StateBackend for FullState, + prefix: Option, + count: u32, + start_key: Option, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| + self.client.storage_keys_iter( + &BlockId::Hash(block), prefix.as_ref(), start_key.as_ref() + ) + ) + .map(|v| v.take(count as usize).collect()) + .map_err(client_err))) + } + fn storage( &self, block: Option, diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index cc3d1a4951..f25d6e2186 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -199,6 +199,16 @@ impl StateBackend for LightState, + _prefix: Option, + _count: u32, + _start_key: Option, + ) -> FutureResult> { + Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient)))) + } + fn storage( &self, block: Option, diff --git a/client/src/client.rs b/client/src/client.rs index a3bbf84f7d..ca8b0c5dd7 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -99,6 +99,46 @@ pub struct Client where Block: BlockT { _phantom: PhantomData, } +/// An `Iterator` that iterates keys in a given block under a prefix. +pub struct KeyIterator<'a, State, Block> { + state: State, + prefix: Option<&'a StorageKey>, + current_key: Vec, + _phantom: PhantomData, +} + +impl <'a, State, Block> KeyIterator<'a, State, Block> { + fn new(state: State, prefix: Option<&'a StorageKey>, current_key: Vec) -> Self { + Self { + state, + prefix, + current_key, + _phantom: PhantomData, + } + } +} + +impl<'a, State, Block> Iterator for KeyIterator<'a, State, Block> where + Block: BlockT, + State: StateBackend>, +{ + type Item = StorageKey; + + fn next(&mut self) -> Option { + let next_key = self.state + .next_storage_key(&self.current_key) + .ok() + .flatten()?; + if let Some(prefix) = self.prefix { + if !next_key.starts_with(&prefix.0[..]) { + return None; + } + } + self.current_key = next_key.clone(); + Some(StorageKey(next_key)) + } +} + // used in importing a block, where additional changes are made after the runtime // executed. enum PrePostHeader { @@ -234,12 +274,27 @@ impl Client where self.backend.state_at(*block) } - /// Given a `BlockId` and a key prefix, return the matching child storage keys in that block. + /// Given a `BlockId` and a key prefix, return the matching storage keys in that block. 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 prefix, return a `KeyIterator` iterates matching storage keys in that block. + pub fn storage_keys_iter<'a>( + &self, + id: &BlockId, + prefix: Option<&'a StorageKey>, + start_key: Option<&StorageKey> + ) -> sp_blockchain::Result> { + let state = self.state_at(id)?; + let start_key = start_key + .or(prefix) + .map(|key| key.0.clone()) + .unwrap_or_else(Vec::new); + Ok(KeyIterator::new(state, prefix, start_key)) + } + /// Given a `BlockId` and a key, return the value under the key in that block. pub fn storage(&self, id: &BlockId, key: &StorageKey) -> sp_blockchain::Result> { Ok(self.state_at(id)? @@ -1900,6 +1955,7 @@ pub(crate) mod tests { sc_client_db::{Backend, DatabaseSettings, DatabaseSettingsSrc, PruningMode}, runtime::{self, Block, Transfer, RuntimeApi, TestAPI}, }; + use hex_literal::hex; /// Returns tuple, consisting of: /// 1) test client pre-filled with blocks changing balances; @@ -3303,4 +3359,61 @@ pub(crate) mod tests { vec![(30, 0), (27, 0), (25, 0), (24, 0), (11, 0)] ); } + + #[test] + fn storage_keys_iter_prefix_and_start_key_works() { + let client = substrate_test_runtime_client::new(); + + let prefix = StorageKey(hex!("3a").to_vec()); + + let res: Vec<_> = client.storage_keys_iter(&BlockId::Number(0), Some(&prefix), None) + .unwrap() + .map(|x| x.0) + .collect(); + assert_eq!(res, [hex!("3a636f6465").to_vec(), hex!("3a686561707061676573").to_vec()]); + + let res: Vec<_> = client.storage_keys_iter(&BlockId::Number(0), Some(&prefix), Some(&StorageKey(hex!("3a636f6465").to_vec()))) + .unwrap() + .map(|x| x.0) + .collect(); + assert_eq!(res, [hex!("3a686561707061676573").to_vec()]); + + let res: Vec<_> = client.storage_keys_iter(&BlockId::Number(0), Some(&prefix), Some(&StorageKey(hex!("3a686561707061676573").to_vec()))) + .unwrap() + .map(|x| x.0) + .collect(); + assert_eq!(res, Vec::>::new()); + } + + #[test] + fn storage_keys_iter_works() { + let client = substrate_test_runtime_client::new(); + + let prefix = StorageKey(hex!("").to_vec()); + + let res: Vec<_> = client.storage_keys_iter(&BlockId::Number(0), Some(&prefix), None) + .unwrap() + .take(2) + .map(|x| x.0) + .collect(); + assert_eq!(res, [hex!("0befda6e1ca4ef40219d588a727f1271").to_vec(), hex!("3a636f6465").to_vec()]); + + let res: Vec<_> = client.storage_keys_iter(&BlockId::Number(0), Some(&prefix), Some(&StorageKey(hex!("3a636f6465").to_vec()))) + .unwrap() + .take(3) + .map(|x| x.0) + .collect(); + assert_eq!(res, [ + hex!("3a686561707061676573").to_vec(), + hex!("6644b9b8bc315888ac8e41a7968dc2b4141a5403c58acdf70b7e8f7e07bf5081").to_vec(), + hex!("79c07e2b1d2e2abfd4855b936617eeff5e0621c4869aa60c02be9adcc98a0d1d").to_vec(), + ]); + + let res: Vec<_> = client.storage_keys_iter(&BlockId::Number(0), Some(&prefix), Some(&StorageKey(hex!("79c07e2b1d2e2abfd4855b936617eeff5e0621c4869aa60c02be9adcc98a0d1d").to_vec()))) + .unwrap() + .take(1) + .map(|x| x.0) + .collect(); + assert_eq!(res, [hex!("cf722c0832b5231d35e29f319ff27389f5032bfc7bfc3ba5ed7839f2042fb99f").to_vec()]); + } } -- GitLab From eed99bdd990e61037b8c6127d18b1a60706632ac Mon Sep 17 00:00:00 2001 From: Gautam Dhameja Date: Tue, 4 Feb 2020 11:25:04 +0100 Subject: [PATCH 077/180] Added GetCallMetadata for extrinsic calls. (#4791) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added GetCallMetadata for extrinsic calls. Co-Authored-By: Bastian Köcher * Improved test for outer call metadata. * fixed review comments * removed dead code * fixed review suggestions * Update frame/support/src/dispatch.rs Co-authored-by: Bastian Köcher --- frame/support/src/dispatch.rs | 104 ++++++++++++++++++++++------------ frame/support/src/traits.rs | 22 +++++++ 2 files changed, 91 insertions(+), 35 deletions(-) diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index b2d7e6e1d4..85cf8d6ede 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -28,6 +28,7 @@ pub use crate::weights::{ TransactionPriority, Weight, WeighBlock, PaysFee, }; pub use sp_runtime::{traits::Dispatchable, DispatchError, DispatchResult}; +pub use crate::traits::{CallMetadata, GetCallMetadata, GetCallName}; /// A type that cannot be instantiated. pub enum Never {} @@ -1302,42 +1303,48 @@ macro_rules! decl_module { for $call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )* { fn get_dispatch_info(&self) -> $crate::dispatch::DispatchInfo { - $( - if let $call_type::$fn_name($( ref $param_name ),*) = self { - let weight = >::weigh_data( - &$weight, - ($( $param_name, )*) - ); - let class = >::classify_dispatch( - &$weight, - ($( $param_name, )*) - ); - let pays_fee = >::pays_fee( - &$weight, - ($( $param_name, )*) - ); - return $crate::dispatch::DispatchInfo { weight, class, pays_fee }; - } - if let $call_type::__PhantomItem(_, _) = self { unreachable!("__PhantomItem should never be used.") } - )* - // Defensive only: this function must have already returned at this point. - // all dispatchable function will have a weight which has the `::default` - // implementation of `SimpleDispatchInfo`. Nonetheless, we create one if it does - // not exist. - let weight = >::weigh_data( - &$crate::dispatch::SimpleDispatchInfo::default(), - () - ); - let class = >::classify_dispatch( - &$crate::dispatch::SimpleDispatchInfo::default(), - () - ); - let pays_fee = >::pays_fee( - &$crate::dispatch::SimpleDispatchInfo::default(), - () - ); - $crate::dispatch::DispatchInfo { weight, class, pays_fee } + match *self { + $( + $call_type::$fn_name( $( ref $param_name ),* ) => { + let weight = >::weigh_data( + &$weight, + ($( $param_name, )*) + ); + let class = >::classify_dispatch( + &$weight, + ($( $param_name, )*) + ); + let pays_fee = >::pays_fee( + &$weight, + ($( $param_name, )*) + ); + $crate::dispatch::DispatchInfo { + weight, + class, + pays_fee, + } + }, + )* + $call_type::__PhantomItem(_, _) => unreachable!("__PhantomItem should never be used."), + } + } + } + // Implement GetCallName for the Call. + impl<$trait_instance: $trait_name $(, $instance: $instantiable)?> $crate::dispatch::GetCallName + for $call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )* + { + fn get_call_name(&self) -> &'static str { + match *self { + $( + $call_type::$fn_name( $( ref $param_name ),* ) => { + // Don't generate any warnings for unused variables + let _ = ( $( $param_name ),* ); + stringify!($fn_name) + }, + )* + $call_type::__PhantomItem(_, _) => unreachable!("__PhantomItem should never be used."), + } } } @@ -1500,6 +1507,18 @@ macro_rules! impl_outer_dispatch { } } } + impl $crate::dispatch::GetCallMetadata for $call_type { + fn get_call_metadata(&self) -> $crate::dispatch::CallMetadata { + use $crate::dispatch::GetCallName; + match self { + $( $call_type::$camelcase(call) => { + let function_name = call.get_call_name(); + let pallet_name = stringify!($camelcase); + $crate::dispatch::CallMetadata { function_name, pallet_name } + }, )* + } + } + } impl $crate::dispatch::Dispatchable for $call_type { type Origin = $origin; type Trait = $call_type; @@ -1871,6 +1890,7 @@ mod tests { use super::*; use crate::sp_runtime::traits::{OnInitialize, OnFinalize}; use crate::weights::{DispatchInfo, DispatchClass}; + use crate::traits::{CallMetadata, GetCallMetadata, GetCallName}; pub trait Trait: system::Trait + Sized where Self::AccountId: From { type Origin; @@ -2084,4 +2104,18 @@ mod tests { assert_eq!(>::on_finalize(2), 10); assert_eq!(>::on_finalize(3), 0); } + + #[test] + fn call_name() { + let name = Call::::aux_3().get_call_name(); + assert_eq!("aux_3", name); + } + + #[test] + fn call_metadata() { + let call = OuterCall::Test(Call::::aux_3()); + let metadata = call.get_call_metadata(); + let expected = CallMetadata { function_name: "aux_3".into(), pallet_name: "Test".into() }; + assert_eq!(metadata, expected); + } } diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index 02e6085046..ecfababfc0 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -22,6 +22,7 @@ use sp_std::{prelude::*, result, marker::PhantomData, ops::Div, fmt::Debug}; use codec::{FullCodec, Codec, Encode, Decode}; use sp_core::u32_trait::Value as U32; use sp_runtime::{ + RuntimeDebug, ConsensusEngineId, DispatchResult, DispatchError, traits::{MaybeSerializeDeserialize, SimpleArithmetic, Saturating, TrailingZeroInput}, }; @@ -800,3 +801,24 @@ pub trait ModuleToIndex { impl ModuleToIndex for () { fn module_to_index() -> Option { Some(0) } } + +/// The function and pallet name of the Call. +#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug)] +pub struct CallMetadata { + /// Name of the function. + pub function_name: &'static str, + /// Name of the pallet to which the function belongs. + pub pallet_name: &'static str, +} + +/// Gets the function name of the Call. +pub trait GetCallName { + /// Return the function name of the Call. + fn get_call_name(&self) -> &'static str; +} + +/// Gets the metadata for the Call - function name and pallet name. +pub trait GetCallMetadata { + /// Return a [`CallMetadata`], containing function and pallet name of the Call. + fn get_call_metadata(&self) -> CallMetadata; +} -- GitLab From 4d41362b1b4d53af68bc92baed1ec77049269209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Tue, 4 Feb 2020 12:39:56 +0100 Subject: [PATCH 078/180] Fix flaky messed signature test (#4819) When messing with the signature, we need to make sure that we acutally mess-up the signature. As the generated private/public key is random, the signature is random as well. It can happen that `bytes[0] == bytes[2]` which makes the test fail. We fix this problem by just inverting the bytes at `0` and `2`. --- primitives/core/src/sr25519.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/primitives/core/src/sr25519.rs b/primitives/core/src/sr25519.rs index d98aa19e1d..3495f32872 100644 --- a/primitives/core/src/sr25519.rs +++ b/primitives/core/src/sr25519.rs @@ -735,7 +735,8 @@ mod test { let public = pair.public(); let message = b"Signed payload"; let Signature(mut bytes) = pair.sign(&message[..]); - bytes[0] = bytes[2]; + bytes[0] = !bytes[0]; + bytes[2] = !bytes[2]; let signature = Signature(bytes); assert!(!Pair::verify(&signature, &message[..], &public)); } -- GitLab From a9680b40469c8180e5b6b083c01dc04f69e4037c Mon Sep 17 00:00:00 2001 From: Demi Obenour <48690212+DemiMarie-parity@users.noreply.github.com> Date: Tue, 4 Feb 2020 15:56:50 +0000 Subject: [PATCH 079/180] Bump `parking_lot` (#4817) Hopefully this can be merged if the tests pass. --- Cargo.lock | 62 +++++++++---------- client/Cargo.toml | 2 +- client/api/Cargo.toml | 2 +- client/basic-authorship/Cargo.toml | 2 +- client/consensus/aura/Cargo.toml | 2 +- client/consensus/babe/Cargo.toml | 2 +- client/consensus/manual-seal/Cargo.toml | 2 +- client/consensus/slots/Cargo.toml | 2 +- client/db/Cargo.toml | 2 +- client/executor/Cargo.toml | 2 +- client/finality-grandpa/Cargo.toml | 2 +- client/keystore/Cargo.toml | 2 +- client/network-gossip/Cargo.toml | 2 +- client/network/Cargo.toml | 2 +- client/network/test/Cargo.toml | 2 +- client/offchain/Cargo.toml | 2 +- client/rpc-api/Cargo.toml | 2 +- client/rpc/Cargo.toml | 2 +- client/service/Cargo.toml | 2 +- client/state-db/Cargo.toml | 2 +- client/telemetry/Cargo.toml | 2 +- client/tracing/Cargo.toml | 2 +- client/transaction-pool/Cargo.toml | 2 +- client/transaction-pool/graph/Cargo.toml | 2 +- frame/aura/Cargo.toml | 2 +- frame/babe/Cargo.toml | 2 +- primitives/blockchain/Cargo.toml | 2 +- primitives/consensus/common/Cargo.toml | 2 +- primitives/core/Cargo.toml | 2 +- primitives/inherents/Cargo.toml | 2 +- primitives/state-machine/Cargo.toml | 2 +- .../runtime/transaction-pool/Cargo.toml | 2 +- utils/grafana-data-source/Cargo.toml | 2 +- 33 files changed, 63 insertions(+), 63 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d9fbff15de..e27589d5f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1896,7 +1896,7 @@ dependencies = [ "hyper 0.13.2", "lazy_static", "log 0.4.8", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "serde", "serde_json", "tokio 0.2.11", @@ -3813,7 +3813,7 @@ dependencies = [ "pallet-session", "pallet-timestamp", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "serde", "sp-application-crypto", "sp-consensus-aura", @@ -3870,7 +3870,7 @@ dependencies = [ "pallet-session", "pallet-timestamp", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "serde", "sp-consensus-babe", "sp-core", @@ -5474,7 +5474,7 @@ dependencies = [ "futures 0.3.1", "log 0.4.8", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "sc-block-builder", "sc-client", "sc-client-api", @@ -5580,7 +5580,7 @@ dependencies = [ "kvdb-memorydb", "log 0.4.8", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "sc-block-builder", "sc-client-api", "sc-executor", @@ -5615,7 +5615,7 @@ dependencies = [ "kvdb", "log 0.4.8", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "sc-executor", "sc-telemetry", "sp-api", @@ -5647,7 +5647,7 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "parity-util-mem 0.4.1", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "quickcheck", "sc-client", "sc-client-api", @@ -5675,7 +5675,7 @@ dependencies = [ "futures-timer 0.4.0", "log 0.4.8", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "sc-client", "sc-client-api", "sc-consensus-slots", @@ -5719,7 +5719,7 @@ dependencies = [ "num-rational", "num-traits", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "pdqselect", "rand 0.7.3", "sc-block-builder", @@ -5808,7 +5808,7 @@ dependencies = [ "futures-timer 2.0.2", "log 0.4.8", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "sc-client-api", "sc-telemetry", "sp-api", @@ -5846,7 +5846,7 @@ dependencies = [ "log 0.4.8", "parity-scale-codec", "parity-wasm 0.41.0", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "sc-executor-common", "sc-executor-wasmi", "sc-executor-wasmtime", @@ -5934,7 +5934,7 @@ dependencies = [ "futures-timer 2.0.2", "log 0.4.8", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "pin-project", "rand 0.7.3", "sc-client", @@ -5968,7 +5968,7 @@ version = "2.0.0" dependencies = [ "derive_more", "hex", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "rand 0.7.3", "serde_json", "sp-application-crypto", @@ -5998,7 +5998,7 @@ dependencies = [ "log 0.4.8", "lru 0.4.3", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "quickcheck", "rand 0.7.3", "rustc-hex", @@ -6037,7 +6037,7 @@ dependencies = [ "libp2p", "log 0.4.8", "lru 0.1.17", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "sc-network", "sp-runtime", ] @@ -6052,7 +6052,7 @@ dependencies = [ "futures-timer 0.4.0", "libp2p", "log 0.4.8", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "rand 0.7.3", "sc-block-builder", "sc-client", @@ -6084,7 +6084,7 @@ dependencies = [ "log 0.4.8", "num_cpus", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "rand 0.7.3", "sc-client-api", "sc-client-db", @@ -6124,7 +6124,7 @@ dependencies = [ "jsonrpc-pubsub", "log 0.4.8", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "rustc-hex", "sc-client", "sc-client-api", @@ -6161,7 +6161,7 @@ dependencies = [ "jsonrpc-pubsub", "log 0.4.8", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "serde", "serde_json", "sp-core", @@ -6212,7 +6212,7 @@ dependencies = [ "log 0.4.8", "parity-multiaddr 0.5.0", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "sc-chain-spec", "sc-client", "sc-client-api", @@ -6276,7 +6276,7 @@ dependencies = [ "env_logger 0.7.1", "log 0.4.8", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "sp-core", ] @@ -6289,7 +6289,7 @@ dependencies = [ "futures-timer 2.0.2", "libp2p", "log 0.4.8", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "pin-project", "rand 0.7.3", "serde", @@ -6307,7 +6307,7 @@ dependencies = [ "erased-serde", "grafana-data-source", "log 0.4.8", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "sc-telemetry", "serde", "serde_json", @@ -6326,7 +6326,7 @@ dependencies = [ "futures 0.3.1", "log 0.4.8", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "serde", "sp-core", "sp-runtime", @@ -6343,7 +6343,7 @@ dependencies = [ "futures-diagnose", "log 0.4.8", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "sc-client-api", "sc-transaction-graph", "sp-api", @@ -6818,7 +6818,7 @@ dependencies = [ "log 0.4.8", "lru 0.4.3", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "sp-block-builder", "sp-consensus", "sp-runtime", @@ -6836,7 +6836,7 @@ dependencies = [ "libp2p", "log 0.4.8", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "serde", "sp-core", "sp-inherents", @@ -6905,7 +6905,7 @@ dependencies = [ "log 0.4.8", "num-traits", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "pretty_assertions", "primitive-types", "rand 0.7.3", @@ -6974,7 +6974,7 @@ version = "2.0.0" dependencies = [ "derive_more", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "sp-core", "sp-std", ] @@ -7165,7 +7165,7 @@ dependencies = [ "log 0.4.8", "num-traits", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "rand 0.7.3", "sp-core", "sp-externalities", @@ -7525,7 +7525,7 @@ dependencies = [ "derive_more", "futures 0.3.1", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "sc-transaction-graph", "sp-runtime", "sp-transaction-pool", diff --git a/client/Cargo.toml b/client/Cargo.toml index 6437d699d1..8560408569 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -21,7 +21,7 @@ sp-inherents = { version = "2.0.0", path = "../primitives/inherents" } sp-keyring = { version = "2.0.0", path = "../primitives/keyring" } kvdb = "0.3.0" log = { version = "0.4.8" } -parking_lot = { version = "0.9.0" } +parking_lot = "0.10.0" 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" } diff --git a/client/api/Cargo.toml b/client/api/Cargo.toml index ac47537e79..4c2867deb3 100644 --- a/client/api/Cargo.toml +++ b/client/api/Cargo.toml @@ -20,7 +20,7 @@ sp-inherents = { version = "2.0.0", default-features = false, path = "../../prim sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } kvdb = "0.3.0" log = { version = "0.4.8" } -parking_lot = { version = "0.9.0" } +parking_lot = "0.10.0" 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" } diff --git a/client/basic-authorship/Cargo.toml b/client/basic-authorship/Cargo.toml index 68bd4d87f2..6a013f7a74 100644 --- a/client/basic-authorship/Cargo.toml +++ b/client/basic-authorship/Cargo.toml @@ -25,4 +25,4 @@ tokio-executor = { version = "0.2.0-alpha.6", features = ["blocking"] } [dev-dependencies] 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" +parking_lot = "0.10.0" diff --git a/client/consensus/aura/Cargo.toml b/client/consensus/aura/Cargo.toml index 4f15a11302..142b10b9da 100644 --- a/client/consensus/aura/Cargo.toml +++ b/client/consensus/aura/Cargo.toml @@ -20,7 +20,7 @@ futures-timer = "0.4.0" 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" +parking_lot = "0.10.0" 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" } diff --git a/client/consensus/babe/Cargo.toml b/client/consensus/babe/Cargo.toml index 124304093f..551754c7b6 100644 --- a/client/consensus/babe/Cargo.toml +++ b/client/consensus/babe/Cargo.toml @@ -32,7 +32,7 @@ sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } fork-tree = { version = "2.0.0", path = "../../../utils/fork-tree" } futures = "0.3.1" futures-timer = "0.4.0" -parking_lot = "0.9.0" +parking_lot = "0.10.0" log = "0.4.8" schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated"] } rand = "0.7.2" diff --git a/client/consensus/manual-seal/Cargo.toml b/client/consensus/manual-seal/Cargo.toml index de601b4ab3..71c1f6e558 100644 --- a/client/consensus/manual-seal/Cargo.toml +++ b/client/consensus/manual-seal/Cargo.toml @@ -13,7 +13,7 @@ jsonrpc-core = "14.0.5" jsonrpc-core-client = "14.0.5" jsonrpc-derive = "14.0.5" log = "0.4.8" -parking_lot = "0.10" +parking_lot = "0.10.0" serde = { version = "1.0", features=["derive"] } sc-client = { path = "../../../client" } diff --git a/client/consensus/slots/Cargo.toml b/client/consensus/slots/Cargo.toml index d9b55bb07d..d500a0fdc7 100644 --- a/client/consensus/slots/Cargo.toml +++ b/client/consensus/slots/Cargo.toml @@ -20,7 +20,7 @@ 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" +parking_lot = "0.10.0" log = "0.4.8" [dev-dependencies] diff --git a/client/db/Cargo.toml b/client/db/Cargo.toml index ae6445c8d3..ebb9986ef0 100644 --- a/client/db/Cargo.toml +++ b/client/db/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "GPL-3.0" [dependencies] -parking_lot = "0.9.0" +parking_lot = "0.10.0" log = "0.4.8" kvdb = "0.3.0" kvdb-rocksdb = { version = "0.4", optional = true } diff --git a/client/executor/Cargo.toml b/client/executor/Cargo.toml index 21fd00ba90..c8774470fe 100644 --- a/client/executor/Cargo.toml +++ b/client/executor/Cargo.toml @@ -23,7 +23,7 @@ sp-externalities = { version = "0.8.0", path = "../../primitives/externalities" sc-executor-common = { version = "0.8", path = "common" } sc-executor-wasmi = { version = "0.8", path = "wasmi" } sc-executor-wasmtime = { version = "0.8", path = "wasmtime", optional = true } -parking_lot = "0.9.0" +parking_lot = "0.10.0" log = "0.4.8" libsecp256k1 = "0.3.4" diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index 68efa2e644..7c427dfd5c 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -10,7 +10,7 @@ fork-tree = { version = "2.0.0", path = "../../utils/fork-tree" } futures = "0.3.1" futures-timer = "2.0.2" log = "0.4.8" -parking_lot = "0.9.0" +parking_lot = "0.10.0" rand = "0.7.2" assert_matches = "1.3.0" parity-scale-codec = { version = "1.0.0", features = ["derive"] } diff --git a/client/keystore/Cargo.toml b/client/keystore/Cargo.toml index b4dde77e7d..89ab787cb4 100644 --- a/client/keystore/Cargo.toml +++ b/client/keystore/Cargo.toml @@ -13,7 +13,7 @@ hex = "0.4.0" rand = "0.7.2" serde_json = "1.0.41" subtle = "2.1.1" -parking_lot = "0.9.0" +parking_lot = "0.10.0" [dev-dependencies] tempfile = "3.1.0" diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index ca86af7df4..22f22b4856 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -13,6 +13,6 @@ futures01 = { package = "futures", version = "0.1.29" } futures-timer = "0.4.0" libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] } lru = "0.1.2" -parking_lot = "0.9.0" +parking_lot = "0.10.0" sc-network = { version = "0.8", path = "../network" } sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index f20ce36a27..e506a61c75 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -23,7 +23,7 @@ linked-hash-map = "0.5.2" linked_hash_set = "0.1.3" log = "0.4.8" lru = "0.4.0" -parking_lot = "0.9.0" +parking_lot = "0.10.0" rand = "0.7.2" rustc-hex = "2.0.1" sc-block-builder = { version = "0.8", path = "../block-builder" } diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index 19590c2651..3f1d1d5867 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -9,7 +9,7 @@ edition = "2018" [dependencies] sc-network = { version = "0.8", path = "../" } log = "0.4.8" -parking_lot = "0.9.0" +parking_lot = "0.10.0" futures = "0.1.29" futures03 = { package = "futures", version = "0.3.1", features = ["compat"] } futures-timer = "0.4.0" diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index 3ef98f1ab9..bdbf3fa199 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -19,7 +19,7 @@ threadpool = "1.7" num_cpus = "1.10" 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" +parking_lot = "0.10.0" sp-core = { version = "2.0.0", path = "../../primitives/core" } rand = "0.7.2" sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } diff --git a/client/rpc-api/Cargo.toml b/client/rpc-api/Cargo.toml index 1f52f41508..4781c9d350 100644 --- a/client/rpc-api/Cargo.toml +++ b/client/rpc-api/Cargo.toml @@ -14,7 +14,7 @@ jsonrpc-core-client = "14.0.3" jsonrpc-derive = "14.0.3" jsonrpc-pubsub = "14.0.3" log = "0.4.8" -parking_lot = "0.9.0" +parking_lot = "0.10.0" 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"] } diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index a8cbc5c536..d09617ebc1 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -28,7 +28,7 @@ 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" } +parking_lot = "0.10.0" [dev-dependencies] assert_matches = "1.3.0" diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 36213993e3..8e81cce4ee 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -19,7 +19,7 @@ derive_more = "0.99.2" futures01 = { package = "futures", version = "0.1.29" } futures = "0.3.1" futures-diagnose = "1.0" -parking_lot = "0.9.0" +parking_lot = "0.10.0" lazy_static = "1.4.0" log = "0.4.8" slog = { version = "2.5.2", features = ["nested-values"] } diff --git a/client/state-db/Cargo.toml b/client/state-db/Cargo.toml index 3d3eca9d5e..1bfa136937 100644 --- a/client/state-db/Cargo.toml +++ b/client/state-db/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "GPL-3.0" [dependencies] -parking_lot = "0.9.0" +parking_lot = "0.10.0" log = "0.4.8" sp-core = { version = "2.0.0", path = "../../primitives/core" } codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index 5127712e12..44e332b9d7 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -8,7 +8,7 @@ license = "GPL-3.0" [dependencies] bytes = "0.5" -parking_lot = "0.9.0" +parking_lot = "0.10.0" futures = "0.3.1" futures-timer = "2.0.0" libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] } diff --git a/client/tracing/Cargo.toml b/client/tracing/Cargo.toml index 2268c5719f..b476db6a01 100644 --- a/client/tracing/Cargo.toml +++ b/client/tracing/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" [dependencies] erased-serde = "0.3.9" log = { version = "0.4.8" } -parking_lot = "0.9.0" +parking_lot = "0.10.0" serde = "1.0.101" serde_json = "1.0.41" slog = { version = "2.5.2", features = ["nested-values"] } diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index e151e9adbe..1387d1df27 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -11,7 +11,7 @@ derive_more = "0.99.2" futures = { version = "0.3.1", features = ["compat"] } futures-diagnose = "1.0" log = "0.4.8" -parking_lot = "0.9.0" +parking_lot = "0.10.0" 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" } diff --git a/client/transaction-pool/graph/Cargo.toml b/client/transaction-pool/graph/Cargo.toml index 3b0adf5cb1..4f12ab7fcc 100644 --- a/client/transaction-pool/graph/Cargo.toml +++ b/client/transaction-pool/graph/Cargo.toml @@ -9,7 +9,7 @@ license = "GPL-3.0" derive_more = "0.99.2" futures = "0.3.1" log = "0.4.8" -parking_lot = "0.9.0" +parking_lot = "0.10.0" serde = { version = "1.0.101", features = ["derive"] } sp-core = { version = "2.0.0", path = "../../../primitives/core" } sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } diff --git a/frame/aura/Cargo.toml b/frame/aura/Cargo.toml index 8eb91016ff..e982a02b47 100644 --- a/frame/aura/Cargo.toml +++ b/frame/aura/Cargo.toml @@ -24,7 +24,7 @@ pallet-timestamp = { version = "2.0.0", default-features = false, path = "../tim [dev-dependencies] lazy_static = "1.4.0" -parking_lot = "0.9.0" +parking_lot = "0.10.0" [features] default = ["std"] diff --git a/frame/babe/Cargo.toml b/frame/babe/Cargo.toml index 590c1fe5bd..5e7764862a 100644 --- a/frame/babe/Cargo.toml +++ b/frame/babe/Cargo.toml @@ -23,7 +23,7 @@ sp-io ={ path = "../../primitives/io", default-features = false } [dev-dependencies] lazy_static = "1.4.0" -parking_lot = "0.9.0" +parking_lot = "0.10.0" 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" } diff --git a/primitives/blockchain/Cargo.toml b/primitives/blockchain/Cargo.toml index cd8ee78394..8b93436f9a 100644 --- a/primitives/blockchain/Cargo.toml +++ b/primitives/blockchain/Cargo.toml @@ -8,7 +8,7 @@ license = "GPL-3.0" [dependencies] log = "0.4.8" lru = "0.4.0" -parking_lot = "0.9.0" +parking_lot = "0.10.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" } diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index 3ac89ec70c..1b5c54b7e9 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -20,7 +20,7 @@ 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" +parking_lot = "0.10.0" serde = { version = "1.0", features = ["derive"] } [dev-dependencies] diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 0cc7498184..873d607ecd 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -25,7 +25,7 @@ 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 } +parking_lot = { version = "0.10.0", optional = true } sp-debug-derive = { version = "2.0.0", path = "../debug-derive" } sp-externalities = { version = "0.8.0", optional = true, path = "../externalities" } sp-storage = { version = "2.0.0", default-features = false, path = "../storage" } diff --git a/primitives/inherents/Cargo.toml b/primitives/inherents/Cargo.toml index 18fa8412f3..698ab5389a 100644 --- a/primitives/inherents/Cargo.toml +++ b/primitives/inherents/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "GPL-3.0" [dependencies] -parking_lot = { version = "0.9.0", optional = true } +parking_lot = { version = "0.10.0", optional = true } 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"] } diff --git a/primitives/state-machine/Cargo.toml b/primitives/state-machine/Cargo.toml index a856146667..3752e95695 100644 --- a/primitives/state-machine/Cargo.toml +++ b/primitives/state-machine/Cargo.toml @@ -8,7 +8,7 @@ license = "GPL-3.0" [dependencies] log = "0.4.8" -parking_lot = "0.9.0" +parking_lot = "0.10.0" hash-db = "0.15.2" trie-db = "0.19.2" trie-root = "0.15.2" diff --git a/test-utils/runtime/transaction-pool/Cargo.toml b/test-utils/runtime/transaction-pool/Cargo.toml index c10a34f938..615886d987 100644 --- a/test-utils/runtime/transaction-pool/Cargo.toml +++ b/test-utils/runtime/transaction-pool/Cargo.toml @@ -7,7 +7,7 @@ license = "GPL-3.0" [dependencies] substrate-test-runtime-client = { version = "2.0.0", path = "../client" } -parking_lot = "0.9.0" +parking_lot = "0.10.0" codec = { package = "parity-scale-codec", version = "1.0.0" } sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } sp-transaction-pool = { version = "2.0.0", path = "../../../primitives/transaction-pool" } diff --git a/utils/grafana-data-source/Cargo.toml b/utils/grafana-data-source/Cargo.toml index 4487b5359f..ab4251ef57 100644 --- a/utils/grafana-data-source/Cargo.toml +++ b/utils/grafana-data-source/Cargo.toml @@ -15,7 +15,7 @@ serde_json = "1" serde = { version = "1", features = ["derive"] } chrono = { version = "0.4", features = ["serde"] } lazy_static = "1.4" -parking_lot = "0.9" +parking_lot = "0.10.0" futures-timer = "2.0" derive_more = "0.99" -- GitLab From efd27a538e6be0f0f077a81442c8f0547acee918 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Tue, 4 Feb 2020 16:58:23 +0100 Subject: [PATCH 080/180] pallet-evm: log created address (#4821) * pallet-evm: log created address * Bump spec_version * Only emit Created event when ExitReason is Succeed --- Cargo.lock | 6 +++--- bin/node/runtime/src/lib.rs | 2 +- frame/evm/src/lib.rs | 8 +++++++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e27589d5f6..ed97668987 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1229,9 +1229,9 @@ dependencies = [ [[package]] name = "evm" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a2c6961fdc9952371fc5f0416f03a9d90378a9dfb6862f6a7a9a3b8986b8dd" +checksum = "73f887b371f9999682ccc5b1cb771e7d4408ae61e93fc0343ceaeb761fca42d1" dependencies = [ "evm-core", "evm-gasometer", @@ -8190,7 +8190,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" dependencies = [ - "rand 0.7.3", + "rand 0.3.23", ] [[package]] diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index f2c374cedd..65e09e99d2 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -79,7 +79,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 212, + spec_version: 213, impl_version: 0, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index 9c79274b4a..edd3d46a9a 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -174,6 +174,8 @@ decl_event! { pub enum Event { /// Ethereum events from contracts. Log(Log), + /// A contract has been created at given address. + Created(H160), } } @@ -343,6 +345,7 @@ decl_module! { } executor.withdraw(source, total_fee).map_err(|_| Error::::WithdrawFailed)?; + let create_address = executor.create_address(source, evm::CreateScheme::Dynamic); let reason = executor.transact_create( source, value, @@ -351,7 +354,10 @@ decl_module! { ); let ret = match reason { - ExitReason::Succeed(_) => Ok(()), + ExitReason::Succeed(_) => { + Module::::deposit_event(Event::Created(create_address)); + Ok(()) + }, ExitReason::Error(_) => Err(Error::::ExitReasonFailed), ExitReason::Revert(_) => Err(Error::::ExitReasonRevert), ExitReason::Fatal(_) => Err(Error::::ExitReasonFatal), -- GitLab From 7b22fbfc6ba567af8ac0a693ef6593e179f46a53 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 5 Feb 2020 11:56:59 +0100 Subject: [PATCH 081/180] Fix missing overrides of NetworkBehaviour (#4829) --- client/network/src/debug_info.rs | 12 ++++++++ client/network/src/discovery.rs | 29 ++++++++++++++++++- client/network/src/protocol.rs | 10 ++++++- .../src/protocol/legacy_proto/tests.rs | 12 ++++++-- 4 files changed, 59 insertions(+), 4 deletions(-) diff --git a/client/network/src/debug_info.rs b/client/network/src/debug_info.rs index 9cc39baae6..b06e275d1d 100644 --- a/client/network/src/debug_info.rs +++ b/client/network/src/debug_info.rs @@ -17,12 +17,14 @@ use fnv::FnvHashMap; use futures::prelude::*; use libp2p::Multiaddr; +use libp2p::core::nodes::listeners::ListenerId; use libp2p::core::{ConnectedPoint, either::EitherOutput, PeerId, PublicKey}; use libp2p::swarm::{IntoProtocolsHandler, IntoProtocolsHandlerSelect, ProtocolsHandler}; use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use libp2p::identify::{Identify, IdentifyEvent, IdentifyInfo}; use libp2p::ping::{Ping, PingConfig, PingEvent, PingSuccess}; use log::{debug, trace, error}; +use std::error; use std::collections::hash_map::Entry; use std::pin::Pin; use std::task::{Context, Poll}; @@ -251,6 +253,16 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin + Send + 'static { self.identify.inject_new_external_addr(addr); } + fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn error::Error + 'static)) { + self.ping.inject_listener_error(id, err); + self.identify.inject_listener_error(id, err); + } + + fn inject_listener_closed(&mut self, id: ListenerId) { + self.ping.inject_listener_closed(id); + self.identify.inject_listener_closed(id); + } + fn poll( &mut self, cx: &mut Context, diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index 531e769cce..ab5ab0a1f4 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -47,7 +47,7 @@ use futures::prelude::*; use futures_timer::Delay; -use libp2p::core::{ConnectedPoint, Multiaddr, PeerId, PublicKey}; +use libp2p::core::{nodes::listeners::ListenerId, ConnectedPoint, Multiaddr, PeerId, PublicKey}; use libp2p::swarm::{ProtocolsHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use libp2p::kad::{Kademlia, KademliaEvent, Quorum, Record}; use libp2p::kad::GetClosestPeersError; @@ -266,6 +266,15 @@ where NetworkBehaviour::inject_replaced(&mut self.kademlia, peer_id, closed, opened) } + fn inject_addr_reach_failure( + &mut self, + peer_id: Option<&PeerId>, + addr: &Multiaddr, + error: &dyn std::error::Error + ) { + NetworkBehaviour::inject_addr_reach_failure(&mut self.kademlia, peer_id, addr, error) + } + fn inject_node_event( &mut self, peer_id: PeerId, @@ -278,10 +287,28 @@ where let new_addr = addr.clone() .with(Protocol::P2p(self.local_peer_id.clone().into())); info!(target: "sub-libp2p", "Discovered new external address for our node: {}", new_addr); + NetworkBehaviour::inject_new_external_addr(&mut self.kademlia, addr) } fn inject_expired_listen_addr(&mut self, addr: &Multiaddr) { info!(target: "sub-libp2p", "No longer listening on {}", addr); + NetworkBehaviour::inject_expired_listen_addr(&mut self.kademlia, addr) + } + + fn inject_dial_failure(&mut self, peer_id: &PeerId) { + NetworkBehaviour::inject_dial_failure(&mut self.kademlia, peer_id) + } + + fn inject_new_listen_addr(&mut self, addr: &Multiaddr) { + NetworkBehaviour::inject_new_listen_addr(&mut self.kademlia, addr) + } + + fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) { + NetworkBehaviour::inject_listener_error(&mut self.kademlia, id, err); + } + + fn inject_listener_closed(&mut self, id: ListenerId) { + NetworkBehaviour::inject_listener_closed(&mut self.kademlia, id); } fn poll( diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 2df8f6597c..5e8df2831b 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -20,7 +20,7 @@ use crate::utils::interval; use bytes::{Bytes, BytesMut}; use futures::prelude::*; use libp2p::{Multiaddr, PeerId}; -use libp2p::core::{ConnectedPoint, nodes::Substream, muxing::StreamMuxerBox}; +use libp2p::core::{ConnectedPoint, nodes::{listeners::ListenerId, Substream}, muxing::StreamMuxerBox}; use libp2p::swarm::{ProtocolsHandler, IntoProtocolsHandler}; use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use sp_core::storage::{StorageKey, ChildInfo}; @@ -2004,6 +2004,14 @@ Protocol { fn inject_new_external_addr(&mut self, addr: &Multiaddr) { self.behaviour.inject_new_external_addr(addr) } + + fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) { + self.behaviour.inject_listener_error(id, err); + } + + fn inject_listener_closed(&mut self, id: ListenerId) { + self.behaviour.inject_listener_closed(id); + } } impl, H: ExHashT> DiscoveryNetBehaviour for Protocol { diff --git a/client/network/src/protocol/legacy_proto/tests.rs b/client/network/src/protocol/legacy_proto/tests.rs index 6a2174f30c..18e32f1d01 100644 --- a/client/network/src/protocol/legacy_proto/tests.rs +++ b/client/network/src/protocol/legacy_proto/tests.rs @@ -18,13 +18,13 @@ use futures::{prelude::*, ready}; use codec::{Encode, Decode}; -use libp2p::core::nodes::Substream; +use libp2p::core::nodes::{Substream, listeners::ListenerId}; use libp2p::core::{ConnectedPoint, transport::boxed::Boxed, muxing::StreamMuxerBox}; use libp2p::swarm::{Swarm, ProtocolsHandler, IntoProtocolsHandler}; use libp2p::swarm::{PollParameters, NetworkBehaviour, NetworkBehaviourAction}; use libp2p::{PeerId, Multiaddr, Transport}; use rand::seq::SliceRandom; -use std::{io, task::Context, task::Poll, time::Duration}; +use std::{error, io, task::Context, task::Poll, time::Duration}; use crate::message::Message; use crate::protocol::legacy_proto::{LegacyProto, LegacyProtoOut}; use sp_test_primitives::Block; @@ -204,6 +204,14 @@ impl NetworkBehaviour for CustomProtoWithAddr { fn inject_new_external_addr(&mut self, addr: &Multiaddr) { self.inner.inject_new_external_addr(addr) } + + fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn error::Error + 'static)) { + self.inner.inject_listener_error(id, err); + } + + fn inject_listener_closed(&mut self, id: ListenerId) { + self.inner.inject_listener_closed(id); + } } #[test] -- GitLab From eefb472c33f8acb1852e90526af46f2ac878c155 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 5 Feb 2020 16:56:49 +0100 Subject: [PATCH 082/180] Remove support for secio (#4831) --- client/network/src/transport.rs | 36 +++++++++++++-------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/client/network/src/transport.rs b/client/network/src/transport.rs index d632f9b75c..b11b187051 100644 --- a/client/network/src/transport.rs +++ b/client/network/src/transport.rs @@ -17,12 +17,10 @@ use futures::prelude::*; use libp2p::{ InboundUpgradeExt, OutboundUpgradeExt, PeerId, Transport, - mplex, identity, secio, yamux, bandwidth, wasm_ext + mplex, identity, yamux, bandwidth, wasm_ext }; #[cfg(not(target_os = "unknown"))] use libp2p::{tcp, dns, websocket, noise}; -#[cfg(not(target_os = "unknown"))] -use libp2p::core::{either::EitherError, either::EitherOutput}; use libp2p::core::{self, upgrade, transport::boxed::Boxed, transport::OptionalTransport, muxing::StreamMuxerBox}; use std::{io, sync::Arc, time::Duration, usize}; @@ -52,7 +50,6 @@ pub fn build_transport( rare panic here is basically zero"); noise::NoiseConfig::ix(noise_keypair) }; - let secio_config = secio::SecioConfig::new(keypair); // Build configuration objects for multiplexing mechanisms. let mut mplex_config = mplex::MplexConfig::new(); @@ -93,28 +90,23 @@ pub fn build_transport( // For non-WASM, we support both secio and noise. #[cfg(not(target_os = "unknown"))] let transport = transport.and_then(move |stream, endpoint| { - let upgrade = core::upgrade::SelectUpgrade::new(noise_config, secio_config); - core::upgrade::apply(stream, upgrade, endpoint, upgrade::Version::V1) - .map(|out| match out? { - // We negotiated noise - EitherOutput::First((remote_id, out)) => { - let remote_key = match remote_id { - noise::RemoteIdentity::IdentityKey(key) => key, - _ => return Err(upgrade::UpgradeError::Apply(EitherError::A(noise::NoiseError::InvalidKey))) - }; - Ok((EitherOutput::First(out), remote_key.into_peer_id())) - } - // We negotiated secio - EitherOutput::Second((remote_id, out)) => - Ok((EitherOutput::Second(out), remote_id)) + core::upgrade::apply(stream, noise_config, endpoint, upgrade::Version::V1) + .and_then(|(remote_id, out)| async move { + let remote_key = match remote_id { + noise::RemoteIdentity::IdentityKey(key) => key, + _ => return Err(upgrade::UpgradeError::Apply(noise::NoiseError::InvalidKey)) + }; + Ok((out, remote_key.into_peer_id())) }) }); - // For WASM, we only support secio for now. + // We refuse all WASM connections for now. It is intended that we negotiate noise in the + // future. See https://github.com/libp2p/rust-libp2p/issues/1414 #[cfg(target_os = "unknown")] - let transport = transport.and_then(move |stream, endpoint| { - core::upgrade::apply(stream, secio_config, endpoint, upgrade::Version::V1) - .map_ok(|(id, stream)| ((stream, id))) + let transport = transport.and_then(move |_, _| async move { + let r: Result<(wasm_ext::Connection, PeerId), _> = + Err(io::Error::new(io::ErrorKind::Other, format!("No encryption protocol supported"))); + r }); // Multiplexing -- GitLab From b9ee3dfeca8b4d105111564238ec2943c2130adc Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 5 Feb 2020 17:25:14 +0100 Subject: [PATCH 083/180] Print an error if listener is closed (#4830) * Print an error if listener is closed * Oops, forgot to commit this --- client/network/src/discovery.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index ab5ab0a1f4..de49913b26 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -59,7 +59,7 @@ use libp2p::core::{nodes::Substream, muxing::StreamMuxerBox}; #[cfg(not(target_os = "unknown"))] use libp2p::mdns::{Mdns, MdnsEvent}; use libp2p::multiaddr::Protocol; -use log::{debug, info, trace, warn}; +use log::{debug, info, trace, warn, error}; use std::{cmp, collections::VecDeque, time::Duration}; use std::task::{Context, Poll}; use sp_core::hexdisplay::HexDisplay; @@ -304,10 +304,12 @@ where } fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) { + error!(target: "sub-libp2p", "Error on libp2p listener {:?}: {}", id, err); NetworkBehaviour::inject_listener_error(&mut self.kademlia, id, err); } fn inject_listener_closed(&mut self, id: ListenerId) { + error!(target: "sub-libp2p", "Libp2p listener {:?} closed", id); NetworkBehaviour::inject_listener_closed(&mut self.kademlia, id); } -- GitLab From 584ac4f8d925387efcbf5af805f06173e42c338d Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Wed, 5 Feb 2020 17:26:07 +0100 Subject: [PATCH 084/180] Avoid losing values in intermediate take (#4833) --- primitives/consensus/common/src/block_import.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/primitives/consensus/common/src/block_import.rs b/primitives/consensus/common/src/block_import.rs index 952a044e9b..dabe6331e8 100644 --- a/primitives/consensus/common/src/block_import.rs +++ b/primitives/consensus/common/src/block_import.rs @@ -228,15 +228,14 @@ impl BlockImportParams { /// Take interemdiate by given key, and remove it from the processing list. pub fn take_intermediate(&mut self, key: &[u8]) -> Result, Error> { - if self.intermediates.contains_key(key) { - self.intermediates.remove(key) - .ok_or(Error::NoIntermediate) - .and_then(|value| { - value.downcast::() - .map_err(|_| Error::InvalidIntermediate) - }) - } else { - Err(Error::NoIntermediate) + let (k, v) = self.intermediates.remove_entry(key).ok_or(Error::NoIntermediate)?; + + match v.downcast::() { + Ok(v) => Ok(v), + Err(v) => { + self.intermediates.insert(k, v); + Err(Error::InvalidIntermediate) + }, } } -- GitLab From 4e0e8c179faaad362e3013024c70abda6493fa1b Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Wed, 5 Feb 2020 17:26:48 +0100 Subject: [PATCH 085/180] Get rid of in-substrate usages of `core_intrinsics` feature (#4823) * Remove usage of unneeded Rust feature core_intrinsics * core::intrinsics::abort -> arch::wasm32::unreachable * Don't publish `core::intrinsics`. * Disable panic_handler and alloc_error_handler for no_std non wasm builds --- primitives/application-crypto/Cargo.toml | 6 +++++- primitives/io/src/lib.rs | 5 ++--- primitives/sandbox/src/lib.rs | 1 - primitives/std/src/lib.rs | 2 +- primitives/std/without_std.rs | 1 - 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/primitives/application-crypto/Cargo.toml b/primitives/application-crypto/Cargo.toml index 9377bcff8a..1fa9a6631c 100644 --- a/primitives/application-crypto/Cargo.toml +++ b/primitives/application-crypto/Cargo.toml @@ -21,5 +21,9 @@ std = [ "full_crypto", "sp-core/std", "codec/std", "serde", "sp-std/std", "sp-io # or Intel SGX. # For the regular wasm runtime builds this should not be used. full_crypto = [ - "sp-core/full_crypto" + "sp-core/full_crypto", + # Don't add `panic_handler` and `alloc_error_handler` since they are expected to be provided + # by the user anyway. + "sp-io/disable_panic_handler", + "sp-io/disable_oom", ] diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index dce67133d3..1b531725fe 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -20,7 +20,6 @@ #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), feature(alloc_error_handler))] -#![cfg_attr(not(feature = "std"), feature(core_intrinsics))] #![cfg_attr(feature = "std", doc = "Substrate runtime standard library as compiled when linked with Rust's standard library.")] @@ -892,7 +891,7 @@ pub fn panic(info: &core::panic::PanicInfo) -> ! { unsafe { let message = sp_std::alloc::format!("{}", info); logging::log(LogLevel::Error, "runtime", message.as_bytes()); - core::intrinsics::abort() + core::arch::wasm32::unreachable(); } } @@ -902,7 +901,7 @@ pub fn panic(info: &core::panic::PanicInfo) -> ! { pub fn oom(_: core::alloc::Layout) -> ! { unsafe { logging::log(LogLevel::Error, "runtime", b"Runtime memory exhausted. Aborting"); - core::intrinsics::abort(); + core::arch::wasm32::unreachable(); } } diff --git a/primitives/sandbox/src/lib.rs b/primitives/sandbox/src/lib.rs index 17712ad365..e7cd684b45 100755 --- a/primitives/sandbox/src/lib.rs +++ b/primitives/sandbox/src/lib.rs @@ -36,7 +36,6 @@ #![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(not(feature = "std"), feature(core_intrinsics))] use sp_std::prelude::*; diff --git a/primitives/std/src/lib.rs b/primitives/std/src/lib.rs index 3fcf5daeb4..856b095403 100644 --- a/primitives/std/src/lib.rs +++ b/primitives/std/src/lib.rs @@ -18,7 +18,7 @@ //! or client/alloc to be used with any code that depends on the runtime. #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(not(feature = "std"), feature(core_intrinsics))] + #![cfg_attr(feature = "std", doc = "Substrate runtime standard library as compiled when linked with Rust's standard library.")] diff --git a/primitives/std/without_std.rs b/primitives/std/without_std.rs index ad587531dd..4424ca0e7d 100755 --- a/primitives/std/without_std.rs +++ b/primitives/std/without_std.rs @@ -27,7 +27,6 @@ pub use core::convert; pub use core::default; pub use core::fmt; pub use core::hash; -pub use core::intrinsics; pub use core::iter; pub use core::marker; pub use core::mem; -- GitLab From 53008ba412c54f534e6033d9055ea1f403dcfe34 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Wed, 5 Feb 2020 17:27:50 +0100 Subject: [PATCH 086/180] Additional RPC for dumping all main storage key pairs under a prefix (#4803) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Merge branch 'gav-split-balanecs-vesting' into gav-upsub # Conflicts: # Cargo.lock # cli/Cargo.toml # collator/Cargo.toml # primitives/Cargo.toml # runtime/common/Cargo.toml # runtime/common/src/claims.rs # runtime/kusama/Cargo.toml # runtime/polkadot/Cargo.toml # service/Cargo.toml * Update client/src/client.rs * Update client/src/client.rs * Fix merge conflict Co-authored-by: Bastian Köcher --- client/rpc-api/src/state/mod.rs | 4 ++++ client/rpc/src/state/mod.rs | 15 +++++++++++++++ client/rpc/src/state/state_full.rs | 11 +++++++++++ client/rpc/src/state/state_light.rs | 8 ++++++++ client/src/client.rs | 23 +++++++++++++++++++++-- 5 files changed, 59 insertions(+), 2 deletions(-) diff --git a/client/rpc-api/src/state/mod.rs b/client/rpc-api/src/state/mod.rs index 6901738efe..b2cf8ce909 100644 --- a/client/rpc-api/src/state/mod.rs +++ b/client/rpc-api/src/state/mod.rs @@ -44,6 +44,10 @@ pub trait StateApi { #[rpc(name = "state_getKeys")] fn storage_keys(&self, prefix: StorageKey, hash: Option) -> FutureResult>; + /// Returns the keys with prefix, leave empty to get all the keys + #[rpc(name = "state_getPairs")] + fn storage_pairs(&self, prefix: StorageKey, hash: Option) -> FutureResult>; + /// Returns the keys with prefix with pagination support. /// Up to `count` keys will be returned. /// If `start_key` is passed, return next keys in storage in lexicographic order. diff --git a/client/rpc/src/state/mod.rs b/client/rpc/src/state/mod.rs index df26daa929..8f621cc8af 100644 --- a/client/rpc/src/state/mod.rs +++ b/client/rpc/src/state/mod.rs @@ -63,6 +63,13 @@ pub trait StateBackend: Send + Sync + 'static prefix: StorageKey, ) -> FutureResult>; + /// Returns the keys with prefix along with their values, leave empty to get all the pairs. + fn storage_pairs( + &self, + block: Option, + prefix: StorageKey, + ) -> FutureResult>; + /// Returns the keys with prefix with pagination support. fn storage_keys_paged( &self, @@ -255,6 +262,14 @@ impl StateApi for State self.backend.storage_keys(block, key_prefix) } + fn storage_pairs( + &self, + key_prefix: StorageKey, + block: Option, + ) -> FutureResult> { + self.backend.storage_pairs(block, key_prefix) + } + fn storage_keys_paged( &self, prefix: Option, diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index 87c75e77a6..3d5613626e 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -254,6 +254,17 @@ impl StateBackend for FullState, + prefix: StorageKey, + ) -> FutureResult> { + Box::new(result( + self.block_or_best(block) + .and_then(|block| self.client.storage_pairs(&BlockId::Hash(block), &prefix)) + .map_err(client_err))) + } + fn storage_keys_paged( &self, block: Option, diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index f25d6e2186..7b2455a8fc 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -199,6 +199,14 @@ impl StateBackend for LightState, + _prefix: StorageKey, + ) -> FutureResult> { + Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient)))) + } + fn storage_keys_paged( &self, _block: Option, diff --git a/client/src/client.rs b/client/src/client.rs index ca8b0c5dd7..9e30c7b2ea 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -280,6 +280,22 @@ impl Client where Ok(keys) } + /// Given a `BlockId` and a key prefix, return the matching child storage keys and values in that block. + pub fn storage_pairs(&self, id: &BlockId, key_prefix: &StorageKey) + -> sp_blockchain::Result> + { + let state = self.state_at(id)?; + let keys = state + .keys(&key_prefix.0) + .into_iter() + .map(|k| { + let d = state.storage(&k).ok().flatten().unwrap_or_default(); + (StorageKey(k), StorageData(d)) + }) + .collect(); + Ok(keys) + } + /// Given a `BlockId` and a key prefix, return a `KeyIterator` iterates matching storage keys in that block. pub fn storage_keys_iter<'a>( &self, @@ -296,7 +312,9 @@ impl Client where } /// Given a `BlockId` and a key, return the value under the key in that block. - pub fn storage(&self, id: &BlockId, key: &StorageKey) -> sp_blockchain::Result> { + pub fn storage(&self, id: &BlockId, key: &StorageKey) + -> sp_blockchain::Result> + { Ok(self.state_at(id)? .storage(&key.0).map_err(|e| sp_blockchain::Error::from_state(Box::new(e)))? .map(StorageData) @@ -305,7 +323,8 @@ impl Client where /// Given a `BlockId` and a key, return the value under the hash in that block. pub fn storage_hash(&self, id: &BlockId, key: &StorageKey) - -> sp_blockchain::Result> { + -> sp_blockchain::Result> + { Ok(self.state_at(id)? .storage_hash(&key.0).map_err(|e| sp_blockchain::Error::from_state(Box::new(e)))? ) -- GitLab From 7019e30466feb4fc09d28a5e9e13afd54de54f93 Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Wed, 5 Feb 2020 18:20:25 +0100 Subject: [PATCH 087/180] executor: Simplify the SandboxCapabilities interface (#4825) * Don't require `store` and `store_mut` in `SandboxCapabilities`. * Simplify the sandbox a bit --- client/executor/common/src/sandbox.rs | 123 +++++++++--------- client/executor/wasmi/src/lib.rs | 34 ++--- .../wasmtime/src/function_executor.rs | 35 ++--- 3 files changed, 81 insertions(+), 111 deletions(-) diff --git a/client/executor/common/src/sandbox.rs b/client/executor/common/src/sandbox.rs index 89285a75fc..f920a47ca7 100644 --- a/client/executor/common/src/sandbox.rs +++ b/client/executor/common/src/sandbox.rs @@ -27,7 +27,7 @@ use wasmi::{ Externals, ImportResolver, MemoryInstance, MemoryRef, Module, ModuleInstance, ModuleRef, RuntimeArgs, RuntimeValue, Trap, TrapKind, memory_units::Pages, }; -use sp_wasm_interface::{Pointer, WordSize}; +use sp_wasm_interface::{FunctionContext, Pointer, WordSize}; /// Index of a function inside the supervisor. /// @@ -144,48 +144,10 @@ impl ImportResolver for Imports { /// This trait encapsulates sandboxing capabilities. /// /// Note that this functions are only called in the `supervisor` context. -pub trait SandboxCapabilities { +pub trait SandboxCapabilities: FunctionContext { /// Represents a function reference into the supervisor environment. type SupervisorFuncRef; - /// Returns a reference to an associated sandbox `Store`. - fn store(&self) -> &Store; - - /// Returns a mutable reference to an associated sandbox `Store`. - fn store_mut(&mut self) -> &mut Store; - - /// Allocate space of the specified length in the supervisor memory. - /// - /// # Errors - /// - /// Returns `Err` if allocation not possible or errors during heap management. - /// - /// Returns pointer to the allocated block. - fn allocate(&mut self, len: WordSize) -> Result>; - - /// Deallocate space specified by the pointer that was previously returned by [`allocate`]. - /// - /// # Errors - /// - /// Returns `Err` if deallocation not possible or because of errors in heap management. - /// - /// [`allocate`]: #tymethod.allocate - fn deallocate(&mut self, ptr: Pointer) -> Result<()>; - - /// Write `data` into the supervisor memory at offset specified by `ptr`. - /// - /// # Errors - /// - /// Returns `Err` if `ptr + data.len()` is out of bounds. - fn write_memory(&mut self, ptr: Pointer, data: &[u8]) -> Result<()>; - - /// Read `len` bytes from the supervisor memory. - /// - /// # Errors - /// - /// Returns `Err` if `ptr + len` is out of bounds. - fn read_memory(&self, ptr: Pointer, len: WordSize) -> Result>; - /// Invoke a function in the supervisor environment. /// /// This first invokes the dispatch_thunk function, passing in the function index of the @@ -270,8 +232,14 @@ impl<'a, FE: SandboxCapabilities + 'a> Externals for GuestExternals<'a, FE> { // Move serialized arguments inside the memory and invoke dispatch thunk and // then free allocated memory. let invoke_args_len = invoke_args_data.len() as WordSize; - let invoke_args_ptr = self.supervisor_externals.allocate(invoke_args_len)?; - self.supervisor_externals.write_memory(invoke_args_ptr, &invoke_args_data)?; + let invoke_args_ptr = self + .supervisor_externals + .allocate_memory(invoke_args_len) + .map_err(|_| trap("Can't allocate memory in supervisor for the arguments"))?; + self + .supervisor_externals + .write_memory(invoke_args_ptr, &invoke_args_data) + .map_err(|_| trap("Can't write invoke args into memory"))?; let result = self.supervisor_externals.invoke( &self.sandbox_instance.dispatch_thunk, invoke_args_ptr, @@ -279,7 +247,10 @@ impl<'a, FE: SandboxCapabilities + 'a> Externals for GuestExternals<'a, FE> { state, func_idx, )?; - self.supervisor_externals.deallocate(invoke_args_ptr)?; + self + .supervisor_externals + .deallocate_memory(invoke_args_ptr) + .map_err(|_| trap("Can't deallocate memory for dispatch thunk's invoke arguments"))?; // dispatch_thunk returns pointer to serialized arguments. // Unpack pointer and len of the serialized result data. @@ -292,9 +263,11 @@ impl<'a, FE: SandboxCapabilities + 'a> Externals for GuestExternals<'a, FE> { }; let serialized_result_val = self.supervisor_externals - .read_memory(serialized_result_val_ptr, serialized_result_val_len)?; + .read_memory(serialized_result_val_ptr, serialized_result_val_len) + .map_err(|_| trap("Can't read the serialized result from dispatch thunk"))?; self.supervisor_externals - .deallocate(serialized_result_val_ptr)?; + .deallocate_memory(serialized_result_val_ptr) + .map_err(|_| trap("Can't deallocate memory for dispatch thunk's result"))?; deserialize_result(&serialized_result_val) } @@ -433,6 +406,46 @@ fn decode_environment_definition( )) } +/// An environment in which the guest module is instantiated. +pub struct GuestEnvironment { + imports: Imports, + guest_to_supervisor_mapping: GuestToSupervisorFunctionMapping, +} + +impl GuestEnvironment { + /// Decodes an environment definition from the given raw bytes. + /// + /// Returns `Err` if the definition cannot be decoded. + pub fn decode( + store: &Store, + raw_env_def: &[u8], + ) -> std::result::Result { + let (imports, guest_to_supervisor_mapping) = + decode_environment_definition(raw_env_def, &store.memories)?; + Ok(Self { + imports, + guest_to_supervisor_mapping, + }) + } +} + +/// An unregistered sandboxed instance. +/// +/// To finish off the instantiation the user must call `register`. +#[must_use] +pub struct UnregisteredInstance { + sandbox_instance: Rc>, +} + +impl UnregisteredInstance { + /// Finalizes instantiation of this module. + pub fn register(self, store: &mut Store) -> u32 { + // At last, register the instance. + let instance_idx = store.register_sandbox_instance(self.sandbox_instance); + instance_idx + } +} + /// Instantiate a guest module and return it's index in the store. /// /// The guest module's code is specified in `wasm`. Environment that will be available to @@ -447,18 +460,16 @@ fn decode_environment_definition( /// - Module in `wasm` is invalid or couldn't be instantiated. /// /// [`EnvironmentDefinition`]: ../sandbox/struct.EnvironmentDefinition.html -pub fn instantiate( +pub fn instantiate<'a, FE: SandboxCapabilities>( supervisor_externals: &mut FE, dispatch_thunk: FE::SupervisorFuncRef, wasm: &[u8], - raw_env_def: &[u8], + host_env: GuestEnvironment, state: u32, -) -> std::result::Result { - let (imports, guest_to_supervisor_mapping) = - decode_environment_definition(raw_env_def, &supervisor_externals.store().memories)?; - +) -> std::result::Result, InstantiationError> { let module = Module::from_buffer(wasm).map_err(|_| InstantiationError::ModuleDecoding)?; - let instance = ModuleInstance::new(&module, &imports).map_err(|_| InstantiationError::Instantiation)?; + let instance = ModuleInstance::new(&module, &host_env.imports) + .map_err(|_| InstantiationError::Instantiation)?; let sandbox_instance = Rc::new(SandboxInstance { // In general, it's not a very good idea to use `.not_started_instance()` for anything @@ -466,7 +477,7 @@ pub fn instantiate( // for the purpose of running `start` function which should be ok. instance: instance.not_started_instance().clone(), dispatch_thunk, - guest_to_supervisor_mapping, + guest_to_supervisor_mapping: host_env.guest_to_supervisor_mapping, }); with_guest_externals( @@ -480,11 +491,7 @@ pub fn instantiate( }, )?; - // At last, register the instance. - let instance_idx = supervisor_externals - .store_mut() - .register_sandbox_instance(sandbox_instance); - Ok(instance_idx) + Ok(UnregisteredInstance { sandbox_instance }) } /// This struct keeps track of all sandboxed components. diff --git a/client/executor/wasmi/src/lib.rs b/client/executor/wasmi/src/lib.rs index 1bcb1aab8a..6fbfdbc1cc 100644 --- a/client/executor/wasmi/src/lib.rs +++ b/client/executor/wasmi/src/lib.rs @@ -66,31 +66,6 @@ impl<'a> FunctionExecutor<'a> { impl<'a> sandbox::SandboxCapabilities for FunctionExecutor<'a> { type SupervisorFuncRef = wasmi::FuncRef; - fn store(&self) -> &sandbox::Store { - &self.sandbox_store - } - fn store_mut(&mut self) -> &mut sandbox::Store { - &mut self.sandbox_store - } - fn allocate(&mut self, len: WordSize) -> Result, Error> { - let heap = &mut self.heap; - self.memory.with_direct_access_mut(|mem| { - heap.allocate(mem, len).map_err(Into::into) - }) - } - fn deallocate(&mut self, ptr: Pointer) -> Result<(), Error> { - let heap = &mut self.heap; - self.memory.with_direct_access_mut(|mem| { - heap.deallocate(mem, ptr).map_err(Into::into) - }) - } - fn write_memory(&mut self, ptr: Pointer, data: &[u8]) -> Result<(), Error> { - self.memory.set(ptr.into(), data).map_err(Into::into) - } - fn read_memory(&self, ptr: Pointer, len: WordSize) -> Result, Error> { - self.memory.get(ptr.into(), len as usize).map_err(Into::into) - } - fn invoke( &mut self, dispatch_thunk: &Self::SupervisorFuncRef, @@ -259,8 +234,15 @@ impl<'a> Sandbox for FunctionExecutor<'a> { .clone() }; + let guest_env = match sandbox::GuestEnvironment::decode(&self.sandbox_store, raw_env_def) { + Ok(guest_env) => guest_env, + Err(_) => return Ok(sandbox_primitives::ERR_MODULE as u32), + }; + let instance_idx_or_err_code = - match sandbox::instantiate(self, dispatch_thunk, wasm, raw_env_def, state) { + match sandbox::instantiate(self, dispatch_thunk, wasm, guest_env, state) + .map(|i| i.register(&mut self.sandbox_store)) + { Ok(instance_idx) => instance_idx, Err(sandbox::InstantiationError::StartTrapped) => sandbox_primitives::ERR_EXECUTION, diff --git a/client/executor/wasmtime/src/function_executor.rs b/client/executor/wasmtime/src/function_executor.rs index 7bbf5a456b..b4971f8b8a 100644 --- a/client/executor/wasmtime/src/function_executor.rs +++ b/client/executor/wasmtime/src/function_executor.rs @@ -118,32 +118,6 @@ impl<'a> FunctionExecutor<'a> { impl<'a> SandboxCapabilities for FunctionExecutor<'a> { type SupervisorFuncRef = SupervisorFuncRef; - fn store(&self) -> &sandbox::Store { - &self.sandbox_store - } - - fn store_mut(&mut self) -> &mut sandbox::Store { - &mut self.sandbox_store - } - - fn allocate(&mut self, len: WordSize) -> Result> { - self.heap.allocate(self.memory, len).map_err(Into::into) - } - - fn deallocate(&mut self, ptr: Pointer) -> Result<()> { - self.heap.deallocate(self.memory, ptr).map_err(Into::into) - } - - fn write_memory(&mut self, ptr: Pointer, data: &[u8]) -> Result<()> { - write_memory_from(self.memory, ptr, data) - } - - fn read_memory(&self, ptr: Pointer, len: WordSize) -> Result> { - let mut output = vec![0; len as usize]; - read_memory_into(self.memory, ptr, output.as_mut())?; - Ok(output) - } - fn invoke( &mut self, dispatch_thunk: &Self::SupervisorFuncRef, @@ -327,8 +301,15 @@ impl<'a> Sandbox for FunctionExecutor<'a> { SupervisorFuncRef(func_ref) }; + let guest_env = match sandbox::GuestEnvironment::decode(&self.sandbox_store, raw_env_def) { + Ok(guest_env) => guest_env, + Err(_) => return Ok(sandbox_primitives::ERR_MODULE as u32), + }; + let instance_idx_or_err_code = - match sandbox::instantiate(self, dispatch_thunk, wasm, raw_env_def, state) { + match sandbox::instantiate(self, dispatch_thunk, wasm, guest_env, state) + .map(|i| i.register(&mut self.sandbox_store)) + { Ok(instance_idx) => instance_idx, Err(sandbox::InstantiationError::StartTrapped) => sandbox_primitives::ERR_EXECUTION, -- GitLab From 0d19d9566f8628a7b33a7730d1201a7f63af2968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Wed, 5 Feb 2020 20:47:11 +0000 Subject: [PATCH 088/180] grandpa: bump version to v0.11.1 (#4813) --- client/finality-grandpa/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index 7c427dfd5c..1249bff751 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -29,11 +29,11 @@ sc-network = { version = "0.8", path = "../network" } sc-network-gossip = { version = "0.8", 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.11.0", features = ["derive-codec"] } +finality-grandpa = { version = "0.11.1", features = ["derive-codec"] } pin-project = "0.4.6" [dev-dependencies] -finality-grandpa = { version = "0.11.0", features = ["derive-codec", "test-helpers"] } +finality-grandpa = { version = "0.11.1", features = ["derive-codec", "test-helpers"] } sc-network = { version = "0.8", path = "../network" } sc-network-test = { version = "0.8.0", path = "../network/test" } sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } -- GitLab From 1fa99067a86962a18f5d7ef4db83bb9797b93dbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Wed, 5 Feb 2020 23:10:35 +0000 Subject: [PATCH 089/180] node: disable grandpa automatic finality fallback (#4835) * node: disable grandpa automatic finality fallback * node: bump spec_version --- bin/node/runtime/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 65e09e99d2..40342c1ce8 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -79,7 +79,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 213, + spec_version: 214, impl_version: 0, apis: RUNTIME_API_VERSIONS, }; @@ -476,7 +476,7 @@ parameter_types! { } impl pallet_finality_tracker::Trait for Runtime { - type OnFinalizationStalled = Grandpa; + type OnFinalizationStalled = (); type WindowSize = WindowSize; type ReportLatency = ReportLatency; } -- GitLab From c9e8aa3a8e6a2b3a049c2a84dd7ccbcb7d90ac1f Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Thu, 6 Feb 2020 13:07:52 +0100 Subject: [PATCH 090/180] do join_all (#4832) --- client/transaction-pool/graph/src/pool.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/client/transaction-pool/graph/src/pool.rs b/client/transaction-pool/graph/src/pool.rs index 815b5871ea..91ce58518a 100644 --- a/client/transaction-pool/graph/src/pool.rs +++ b/client/transaction-pool/graph/src/pool.rs @@ -378,8 +378,13 @@ impl Pool { let block_number = self.resolve_block_number(at)?; let mut result = HashMap::new(); - for xt in xts { - let (hash, validated_tx) = self.verify_one(at, block_number, xt, force).await; + for (hash, validated_tx) in + futures::future::join_all( + xts.into_iter() + .map(|xt| self.verify_one(at, block_number, xt, force)) + ) + .await + { result.insert(hash, validated_tx); } -- GitLab From 3fc91c76b1ed62a8db9d6b78910e8b7d7c928911 Mon Sep 17 00:00:00 2001 From: Jimmy Chu Date: Thu, 6 Feb 2020 20:13:44 +0800 Subject: [PATCH 091/180] Node template folders restructuring (#4811) * Restructure node-template so it is clear that node, runtime, and pallets are separated * Separating to mock and tests * restructuring runtime to top-level * updated release script * updated Cargo.lock --- .maintain/node-template-release/src/main.rs | 16 +++- Cargo.lock | 14 +++ Cargo.toml | 3 +- bin/node-template/Cargo.toml | 37 -------- bin/node-template/node/Cargo.toml | 38 ++++++++ bin/node-template/{ => node}/build.rs | 0 .../{ => node}/src/chain_spec.rs | 0 bin/node-template/{ => node}/src/cli.rs | 0 bin/node-template/{ => node}/src/command.rs | 0 bin/node-template/{ => node}/src/main.rs | 0 bin/node-template/{ => node}/src/service.rs | 0 bin/node-template/pallets/template/Cargo.toml | 44 ++++++++++ .../template/src/lib.rs} | 88 ++----------------- .../pallets/template/src/mock.rs | 52 +++++++++++ .../pallets/template/src/tests.rs | 26 ++++++ bin/node-template/runtime/Cargo.toml | 7 +- bin/node-template/runtime/src/lib.rs | 6 +- 17 files changed, 205 insertions(+), 126 deletions(-) delete mode 100644 bin/node-template/Cargo.toml create mode 100644 bin/node-template/node/Cargo.toml rename bin/node-template/{ => node}/build.rs (100%) rename bin/node-template/{ => node}/src/chain_spec.rs (100%) rename bin/node-template/{ => node}/src/cli.rs (100%) rename bin/node-template/{ => node}/src/command.rs (100%) rename bin/node-template/{ => node}/src/main.rs (100%) rename bin/node-template/{ => node}/src/service.rs (100%) create mode 100644 bin/node-template/pallets/template/Cargo.toml rename bin/node-template/{runtime/src/template.rs => pallets/template/src/lib.rs} (59%) create mode 100644 bin/node-template/pallets/template/src/mock.rs create mode 100644 bin/node-template/pallets/template/src/tests.rs diff --git a/.maintain/node-template-release/src/main.rs b/.maintain/node-template-release/src/main.rs index db42b155e6..a1d85bf33f 100644 --- a/.maintain/node-template-release/src/main.rs +++ b/.maintain/node-template-release/src/main.rs @@ -1,7 +1,7 @@ use structopt::StructOpt; use std::{ - path::{PathBuf, Path}, collections::HashMap, fs::{File, self}, io::{Read, Write}, + path::{PathBuf, Path}, collections::HashMap, fs::{File, OpenOptions, self}, io::{Read, Write}, process::Command }; @@ -88,7 +88,7 @@ fn replace_path_dependencies_with_git(cargo_toml_path: &Path, commit_id: &str, c // remove `Cargo.toml` cargo_toml_path.pop(); - for &table in &["dependencies", "build-dependencies"] { + for &table in &["dependencies", "build-dependencies", "dev-dependencies"] { let mut dependencies: toml::value::Table = match cargo_toml .remove(table) .and_then(|v| v.try_into().ok()) { @@ -212,11 +212,21 @@ fn main() { let node_template_path = build_dir.path().join(node_template_folder); copy_node_template(&options.node_template, build_dir.path()); - let cargo_tomls = find_cargo_tomls(build_dir.path().to_owned()); + let mut cargo_tomls = find_cargo_tomls(build_dir.path().to_owned()); let commit_id = get_git_commit_id(&options.node_template); let top_level_cargo_toml_path = node_template_path.join("Cargo.toml"); + // Check if top level Cargo.toml exists. If not, create one in the destination + if !cargo_tomls.contains(&top_level_cargo_toml_path) { + // create the top_level_cargo_toml + OpenOptions::new().create(true).write(true).open(top_level_cargo_toml_path.clone()) + .expect("Create root level `Cargo.toml` failed."); + + // push into our data structure + cargo_tomls.push(PathBuf::from(top_level_cargo_toml_path.clone())); + } + cargo_tomls.iter().for_each(|t| { let mut cargo_toml = parse_cargo_toml(&t); replace_path_dependencies_with_git(&t, &commit_id, &mut cargo_toml); diff --git a/Cargo.lock b/Cargo.lock index ed97668987..f521817b2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3554,6 +3554,7 @@ dependencies = [ "pallet-indices", "pallet-randomness-collective-flip", "pallet-sudo", + "pallet-template", "pallet-timestamp", "pallet-transaction-payment", "parity-scale-codec", @@ -4337,6 +4338,19 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-template" +version = "2.0.0" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "safe-mix", + "sp-core", + "sp-io", + "sp-runtime", +] + [[package]] name = "pallet-timestamp" version = "2.0.0" diff --git a/Cargo.toml b/Cargo.toml index 0bd6b4c0b0..552f1eadc7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,8 @@ [workspace] members = [ - "bin/node-template", + "bin/node-template/node", "bin/node-template/runtime", + "bin/node-template/pallets/template", "bin/node/cli", "bin/node/executor", "bin/node/primitives", diff --git a/bin/node-template/Cargo.toml b/bin/node-template/Cargo.toml deleted file mode 100644 index 7001099b0b..0000000000 --- a/bin/node-template/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "node-template" -version = "2.0.0" -authors = ["Anonymous"] -build = "build.rs" -edition = "2018" -license = "Unlicense" - -[[bin]] -name = "node-template" -path = "src/main.rs" - -[dependencies] -futures = "0.3.1" -log = "0.4.8" -sc-cli = { version = "0.8.0", path = "../../client/cli" } -sp-core = { version = "2.0.0", path = "../../primitives/core" } -sc-executor = { version = "0.8", path = "../../client/executor" } -sc-service = { version = "0.8", 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 = "0.8", 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 = "0.8", path = "../../client/" } -node-template-runtime = { version = "2.0.0", path = "runtime" } -sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } -sc-basic-authorship = { path = "../../client/basic-authorship" } -structopt = "0.3.8" - -[build-dependencies] -vergen = "3.0.4" -build-script-utils = { version = "2.0.0", package = "substrate-build-script-utils", path = "../../utils/build-script-utils" } diff --git a/bin/node-template/node/Cargo.toml b/bin/node-template/node/Cargo.toml new file mode 100644 index 0000000000..9ad4a0e8a5 --- /dev/null +++ b/bin/node-template/node/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "node-template" +version = "2.0.0" +authors = ["Anonymous"] +edition = "2018" +license = "Unlicense" +build = "build.rs" + +[[bin]] +name = "node-template" + +[dependencies] +futures = "0.3.1" +log = "0.4.8" +structopt = "0.3.8" + +sc-cli = { version = "0.8.0", path = "../../../client/cli" } +sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sc-executor = { version = "0.8", path = "../../../client/executor" } +sc-service = { version = "0.8", 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 = "0.8", 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 = "0.8", path = "../../../client/" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +sc-basic-authorship = { path = "../../../client/basic-authorship" } + +node-template-runtime = { version = "2.0.0", path = "../runtime" } + +[build-dependencies] +vergen = "3.0.4" +build-script-utils = { version = "2.0.0", package = "substrate-build-script-utils", path = "../../../utils/build-script-utils" } diff --git a/bin/node-template/build.rs b/bin/node-template/node/build.rs similarity index 100% rename from bin/node-template/build.rs rename to bin/node-template/node/build.rs diff --git a/bin/node-template/src/chain_spec.rs b/bin/node-template/node/src/chain_spec.rs similarity index 100% rename from bin/node-template/src/chain_spec.rs rename to bin/node-template/node/src/chain_spec.rs diff --git a/bin/node-template/src/cli.rs b/bin/node-template/node/src/cli.rs similarity index 100% rename from bin/node-template/src/cli.rs rename to bin/node-template/node/src/cli.rs diff --git a/bin/node-template/src/command.rs b/bin/node-template/node/src/command.rs similarity index 100% rename from bin/node-template/src/command.rs rename to bin/node-template/node/src/command.rs diff --git a/bin/node-template/src/main.rs b/bin/node-template/node/src/main.rs similarity index 100% rename from bin/node-template/src/main.rs rename to bin/node-template/node/src/main.rs diff --git a/bin/node-template/src/service.rs b/bin/node-template/node/src/service.rs similarity index 100% rename from bin/node-template/src/service.rs rename to bin/node-template/node/src/service.rs diff --git a/bin/node-template/pallets/template/Cargo.toml b/bin/node-template/pallets/template/Cargo.toml new file mode 100644 index 0000000000..8ea3f3adab --- /dev/null +++ b/bin/node-template/pallets/template/Cargo.toml @@ -0,0 +1,44 @@ +[package] +authors = ['Anonymous'] +edition = '2018' +name = 'pallet-template' +version = '2.0.0' + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } +safe-mix = { default-features = false, version = '1.0.0' } + +[dependencies.frame-support] +default-features = false +version = '2.0.0' +path = "../../../../frame/support" + +[dependencies.system] +default-features = false +package = 'frame-system' +version = '2.0.0' +path = "../../../../frame/system" + +[dev-dependencies.sp-core] +default-features = false +version = '2.0.0' +path = "../../../../primitives/core" + +[dev-dependencies.sp-io] +default-features = false +version = '2.0.0' +path = "../../../../primitives/io" + +[dev-dependencies.sp-runtime] +default-features = false +version = '2.0.0' +path = "../../../../primitives/runtime" + +[features] +default = ['std'] +std = [ + 'codec/std', + 'frame-support/std', + 'safe-mix/std', + 'system/std' +] diff --git a/bin/node-template/runtime/src/template.rs b/bin/node-template/pallets/template/src/lib.rs similarity index 59% rename from bin/node-template/runtime/src/template.rs rename to bin/node-template/pallets/template/src/lib.rs index 4ed8066578..a1615b4c1f 100644 --- a/bin/node-template/runtime/src/template.rs +++ b/bin/node-template/pallets/template/src/lib.rs @@ -1,16 +1,23 @@ +#![cfg_attr(not(feature = "std"), no_std)] + /// A runtime module template with necessary imports /// Feel free to remove or edit this file as needed. /// If you change the name of this file, make sure to update its references in runtime/src/lib.rs /// If you remove this file, you can remove those references - /// For more guidance on Substrate modules, see the example module /// https://github.com/paritytech/substrate/blob/master/frame/example/src/lib.rs use frame_support::{decl_module, decl_storage, decl_event, decl_error, dispatch}; use system::ensure_signed; +#[cfg(test)] +mod mock; + +#[cfg(test)] +mod tests; + /// The pallet's configuration trait. pub trait Trait: system::Trait { // Add other types and constants required to configure this pallet. @@ -95,82 +102,3 @@ decl_module! { } } } - - -/// Tests for this pallet -#[cfg(test)] -mod tests { - use super::*; - - use sp_core::H256; - use frame_support::{impl_outer_origin, assert_ok, assert_noop, parameter_types, weights::Weight}; - use sp_runtime::{ - traits::{BlakeTwo256, IdentityLookup}, testing::Header, Perbill, - }; - - impl_outer_origin! { - pub enum Origin for Test {} - } - - // 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::from_percent(75); - } - impl system::Trait for Test { - type Origin = Origin; - type Call = (); - type Index = u64; - type BlockNumber = u64; - type Hash = H256; - 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 = (); - } - impl Trait for Test { - type Event = (); - } - type TemplateModule = Module; - - // This function basically just builds a genesis storage key/value store according to - // our desired mockup. - fn new_test_ext() -> sp_io::TestExternalities { - system::GenesisConfig::default().build_storage::().unwrap().into() - } - - #[test] - fn it_works_for_default_value() { - new_test_ext().execute_with(|| { - // Just a dummy test for the dummy funtion `do_something` - // calling the `do_something` function with a value 42 - assert_ok!(TemplateModule::do_something(Origin::signed(1), 42)); - // asserting that the stored value is equal to what we stored - assert_eq!(TemplateModule::something(), Some(42)); - }); - } - - #[test] - fn correct_error_for_none_value() { - new_test_ext().execute_with(|| { - // Ensure the correct error is thrown on None value - assert_noop!( - TemplateModule::cause_error(Origin::signed(1)), - Error::::NoneValue - ); - }); - } -} diff --git a/bin/node-template/pallets/template/src/mock.rs b/bin/node-template/pallets/template/src/mock.rs new file mode 100644 index 0000000000..2cbfc89d5b --- /dev/null +++ b/bin/node-template/pallets/template/src/mock.rs @@ -0,0 +1,52 @@ +// Creating mock runtime here + +use crate::{Module, Trait}; +use sp_core::H256; +use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; +use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup}, testing::Header, Perbill, +}; + +impl_outer_origin! { + pub enum Origin for Test {} +} + +// 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::from_percent(75); +} +impl system::Trait for Test { + type Origin = Origin; + type Call = (); + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + 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 = (); +} +impl Trait for Test { + type Event = (); +} +pub type TemplateModule = Module; + +// This function basically just builds a genesis storage key/value store according to +// our desired mockup. +pub fn new_test_ext() -> sp_io::TestExternalities { + system::GenesisConfig::default().build_storage::().unwrap().into() +} diff --git a/bin/node-template/pallets/template/src/tests.rs b/bin/node-template/pallets/template/src/tests.rs new file mode 100644 index 0000000000..44a423c948 --- /dev/null +++ b/bin/node-template/pallets/template/src/tests.rs @@ -0,0 +1,26 @@ +// Tests to be written here + +use crate::{Error, mock::*}; +use frame_support::{assert_ok, assert_noop}; + +#[test] +fn it_works_for_default_value() { + new_test_ext().execute_with(|| { + // Just a dummy test for the dummy funtion `do_something` + // calling the `do_something` function with a value 42 + assert_ok!(TemplateModule::do_something(Origin::signed(1), 42)); + // asserting that the stored value is equal to what we stored + assert_eq!(TemplateModule::something(), Some(42)); + }); +} + +#[test] +fn correct_error_for_none_value() { + new_test_ext().execute_with(|| { + // Ensure the correct error is thrown on None value + assert_noop!( + TemplateModule::cause_error(Origin::signed(1)), + Error::::NoneValue + ); + }); +} diff --git a/bin/node-template/runtime/Cargo.toml b/bin/node-template/runtime/Cargo.toml index 299e78996a..ddecb0e4cf 100644 --- a/bin/node-template/runtime/Cargo.toml +++ b/bin/node-template/runtime/Cargo.toml @@ -6,6 +6,8 @@ edition = "2018" license = "Unlicense" [dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } + 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" } @@ -16,8 +18,6 @@ sudo = { version = "2.0.0", default-features = false, package = "pallet-sudo", p 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"] } frame-executive = { version = "2.0.0", default-features = false, path = "../../../frame/executive" } serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-api = { version = "2.0.0", default-features = false, path = "../../../primitives/api" } @@ -33,6 +33,8 @@ sp-std = { version = "2.0.0", default-features = false, path = "../../../primiti 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" } +template = { version = "2.0.0", default-features = false, path = "../pallets/template", package = "pallet-template" } + [build-dependencies] wasm-builder-runner = { version = "1.0.4", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } @@ -64,4 +66,5 @@ std = [ "system/std", "timestamp/std", "transaction-payment/std", + "template/std", ] diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index ea4535e26d..a863ec40a7 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -37,6 +37,9 @@ pub use frame_support::{ weights::Weight, }; +/// Importing a template pallet +pub use template; + /// An index to a block. pub type BlockNumber = u32; @@ -63,9 +66,6 @@ pub type Hash = sp_core::H256; /// Digest item type. pub type DigestItem = generic::DigestItem; -/// Used for the module template in `./template.rs` -mod template; - /// Opaque types. These are used by the CLI to instantiate machinery that don't need to know /// the specifics of the runtime. They can then be made to be agnostic over specific formats /// of data like extrinsics, allowing for them to continue syncing the network through upgrades -- GitLab From 666b1c9f86258c48d65efb50f1e86ac25b25332e Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Thu, 6 Feb 2020 14:06:53 +0100 Subject: [PATCH 092/180] Fixed a few warnings (#4841) --- client/cli/src/node_key.rs | 3 ++- client/network/src/behaviour.rs | 2 +- frame/authority-discovery/src/lib.rs | 1 - frame/executive/src/lib.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/cli/src/node_key.rs b/client/cli/src/node_key.rs index 88102acc63..4401481ca5 100644 --- a/client/cli/src/node_key.rs +++ b/client/cli/src/node_key.rs @@ -91,9 +91,10 @@ where net_config_dir.as_ref().map(|d| d.as_ref().join(name)) } +#[cfg(test)] mod tests { - use super::*; use sc_network::config::identity::ed25519; + use super::*; #[test] fn tests_node_name_good() { diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index c31fd84eff..8b903cec35 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -25,7 +25,7 @@ use libp2p::core::{Multiaddr, PeerId, PublicKey}; use libp2p::kad::record; use libp2p::swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess}; use libp2p::core::{nodes::Substream, muxing::StreamMuxerBox}; -use log::{debug, warn}; +use log::debug; use sp_consensus::{BlockOrigin, import_queue::{IncomingBlock, Origin}}; use sp_runtime::{traits::{Block as BlockT, NumberFor}, Justification}; use std::{iter, task::Context, task::Poll}; diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index c427043397..22ea3d3bba 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -103,7 +103,6 @@ mod tests { use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; type AuthorityDiscovery = Module; - type SessionIndex = u32; #[derive(Clone, Eq, PartialEq)] pub struct Test; diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 936da70211..93db141856 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -357,7 +357,7 @@ mod tests { use sp_core::H256; use sp_runtime::{ generic::Era, Perbill, DispatchError, testing::{Digest, Header, Block}, - traits::{Bounded, Header as HeaderT, BlakeTwo256, IdentityLookup, ConvertInto}, + traits::{Header as HeaderT, BlakeTwo256, IdentityLookup, ConvertInto}, transaction_validity::{InvalidTransaction, UnknownTransaction, TransactionValidityError}, }; use frame_support::{ -- GitLab From 7d83cabf678a0cd51d017b5dcf59d1a5de376a13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 6 Feb 2020 14:26:41 +0100 Subject: [PATCH 093/180] Fix memory leak in runtime interface (#4837) * Fix memory leak in runtime interface We used `slice::from_raw_parts` in runtime-interface which did not free the memory afterwards. This pr changes it to `Vec::from_raw_parts` to make sure `drop` is called properly and the values are freed. * Check that `len` is non-zero * Adds comment --- primitives/runtime-interface/src/impls.rs | 19 +++++----- primitives/runtime-interface/src/pass_by.rs | 11 ++++-- .../runtime-interface/test-wasm/src/lib.rs | 35 +++++++++++++++++++ primitives/runtime-interface/test/src/lib.rs | 15 ++++++++ 4 files changed, 68 insertions(+), 12 deletions(-) diff --git a/primitives/runtime-interface/src/impls.rs b/primitives/runtime-interface/src/impls.rs index 35bd96bd05..084b5e11eb 100644 --- a/primitives/runtime-interface/src/impls.rs +++ b/primitives/runtime-interface/src/impls.rs @@ -38,9 +38,6 @@ use sp_std::{any::TypeId, mem, vec::Vec}; #[cfg(feature = "std")] use sp_std::borrow::Cow; -#[cfg(not(feature = "std"))] -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")))] assert_eq_size!(usize, u32); @@ -196,11 +193,16 @@ impl FromFFIValue for Vec { let (ptr, len) = unpack_ptr_and_len(arg); let len = len as usize; + if len == 0 { + return Vec::new(); + } + + let data = unsafe { Vec::from_raw_parts(ptr as *mut u8, len, len) }; + if TypeId::of::() == TypeId::of::() { - unsafe { mem::transmute(Vec::from_raw_parts(ptr as *mut u8, len, len)) } + unsafe { mem::transmute(data) } } else { - let slice = unsafe { slice::from_raw_parts(ptr as *const u8, len) }; - Self::decode(&mut &slice[..]).expect("Host to wasm values are encoded correctly; qed") + Self::decode(&mut &data[..]).expect("Host to wasm values are encoded correctly; qed") } } } @@ -302,10 +304,9 @@ macro_rules! impl_traits_for_arrays { impl FromFFIValue for [u8; $n] { fn from_ffi_value(arg: u32) -> [u8; $n] { let mut res = [0u8; $n]; - res.copy_from_slice(unsafe { slice::from_raw_parts(arg as *const u8, $n) }); + let data = unsafe { Vec::from_raw_parts(arg as *mut u8, $n, $n) }; - // Make sure we free the pointer. - let _ = unsafe { Box::from_raw(arg as *mut u8) }; + res.copy_from_slice(&data); res } diff --git a/primitives/runtime-interface/src/pass_by.rs b/primitives/runtime-interface/src/pass_by.rs index 597a0284ee..d6767b5ebb 100644 --- a/primitives/runtime-interface/src/pass_by.rs +++ b/primitives/runtime-interface/src/pass_by.rs @@ -32,7 +32,7 @@ use sp_wasm_interface::{FunctionContext, Pointer, Result}; use sp_std::{marker::PhantomData, convert::TryFrom}; #[cfg(not(feature = "std"))] -use sp_std::{slice, vec::Vec}; +use sp_std::vec::Vec; /// Derive macro for implementing [`PassBy`] with the [`Codec`] strategy. /// @@ -255,8 +255,13 @@ impl PassByImpl for Codec { let (ptr, len) = unpack_ptr_and_len(arg); let len = len as usize; - let slice = unsafe { slice::from_raw_parts(ptr as *const u8, len) }; - T::decode(&mut &slice[..]).expect("Host to wasm values are encoded correctly; qed") + let encoded = if len == 0 { + Vec::new() + } else { + unsafe { Vec::from_raw_parts(ptr as *mut u8, len, len) } + }; + + T::decode(&mut &encoded[..]).expect("Host to wasm values are encoded correctly; qed") } } diff --git a/primitives/runtime-interface/test-wasm/src/lib.rs b/primitives/runtime-interface/test-wasm/src/lib.rs index 67fbfdcfec..c6e2c9909f 100644 --- a/primitives/runtime-interface/test-wasm/src/lib.rs +++ b/primitives/runtime-interface/test-wasm/src/lib.rs @@ -39,6 +39,17 @@ pub trait TestApi { data } + /// Returns 16kb data. + /// + /// # Note + /// + /// We return a `Vec` because this will use the code path that uses SCALE + /// to pass the data between native/wasm. (Vec is passed without encoding the + /// data) + fn return_16kb() -> Vec { + vec![0; 4 * 1024] + } + /// Set the storage at key with value. fn set_storage(&mut self, key: &[u8], data: &[u8]) { self.place_storage(key.to_vec(), Some(data.to_vec())); @@ -211,4 +222,28 @@ wasm_export_functions! { assert_eq!(*val, test_api::get_and_return_i128(*val)); } } + + fn test_vec_return_value_memory_is_freed() { + let mut len = 0; + for _ in 0..1024 { + len += test_api::return_16kb().len(); + } + assert_eq!(1024 * 1024 * 4, len); + } + + fn test_encoded_return_value_memory_is_freed() { + let mut len = 0; + for _ in 0..1024 { + len += test_api::return_option_input(vec![0; 16 * 1024]).map(|v| v.len()).unwrap(); + } + assert_eq!(1024 * 1024 * 16, len); + } + + fn test_array_return_value_memory_is_freed() { + let mut len = 0; + for _ in 0..1024 * 1024 { + len += test_api::get_and_return_array([0; 34])[1]; + } + assert_eq!(0, len); + } } diff --git a/primitives/runtime-interface/test/src/lib.rs b/primitives/runtime-interface/test/src/lib.rs index 48c120b2c9..559a4281e0 100644 --- a/primitives/runtime-interface/test/src/lib.rs +++ b/primitives/runtime-interface/test/src/lib.rs @@ -113,3 +113,18 @@ fn test_overwrite_native_function_implementation() { fn test_u128_i128_as_parameter_and_return_value() { call_wasm_method::("test_u128_i128_as_parameter_and_return_value"); } + +#[test] +fn test_vec_return_value_memory_is_freed() { + call_wasm_method::("test_vec_return_value_memory_is_freed"); +} + +#[test] +fn test_encoded_return_value_memory_is_freed() { + call_wasm_method::("test_encoded_return_value_memory_is_freed"); +} + +#[test] +fn test_array_return_value_memory_is_freed() { + call_wasm_method::("test_array_return_value_memory_is_freed"); +} -- GitLab From faf608eeeda0031629f7608321c7ab41fac6024f Mon Sep 17 00:00:00 2001 From: Marcio Diaz Date: Thu, 6 Feb 2020 14:48:19 +0100 Subject: [PATCH 094/180] Fix broken factory by adding keystore back. (#4840) --- bin/node/cli/src/command.rs | 2 ++ client/cli/src/lib.rs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/node/cli/src/command.rs b/bin/node/cli/src/command.rs index 3395717f2f..7a22710ec1 100644 --- a/bin/node/cli/src/command.rs +++ b/bin/node/cli/src/command.rs @@ -50,6 +50,8 @@ where cli_args.shared_params.dev, )?; + sc_cli::fill_config_keystore_in_memory(&mut config)?; + match ChainSpec::from(config.expect_chain_spec().id()) { Some(ref c) if c == &ChainSpec::Development || c == &ChainSpec::LocalTestnet => {}, _ => panic!("Factory is only supported for development and local testnet."), diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index c602d52ed9..785a6fb073 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -445,7 +445,7 @@ fn input_keystore_password() -> Result { } /// Use in memory keystore config when it is not required at all. -fn fill_config_keystore_in_memory(config: &mut sc_service::Configuration) +pub fn fill_config_keystore_in_memory(config: &mut sc_service::Configuration) -> Result<(), String> { match &mut config.keystore { -- GitLab From 099cd0f2ba2a041f087978ef9d53473d0a6d0aee Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Thu, 6 Feb 2020 15:46:49 +0100 Subject: [PATCH 095/180] CLI improvements & fixes (#4812) These are a few changes I missed during the refactoring. 1. Initialization issue and boilerplate Most importantly: part of the `Configuration` initialization was done in `sc_cli::init`. This means the user can not benefit from this initialization boilerplate if they have multiple `Configuration` since `sc_cli::init` can only be called once. 2. Boilerplate for `VersionInfo` and `Configuration` I'm also answering to the critic of @bkchr on the initialization using version: https://github.com/paritytech/substrate/pull/4692/files/bea809d4c14a2ede953227ac885e3b3f9771c548#r372047238 This will allow initializing a `Configuration` and provide the version by default. 3. Loading the `chain_spec` explicitly In the past it was done automatically but in some cases we want to delay this. I moved the code to `Configuration.load_spec()` so it can be called later on. `chain_spec` can also be written directly to the `Configuration` without using this `load_spec` helper. 4. [deleted] 5. Fixing issue that prevents the user to override the port In the refactoring I introduced a bug by mistake that could potentially prevent the CLI user to override the ports if defaults where provided for these ports (only on cumulus). 6. Change task_executor from Box to Arc This is useful for cumulus where we have 2 nodes with 2 separate Configuration that need to spawn tasks to the same runtime. 7. Renamed TasksExecutorRequired to TaskExecutor For consistency. This is related to https://github.com/paritytech/cumulus/issues/24 This is the continuation (and hopefully the end of) #4692 --- .gitlab-ci.yml | 9 - .maintain/check_for_exit.sh | 16 -- Cargo.lock | 74 ++++++- bin/node-template/node/src/command.rs | 3 +- bin/node/cli/Cargo.toml | 2 + bin/node/cli/src/command.rs | 7 +- .../tests/running_the_node_and_interrupt.rs | 58 ++++++ client/cli/src/lib.rs | 193 +++++++++++------- client/cli/src/params.rs | 5 +- client/cli/src/runtime.rs | 6 +- client/service/src/builder.rs | 6 +- client/service/src/config.rs | 56 ++++- client/service/src/error.rs | 2 +- client/service/src/lib.rs | 2 +- client/service/test/src/lib.rs | 12 +- utils/browser/src/lib.rs | 6 +- 16 files changed, 321 insertions(+), 136 deletions(-) delete mode 100755 .maintain/check_for_exit.sh create mode 100644 bin/node/cli/tests/running_the_node_and_interrupt.rs diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 828c830948..ced3e33eaa 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -235,15 +235,6 @@ check-web-wasm: - time cargo build --manifest-path=bin/node/cli/Cargo.toml --no-default-features --features "browser" --target=wasm32-unknown-unknown - sccache -s -node-exits: - stage: test - <<: *docker-env - except: - - /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 - script: - - ./.maintain/check_for_exit.sh - - test-full-crypto-feature: stage: test <<: *docker-env diff --git a/.maintain/check_for_exit.sh b/.maintain/check_for_exit.sh deleted file mode 100755 index edc2130e57..0000000000 --- a/.maintain/check_for_exit.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash - -# Script that checks that a node exits after `SIGINT` was send. - -set -e - -cargo build -./target/debug/substrate --dev & -PID=$! - -# Let the chain running for 60 seconds -sleep 60 - -# Send `SIGINT` and give the process 30 seconds to end -kill -INT $PID -timeout 30 tail --pid=$PID -f /dev/null diff --git a/Cargo.lock b/Cargo.lock index f521817b2c..3f94778b84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -150,6 +150,19 @@ dependencies = [ "syn", ] +[[package]] +name = "assert_cmd" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6283bac8dd7226470d491bc4737816fea4ca1fba7a2847f2e9097fd6bfb4624c" +dependencies = [ + "doc-comment", + "escargot", + "predicates", + "predicates-core", + "predicates-tree", +] + [[package]] name = "assert_matches" version = "1.3.0" @@ -1227,6 +1240,18 @@ dependencies = [ "libc", ] +[[package]] +name = "escargot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74cf96bec282dcdb07099f7e31d9fed323bca9435a09aba7b6d99b7617bca96d" +dependencies = [ + "lazy_static", + "log 0.4.8", + "serde", + "serde_json", +] + [[package]] name = "evm" version = "0.14.2" @@ -3318,10 +3343,24 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "nix" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", + "void", +] + [[package]] name = "node-cli" version = "2.0.0" dependencies = [ + "assert_cmd", "browser-utils", "frame-support", "frame-system", @@ -3329,6 +3368,7 @@ dependencies = [ "hex-literal", "jsonrpc-core", "log 0.4.8", + "nix", "node-executor", "node-primitives", "node-rpc", @@ -4816,6 +4856,32 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" +[[package]] +name = "predicates" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9bfe52247e5cc9b2f943682a85a5549fb9662245caf094504e69a2f03fe64d4" +dependencies = [ + "difference", + "predicates-core", +] + +[[package]] +name = "predicates-core" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06075c3a3e92559ff8929e7a280684489ea27fe44805174c3ebd9328dcb37178" + +[[package]] +name = "predicates-tree" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e63c4859013b38a76eca2414c64911fba30def9e3202ac461a2d22831220124" +dependencies = [ + "predicates-core", + "treeline", +] + [[package]] name = "pretty_assertions" version = "0.6.1" @@ -8118,6 +8184,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" +[[package]] +name = "treeline" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" + [[package]] name = "trie-bench" version = "0.19.0" @@ -8204,7 +8276,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" dependencies = [ - "rand 0.3.23", + "rand 0.7.3", ] [[package]] diff --git a/bin/node-template/node/src/command.rs b/bin/node-template/node/src/command.rs index 86058929b0..585b8e1ca8 100644 --- a/bin/node-template/node/src/command.rs +++ b/bin/node-template/node/src/command.rs @@ -25,8 +25,7 @@ pub fn run(version: VersionInfo) -> error::Result<()> { let opt = sc_cli::from_args::(&version); - let mut config = sc_service::Configuration::default(); - config.impl_name = "node-template"; + let config = sc_service::Configuration::new(&version); match opt.subcommand { Some(subcommand) => sc_cli::run_subcommand( diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index ef6e90f91a..cf666ffdc5 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -95,6 +95,8 @@ sc-consensus-babe = { version = "0.8", features = ["test-helpers"], path = "../. sc-service-test = { version = "2.0.0", path = "../../../client/service/test" } futures = "0.3.1" tempfile = "3.1.0" +assert_cmd = "0.12" +nix = "0.17" [build-dependencies] build-script-utils = { version = "2.0.0", package = "substrate-build-script-utils", path = "../../../utils/build-script-utils" } diff --git a/bin/node/cli/src/command.rs b/bin/node/cli/src/command.rs index 7a22710ec1..eb18d6d8b3 100644 --- a/bin/node/cli/src/command.rs +++ b/bin/node/cli/src/command.rs @@ -28,8 +28,7 @@ where let args: Vec<_> = args.collect(); let opt = sc_cli::from_iter::(args.clone(), &version); - let mut config = sc_service::Configuration::default(); - config.impl_name = "substrate-node"; + let mut config = sc_service::Configuration::new(&version); match opt.subcommand { None => sc_cli::run( @@ -41,8 +40,8 @@ where &version, ), Some(Subcommand::Factory(cli_args)) => { - sc_cli::init(&mut config, load_spec, &cli_args.shared_params, &version)?; - + sc_cli::init(&cli_args.shared_params, &version)?; + sc_cli::load_spec(&mut config, &cli_args.shared_params, load_spec)?; sc_cli::fill_import_params( &mut config, &cli_args.import_params, diff --git a/bin/node/cli/tests/running_the_node_and_interrupt.rs b/bin/node/cli/tests/running_the_node_and_interrupt.rs new file mode 100644 index 0000000000..6b0d696396 --- /dev/null +++ b/bin/node/cli/tests/running_the_node_and_interrupt.rs @@ -0,0 +1,58 @@ +// Copyright 2020 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 assert_cmd::cargo::cargo_bin; +use std::convert::TryInto; +use std::process::{Child, Command, ExitStatus}; +use std::thread::sleep; +use std::time::Duration; + +#[test] +#[cfg(unix)] +fn running_the_node_works_and_can_be_interrupted() { + use nix::sys::signal::{kill, Signal::{self, SIGINT, SIGTERM}}; + use nix::unistd::Pid; + + fn wait_for(child: &mut Child, secs: usize) -> Option { + for _ in 0..secs { + match child.try_wait().unwrap() { + Some(status) => return Some(status), + None => sleep(Duration::from_secs(1)), + } + } + eprintln!("Took to long to exit. Killing..."); + let _ = child.kill(); + child.wait().unwrap(); + + None + } + + fn run_command_and_kill(signal: Signal) { + let mut cmd = Command::new(cargo_bin("substrate")).spawn().unwrap(); + sleep(Duration::from_secs(30)); + assert!(cmd.try_wait().unwrap().is_none(), "the process should still be running"); + kill(Pid::from_raw(cmd.id().try_into().unwrap()), signal).unwrap(); + assert_eq!( + wait_for(&mut cmd, 30).map(|x| x.success()), + Some(true), + "the pocess must exit gracefully after signal {}", + signal, + ); + } + + run_command_and_kill(SIGINT); + run_command_and_kill(SIGTERM); +} diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index 785a6fb073..7f72689336 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -35,6 +35,7 @@ use sc_service::{ RuntimeGenesis, ChainSpecExtension, PruningMode, ChainSpec, AbstractService, Roles as ServiceRoles, }; +pub use sc_service::config::VersionInfo; use sc_network::{ self, multiaddr::Protocol, @@ -74,32 +75,11 @@ const DEFAULT_NETWORK_CONFIG_PATH : &'static str = "network"; /// default sub directory to store database const DEFAULT_DB_CONFIG_PATH : &'static str = "db"; /// default sub directory for the key store -const DEFAULT_KEYSTORE_CONFIG_PATH : &'static str = "keystore"; +const DEFAULT_KEYSTORE_CONFIG_PATH : &'static str = "keystore"; /// The maximum number of characters for a node name. const NODE_NAME_MAX_LENGTH: usize = 32; -/// Executable version. Used to pass version information from the root crate. -#[derive(Clone)] -pub struct VersionInfo { - /// Implementaiton name. - pub name: &'static str, - /// Implementation version. - pub version: &'static str, - /// SCM Commit hash. - pub commit: &'static str, - /// Executable file name. - pub executable_name: &'static str, - /// Executable file description. - pub description: &'static str, - /// Executable file author. - pub author: &'static str, - /// Support URL. - pub support_url: &'static str, - /// Copyright starting year (x-current year) - pub copyright_start_year: i32, -} - fn get_chain_key(cli: &SharedParams) -> String { match cli.chain { Some(ref chain) => chain.clone(), @@ -120,8 +100,12 @@ fn generate_node_name() -> String { result } -/// Load spec give shared params and spec factory. -pub fn load_spec(cli: &SharedParams, factory: F) -> error::Result> where +/// Load spec to `Configuration` from shared params and spec factory. +pub fn load_spec<'a, G, E, F>( + mut config: &'a mut Configuration, + cli: &SharedParams, + factory: F, +) -> error::Result<&'a ChainSpec> where G: RuntimeGenesis, E: ChainSpecExtension, F: FnOnce(&str) -> Result>, String>, @@ -131,7 +115,13 @@ pub fn load_spec(cli: &SharedParams, factory: F) -> error::Result spec, None => ChainSpec::from_json_file(PathBuf::from(chain_key))? }; - Ok(spec) + + config.network.boot_nodes = spec.boot_nodes().to_vec(); + config.telemetry_endpoints = spec.telemetry_endpoints().clone(); + + config.chain_spec = Some(spec); + + Ok(config.chain_spec.as_ref().unwrap()) } fn base_path(cli: &SharedParams, version: &VersionInfo) -> PathBuf { @@ -243,8 +233,8 @@ where SL: AbstractService + Unpin, SF: AbstractService + Unpin, { - init(&mut config, spec_factory, &run_cmd.shared_params, version)?; - + init(&run_cmd.shared_params, version)?; + load_spec(&mut config, &run_cmd.shared_params, spec_factory)?; run_cmd.run(config, new_light, new_full, version) } @@ -266,30 +256,21 @@ where <<::Header as HeaderT>::Number as std::str::FromStr>::Err: std::fmt::Debug, ::Hash: std::str::FromStr, { - init(&mut config, spec_factory, &subcommand.get_shared_params(), version)?; + let shared_params = subcommand.get_shared_params(); + init(shared_params, version)?; + load_spec(&mut config, shared_params, spec_factory)?; subcommand.run(config, builder) } -/// Initialize substrate and its configuration +/// Initialize substrate. This must be done only once. /// /// This method: /// /// 1. set the panic handler /// 2. raise the FD limit /// 3. initialize the logger -/// 4. update the configuration provided with the chain specification, config directory, -/// information (version, commit), database's path, boot nodes and telemetry endpoints -pub fn init( - mut config: &mut Configuration, - spec_factory: F, - shared_params: &SharedParams, - version: &VersionInfo, -) -> error::Result<()> -where - G: RuntimeGenesis, - E: ChainSpecExtension, - F: FnOnce(&str) -> Result>, String>, +pub fn init(shared_params: &SharedParams, version: &VersionInfo) -> error::Result<()> { let full_version = sc_service::config::full_version_from_strs( version.version, @@ -300,21 +281,6 @@ where fdlimit::raise_fd_limit(); init_logger(shared_params.log.as_ref().map(|v| v.as_ref()).unwrap_or("")); - config.chain_spec = Some(load_spec(shared_params, spec_factory)?); - config.config_dir = Some(base_path(shared_params, version)); - config.impl_commit = version.commit; - config.impl_version = version.version; - - config.database = DatabaseConfig::Path { - path: config - .in_chain_config_dir(DEFAULT_DB_CONFIG_PATH) - .expect("We provided a base_path/config_dir."), - cache_size: None, - }; - - config.network.boot_nodes = config.expect_chain_spec().boot_nodes().to_vec(); - config.telemetry_endpoints = config.expect_chain_spec().telemetry_endpoints().clone(); - Ok(()) } @@ -419,8 +385,6 @@ fn fill_network_configuration( ]; } - config.public_addresses = Vec::new(); - config.client_version = client_id; config.node_key = node_key::node_key_config(cli.node_key_params, &config.net_config_path)?; @@ -496,10 +460,8 @@ pub fn fill_import_params( where G: RuntimeGenesis, { - match config.database { - DatabaseConfig::Path { ref mut cache_size, .. } => - *cache_size = Some(cli.database_cache_size), - DatabaseConfig::Custom(_) => {}, + if let Some(DatabaseConfig::Path { ref mut cache_size, .. }) = config.database { + *cache_size = Some(cli.database_cache_size); } config.state_cache_size = cli.state_cache_size; @@ -549,14 +511,30 @@ where Ok(()) } -/// Update and prepare a `Configuration` with command line parameters of `RunCmd` +/// Update and prepare a `Configuration` with command line parameters of `RunCmd` and `VersionInfo` pub fn update_config_for_running_node( mut config: &mut Configuration, cli: RunCmd, + version: &VersionInfo, ) -> error::Result<()> where G: RuntimeGenesis, { + if config.config_dir.is_none() { + config.config_dir = Some(base_path(&cli.shared_params, version)); + } + + if config.database.is_none() { + // NOTE: the loading of the DatabaseConfig is voluntarily delayed to here + // in case config.config_dir has been customized + config.database = Some(DatabaseConfig::Path { + path: config + .in_chain_config_dir(DEFAULT_DB_CONFIG_PATH) + .expect("We provided a base_path/config_dir."), + cache_size: None, + }); + } + fill_config_keystore_password_and_path(&mut config, &cli)?; let keyring = cli.get_keyring(); @@ -580,16 +558,13 @@ where (_, Some(keyring)) => keyring.to_string(), (None, None) => generate_node_name(), }; - match node_key::is_node_name_valid(&config.name) { - Ok(_) => (), - Err(msg) => Err( - error::Error::Input( - format!("Invalid node name '{}'. Reason: {}. If unsure, use none.", - config.name, - msg - ) + if let Err(msg) = node_key::is_node_name_valid(&config.name) { + return Err(error::Error::Input( + format!("Invalid node name '{}'. Reason: {}. If unsure, use none.", + config.name, + msg, ) - )? + )); } // set sentry mode (i.e. act as an authority but **never** actively participate) @@ -625,16 +600,16 @@ where } }); - if config.rpc_http.is_none() { + if config.rpc_http.is_none() || cli.rpc_port.is_some() { let rpc_interface: &str = interface_str(cli.rpc_external, cli.unsafe_rpc_external, cli.validator)?; config.rpc_http = Some(parse_address(&format!("{}:{}", rpc_interface, 9933), cli.rpc_port)?); } - if config.rpc_ws.is_none() { + if config.rpc_ws.is_none() || cli.ws_port.is_some() { let ws_interface: &str = interface_str(cli.ws_external, cli.unsafe_ws_external, cli.validator)?; config.rpc_ws = Some(parse_address(&format!("{}:{}", ws_interface, 9944), cli.ws_port)?); } - if config.grafana_port.is_none() { + if config.grafana_port.is_none() || cli.grafana_port.is_some() { let grafana_interface: &str = if cli.grafana_external { "0.0.0.0" } else { "127.0.0.1" }; config.grafana_port = Some( parse_address(&format!("{}:{}", grafana_interface, 9955), cli.grafana_port)? @@ -781,6 +756,17 @@ fn kill_color(s: &str) -> String { mod tests { use super::*; + const TEST_VERSION_INFO: &'static VersionInfo = &VersionInfo { + name: "node-test", + version: "0.1.0", + commit: "some_commit", + executable_name: "node-test", + description: "description", + author: "author", + support_url: "http://example.org", + copyright_start_year: 2020, + }; + #[test] fn keystore_path_is_generated_correctly() { let chain_spec = ChainSpec::from_genesis( @@ -805,6 +791,7 @@ mod tests { update_config_for_running_node( &mut node_config, run_cmds.clone(), + TEST_VERSION_INFO, ).unwrap(); let expected_path = match keystore_path { @@ -815,4 +802,60 @@ mod tests { assert_eq!(expected_path, node_config.keystore.path().unwrap().to_owned()); } } + + #[test] + fn ensure_load_spec_provide_defaults() { + let chain_spec = ChainSpec::from_genesis( + "test", + "test-id", + || (), + vec!["boo".to_string()], + Some(TelemetryEndpoints::new(vec![("foo".to_string(), 42)])), + None, + None, + None::<()>, + ); + + let args: Vec<&str> = vec![]; + let cli = RunCmd::from_iter(args); + + let mut config = Configuration::new(TEST_VERSION_INFO); + load_spec(&mut config, &cli.shared_params, |_| Ok(Some(chain_spec))).unwrap(); + + assert!(config.chain_spec.is_some()); + assert!(!config.network.boot_nodes.is_empty()); + assert!(config.telemetry_endpoints.is_some()); + } + + #[test] + fn ensure_update_config_for_running_node_provides_defaults() { + let chain_spec = ChainSpec::from_genesis( + "test", + "test-id", + || (), + vec![], + None, + None, + None, + None::<()>, + ); + + let args: Vec<&str> = vec![]; + let cli = RunCmd::from_iter(args); + + let mut config = Configuration::new(TEST_VERSION_INFO); + config.chain_spec = Some(chain_spec); + update_config_for_running_node(&mut config, cli, TEST_VERSION_INFO).unwrap(); + + assert!(config.config_dir.is_some()); + assert!(config.database.is_some()); + if let Some(DatabaseConfig::Path { ref cache_size, .. }) = config.database { + assert!(cache_size.is_some()); + } else { + panic!("invalid config.database variant"); + } + assert!(!config.name.is_empty()); + assert!(config.network.config_path.is_some()); + assert!(!config.network.listen_addresses.is_empty()); + } } diff --git a/client/cli/src/params.rs b/client/cli/src/params.rs index eddd8578b3..3a4aa319c6 100644 --- a/client/cli/src/params.rs +++ b/client/cli/src/params.rs @@ -936,6 +936,7 @@ impl RunCmd { crate::update_config_for_running_node( &mut config, self, + &version, )?; crate::run_node(config, new_light, new_full, &version) @@ -1003,7 +1004,7 @@ impl ExportBlocksCmd { crate::fill_config_keystore_in_memory(&mut config)?; - if let DatabaseConfig::Path { ref path, .. } = &config.database { + if let DatabaseConfig::Path { ref path, .. } = config.expect_database() { info!("DB path: {}", path.display()); } let from = self.from.as_ref().and_then(|f| f.parse().ok()).unwrap_or(1); @@ -1124,7 +1125,7 @@ impl PurgeChainCmd { crate::fill_config_keystore_in_memory(&mut config)?; - let db_path = match config.database { + let db_path = match config.expect_database() { DatabaseConfig::Path { path, .. } => path, _ => { eprintln!("Cannot purge custom database implementation"); diff --git a/client/cli/src/runtime.rs b/client/cli/src/runtime.rs index 3eee94c049..62a2245c9e 100644 --- a/client/cli/src/runtime.rs +++ b/client/cli/src/runtime.rs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +use std::sync::Arc; + use futures::{Future, future, future::FutureExt}; use futures::select; use futures::pin_mut; @@ -91,7 +93,7 @@ where config.task_executor = { let runtime_handle = runtime.handle().clone(); - Some(Box::new(move |fut| { runtime_handle.spawn(fut); })) + Some(Arc::new(move |fut| { runtime_handle.spawn(fut); })) }; let f = future_builder(config)?; @@ -117,7 +119,7 @@ where config.task_executor = { let runtime_handle = runtime.handle().clone(); - Some(Box::new(move |fut| { runtime_handle.spawn(fut); })) + Some(Arc::new(move |fut| { runtime_handle.spawn(fut); })) }; let service = service_builder(config)?; diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 7a6ca8dc79..ad1d225134 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -196,7 +196,7 @@ fn new_full_parts( state_cache_child_ratio: config.state_cache_child_ratio.map(|v| (v, 100)), pruning: config.pruning.clone(), - source: match &config.database { + source: match config.expect_database() { DatabaseConfig::Path { path, cache_size } => sc_client_db::DatabaseSettingsSrc::Path { path: path.clone(), @@ -307,7 +307,7 @@ where TGen: RuntimeGenesis, TCSExt: Extension { state_cache_child_ratio: config.state_cache_child_ratio.map(|v| (v, 100)), pruning: config.pruning.clone(), - source: match &config.database { + source: match config.expect_database() { DatabaseConfig::Path { path, cache_size } => sc_client_db::DatabaseSettingsSrc::Path { path: path.clone(), @@ -1187,7 +1187,7 @@ ServiceBuilder< task_executor: if let Some(exec) = config.task_executor { exec } else { - return Err(Error::TasksExecutorRequired); + return Err(Error::TaskExecutorRequired); }, rpc_handlers, _rpc: rpc, diff --git a/client/service/src/config.rs b/client/service/src/config.rs index cb8170f7f4..f4043d533e 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -28,6 +28,27 @@ use sp_core::crypto::Protected; use target_info::Target; use sc_telemetry::TelemetryEndpoints; +/// Executable version. Used to pass version information from the root crate. +#[derive(Clone)] +pub struct VersionInfo { + /// Implementation name. + pub name: &'static str, + /// Implementation version. + pub version: &'static str, + /// SCM Commit hash. + pub commit: &'static str, + /// Executable file name. + pub executable_name: &'static str, + /// Executable file description. + pub description: &'static str, + /// Executable file author. + pub author: &'static str, + /// Support URL. + pub support_url: &'static str, + /// Copyright starting year (x-current year) + pub copyright_start_year: i32, +} + /// Service configuration. pub struct Configuration { /// Implementation name @@ -39,7 +60,7 @@ pub struct Configuration { /// Node roles. pub roles: Roles, /// How to spawn background tasks. Mandatory, otherwise creating a `Service` will error. - pub task_executor: Option + Send>>) + Send>>, + pub task_executor: Option + Send>>) + Send + Sync>>, /// Extrinsic pool configuration. pub transaction_pool: TransactionPoolOptions, /// Network configuration. @@ -49,7 +70,7 @@ pub struct Configuration { /// Configuration for the keystore. pub keystore: KeystoreConfig, /// Configuration for the database. - pub database: DatabaseConfig, + pub database: Option, /// Size of internal state cache in Bytes pub state_cache_size: usize, /// Size in percent of cache size dedicated to child tries @@ -147,7 +168,7 @@ pub enum DatabaseConfig { impl Default for Configuration { /// Create a default config fn default() -> Self { - let configuration = Configuration { + Configuration { impl_name: "parity-substrate", impl_version: "0.0.0", impl_commit: "", @@ -159,10 +180,7 @@ impl Default for Configuration { transaction_pool: Default::default(), network: Default::default(), keystore: KeystoreConfig::None, - database: DatabaseConfig::Path { - path: Default::default(), - cache_size: Default::default(), - }, + database: None, state_cache_size: Default::default(), state_cache_child_ratio: Default::default(), pruning: PruningMode::default(), @@ -183,14 +201,21 @@ impl Default for Configuration { dev_key_seed: None, tracing_targets: Default::default(), tracing_receiver: Default::default(), - }; - - configuration + } } - } impl Configuration { + /// Create a default config using `VersionInfo` + pub fn new(version: &VersionInfo) -> Self { + let mut config = Configuration::default(); + config.impl_name = version.name; + config.impl_version = version.version; + config.impl_commit = version.commit; + + config + } + /// Returns full version string of this configuration. pub fn full_version(&self) -> String { full_version_from_strs(self.impl_version, self.impl_commit) @@ -220,6 +245,15 @@ impl Configuration { pub fn expect_chain_spec(&self) -> &ChainSpec { self.chain_spec.as_ref().expect("chain_spec must be specified") } + + /// Return a reference to the `DatabaseConfig` of this `Configuration`. + /// + /// ### Panics + /// + /// This method panic if the `database` is `None` + pub fn expect_database(&self) -> &DatabaseConfig { + self.database.as_ref().expect("database must be specified") + } } /// Returns platform info diff --git a/client/service/src/error.rs b/client/service/src/error.rs index 14b03d7e95..059e1c19e4 100644 --- a/client/service/src/error.rs +++ b/client/service/src/error.rs @@ -42,7 +42,7 @@ pub enum Error { SelectChainRequired, /// Tasks executor is missing. #[display(fmt="Tasks executor hasn't been provided.")] - TasksExecutorRequired, + TaskExecutorRequired, /// Other error. Other(String), } diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index dc158f1300..577f36572a 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -96,7 +96,7 @@ pub struct Service { /// Receiver for futures that must be spawned as background tasks. to_spawn_rx: mpsc::UnboundedReceiver<(Pin + Send>>, Cow<'static, str>)>, /// How to spawn background tasks. - task_executor: Box + Send>>) + Send>, + task_executor: Arc + Send>>) + Send + Sync>, rpc_handlers: sc_rpc_server::RpcHandler, _rpc: Box, _telemetry: Option, diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index cb458d533f..2976e66a29 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -133,7 +133,7 @@ fn node_config ( index: usize, spec: &ChainSpec, role: Roles, - task_executor: Box + Send>>) + Send>, + task_executor: Arc + Send>>) + Send + Sync>, key_seed: Option, base_port: u16, root: &TempDir, @@ -183,10 +183,10 @@ fn node_config ( password: None }, config_dir: Some(root.clone()), - database: DatabaseConfig::Path { + database: Some(DatabaseConfig::Path { path: root.join("db"), cache_size: None - }, + }), state_cache_size: 16777216, state_cache_child_ratio: None, pruning: Default::default(), @@ -256,7 +256,7 @@ impl TestNet where for (key, authority) in authorities { let task_executor = { let executor = executor.clone(); - Box::new(move |fut: Pin + Send>>| executor.spawn(fut.unit_error().compat())) + Arc::new(move |fut: Pin + Send>>| executor.spawn(fut.unit_error().compat())) }; let node_config = node_config( self.nodes, @@ -280,7 +280,7 @@ impl TestNet where for full in full { let task_executor = { let executor = executor.clone(); - Box::new(move |fut: Pin + Send>>| executor.spawn(fut.unit_error().compat())) + Arc::new(move |fut: Pin + Send>>| executor.spawn(fut.unit_error().compat())) }; let node_config = node_config(self.nodes, &self.chain_spec, Roles::FULL, task_executor, None, self.base_port, &temp); let addr = node_config.network.listen_addresses.iter().next().unwrap().clone(); @@ -296,7 +296,7 @@ impl TestNet where for light in light { let task_executor = { let executor = executor.clone(); - Box::new(move |fut: Pin + Send>>| executor.spawn(fut.unit_error().compat())) + Arc::new(move |fut: Pin + Send>>| executor.spawn(fut.unit_error().compat())) }; let node_config = node_config(self.nodes, &self.chain_spec, Roles::LIGHT, task_executor, None, self.base_port, &temp); let addr = node_config.network.listen_addresses.iter().next().unwrap().clone(); diff --git a/utils/browser/src/lib.rs b/utils/browser/src/lib.rs index 4f985871f5..d7ffdca1aa 100644 --- a/utils/browser/src/lib.rs +++ b/utils/browser/src/lib.rs @@ -51,18 +51,18 @@ where allow_private_ipv4: true, enable_mdns: false, }; - config.task_executor = Some(Box::new(move |fut| { + config.task_executor = Some(Arc::new(move |fut| { wasm_bindgen_futures::spawn_local(fut) })); config.telemetry_external_transport = Some(transport); config.roles = Roles::LIGHT; config.name = format!("{} (Browser)", name); - config.database = { + config.database = Some({ info!("Opening Indexed DB database '{}'...", name); let db = kvdb_web::Database::open(name, 10) .await?; DatabaseConfig::Custom(Arc::new(db)) - }; + }); config.keystore = KeystoreConfig::InMemory; Ok(config) -- GitLab From 13d88accd2fa81be421b1102ff4c590a69260f09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 6 Feb 2020 16:08:11 +0100 Subject: [PATCH 096/180] Allocator improvements/clean ups (#4838) * FreeingBumpAllocator: Initialize the heads to `u32::max_value()` `self.heads` can point to an element with the index `0` in the heap. This would make the allocator fail to reuse this element. * Simplify the `PREFIX_SIZE` handling --- primitives/allocator/src/freeing_bump.rs | 43 +++++++++++++++--------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/primitives/allocator/src/freeing_bump.rs b/primitives/allocator/src/freeing_bump.rs index 46c314c2c2..f51dc222a2 100644 --- a/primitives/allocator/src/freeing_bump.rs +++ b/primitives/allocator/src/freeing_bump.rs @@ -106,7 +106,7 @@ impl FreeingBumpHeapAllocator { FreeingBumpHeapAllocator { bumper: 0, - heads: [0; N], + heads: [u32::max_value(); N], ptr_offset, total_size: 0, } @@ -138,31 +138,30 @@ impl FreeingBumpHeapAllocator { } let list_index = (item_size.trailing_zeros() - 3) as usize; - let ptr: u32 = if self.heads[list_index] != 0 { + let ptr: u32 = if self.heads[list_index] != u32::max_value() { // Something from the free list - let item = self.heads[list_index]; - let ptr = item + PREFIX_SIZE; + let ptr = self.heads[list_index]; assert!( - ptr + item_size <= max_heap_size, + ptr + item_size + PREFIX_SIZE <= max_heap_size, "Pointer is looked up in list of free entries, into which only valid values are inserted; qed" ); - self.heads[list_index] = self.get_heap_u64(mem, item)? + self.heads[list_index] = self.get_heap_u64(mem, ptr)? .try_into() .map_err(|_| error("read invalid free list pointer"))?; ptr } else { // Nothing to be freed. Bump. - self.bump(item_size, max_heap_size)? + PREFIX_SIZE + self.bump(item_size, max_heap_size)? }; - self.set_heap_u64(mem, ptr - PREFIX_SIZE, list_index as u64)?; + self.set_heap_u64(mem, ptr, list_index as u64)?; self.total_size = self.total_size + item_size + PREFIX_SIZE; trace!("Heap size is {} bytes after allocation", self.total_size); - Ok(Pointer::new(self.ptr_offset + ptr)) + Ok(Pointer::new(self.ptr_offset + ptr + PREFIX_SIZE)) } /// Deallocates the space which was allocated for a pointer. @@ -173,18 +172,18 @@ impl FreeingBumpHeapAllocator { /// - `ptr` - pointer to the allocated chunk pub fn deallocate(&mut self, mem: &mut [u8], ptr: Pointer) -> Result<(), Error> { let ptr = u32::from(ptr) - self.ptr_offset; - if ptr < PREFIX_SIZE { - return Err(error("Invalid pointer for deallocation")); - } + let ptr = ptr.checked_sub(PREFIX_SIZE).ok_or_else(|| + error("Invalid pointer for deallocation") + )?; - let list_index: usize = self.get_heap_u64(mem, ptr - PREFIX_SIZE)? + let list_index: usize = self.get_heap_u64(mem, ptr)? .try_into() .map_err(|_| error("read invalid list index"))?; if list_index > self.heads.len() { return Err(error("read invalid list index")); } - self.set_heap_u64(mem, ptr - PREFIX_SIZE, self.heads[list_index] as u64)?; - self.heads[list_index] = ptr - PREFIX_SIZE; + self.set_heap_u64(mem, ptr, self.heads[list_index] as u64)?; + self.heads[list_index] = ptr; let item_size = Self::get_item_size_from_index(list_index); self.total_size = self.total_size.checked_sub(item_size as u32 + PREFIX_SIZE) @@ -357,7 +356,7 @@ mod tests { // then // should have re-allocated assert_eq!(ptr3, to_pointer(padded_offset + 16 + PREFIX_SIZE)); - assert_eq!(heap.heads, [0; N]); + assert_eq!(heap.heads, [u32::max_value(); N]); } #[test] @@ -563,4 +562,16 @@ mod tests { assert_eq!(item_size as u32, MAX_POSSIBLE_ALLOCATION); } + #[test] + fn deallocate_needs_to_maintain_linked_list() { + let mut mem = [0u8; 8 * 2 * 4 + ALIGNMENT as usize]; + let mut heap = FreeingBumpHeapAllocator::new(0); + + // Allocate and free some pointers + let ptrs = (0..4).map(|_| heap.allocate(&mut mem, 8).unwrap()).collect::>(); + ptrs.into_iter().for_each(|ptr| heap.deallocate(&mut mem, ptr).unwrap()); + + // Second time we should be able to allocate all of them again. + let _ = (0..4).map(|_| heap.allocate(&mut mem, 8).unwrap()).collect::>(); + } } -- GitLab From 203445bb155249e0e69592864a23510fd6c4c46e Mon Sep 17 00:00:00 2001 From: gabriel klawitter Date: Thu, 6 Feb 2020 16:47:44 +0100 Subject: [PATCH 097/180] ci: enable build for pre-tags (#4836) * build for pre-tags * shallow clone rustdocs --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ced3e33eaa..62a6c2de32 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -65,6 +65,7 @@ variables: only: - master - /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 + - /^pre-v[0-9]+\.[0-9]+-[0-9a-f]+$/ - web @@ -515,7 +516,7 @@ publish-gh-doc: insteadOf = "https://github.com/" EOC - unset GITHUB_TOKEN - - git clone https://github.com/substrate-developer-hub/rustdocs.git + - git clone --depth 1 https://github.com/substrate-developer-hub/rustdocs.git - rsync -ax --delete ./crate-docs/ ./rustdocs/${CI_COMMIT_REF_NAME}/ - cd ./rustdocs; git add . - git commit -m "update rustdoc ${CI_COMMIT_REF_NAME}" -- GitLab From 8d7bf66719ff5469c71ea50f5651c5df638c65dd Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Thu, 6 Feb 2020 16:48:38 +0100 Subject: [PATCH 098/180] Refactor epoch changes to a separate crate (#4785) * Init epoch changes module * Initial integration of new epoch changes module for BABE * Fix all initial compile errors * rename: digest -> digests * Fix babe tests * Bump impl_version * Fix more test issues * Remove test flag for tree It unfortunately won't work for multiple crates. * Update cargo lock * Fix duplicate parking_lot version * Add missing license header --- Cargo.lock | 13 ++ Cargo.toml | 3 +- bin/node/runtime/src/lib.rs | 2 +- client/consensus/babe/Cargo.toml | 1 + client/consensus/babe/src/authorship.rs | 18 +- client/consensus/babe/src/aux_schema.rs | 16 +- client/consensus/babe/src/lib.rs | 76 +++++-- client/consensus/babe/src/tests.rs | 5 +- client/consensus/babe/src/verification.rs | 12 +- client/consensus/epochs/Cargo.toml | 14 ++ .../epoch_changes.rs => epochs/src/lib.rs} | 203 ++++++++++-------- frame/babe/src/lib.rs | 15 +- frame/babe/src/tests.rs | 4 +- .../babe/src/{digest.rs => digests.rs} | 57 +++-- primitives/consensus/babe/src/lib.rs | 44 +--- 15 files changed, 265 insertions(+), 218 deletions(-) create mode 100644 client/consensus/epochs/Cargo.toml rename client/consensus/{babe/src/epoch_changes.rs => epochs/src/lib.rs} (79%) rename primitives/consensus/babe/src/{digest.rs => digests.rs} (85%) diff --git a/Cargo.lock b/Cargo.lock index 3f94778b84..4771b78586 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5805,6 +5805,7 @@ dependencies = [ "sc-block-builder", "sc-client", "sc-client-api", + "sc-consensus-epochs", "sc-consensus-slots", "sc-consensus-uncles", "sc-executor", @@ -5832,6 +5833,18 @@ dependencies = [ "tokio 0.1.22", ] +[[package]] +name = "sc-consensus-epochs" +version = "0.8.0" +dependencies = [ + "fork-tree", + "parity-scale-codec", + "parking_lot 0.10.0", + "sc-client-api", + "sp-blockchain", + "sp-runtime", +] + [[package]] name = "sc-consensus-manual-seal" version = "0.8.0" diff --git a/Cargo.toml b/Cargo.toml index 552f1eadc7..47e3fe3f0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,8 +25,9 @@ members = [ "client/consensus/babe", "client/consensus/manual-seal", "client/consensus/pow", - "client/consensus/slots", "client/consensus/uncles", + "client/consensus/slots", + "client/consensus/epochs", "client/db", "client/executor", "client/executor/common", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 40342c1ce8..7b718ca21f 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -80,7 +80,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 214, - impl_version: 0, + impl_version: 1, apis: RUNTIME_API_VERSIONS, }; diff --git a/client/consensus/babe/Cargo.toml b/client/consensus/babe/Cargo.toml index 551754c7b6..23bf9cea28 100644 --- a/client/consensus/babe/Cargo.toml +++ b/client/consensus/babe/Cargo.toml @@ -22,6 +22,7 @@ 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 = "0.8", path = "../../" } +sc-consensus-epochs = { version = "0.8", path = "../epochs" } 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" } diff --git a/client/consensus/babe/src/authorship.rs b/client/consensus/babe/src/authorship.rs index 62667ef397..8b28aefa2f 100644 --- a/client/consensus/babe/src/authorship.rs +++ b/client/consensus/babe/src/authorship.rs @@ -17,13 +17,17 @@ //! BABE authority selection and slot claiming. use merlin::Transcript; -use sp_consensus_babe::{AuthorityId, BabeAuthorityWeight, BABE_ENGINE_ID, BABE_VRF_PREFIX}; -use sp_consensus_babe::{Epoch, SlotNumber, AuthorityPair, BabePreDigest, BabeConfiguration}; +use sp_consensus_babe::{ + AuthorityId, BabeAuthorityWeight, BABE_ENGINE_ID, BABE_VRF_PREFIX, + SlotNumber, AuthorityPair, BabeConfiguration +}; +use sp_consensus_babe::digests::PreDigest; use sp_core::{U256, blake2_256}; use codec::Encode; use schnorrkel::vrf::VRFInOut; use sp_core::Pair; use sc_keystore::KeyStorePtr; +use super::Epoch; /// Calculates the primary selection threshold for a given authority, taking /// into account `c` (`1 - c` represents the probability of a slot being empty). @@ -104,7 +108,7 @@ fn claim_secondary_slot( authorities: &[(AuthorityId, BabeAuthorityWeight)], keystore: &KeyStorePtr, randomness: [u8; 32], -) -> Option<(BabePreDigest, AuthorityPair)> { +) -> Option<(PreDigest, AuthorityPair)> { if authorities.is_empty() { return None; } @@ -124,7 +128,7 @@ fn claim_secondary_slot( }) { if pair.public() == *expected_author { - let pre_digest = BabePreDigest::Secondary { + let pre_digest = PreDigest::Secondary { slot_number, authority_index: authority_index as u32, }; @@ -145,7 +149,7 @@ pub(super) fn claim_slot( epoch: &Epoch, config: &BabeConfiguration, keystore: &KeyStorePtr, -) -> Option<(BabePreDigest, AuthorityPair)> { +) -> Option<(PreDigest, AuthorityPair)> { claim_primary_slot(slot_number, epoch, config.c, keystore) .or_else(|| { if config.secondary_slots { @@ -175,7 +179,7 @@ fn claim_primary_slot( epoch: &Epoch, c: (u64, u64), keystore: &KeyStorePtr, -) -> Option<(BabePreDigest, AuthorityPair)> { +) -> Option<(PreDigest, AuthorityPair)> { let Epoch { authorities, randomness, epoch_index, .. } = epoch; let keystore = keystore.read(); @@ -196,7 +200,7 @@ fn claim_primary_slot( let pre_digest = get_keypair(&pair) .vrf_sign_after_check(transcript, |inout| super::authorship::check_primary_threshold(inout, threshold)) .map(|s| { - BabePreDigest::Primary { + PreDigest::Primary { slot_number, vrf_output: s.0.to_output(), vrf_proof: s.1, diff --git a/client/consensus/babe/src/aux_schema.rs b/client/consensus/babe/src/aux_schema.rs index 170c2bf42d..2f64157f22 100644 --- a/client/consensus/babe/src/aux_schema.rs +++ b/client/consensus/babe/src/aux_schema.rs @@ -16,6 +16,8 @@ //! Schema for BABE epoch changes in the aux-db. +use std::sync::Arc; +use parking_lot::Mutex; use log::info; use codec::{Decode, Encode}; @@ -23,8 +25,8 @@ 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}; +use sc_consensus_epochs::{EpochChangesFor, SharedEpochChanges}; +use crate::Epoch; const BABE_EPOCH_CHANGES: &[u8] = b"babe_epoch_changes"; @@ -49,14 +51,14 @@ fn load_decode(backend: &B, key: &[u8]) -> ClientResult> /// Load or initialize persistent epoch change data from backend. pub(crate) fn load_epoch_changes( backend: &B, -) -> ClientResult> { - let epoch_changes = load_decode::<_, EpochChangesFor>(backend, BABE_EPOCH_CHANGES)? - .map(Into::into) +) -> ClientResult> { + let epoch_changes = load_decode::<_, EpochChangesFor>(backend, BABE_EPOCH_CHANGES)? + .map(|v| Arc::new(Mutex::new(v))) .unwrap_or_else(|| { info!(target: "babe", "Creating empty BABE epoch changes on what appears to be first startup." ); - SharedEpochChanges::new() + SharedEpochChanges::::default() }); // rebalance the tree after deserialization. this isn't strictly necessary @@ -70,7 +72,7 @@ pub(crate) fn load_epoch_changes( /// Update the epoch changes on disk after a change. pub(crate) fn write_epoch_changes( - epoch_changes: &EpochChangesFor, + epoch_changes: &EpochChangesFor, write_aux: F, ) -> R where F: FnOnce(&[(&'static [u8], &[u8])]) -> R, diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index 8480972311..dbf61692eb 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -59,8 +59,10 @@ #![forbid(unsafe_code)] #![warn(missing_docs)] pub use sp_consensus_babe::{ - BabeApi, ConsensusLog, BABE_ENGINE_ID, BabePreDigest, SlotNumber, BabeConfiguration, - CompatibleDigestItem, + BabeApi, ConsensusLog, BABE_ENGINE_ID, SlotNumber, BabeConfiguration, + AuthorityId, AuthorityPair, AuthoritySignature, + BabeAuthorityWeight, VRF_OUTPUT_LENGTH, + digests::{PreDigest, CompatibleDigestItem, NextEpochDescriptor}, }; pub use sp_consensus::SyncOracle; use std::{collections::HashMap, sync::Arc, u64, pin::Pin, time::{Instant, Duration}}; @@ -101,26 +103,58 @@ use log::{warn, debug, info, trace}; use sc_consensus_slots::{ SlotWorker, SlotInfo, SlotCompatible, StorageChanges, CheckedHeader, check_equivocation, }; -use epoch_changes::descendent_query; +use sc_consensus_epochs::{descendent_query, SharedEpochChanges, EpochChangesFor, Epoch as EpochT}; use sp_blockchain::{ Result as ClientResult, Error as ClientError, HeaderBackend, ProvideCache, HeaderMetadata }; use schnorrkel::SignatureError; - +use codec::{Encode, Decode}; use sp_api::ApiExt; mod aux_schema; mod verification; -mod epoch_changes; mod authorship; #[cfg(test)] mod tests; -pub use sp_consensus_babe::{ - AuthorityId, AuthorityPair, AuthoritySignature, Epoch, NextEpochDescriptor, -}; -pub use epoch_changes::{EpochChanges, EpochChangesFor, SharedEpochChanges}; +/// BABE epoch information +#[derive(Decode, Encode, Default, PartialEq, Eq, Clone, Debug)] +pub struct Epoch { + /// The epoch index + pub epoch_index: u64, + /// The starting slot of the epoch, + pub start_slot: SlotNumber, + /// The duration of this epoch + pub duration: SlotNumber, + /// The authorities and their weights + pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, + /// Randomness for this epoch + pub randomness: [u8; VRF_OUTPUT_LENGTH], +} + +impl EpochT for Epoch { + type NextEpochDescriptor = NextEpochDescriptor; + type SlotNumber = SlotNumber; + + fn increment(&self, descriptor: NextEpochDescriptor) -> Epoch { + Epoch { + epoch_index: self.epoch_index + 1, + start_slot: self.start_slot + self.duration, + duration: self.duration, + authorities: descriptor.authorities, + randomness: descriptor.randomness, + } + } + + fn start_slot(&self) -> SlotNumber { + self.start_slot + } + + fn end_slot(&self) -> SlotNumber { + self.start_slot + self.duration + } +} #[derive(derive_more::Display, Debug)] enum Error { @@ -343,7 +377,7 @@ struct BabeWorker { sync_oracle: SO, force_authoring: bool, keystore: KeyStorePtr, - epoch_changes: SharedEpochChanges, + epoch_changes: SharedEpochChanges, config: Config, } @@ -361,7 +395,7 @@ impl sc_consensus_slots::SimpleSlotWorker for BabeWork Error: std::error::Error + Send + From + From + 'static, { type EpochData = Epoch; - type Claim = (BabePreDigest, AuthorityPair); + type Claim = (PreDigest, AuthorityPair); type SyncOracle = SO; type CreateProposer = Pin> + Send + 'static @@ -533,12 +567,12 @@ impl SlotWorker for BabeWorker where /// Extract the BABE pre digest from the given header. Pre-runtime digests are /// mandatory, the function will return `Err` if none is found. -fn find_pre_digest(header: &B::Header) -> Result> +fn find_pre_digest(header: &B::Header) -> Result> { // genesis block doesn't contain a pre digest so let's generate a // dummy one to not break any invariants in the rest of the code if header.number().is_zero() { - return Ok(BabePreDigest::Secondary { + return Ok(PreDigest::Secondary { slot_number: 0, authority_index: 0, }); @@ -597,7 +631,7 @@ impl SlotCompatible for TimeSource { #[derive(Clone)] pub struct BabeLink { time_source: TimeSource, - epoch_changes: SharedEpochChanges, + epoch_changes: SharedEpochChanges, config: Config, } /// A verifier for Babe blocks. @@ -606,7 +640,7 @@ pub struct BabeVerifier { api: Arc, inherent_data_providers: sp_inherents::InherentDataProviders, config: Config, - epoch_changes: SharedEpochChanges, + epoch_changes: SharedEpochChanges, time_source: TimeSource, } @@ -711,7 +745,7 @@ impl Verifier for BabeVerifier::Runtime)?; + .map_err(Error::::Runtime)?; let (_, slot_now, _) = self.time_source.extract_timestamp_and_slot(&inherent_data) .map_err(Error::::Extraction)?; @@ -855,7 +889,7 @@ pub struct BabeBlockImport { inner: I, client: Arc>, api: Arc, - epoch_changes: SharedEpochChanges, + epoch_changes: SharedEpochChanges, config: Config, } @@ -875,7 +909,7 @@ impl BabeBlockImport { fn new( client: Arc>, api: Arc, - epoch_changes: SharedEpochChanges, + epoch_changes: SharedEpochChanges, block_import: I, config: Config, ) -> Self { @@ -1114,7 +1148,7 @@ impl BlockImport for BabeBlockImport( client: &Client, - epoch_changes: &mut EpochChangesFor, + epoch_changes: &mut EpochChangesFor, ) -> Result<(), ConsensusError> where Block: BlockT, E: CallExecutor + Send + Sync, @@ -1161,7 +1195,7 @@ pub fn block_import( RA: Send + Sync, Client: AuxStore, { - let epoch_changes = aux_schema::load_epoch_changes(&*client)?; + let epoch_changes = aux_schema::load_epoch_changes::(&*client)?; let link = BabeLink { epoch_changes: epoch_changes.clone(), time_source: Default::default(), @@ -1245,7 +1279,7 @@ pub mod test_helpers { client: &C, keystore: &KeyStorePtr, link: &BabeLink, - ) -> Option where + ) -> Option where B: BlockT, C: ProvideRuntimeApi + ProvideCache + diff --git a/client/consensus/babe/src/tests.rs b/client/consensus/babe/src/tests.rs index 3339c06d65..701155e7cc 100644 --- a/client/consensus/babe/src/tests.rs +++ b/client/consensus/babe/src/tests.rs @@ -59,7 +59,7 @@ type Mutator = Arc; #[derive(Clone)] struct DummyFactory { client: Arc, - epoch_changes: crate::SharedEpochChanges, + epoch_changes: SharedEpochChanges, config: Config, mutator: Mutator, } @@ -105,7 +105,6 @@ impl DummyProposer { > > { - use codec::Encode; let block_builder = self.factory.client.new_block_at( &BlockId::Hash(self.parent_hash), pre_digests, @@ -558,7 +557,7 @@ fn propose_and_import_block( let pre_digest = sp_runtime::generic::Digest { logs: vec![ Item::babe_pre_digest( - BabePreDigest::Secondary { + PreDigest::Secondary { authority_index: 0, slot_number, }, diff --git a/client/consensus/babe/src/verification.rs b/client/consensus/babe/src/verification.rs index ee5a99ec9d..70418b8aea 100644 --- a/client/consensus/babe/src/verification.rs +++ b/client/consensus/babe/src/verification.rs @@ -18,11 +18,11 @@ use schnorrkel::vrf::{VRFOutput, VRFProof}; 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 sp_consensus_babe::{AuthoritySignature, SlotNumber, AuthorityIndex, AuthorityPair, AuthorityId}; +use sp_consensus_babe::digests::{PreDigest, CompatibleDigestItem}; use sc_consensus_slots::CheckedHeader; use log::{debug, trace}; -use super::{find_pre_digest, babe_err, BlockT, Error}; +use super::{find_pre_digest, babe_err, Epoch, BlockT, Error}; use super::authorship::{make_transcript, calculate_primary_threshold, check_primary_threshold, secondary_slot_author}; /// BABE verification parameters @@ -32,7 +32,7 @@ pub(super) struct VerificationParams<'a, B: 'a + BlockT> { /// the pre-digest of the header being verified. this is optional - if prior /// verification code had to read it, it can be included here to avoid duplicate /// work. - pub(super) pre_digest: Option, + pub(super) pre_digest: Option, /// the slot number of the current time. pub(super) slot_now: SlotNumber, /// epoch descriptor of the epoch this block _should_ be under, if it's valid. @@ -93,7 +93,7 @@ pub(super) fn check_header( }; match &pre_digest { - BabePreDigest::Primary { vrf_output, vrf_proof, authority_index, slot_number } => { + PreDigest::Primary { vrf_output, vrf_proof, authority_index, slot_number } => { debug!(target: "babe", "Verifying Primary block"); let digest = (vrf_output, vrf_proof, *authority_index, *slot_number); @@ -106,7 +106,7 @@ pub(super) fn check_header( config.c, )?; }, - BabePreDigest::Secondary { authority_index, slot_number } if config.secondary_slots => { + PreDigest::Secondary { authority_index, slot_number } if config.secondary_slots => { debug!(target: "babe", "Verifying Secondary block"); let digest = (*authority_index, *slot_number); diff --git a/client/consensus/epochs/Cargo.toml b/client/consensus/epochs/Cargo.toml new file mode 100644 index 0000000000..e08553a241 --- /dev/null +++ b/client/consensus/epochs/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "sc-consensus-epochs" +version = "0.8.0" +authors = ["Parity Technologies "] +description = "Generic epochs-based utilities for consensus" +edition = "2018" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0", features = ["derive"] } +parking_lot = "0.10.0" +fork-tree = { version = "2.0.0", path = "../../../utils/fork-tree" } +sp-runtime = { path = "../../../primitives/runtime" } +sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" } +sc-client-api = { path = "../../api" } diff --git a/client/consensus/babe/src/epoch_changes.rs b/client/consensus/epochs/src/lib.rs similarity index 79% rename from client/consensus/babe/src/epoch_changes.rs rename to client/consensus/epochs/src/lib.rs index 01e957c499..cf3d9f5c4c 100644 --- a/client/consensus/babe/src/epoch_changes.rs +++ b/client/consensus/epochs/src/lib.rs @@ -14,20 +14,15 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Handling epoch changes in BABE. -//! -//! This exposes the `SharedEpochChanges`, which is a wrapper around a -//! persistent DAG superimposed over the forks of the blockchain. +//! Generic utilities for epoch-based consensus engines. -use std::sync::Arc; -use sp_consensus_babe::{Epoch, SlotNumber, NextEpochDescriptor}; -use fork_tree::ForkTree; -use parking_lot::{Mutex, MutexGuard}; -use sp_runtime::traits::{Block as BlockT, NumberFor, One, Zero}; +use std::{sync::Arc, ops::Add}; +use parking_lot::Mutex; use codec::{Encode, Decode}; +use fork_tree::ForkTree; use sc_client_api::utils::is_descendent_of; use sp_blockchain::{HeaderMetadata, HeaderBackend, Error as ClientError}; -use std::ops::Add; +use sp_runtime::traits::{Block as BlockT, NumberFor, One, Zero}; /// A builder for `is_descendent_of` functions. pub trait IsDescendentOfBuilder { @@ -48,13 +43,13 @@ pub trait IsDescendentOfBuilder { } /// Produce a descendent query object given the client. -pub(crate) fn descendent_query(client: &H) -> HeaderBackendDescendentBuilder<&H, Block> { +pub fn descendent_query(client: &H) -> HeaderBackendDescendentBuilder<&H, Block> { HeaderBackendDescendentBuilder(client, std::marker::PhantomData) } /// Wrapper to get around unconstrained type errors when implementing /// `IsDescendentOfBuilder` for header backends. -pub(crate) struct HeaderBackendDescendentBuilder(H, std::marker::PhantomData); +pub struct HeaderBackendDescendentBuilder(H, std::marker::PhantomData); impl<'a, H, Block> IsDescendentOfBuilder for HeaderBackendDescendentBuilder<&'a H, Block> where @@ -71,49 +66,73 @@ impl<'a, H, Block> IsDescendentOfBuilder } } +/// Epoch data, distinguish whether it is genesis or not. +pub trait Epoch { + /// Descriptor for the next epoch. + type NextEpochDescriptor; + /// Type of the slot number. + type SlotNumber: Ord; + + /// Increment the epoch data, using the next epoch descriptor. + fn increment(&self, descriptor: Self::NextEpochDescriptor) -> Self; + + /// Produce the "end slot" of the epoch. This is NOT inclusive to the epoch, + /// i.e. the slots covered by the epoch are `self.start_slot() .. self.end_slot()`. + fn end_slot(&self) -> Self::SlotNumber; + /// Produce the "start slot" of the epoch. + fn start_slot(&self) -> Self::SlotNumber; +} + /// An unimported genesis epoch. -pub struct UnimportedGenesis(Epoch); +pub struct UnimportedGenesisEpoch(Epoch); /// The viable epoch under which a block can be verified. /// /// If this is the first non-genesis block in the chain, then it will /// hold an `UnimportedGenesis` epoch. -pub enum ViableEpoch { - Genesis(UnimportedGenesis), +pub enum ViableEpoch { + /// Genesis viable epoch data. + Genesis(UnimportedGenesisEpoch), + /// Regular viable epoch data. Regular(Epoch), } -impl From for ViableEpoch { - fn from(epoch: Epoch) -> ViableEpoch { +impl From for ViableEpoch { + fn from(epoch: Epoch) -> ViableEpoch { ViableEpoch::Regular(epoch) } } -impl AsRef for ViableEpoch { +impl AsRef for ViableEpoch { fn as_ref(&self) -> &Epoch { match *self { - ViableEpoch::Genesis(UnimportedGenesis(ref e)) => e, + ViableEpoch::Genesis(UnimportedGenesisEpoch(ref e)) => e, ViableEpoch::Regular(ref e) => e, } } } -impl ViableEpoch { +impl ViableEpoch where + Epoch: crate::Epoch + Clone, +{ /// Extract the underlying epoch, disregarding the fact that a genesis /// epoch may be unimported. pub fn into_inner(self) -> Epoch { match self { - ViableEpoch::Genesis(UnimportedGenesis(e)) => e, + ViableEpoch::Genesis(UnimportedGenesisEpoch(e)) => e, ViableEpoch::Regular(e) => e, } } /// Increment the epoch, yielding an `IncrementedEpoch` to be imported /// into the fork-tree. - pub fn increment(&self, next_descriptor: NextEpochDescriptor) -> IncrementedEpoch { + pub fn increment( + &self, + next_descriptor: Epoch::NextEpochDescriptor + ) -> IncrementedEpoch { let next = self.as_ref().increment(next_descriptor); let to_persist = match *self { - ViableEpoch::Genesis(UnimportedGenesis(ref epoch_0)) => + ViableEpoch::Genesis(UnimportedGenesisEpoch(ref epoch_0)) => PersistedEpoch::Genesis(epoch_0.clone(), next), ViableEpoch::Regular(_) => PersistedEpoch::Regular(next), }; @@ -123,12 +142,11 @@ impl ViableEpoch { } /// The datatype encoded on disk. -// This really shouldn't be public, but the encode/decode derives force it to be. #[derive(Clone, Encode, Decode)] -pub enum PersistedEpoch { - // epoch_0, epoch_1, +pub enum PersistedEpoch { + /// Genesis persisted epoch data. epoch_0, epoch_1. Genesis(Epoch, Epoch), - // epoch_n + /// Regular persisted epoch data. epoch_n. Regular(Epoch), } @@ -136,9 +154,9 @@ pub enum PersistedEpoch { /// /// Create this with `ViableEpoch::increment`. #[must_use = "Freshly-incremented epoch must be imported with `EpochChanges::import`"] -pub struct IncrementedEpoch(PersistedEpoch); +pub struct IncrementedEpoch(PersistedEpoch); -impl AsRef for IncrementedEpoch { +impl AsRef for IncrementedEpoch { fn as_ref(&self) -> &Epoch { match self.0 { PersistedEpoch::Genesis(_, ref epoch_1) => epoch_1, @@ -151,7 +169,7 @@ impl AsRef for IncrementedEpoch { /// the hash and block number of the block signaling the epoch change, and the /// epoch that was signalled at that block. /// -/// BABE special-cases the first epoch, epoch_0, by saying that it starts at +/// The first epoch, epoch_0, is special cased by saying that it starts at /// slot number of the first block in the chain. When bootstrapping a chain, /// there can be multiple competing block #1s, so we have to ensure that the overlayed /// DAG doesn't get confused. @@ -163,8 +181,8 @@ impl AsRef for IncrementedEpoch { /// /// Further epochs (epoch_2, ..., epoch_n) each get their own entry. #[derive(Clone, Encode, Decode)] -pub struct EpochChanges { - inner: ForkTree, +pub struct EpochChanges { + inner: ForkTree>, } // create a fake header hash which hasn't been included in the chain. @@ -176,13 +194,23 @@ fn fake_head_hash + AsMut<[u8]> + Clone>(parent_hash: &H) -> H { h } -impl EpochChanges where +impl Default for EpochChanges where + Hash: PartialEq, + Number: Ord, +{ + fn default() -> Self { + EpochChanges { inner: ForkTree::new() } + } +} + +impl EpochChanges where Hash: PartialEq + AsRef<[u8]> + AsMut<[u8]> + Copy, Number: Ord + One + Zero + Add + Copy, + Epoch: crate::Epoch + Clone, { - /// Create a new epoch-change tracker. - fn new() -> Self { - EpochChanges { inner: ForkTree::new() } + /// Create a new epoch change. + pub fn new() -> Self { + Self::default() } /// Rebalances the tree of epoch changes so that it is sorted by length of @@ -199,12 +227,12 @@ impl EpochChanges where descendent_of_builder: D, hash: &Hash, number: Number, - slot: SlotNumber, + slot: Epoch::SlotNumber, ) -> Result<(), fork_tree::Error> { let is_descendent_of = descendent_of_builder .build_is_descendent_of(None); - let predicate = |epoch: &PersistedEpoch| match *epoch { + let predicate = |epoch: &PersistedEpoch| match *epoch { PersistedEpoch::Genesis(_, ref epoch_1) => slot >= epoch_1.end_slot(), PersistedEpoch::Regular(ref epoch_n) => @@ -233,10 +261,10 @@ impl EpochChanges where descendent_of_builder: D, parent_hash: &Hash, parent_number: Number, - slot_number: SlotNumber, + slot_number: Epoch::SlotNumber, make_genesis: G, - ) -> Result, fork_tree::Error> - where G: FnOnce(SlotNumber) -> Epoch + ) -> Result>, fork_tree::Error> + where G: FnOnce(Epoch::SlotNumber) -> Epoch { // find_node_where will give you the node in the fork-tree which is an ancestor // of the `parent_hash` by default. if the last epoch was signalled at the parent_hash, @@ -250,7 +278,7 @@ impl EpochChanges where if parent_number == Zero::zero() { // need to insert the genesis epoch. let genesis_epoch = make_genesis(slot_number); - return Ok(Some(ViableEpoch::Genesis(UnimportedGenesis(genesis_epoch)))); + return Ok(Some(ViableEpoch::Genesis(UnimportedGenesisEpoch(genesis_epoch)))); } // We want to find the deepest node in the tree which is an ancestor @@ -258,11 +286,11 @@ impl EpochChanges where // slot of our block. The genesis special-case doesn't need to look // at epoch_1 -- all we're doing here is figuring out which node // we need. - let predicate = |epoch: &PersistedEpoch| match *epoch { + let predicate = |epoch: &PersistedEpoch| match *epoch { PersistedEpoch::Genesis(ref epoch_0, _) => - epoch_0.start_slot <= slot_number, + epoch_0.start_slot() <= slot_number, PersistedEpoch::Regular(ref epoch_n) => - epoch_n.start_slot <= slot_number, + epoch_n.start_slot() <= slot_number, }; self.inner.find_node_where( @@ -276,7 +304,7 @@ impl EpochChanges where // and here we figure out which of the internal epochs // of a genesis node to use based on their start slot. PersistedEpoch::Genesis(ref epoch_0, ref epoch_1) => - if epoch_1.start_slot <= slot_number { + if epoch_1.start_slot() <= slot_number { epoch_1.clone() } else { epoch_0.clone() @@ -296,7 +324,7 @@ impl EpochChanges where hash: Hash, number: Number, parent_hash: Hash, - epoch: IncrementedEpoch, + epoch: IncrementedEpoch, ) -> Result<(), fork_tree::Error> { let is_descendent_of = descendent_of_builder .build_is_descendent_of(Some((hash, parent_hash))); @@ -314,47 +342,22 @@ impl EpochChanges where } } - /// Return the inner fork tree, useful for testing purposes. - #[cfg(test)] - pub fn tree(&self) -> &ForkTree { + /// Return the inner fork tree. + pub fn tree(&self) -> &ForkTree> { &self.inner } } /// Type alias to produce the epoch-changes tree from a block type. -pub type EpochChangesFor = EpochChanges<::Hash, NumberFor>; +pub type EpochChangesFor = EpochChanges<::Hash, NumberFor, Epoch>; /// A shared epoch changes tree. -#[derive(Clone)] -pub struct SharedEpochChanges { - inner: Arc>>, -} - -impl SharedEpochChanges { - /// Create a new instance of the `SharedEpochChanges`. - pub fn new() -> Self { - SharedEpochChanges { - inner: Arc::new(Mutex::new(EpochChanges::<_, _>::new())) - } - } - - /// Lock the shared epoch changes, - pub fn lock(&self) -> MutexGuard> { - self.inner.lock() - } -} - -impl From> for SharedEpochChanges { - fn from(epoch_changes: EpochChangesFor) -> Self { - SharedEpochChanges { - inner: Arc::new(Mutex::new(epoch_changes)) - } - } -} +pub type SharedEpochChanges = Arc>>; #[cfg(test)] mod tests { use super::*; + use super::Epoch as EpochT; #[derive(Debug, PartialEq)] pub struct TestError; @@ -396,6 +399,33 @@ mod tests { } type Hash = [u8; 1]; + type SlotNumber = u64; + + #[derive(Debug, Clone, Eq, PartialEq)] + struct Epoch { + start_slot: SlotNumber, + duration: SlotNumber, + } + + impl EpochT for Epoch { + type NextEpochDescriptor = (); + type SlotNumber = SlotNumber; + + fn increment(&self, _: ()) -> Self { + Epoch { + start_slot: self.start_slot + self.duration, + duration: self.duration, + } + } + + fn end_slot(&self) -> SlotNumber { + self.start_slot + self.duration + } + + fn start_slot(&self) -> SlotNumber { + self.start_slot + } + } #[test] fn genesis_epoch_is_created_but_not_imported() { @@ -414,11 +444,8 @@ mod tests { }; let make_genesis = |slot| Epoch { - epoch_index: 0, start_slot: slot, duration: 100, - authorities: Vec::new(), - randomness: [0; 32], }; let epoch_changes = EpochChanges::new(); @@ -468,11 +495,8 @@ mod tests { }; let make_genesis = |slot| Epoch { - epoch_index: 0, start_slot: slot, duration: 100, - authorities: Vec::new(), - randomness: [0; 32], }; let mut epoch_changes = EpochChanges::new(); @@ -486,10 +510,7 @@ mod tests { assert_eq!(genesis_epoch.as_ref(), &make_genesis(100)); - let import_epoch_1 = genesis_epoch.increment(NextEpochDescriptor { - authorities: Vec::new(), - randomness: [1; 32], - }); + let import_epoch_1 = genesis_epoch.increment(()); let epoch_1 = import_epoch_1.as_ref().clone(); epoch_changes.import( @@ -566,18 +587,12 @@ mod tests { let duration = 100; let make_genesis = |slot| Epoch { - epoch_index: 0, start_slot: slot, duration, - authorities: Vec::new(), - randomness: [0; 32], }; let mut epoch_changes = EpochChanges::new(); - let next_descriptor = NextEpochDescriptor { - authorities: Vec::new(), - randomness: [0; 32], - }; + let next_descriptor = (); // insert genesis epoch for A { diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index ab1822712f..1578d5c556 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -35,8 +35,9 @@ use sp_staking::{ use codec::{Encode, Decode}; use sp_inherents::{InherentIdentifier, InherentData, ProvideInherent, MakeFatalError}; use sp_consensus_babe::{ - BABE_ENGINE_ID, ConsensusLog, BabeAuthorityWeight, NextEpochDescriptor, RawBabePreDigest, - SlotNumber, inherents::{INHERENT_IDENTIFIER, BabeInherentData} + BABE_ENGINE_ID, ConsensusLog, BabeAuthorityWeight, SlotNumber, + inherents::{INHERENT_IDENTIFIER, BabeInherentData}, + digests::{NextEpochDescriptor, RawPreDigest}, }; pub use sp_consensus_babe::{AuthorityId, VRF_OUTPUT_LENGTH, PUBLIC_KEY_LENGTH}; @@ -205,11 +206,11 @@ impl FindAuthor for Module { { for (id, mut data) in digests.into_iter() { if id == BABE_ENGINE_ID { - let pre_digest = RawBabePreDigest::decode(&mut data).ok()?; + let pre_digest = RawPreDigest::decode(&mut data).ok()?; return Some(match pre_digest { - RawBabePreDigest::Primary { authority_index, .. } => + RawPreDigest::Primary { authority_index, .. } => authority_index, - RawBabePreDigest::Secondary { authority_index, .. } => + RawPreDigest::Secondary { authority_index, .. } => authority_index, }); } @@ -397,7 +398,7 @@ impl Module { .iter() .filter_map(|s| s.as_pre_runtime()) .filter_map(|(id, mut data)| if id == BABE_ENGINE_ID { - RawBabePreDigest::decode(&mut data).ok() + RawPreDigest::decode(&mut data).ok() } else { None }) @@ -424,7 +425,7 @@ impl Module { CurrentSlot::put(digest.slot_number()); - if let RawBabePreDigest::Primary { vrf_output, .. } = digest { + if let RawPreDigest::Primary { vrf_output, .. } = digest { // place the VRF output into the `Initialized` storage item // and it'll be put onto the under-construction randomness // later, once we've decided which epoch this block is in. diff --git a/frame/babe/src/tests.rs b/frame/babe/src/tests.rs index dbd6123816..976a264d7b 100644 --- a/frame/babe/src/tests.rs +++ b/frame/babe/src/tests.rs @@ -34,7 +34,7 @@ fn make_pre_digest( vrf_output: [u8; sp_consensus_babe::VRF_OUTPUT_LENGTH], vrf_proof: [u8; sp_consensus_babe::VRF_PROOF_LENGTH], ) -> Digest { - let digest_data = sp_consensus_babe::RawBabePreDigest::Primary { + let digest_data = sp_consensus_babe::digests::RawPreDigest::Primary { authority_index, slot_number, vrf_output, @@ -110,7 +110,7 @@ fn first_block_epoch_zero_start() { let authorities = Babe::authorities(); let consensus_log = sp_consensus_babe::ConsensusLog::NextEpochData( - sp_consensus_babe::NextEpochDescriptor { + sp_consensus_babe::digests::NextEpochDescriptor { authorities, randomness: Babe::randomness(), } diff --git a/primitives/consensus/babe/src/digest.rs b/primitives/consensus/babe/src/digests.rs similarity index 85% rename from primitives/consensus/babe/src/digest.rs rename to primitives/consensus/babe/src/digests.rs index cca088b92b..7ec0f9b977 100644 --- a/primitives/consensus/babe/src/digest.rs +++ b/primitives/consensus/babe/src/digests.rs @@ -41,7 +41,7 @@ use sp_std::vec::Vec; /// (VRF based) and to a secondary (slot number based). #[cfg(feature = "std")] #[derive(Clone, Debug)] -pub enum BabePreDigest { +pub enum PreDigest { /// A primary VRF-based slot assignment. Primary { /// VRF output @@ -63,20 +63,20 @@ pub enum BabePreDigest { } #[cfg(feature = "std")] -impl BabePreDigest { +impl PreDigest { /// Returns the slot number of the pre digest. pub fn authority_index(&self) -> AuthorityIndex { match self { - BabePreDigest::Primary { authority_index, .. } => *authority_index, - BabePreDigest::Secondary { authority_index, .. } => *authority_index, + PreDigest::Primary { authority_index, .. } => *authority_index, + PreDigest::Secondary { authority_index, .. } => *authority_index, } } /// Returns the slot number of the pre digest. pub fn slot_number(&self) -> SlotNumber { match self { - BabePreDigest::Primary { slot_number, .. } => *slot_number, - BabePreDigest::Secondary { slot_number, .. } => *slot_number, + PreDigest::Primary { slot_number, .. } => *slot_number, + PreDigest::Secondary { slot_number, .. } => *slot_number, } } @@ -84,18 +84,15 @@ impl BabePreDigest { /// of the chain. pub fn added_weight(&self) -> crate::BabeBlockWeight { match self { - BabePreDigest::Primary { .. } => 1, - BabePreDigest::Secondary { .. } => 0, + PreDigest::Primary { .. } => 1, + PreDigest::Secondary { .. } => 0, } } } -/// The prefix used by BABE for its VRF keys. -pub const BABE_VRF_PREFIX: &[u8] = b"substrate-babe-vrf"; - /// A raw version of `BabePreDigest`, usable on `no_std`. #[derive(Copy, Clone, Encode, Decode)] -pub enum RawBabePreDigest { +pub enum RawPreDigest { /// A primary VRF-based slot assignment. #[codec(index = "1")] Primary { @@ -123,38 +120,38 @@ pub enum RawBabePreDigest { }, } -impl RawBabePreDigest { +impl RawPreDigest { /// Returns the slot number of the pre digest. pub fn slot_number(&self) -> SlotNumber { match self { - RawBabePreDigest::Primary { slot_number, .. } => *slot_number, - RawBabePreDigest::Secondary { slot_number, .. } => *slot_number, + RawPreDigest::Primary { slot_number, .. } => *slot_number, + RawPreDigest::Secondary { slot_number, .. } => *slot_number, } } } #[cfg(feature = "std")] -impl Encode for BabePreDigest { +impl Encode for PreDigest { fn encode(&self) -> Vec { let raw = match self { - BabePreDigest::Primary { + PreDigest::Primary { vrf_output, vrf_proof, authority_index, slot_number, } => { - RawBabePreDigest::Primary { + RawPreDigest::Primary { vrf_output: *vrf_output.as_bytes(), vrf_proof: vrf_proof.to_bytes(), authority_index: *authority_index, slot_number: *slot_number, } }, - BabePreDigest::Secondary { + PreDigest::Secondary { authority_index, slot_number, } => { - RawBabePreDigest::Secondary { + RawPreDigest::Secondary { authority_index: *authority_index, slot_number: *slot_number, } @@ -166,26 +163,26 @@ impl Encode for BabePreDigest { } #[cfg(feature = "std")] -impl codec::EncodeLike for BabePreDigest {} +impl codec::EncodeLike for PreDigest {} #[cfg(feature = "std")] -impl Decode for BabePreDigest { +impl Decode for PreDigest { fn decode(i: &mut R) -> Result { let pre_digest = match Decode::decode(i)? { - RawBabePreDigest::Primary { vrf_output, vrf_proof, authority_index, slot_number } => { + RawPreDigest::Primary { vrf_output, vrf_proof, authority_index, slot_number } => { // Verify (at compile time) that the sizes in babe_primitives are correct let _: [u8; super::VRF_OUTPUT_LENGTH] = vrf_output; let _: [u8; super::VRF_PROOF_LENGTH] = vrf_proof; - BabePreDigest::Primary { + PreDigest::Primary { vrf_proof: VRFProof::from_bytes(&vrf_proof).map_err(convert_error)?, vrf_output: VRFOutput::from_bytes(&vrf_output).map_err(convert_error)?, authority_index, slot_number, } }, - RawBabePreDigest::Secondary { authority_index, slot_number } => { - BabePreDigest::Secondary { authority_index, slot_number } + RawPreDigest::Secondary { authority_index, slot_number } => { + PreDigest::Secondary { authority_index, slot_number } }, }; @@ -208,10 +205,10 @@ pub struct NextEpochDescriptor { #[cfg(feature = "std")] pub trait CompatibleDigestItem: Sized { /// Construct a digest item which contains a BABE pre-digest. - fn babe_pre_digest(seal: BabePreDigest) -> Self; + fn babe_pre_digest(seal: PreDigest) -> Self; /// If this item is an BABE pre-digest, return it. - fn as_babe_pre_digest(&self) -> Option; + fn as_babe_pre_digest(&self) -> Option; /// Construct a digest item which contains a BABE seal. fn babe_seal(signature: AuthoritySignature) -> Self; @@ -227,11 +224,11 @@ pub trait CompatibleDigestItem: Sized { impl CompatibleDigestItem for DigestItem where Hash: Debug + Send + Sync + Eq + Clone + Codec + 'static { - fn babe_pre_digest(digest: BabePreDigest) -> Self { + fn babe_pre_digest(digest: PreDigest) -> Self { DigestItem::PreRuntime(BABE_ENGINE_ID, digest.encode()) } - fn as_babe_pre_digest(&self) -> Option { + fn as_babe_pre_digest(&self) -> Option { self.try_to(OpaqueDigestItemId::PreRuntime(&BABE_ENGINE_ID)) } diff --git a/primitives/consensus/babe/src/lib.rs b/primitives/consensus/babe/src/lib.rs index 4cdeb072bd..78c63e5022 100644 --- a/primitives/consensus/babe/src/lib.rs +++ b/primitives/consensus/babe/src/lib.rs @@ -19,22 +19,22 @@ #![forbid(unsafe_code, missing_docs, unused_variables, unused_imports)] #![cfg_attr(not(feature = "std"), no_std)] -mod digest; +pub mod digests; pub mod inherents; use codec::{Encode, Decode}; 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}; +use crate::digests::NextEpochDescriptor; mod app { use sp_application_crypto::{app_crypto, key_types::BABE, sr25519}; app_crypto!(sr25519, BABE); } +/// The prefix used by BABE for its VRF keys. +pub const BABE_VRF_PREFIX: &[u8] = b"substrate-babe-vrf"; + /// A Babe authority keypair. Necessarily equivalent to the schnorrkel public key used in /// the main Babe module. If that ever changes, then this must, too. #[cfg(feature = "std")] @@ -78,40 +78,6 @@ pub type BabeAuthorityWeight = u64; /// The weight of a BABE block. pub type BabeBlockWeight = u32; -/// BABE epoch information -#[derive(Decode, Encode, Default, PartialEq, Eq, Clone, RuntimeDebug)] -pub struct Epoch { - /// The epoch index - pub epoch_index: u64, - /// The starting slot of the epoch, - pub start_slot: SlotNumber, - /// The duration of this epoch - pub duration: SlotNumber, - /// The authorities and their weights - pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, - /// Randomness for this epoch - pub randomness: [u8; VRF_OUTPUT_LENGTH], -} - -impl Epoch { - /// "increment" the epoch, with given descriptor for the next. - pub fn increment(&self, descriptor: NextEpochDescriptor) -> Epoch { - Epoch { - epoch_index: self.epoch_index + 1, - start_slot: self.start_slot + self.duration, - duration: self.duration, - authorities: descriptor.authorities, - randomness: descriptor.randomness, - } - } - - /// Produce the "end slot" of the epoch. This is NOT inclusive to the epoch, - // i.e. the slots covered by the epoch are `self.start_slot .. self.end_slot()`. - pub fn end_slot(&self) -> SlotNumber { - self.start_slot + self.duration - } -} - /// An consensus log item for BABE. #[derive(Decode, Encode, Clone, PartialEq, Eq)] pub enum ConsensusLog { -- GitLab From dec1bb7d30f3afee7ab585c661b3f6100441c220 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Thu, 6 Feb 2020 18:52:30 +0100 Subject: [PATCH 099/180] babe: pass epoch data via intermediates (#4807) * babe: pass epoch data via intermediates * Switch to use Box for intermediates * Set intermediate.epoch to be Option * Fix proposer should put out an empty intermediate * Remove unnecessary encode/decode * Add EpochData to block_import_params in slot worker * Fix aura compile * Fix integration test --- Cargo.lock | 1 + bin/node/cli/Cargo.toml | 1 + bin/node/cli/src/service.rs | 28 ++++++++-- client/consensus/aura/src/lib.rs | 3 +- client/consensus/babe/src/lib.rs | 84 ++++++++++++++++++++---------- client/consensus/babe/src/tests.rs | 19 ++++++- client/consensus/slots/src/lib.rs | 4 +- 7 files changed, 106 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4771b78586..0333904bff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3391,6 +3391,7 @@ dependencies = [ "sc-client-api", "sc-client-db", "sc-consensus-babe", + "sc-consensus-epochs", "sc-finality-grandpa", "sc-keystore", "sc-network", diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index cf666ffdc5..d5f3f45b31 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -92,6 +92,7 @@ browser-utils = { path = "../../../utils/browser", optional = true } [dev-dependencies] sc-keystore = { version = "2.0.0", path = "../../../client/keystore" } sc-consensus-babe = { version = "0.8", features = ["test-helpers"], path = "../../../client/consensus/babe" } +sc-consensus-epochs = { version = "0.8", path = "../../../client/consensus/epochs" } sc-service-test = { version = "2.0.0", path = "../../../client/service/test" } futures = "0.3.1" tempfile = "3.1.0" diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index c462a60836..2c500c6a1c 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -371,8 +371,11 @@ pub fn new_light(config: NodeConfiguration) #[cfg(test)] mod tests { - use std::sync::Arc; - use sc_consensus_babe::CompatibleDigestItem; + use std::{sync::Arc, collections::HashMap, borrow::Cow, any::Any}; + use sc_consensus_babe::{ + CompatibleDigestItem, BabeIntermediate, INTERMEDIATE_KEY + }; + use sc_consensus_epochs::descendent_query; use sp_consensus::{ Environment, Proposer, BlockImportParams, BlockOrigin, ForkChoiceStrategy, BlockImport, RecordProof, @@ -384,7 +387,7 @@ mod tests { use sp_core::{crypto::Pair as CryptoPair, H256}; use sp_runtime::{ generic::{BlockId, Era, Digest, SignedPayload}, - traits::Block as BlockT, + traits::{Block as BlockT, Header as HeaderT}, traits::Verify, OpaqueExtrinsic, }; @@ -499,11 +502,21 @@ mod tests { let parent_id = BlockId::number(service.client().chain_info().best_number); let parent_header = service.client().header(&parent_id).unwrap().unwrap(); + let parent_hash = parent_header.hash(); + let parent_number = *parent_header.number(); let mut proposer_factory = sc_basic_authorship::ProposerFactory { client: service.client(), transaction_pool: service.transaction_pool(), }; + let epoch = babe_link.epoch_changes().lock().epoch_for_child_of( + descendent_query(&*service.client()), + &parent_hash, + parent_number, + slot_num, + |slot| babe_link.config().genesis_epoch(slot) + ).unwrap().unwrap(); + let mut digest = Digest::::default(); // even though there's only one authority some slots might be empty, @@ -555,7 +568,14 @@ mod tests { storage_changes: None, finalized: false, auxiliary: Vec::new(), - intermediates: Default::default(), + intermediates: { + let mut intermediates = HashMap::new(); + intermediates.insert( + Cow::from(INTERMEDIATE_KEY), + Box::new(BabeIntermediate { epoch }) as Box, + ); + intermediates + }, fork_choice: Some(ForkChoiceStrategy::LongestChain), allow_missing_state: false, import_existing: false, diff --git a/client/consensus/aura/src/lib.rs b/client/consensus/aura/src/lib.rs index 4b107d87d5..434314a853 100644 --- a/client/consensus/aura/src/lib.rs +++ b/client/consensus/aura/src/lib.rs @@ -274,8 +274,9 @@ impl sc_consensus_slots::SimpleSlotWorker for AuraW Vec, StorageChanges, B>, Self::Claim, + Self::EpochData, ) -> sp_consensus::BlockImportParams> + Send> { - Box::new(|header, header_hash, body, storage_changes, pair| { + Box::new(|header, header_hash, body, storage_changes, pair, _epoch| { // sign the pre-sealed hash of the block and then // add it to a digest item. let signature = pair.sign(header_hash.as_ref()); diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index dbf61692eb..f9e3ef98d6 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -65,7 +65,10 @@ pub use sp_consensus_babe::{ digests::{PreDigest, CompatibleDigestItem, NextEpochDescriptor}, }; pub use sp_consensus::SyncOracle; -use std::{collections::HashMap, sync::Arc, u64, pin::Pin, time::{Instant, Duration}}; +use std::{ + collections::HashMap, sync::Arc, u64, pin::Pin, time::{Instant, Duration}, + any::Any, borrow::Cow +}; use sp_consensus_babe; use sp_consensus::{ImportResult, CanAuthorWith}; use sp_consensus::import_queue::{ @@ -103,7 +106,9 @@ use log::{warn, debug, info, trace}; use sc_consensus_slots::{ SlotWorker, SlotInfo, SlotCompatible, StorageChanges, CheckedHeader, check_equivocation, }; -use sc_consensus_epochs::{descendent_query, SharedEpochChanges, EpochChangesFor, Epoch as EpochT}; +use sc_consensus_epochs::{ + descendent_query, ViableEpoch, SharedEpochChanges, EpochChangesFor, Epoch as EpochT +}; use sp_blockchain::{ Result as ClientResult, Error as ClientError, HeaderBackend, ProvideCache, HeaderMetadata @@ -196,10 +201,6 @@ enum 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>), - #[display(fmt = "Block {} is not valid under any epoch.", _0)] - BlockNotValid(B::Hash), #[display(fmt = "Unexpected epoch change")] UnexpectedEpochChange, #[display(fmt = "Parent block of {} has no associated weight", _0)] @@ -231,6 +232,16 @@ macro_rules! babe_info { }; } + +/// Intermediate value passed to block importer. +pub struct BabeIntermediate { + /// The epoch data, if available. + pub epoch: ViableEpoch, +} + +/// Intermediate key for Babe engine. +pub static INTERMEDIATE_KEY: &[u8] = b"babe1"; + /// A slot duration. Create with `get_or_compute`. // FIXME: Once Rust has higher-kinded types, the duplication between this // and `super::babe::Config` can be eliminated. @@ -394,7 +405,7 @@ impl sc_consensus_slots::SimpleSlotWorker for BabeWork SO: SyncOracle + Send + Clone, Error: std::error::Error + Send + From + From + 'static, { - type EpochData = Epoch; + type EpochData = ViableEpoch; type Claim = (PreDigest, AuthorityPair); type SyncOracle = SO; type CreateProposer = Pin sc_consensus_slots::SimpleSlotWorker for BabeWork |slot| self.config.genesis_epoch(slot) ) .map_err(|e| ConsensusError::ChainLookup(format!("{:?}", e)))? - .map(|e| e.into_inner()) .ok_or(sp_consensus::Error::InvalidAuthoritiesSet) } fn authorities_len(&self, epoch_data: &Self::EpochData) -> usize { - epoch_data.authorities.len() + epoch_data.as_ref().authorities.len() } fn claim_slot( &self, _parent_header: &B::Header, slot_number: SlotNumber, - epoch_data: &Epoch, + epoch_data: &ViableEpoch, ) -> Option { debug!(target: "babe", "Attempting to claim slot {}", slot_number); let s = authorship::claim_slot( slot_number, - epoch_data, + epoch_data.as_ref(), &*self.config, &self.keystore, ); @@ -469,8 +479,9 @@ impl sc_consensus_slots::SimpleSlotWorker for BabeWork Vec, StorageChanges, Self::Claim, + Self::EpochData, ) -> sp_consensus::BlockImportParams + Send> { - Box::new(|header, header_hash, body, storage_changes, (_, pair)| { + Box::new(|header, header_hash, body, storage_changes, (_, pair), epoch| { // sign the pre-sealed hash of the block and then // add it to a digest item. let signature = pair.sign(header_hash.as_ref()); @@ -485,7 +496,14 @@ impl sc_consensus_slots::SimpleSlotWorker for BabeWork storage_changes: Some(storage_changes), finalized: false, auxiliary: Vec::new(), // block-weight is written in block import. - intermediates: Default::default(), + intermediates: { + let mut intermediates = HashMap::new(); + intermediates.insert( + Cow::from(INTERMEDIATE_KEY), + Box::new(BabeIntermediate { epoch }) as Box, + ); + intermediates + }, fork_choice: None, allow_missing_state: false, import_existing: false, @@ -634,6 +652,19 @@ pub struct BabeLink { epoch_changes: SharedEpochChanges, config: Config, } + +impl BabeLink { + /// Get the epoch changes of this link. + pub fn epoch_changes(&self) -> &SharedEpochChanges { + &self.epoch_changes + } + + /// Get the config of this link. + pub fn config(&self) -> &Config { + &self.config + } +} + /// A verifier for Babe blocks. pub struct BabeVerifier { client: Arc>, @@ -830,6 +861,14 @@ impl Verifier for BabeVerifier ?pre_header); + let mut intermediates = HashMap::new(); + intermediates.insert( + Cow::from(INTERMEDIATE_KEY), + Box::new(BabeIntermediate { + epoch, + }) as Box, + ); + let block_import_params = BlockImportParams { origin, header: pre_header, @@ -839,7 +878,7 @@ impl Verifier for BabeVerifier BlockImport for BabeBlockImport| ConsensusError::ChainLookup( - babe_err(Error::::CouldNotLookUpEpoch(Box::new(e))).into() - ))? - .ok_or_else(|| ConsensusError::ClientImport( - babe_err(Error::::BlockNotValid(hash)).into() - ))?; + let intermediate = block.take_intermediate::( + INTERMEDIATE_KEY + )?; + let epoch = intermediate.epoch; let first_in_epoch = parent_slot < epoch.as_ref().start_slot; (epoch, first_in_epoch, parent_weight) }; diff --git a/client/consensus/babe/src/tests.rs b/client/consensus/babe/src/tests.rs index 701155e7cc..687f23e646 100644 --- a/client/consensus/babe/src/tests.rs +++ b/client/consensus/babe/src/tests.rs @@ -565,8 +565,18 @@ fn propose_and_import_block( ], }; + let parent_hash = parent.hash(); + let mut block = futures::executor::block_on(proposer.propose_with(pre_digest)).unwrap().block; + let epoch = proposer_factory.epoch_changes.lock().epoch_for_child_of( + descendent_query(&*proposer_factory.client), + &parent_hash, + *parent.number(), + slot_number, + |slot| proposer_factory.config.genesis_epoch(slot) + ).unwrap().unwrap(); + let seal = { // sign the pre-sealed hash of the block and then // add it to a digest item. @@ -593,7 +603,14 @@ fn propose_and_import_block( storage_changes: None, finalized: false, auxiliary: Vec::new(), - intermediates: Default::default(), + intermediates: { + let mut intermediates = HashMap::new(); + intermediates.insert( + Cow::from(INTERMEDIATE_KEY), + Box::new(BabeIntermediate { epoch }) as Box, + ); + intermediates + }, fork_choice: Some(ForkChoiceStrategy::LongestChain), allow_missing_state: false, import_existing: false, diff --git a/client/consensus/slots/src/lib.rs b/client/consensus/slots/src/lib.rs index c6185d5d30..8bc2547a49 100644 --- a/client/consensus/slots/src/lib.rs +++ b/client/consensus/slots/src/lib.rs @@ -81,7 +81,7 @@ pub trait SimpleSlotWorker { type Claim: Send + 'static; /// Epoch data necessary for authoring. - type EpochData; + type EpochData: Send + 'static; /// The logging target to use when logging messages. fn logging_target(&self) -> &'static str; @@ -119,6 +119,7 @@ pub trait SimpleSlotWorker { Vec, StorageChanges<>::Transaction, B>, Self::Claim, + Self::EpochData, ) -> sp_consensus::BlockImportParams< B, >::Transaction @@ -280,6 +281,7 @@ pub trait SimpleSlotWorker { body, proposal.storage_changes, claim, + epoch_data, ); info!( -- GitLab From f3742e70b2b74c541cf2e8ff2226be7d8f824ffe Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Thu, 6 Feb 2020 23:32:48 +0100 Subject: [PATCH 100/180] easy with threads (#4848) --- client/finality-grandpa/src/tests.rs | 34 ++++++++++++++++------------ 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index 0d7cf0541f..0f4d9dadd0 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -499,11 +499,17 @@ fn add_forced_change( )); } +fn thread_pool() -> futures::executor::ThreadPool { + futures::executor::ThreadPool::builder().pool_size(2) + .create() + .expect("never fails") +} + #[test] fn finalize_3_voters_no_observers() { let _ = env_logger::try_init(); let mut runtime = current_thread::Runtime::new().unwrap(); - let threads_pool = futures::executor::ThreadPool::new().unwrap(); + let threads_pool = thread_pool(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let voters = make_ids(peers); @@ -529,7 +535,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 = futures::executor::ThreadPool::new().unwrap(); + let threads_pool = thread_pool(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let voters = make_ids(peers); @@ -635,7 +641,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 = futures::executor::ThreadPool::new().unwrap(); + let threads_pool = thread_pool(); net.lock().peer(0).push_blocks(1, false); net.lock().block_until_sync(&mut runtime); @@ -770,7 +776,7 @@ 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 = futures::executor::ThreadPool::new().unwrap(); + let threads_pool = thread_pool(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 3); @@ -789,7 +795,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 = futures::executor::ThreadPool::new().unwrap(); + let threads_pool = thread_pool(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let voters = make_ids(peers); @@ -829,7 +835,7 @@ fn consensus_changes_works() { #[test] fn sync_justifications_on_change_blocks() { let mut runtime = current_thread::Runtime::new().unwrap(); - let threads_pool = futures::executor::ThreadPool::new().unwrap(); + let threads_pool = thread_pool(); let peers_a = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let peers_b = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob]; let voters = make_ids(peers_b); @@ -884,7 +890,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 = futures::executor::ThreadPool::new().unwrap(); + let threads_pool = thread_pool(); let peers_a = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let peers_b = &[Ed25519Keyring::Dave, Ed25519Keyring::Eve, Ed25519Keyring::Ferdie]; @@ -945,7 +951,7 @@ fn finalizes_multiple_pending_changes_in_order() { fn force_change_to_new_set() { let _ = env_logger::try_init(); let mut runtime = current_thread::Runtime::new().unwrap(); - let threads_pool = futures::executor::ThreadPool::new().unwrap(); + let threads_pool = thread_pool(); // two of these guys are offline. let genesis_authorities = &[ Ed25519Keyring::Alice, @@ -1126,7 +1132,7 @@ fn voter_persists_its_votes() { let _ = env_logger::try_init(); let mut runtime = current_thread::Runtime::new().unwrap(); - let threads_pool = futures::executor::ThreadPool::new().unwrap(); + let threads_pool = thread_pool(); // 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 @@ -1383,7 +1389,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 = futures::executor::ThreadPool::new().unwrap(); + let threads_pool = thread_pool(); let authorities = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let voters = make_ids(authorities); @@ -1429,7 +1435,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 = futures::executor::ThreadPool::new().unwrap(); + let threads_pool = thread_pool(); let peers = &[Ed25519Keyring::Alice]; let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 1); @@ -1461,7 +1467,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 = futures::executor::ThreadPool::new().unwrap(); + let threads_pool = thread_pool(); // two of these guys are offline. let genesis_authorities = if FORCE_CHANGE { @@ -1526,7 +1532,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 = futures::executor::ThreadPool::new().unwrap(); + let threads_pool = thread_pool(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob]; let voters = make_ids(peers); @@ -1646,7 +1652,7 @@ fn grandpa_environment_respects_voting_rules() { use finality_grandpa::Chain; use sc_network_test::TestClient; - let threads_pool = futures::executor::ThreadPool::new().unwrap(); + let threads_pool = thread_pool(); let peers = &[Ed25519Keyring::Alice]; let voters = make_ids(peers); -- GitLab From 18e6ea00188a50d6fc04de254923ab026228ed77 Mon Sep 17 00:00:00 2001 From: Marcio Diaz Date: Fri, 7 Feb 2020 08:12:19 +0100 Subject: [PATCH 101/180] Enable trace timings logs for transaction factory (#4845) * Enable trace timings logs for transaction factory. --- Cargo.lock | 2 ++ bin/node/cli/Cargo.toml | 2 ++ bin/node/cli/src/command.rs | 10 ++++++++++ client/cli/src/lib.rs | 4 ++-- client/cli/src/params.rs | 28 ++++++++++++++-------------- 5 files changed, 30 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0333904bff..440b3b218e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3400,6 +3400,7 @@ dependencies = [ "sc-service", "sc-service-test", "sc-telemetry", + "sc-tracing", "sc-transaction-pool", "serde", "sp-authority-discovery", @@ -3417,6 +3418,7 @@ dependencies = [ "structopt", "substrate-build-script-utils", "tempfile", + "tracing", "vergen", "wasm-bindgen", "wasm-bindgen-futures", diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index d5f3f45b31..dad76ae4bf 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -32,6 +32,7 @@ jsonrpc-core = "14.0.3" log = "0.4.8" rand = "0.7.2" structopt = { version = "0.3.8", optional = true } +tracing = "0.1.10" # primitives sp-authority-discovery = { version = "2.0.0", path = "../../../primitives/authority-discovery" } @@ -60,6 +61,7 @@ sc-offchain = { version = "2.0.0", path = "../../../client/offchain" } sc-rpc = { version = "2.0.0", path = "../../../client/rpc" } sc-basic-authorship = { version = "0.8", path = "../../../client/basic-authorship" } sc-service = { version = "0.8", default-features = false, path = "../../../client/service" } +sc-tracing = { version = "2.0.0", path = "../../../client/tracing" } sc-telemetry = { version = "2.0.0", path = "../../../client/telemetry" } sc-authority-discovery = { version = "0.8", path = "../../../client/authority-discovery" } diff --git a/bin/node/cli/src/command.rs b/bin/node/cli/src/command.rs index eb18d6d8b3..f5d747a146 100644 --- a/bin/node/cli/src/command.rs +++ b/bin/node/cli/src/command.rs @@ -56,6 +56,16 @@ where _ => panic!("Factory is only supported for development and local testnet."), } + // Setup tracing. + if let Some(tracing_targets) = cli_args.shared_params.tracing_targets.as_ref() { + let subscriber = sc_tracing::ProfilingSubscriber::new( + cli_args.shared_params.tracing_receiver.into(), tracing_targets + ); + if let Err(e) = tracing::subscriber::set_global_default(subscriber) { + panic!("Unable to set global default subscriber {}", e); + } + } + let factory_state = FactoryState::new( cli_args.mode.clone(), cli_args.num, diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index 7f72689336..0965a79f15 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -638,8 +638,8 @@ where config.telemetry_endpoints = Some(TelemetryEndpoints::new(cli.telemetry_endpoints)); } - config.tracing_targets = cli.tracing_targets.into(); - config.tracing_receiver = cli.tracing_receiver.into(); + config.tracing_targets = cli.shared_params.tracing_targets.into(); + config.tracing_receiver = cli.shared_params.tracing_receiver.into(); // Imply forced authoring on --dev config.force_authoring = cli.shared_params.dev || cli.force_authoring; diff --git a/client/cli/src/params.rs b/client/cli/src/params.rs index 3a4aa319c6..1dc6b0567c 100644 --- a/client/cli/src/params.rs +++ b/client/cli/src/params.rs @@ -113,6 +113,20 @@ pub struct SharedParams { /// Sets a custom logging filter. #[structopt(short = "l", long = "log", value_name = "LOG_PATTERN")] pub log: Option, + + /// Comma separated list of targets for tracing + #[structopt(long = "tracing-targets", value_name = "TARGETS")] + pub tracing_targets: Option, + + /// Receiver to process tracing messages + #[structopt( + long = "tracing-receiver", + value_name = "RECEIVER", + possible_values = &TracingReceiver::variants(), + case_insensitive = true, + default_value = "Log" + )] + pub tracing_receiver: TracingReceiver, } /// Parameters for block import. @@ -579,20 +593,6 @@ pub struct RunCmd { #[structopt(long = "force-authoring")] pub force_authoring: bool, - /// Comma separated list of targets for tracing - #[structopt(long = "tracing-targets", value_name = "TARGETS")] - pub tracing_targets: Option, - - /// Receiver to process tracing messages - #[structopt( - long = "tracing-receiver", - value_name = "RECEIVER", - possible_values = &TracingReceiver::variants(), - case_insensitive = true, - default_value = "Log" - )] - pub tracing_receiver: TracingReceiver, - /// Specify custom keystore path. #[structopt(long = "keystore-path", value_name = "PATH", parse(from_os_str))] pub keystore_path: Option, -- GitLab From 65763cdb2474c664337e3a33bc9c7a548d34ea86 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Fri, 7 Feb 2020 11:53:11 +0100 Subject: [PATCH 102/180] Subsystems memory tracking: 1. Transaction pool (#4822) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update sp-runtime * total update * usage informant * update to crates.io version * update Cargo.lock * update dummy update * fix todo * cleanup * avoid custom impl * Update client/transaction-pool/graph/src/future.rs Co-Authored-By: Tomasz Drwięga * remove another custom impl * remove another custom impl * add kb in report * update Cargo.lock * review suggestions * --amend * --amend * bump parity-util-mem to 0.5.0 * bumps * update macro and versions * add to grafana * naming Co-authored-by: Tomasz Drwięga --- Cargo.lock | 45 +++++++++++-------- client/Cargo.toml | 4 +- client/api/Cargo.toml | 2 +- client/cli/Cargo.toml | 1 + client/cli/src/informant.rs | 6 +++ client/db/Cargo.toml | 10 ++--- client/service/Cargo.toml | 1 + client/service/src/builder.rs | 2 + client/transaction-pool/Cargo.toml | 1 + client/transaction-pool/graph/Cargo.toml | 1 + .../transaction-pool/graph/src/base_pool.rs | 31 ++++++++++++- client/transaction-pool/graph/src/future.rs | 30 ++++++++++++- client/transaction-pool/graph/src/pool.rs | 10 +++++ client/transaction-pool/graph/src/ready.rs | 24 ++++++++-- .../graph/src/validated_pool.rs | 11 +++++ client/transaction-pool/src/lib.rs | 12 +++++ client/transaction-pool/src/testing/pool.rs | 11 +++++ frame/system/src/lib.rs | 6 +-- primitives/core/Cargo.toml | 1 + primitives/core/src/changes_trie.rs | 2 +- primitives/runtime/Cargo.toml | 2 + primitives/runtime/src/generic/block.rs | 6 +-- primitives/runtime/src/generic/digest.rs | 5 ++- primitives/runtime/src/generic/header.rs | 22 ++++++++- .../src/generic/unchecked_extrinsic.rs | 12 +++++ primitives/runtime/src/lib.rs | 7 +++ primitives/runtime/src/testing.rs | 13 ++++-- primitives/runtime/src/traits.rs | 26 +++++++---- primitives/test-primitives/Cargo.toml | 1 + primitives/test-primitives/src/lib.rs | 1 + primitives/transaction-pool/src/pool.rs | 4 +- test-utils/runtime/Cargo.toml | 1 + test-utils/runtime/src/lib.rs | 2 + utils/browser/Cargo.toml | 2 +- 34 files changed, 257 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 440b3b218e..ca7a5d1844 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2527,31 +2527,31 @@ dependencies = [ [[package]] name = "kvdb" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8396be0e5561ccd1bf7ff0b2007487cdd7a87a056873fe6ea906b35d4dbf7ed8" +checksum = "03080afe6f42cd996da9f568d6add5d7fb5ee2ea7fb7802d2d2cbd836958fd87" dependencies = [ "parity-bytes", - "parity-util-mem 0.4.1", + "parity-util-mem 0.5.1", "smallvec 1.2.0", ] [[package]] name = "kvdb-memorydb" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d25ef14155e418515c4839e9144c839de3506e68946f255a32b7f166095493d" +checksum = "b9355274e5a9e0a7e8ef43916950eae3949024de2a8dffe4d5a6c13974a37c8e" dependencies = [ "kvdb", - "parity-util-mem 0.4.1", - "parking_lot 0.9.0", + "parity-util-mem 0.5.1", + "parking_lot 0.10.0", ] [[package]] name = "kvdb-rocksdb" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af488cc16c3801705c8d681c3a32c8faa8fafc7fb5309dee0f573f3c6a19d395" +checksum = "af36fd66ccd99f3f771ae39b75aaba28b952372b6debfb971134bf1f03466ab2" dependencies = [ "fs-swap", "interleaved-ordered", @@ -2559,8 +2559,8 @@ dependencies = [ "log 0.4.8", "num_cpus", "owning_ref", - "parity-util-mem 0.4.1", - "parking_lot 0.9.0", + "parity-util-mem 0.5.1", + "parking_lot 0.10.0", "regex", "rocksdb", "smallvec 1.2.0", @@ -2568,16 +2568,16 @@ dependencies = [ [[package]] name = "kvdb-web" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a0e36637fb86454de401e7cb88f40eb0ad1b9bcee837d46785e7c451f1ebf4" +checksum = "7a985c47b4c46429e96033ebf6eaed784a81ceccb4e5df13d63f3b9078a4df81" dependencies = [ "futures 0.3.1", "js-sys", "kvdb", "kvdb-memorydb", "log 0.4.8", - "parity-util-mem 0.4.1", + "parity-util-mem 0.5.1", "send_wrapper 0.3.0", "wasm-bindgen", "web-sys", @@ -4620,14 +4620,15 @@ dependencies = [ [[package]] name = "parity-util-mem" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900dd84654b048e5bad420bb341658fc2c4d7fea628c22bcf4621733e54859b4" +checksum = "ef1476e40bf8f5c6776e9600983435821ca86eb9819d74a6207cca69d091406a" dependencies = [ "cfg-if", "impl-trait-for-tuples", "parity-util-mem-derive", - "parking_lot 0.9.0", + "parking_lot 0.10.0", + "primitive-types", "smallvec 1.2.0", "winapi 0.3.8", ] @@ -5629,6 +5630,7 @@ dependencies = [ "lazy_static", "log 0.4.8", "names", + "parity-util-mem 0.5.1", "regex", "rpassword", "sc-client-api", @@ -5729,7 +5731,7 @@ dependencies = [ "linked-hash-map", "log 0.4.8", "parity-scale-codec", - "parity-util-mem 0.4.1", + "parity-util-mem 0.5.1", "parking_lot 0.10.0", "quickcheck", "sc-client", @@ -6308,6 +6310,7 @@ dependencies = [ "log 0.4.8", "parity-multiaddr 0.5.0", "parity-scale-codec", + "parity-util-mem 0.5.1", "parking_lot 0.10.0", "sc-chain-spec", "sc-client", @@ -6422,6 +6425,7 @@ dependencies = [ "futures 0.3.1", "log 0.4.8", "parity-scale-codec", + "parity-util-mem 0.5.1", "parking_lot 0.10.0", "serde", "sp-core", @@ -6439,6 +6443,7 @@ dependencies = [ "futures-diagnose", "log 0.4.8", "parity-scale-codec", + "parity-util-mem 0.5.1", "parking_lot 0.10.0", "sc-client-api", "sc-transaction-graph", @@ -7001,6 +7006,7 @@ dependencies = [ "log 0.4.8", "num-traits", "parity-scale-codec", + "parity-util-mem 0.5.1", "parking_lot 0.10.0", "pretty_assertions", "primitive-types", @@ -7146,6 +7152,7 @@ dependencies = [ "impl-trait-for-tuples", "log 0.4.8", "parity-scale-codec", + "parity-util-mem 0.5.1", "paste", "rand 0.7.3", "serde", @@ -7290,6 +7297,7 @@ name = "sp-test-primitives" version = "2.0.0" dependencies = [ "parity-scale-codec", + "parity-util-mem 0.5.1", "serde", "sp-application-crypto", "sp-core", @@ -7571,6 +7579,7 @@ dependencies = [ "pallet-babe", "pallet-timestamp", "parity-scale-codec", + "parity-util-mem 0.5.1", "sc-client", "sc-executor", "serde", diff --git a/client/Cargo.toml b/client/Cargo.toml index 8560408569..c89fe88145 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -19,7 +19,7 @@ hash-db = { version = "0.15.2" } hex-literal = { version = "0.2.1" } sp-inherents = { version = "2.0.0", path = "../primitives/inherents" } sp-keyring = { version = "2.0.0", path = "../primitives/keyring" } -kvdb = "0.3.0" +kvdb = "0.4.0" log = { version = "0.4.8" } parking_lot = "0.10.0" sp-core = { version = "2.0.0", path = "../primitives/core" } @@ -37,5 +37,5 @@ tracing = "0.1.10" env_logger = "0.7.0" tempfile = "3.1.0" substrate-test-runtime-client = { version = "2.0.0", path = "../test-utils/runtime/client" } -kvdb-memorydb = "0.3.0" +kvdb-memorydb = "0.4.0" sp-panic-handler = { version = "2.0.0", path = "../primitives/panic-handler" } diff --git a/client/api/Cargo.toml b/client/api/Cargo.toml index 4c2867deb3..27a40c4d94 100644 --- a/client/api/Cargo.toml +++ b/client/api/Cargo.toml @@ -18,7 +18,7 @@ sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } hex-literal = { version = "0.2.1" } sp-inherents = { version = "2.0.0", default-features = false, path = "../../primitives/inherents" } sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } -kvdb = "0.3.0" +kvdb = "0.4.0" log = { version = "0.4.8" } parking_lot = "0.10.0" sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" } diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index abfb53ccb1..e302d53d55 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -35,6 +35,7 @@ names = "0.11.0" structopt = "0.3.8" sc-tracing = { version = "2.0.0", path = "../tracing" } chrono = "0.4.10" +parity-util-mem = { version = "0.5.1", default-features = false, features = ["primitive-types"] } [target.'cfg(not(target_os = "unknown"))'.dependencies] rpassword = "4.0.1" diff --git a/client/cli/src/informant.rs b/client/cli/src/informant.rs index 312e4017d5..9e7c5044e0 100644 --- a/client/cli/src/informant.rs +++ b/client/cli/src/informant.rs @@ -28,6 +28,7 @@ mod display; /// Creates an informant in the form of a `Future` that must be polled regularly. pub fn build(service: &impl AbstractService) -> impl futures::Future { let client = service.client(); + let pool = service.transaction_pool(); let mut display = display::InformantDisplay::new(); @@ -40,6 +41,11 @@ pub fn build(service: &impl AbstractService) -> impl futures::Future info.usage.as_ref().map(|usage| usage.memory.database_cache).unwrap_or(0), "disk_read_per_sec" => info.usage.as_ref().map(|usage| usage.io.bytes_read).unwrap_or(0), "disk_write_per_sec" => info.usage.as_ref().map(|usage| usage.io.bytes_written).unwrap_or(0), + "memory_transaction_pool" => parity_util_mem::malloc_size(&*transaction_pool_), ); ready(()) }); + let _ = to_spawn_tx.unbounded_send(( Box::pin(select(tel_task, exit.clone()).map(drop)), From::from("telemetry-periodic-send") diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index 1387d1df27..524e9a98a0 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -19,6 +19,7 @@ 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" } +parity-util-mem = { version = "0.5.1", default-features = false, features = ["primitive-types"] } [dev-dependencies] sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } diff --git a/client/transaction-pool/graph/Cargo.toml b/client/transaction-pool/graph/Cargo.toml index 4f12ab7fcc..2d3172fc91 100644 --- a/client/transaction-pool/graph/Cargo.toml +++ b/client/transaction-pool/graph/Cargo.toml @@ -14,6 +14,7 @@ serde = { version = "1.0.101", features = ["derive"] } 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" } +parity-util-mem = { version = "0.5.1", default-features = false, features = ["primitive-types"] } [dev-dependencies] assert_matches = "1.3.0" diff --git a/client/transaction-pool/graph/src/base_pool.rs b/client/transaction-pool/graph/src/base_pool.rs index 7b7900c3e9..52e00df363 100644 --- a/client/transaction-pool/graph/src/base_pool.rs +++ b/client/transaction-pool/graph/src/base_pool.rs @@ -84,7 +84,7 @@ pub struct PruneStatus { /// Immutable transaction #[cfg_attr(test, derive(Clone))] -#[derive(PartialEq, Eq)] +#[derive(PartialEq, Eq, parity_util_mem::MallocSizeOf)] pub struct Transaction { /// Raw extrinsic representing that transaction. pub data: Extrinsic, @@ -209,7 +209,7 @@ const RECENTLY_PRUNED_TAGS: usize = 2; /// as-is for the second time will fail or produce unwanted results. /// Most likely it is required to revalidate them and recompute set of /// required tags. -#[derive(Debug)] +#[derive(Debug, parity_util_mem::MallocSizeOf)] pub struct BasePool { reject_future_transactions: bool, future: FutureTransactions, @@ -846,6 +846,33 @@ mod tests { } } + #[test] + fn can_track_heap_size() { + let mut pool = pool(); + pool.import(Transaction { + data: vec![5u8; 1024], + bytes: 1, + hash: 5, + priority: 5u64, + valid_till: 64u64, + requires: vec![], + provides: vec![vec![0], vec![4]], + propagate: true, + }).expect("import 1 should be ok"); + pool.import(Transaction { + data: vec![3u8; 1024], + bytes: 1, + hash: 7, + priority: 5u64, + valid_till: 64u64, + requires: vec![], + provides: vec![vec![2], vec![7]], + propagate: true, + }).expect("import 2 should be ok"); + + assert!(parity_util_mem::malloc_size(&pool) > 5000); + } + #[test] fn should_remove_invalid_transactions() { // given diff --git a/client/transaction-pool/graph/src/future.rs b/client/transaction-pool/graph/src/future.rs index 0de50c1a65..bda26fe34f 100644 --- a/client/transaction-pool/graph/src/future.rs +++ b/client/transaction-pool/graph/src/future.rs @@ -29,6 +29,7 @@ use sp_runtime::transaction_validity::{ use crate::base_pool::Transaction; +#[derive(parity_util_mem::MallocSizeOf)] /// Transaction with partially satisfied dependencies. pub struct WaitingTransaction { /// Transaction details. @@ -109,7 +110,7 @@ impl WaitingTransaction { /// /// Contains transactions that are still awaiting for some other transactions that /// could provide a tag that they require. -#[derive(Debug)] +#[derive(Debug, parity_util_mem::MallocSizeOf)] pub struct FutureTransactions { /// tags that are not yet provided by any transaction and we await for them wanted_tags: HashMap>, @@ -243,3 +244,30 @@ impl FutureTransactions { self.waiting.values().fold(0, |acc, tx| acc + tx.transaction.bytes) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn can_track_heap_size() { + let mut future = FutureTransactions::default(); + future.import(WaitingTransaction { + transaction: Transaction { + data: vec![0u8; 1024], + bytes: 1, + hash: 1, + priority: 1, + valid_till: 2, + requires: vec![vec![1], vec![2]], + provides: vec![vec![3], vec![4]], + propagate: true, + }.into(), + missing_tags: vec![vec![1u8], vec![2u8]].into_iter().collect(), + imported_at: std::time::Instant::now(), + }); + + // data is at least 1024! + assert!(parity_util_mem::malloc_size(&future) > 1024); + } +} diff --git a/client/transaction-pool/graph/src/pool.rs b/client/transaction-pool/graph/src/pool.rs index 91ce58518a..ab4e3a5a79 100644 --- a/client/transaction-pool/graph/src/pool.rs +++ b/client/transaction-pool/graph/src/pool.rs @@ -122,6 +122,16 @@ pub struct Pool { validated_pool: Arc>, } +impl parity_util_mem::MallocSizeOf for Pool +where + B::Hash: parity_util_mem::MallocSizeOf, + ExtrinsicFor: parity_util_mem::MallocSizeOf, +{ + fn size_of(&self, ops: &mut parity_util_mem::MallocSizeOfOps) -> usize { + self.validated_pool.size_of(ops) + } +} + impl Pool { /// Create a new transaction pool. pub fn new(options: Options, api: Arc) -> Self { diff --git a/client/transaction-pool/graph/src/ready.rs b/client/transaction-pool/graph/src/ready.rs index ec8d66e6b9..23f0d49a93 100644 --- a/client/transaction-pool/graph/src/ready.rs +++ b/client/transaction-pool/graph/src/ready.rs @@ -36,7 +36,7 @@ use crate::base_pool::Transaction; /// An in-pool transaction reference. /// /// Should be cheap to clone. -#[derive(Debug)] +#[derive(Debug, parity_util_mem::MallocSizeOf)] pub struct TransactionRef { /// The actual transaction data. pub transaction: Arc>, @@ -74,7 +74,7 @@ impl PartialEq for TransactionRef { } impl Eq for TransactionRef {} -#[derive(Debug)] +#[derive(Debug, parity_util_mem::MallocSizeOf)] pub struct ReadyTx { /// A reference to a transaction pub transaction: TransactionRef, @@ -104,7 +104,7 @@ Hence every hash retrieved from `provided_tags` is always present in `ready`; qed "#; -#[derive(Debug)] +#[derive(Debug, parity_util_mem::MallocSizeOf)] pub struct ReadyTransactions { /// Insertion id insertion_id: u64, @@ -676,6 +676,24 @@ mod tests { assert_eq!(it.next(), None); } + #[test] + fn can_report_heap_size() { + let mut ready = ReadyTransactions::default(); + let tx = Transaction { + data: vec![5], + bytes: 1, + hash: 5, + priority: 1, + valid_till: u64::max_value(), // use the max_value() here for testing. + requires: vec![], + provides: vec![], + propagate: true, + }; + import(&mut ready, tx).unwrap(); + + assert!(parity_util_mem::malloc_size(&ready) > 200); + } + #[test] fn should_order_refs() { let mut id = 1; diff --git a/client/transaction-pool/graph/src/validated_pool.rs b/client/transaction-pool/graph/src/validated_pool.rs index c7e60deb4a..9524284064 100644 --- a/client/transaction-pool/graph/src/validated_pool.rs +++ b/client/transaction-pool/graph/src/validated_pool.rs @@ -74,6 +74,17 @@ pub(crate) struct ValidatedPool { rotator: PoolRotator>, } +impl parity_util_mem::MallocSizeOf for ValidatedPool +where + B::Hash: parity_util_mem::MallocSizeOf, + ExtrinsicFor: parity_util_mem::MallocSizeOf, +{ + fn size_of(&self, ops: &mut parity_util_mem::MallocSizeOfOps) -> usize { + // other entries insignificant or non-primary references + self.pool.size_of(ops) + } +} + impl ValidatedPool { /// Create a new transaction pool. pub fn new(options: Options, api: Arc) -> Self { diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index 85bf2fd327..7084e1c4a0 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -53,6 +53,18 @@ pub struct BasicPool revalidation_strategy: Arc>>>, } +impl parity_util_mem::MallocSizeOf for BasicPool +where + PoolApi: sc_transaction_graph::ChainApi, + PoolApi::Hash: parity_util_mem::MallocSizeOf, + Block: BlockT, +{ + fn size_of(&self, ops: &mut parity_util_mem::MallocSizeOfOps) -> usize { + // other entries insignificant or non-primary references + self.pool.size_of(ops) + } +} + /// Type of revalidation. pub enum RevalidationType { /// Light revalidation type. diff --git a/client/transaction-pool/src/testing/pool.rs b/client/transaction-pool/src/testing/pool.rs index d4f3d0ccb4..fed02067b1 100644 --- a/client/transaction-pool/src/testing/pool.rs +++ b/client/transaction-pool/src/testing/pool.rs @@ -215,3 +215,14 @@ fn should_not_retain_invalid_hashes_from_retracted() { block_on(pool.maintain(&BlockId::number(1), &[retracted_hash])); assert_eq!(pool.status().ready, 0); } + +#[test] +fn can_track_heap_size() { + let pool = maintained_pool(); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 211))).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 212))).expect("1. Imported"); + + assert!(parity_util_mem::malloc_size(&pool) > 3000); +} \ No newline at end of file diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 4a06dec6ee..a0f3700c9d 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -106,7 +106,7 @@ use sp_runtime::{ traits::{ self, CheckEqual, SimpleArithmetic, Zero, SignedExtension, Lookup, LookupError, SimpleBitOps, Hash, Member, MaybeDisplay, EnsureOrigin, BadOrigin, SaturatedConversion, - MaybeSerialize, MaybeSerializeDeserialize, StaticLookup, One, Bounded, + MaybeSerialize, MaybeSerializeDeserialize, MaybeMallocSizeOf, StaticLookup, One, Bounded, }, }; @@ -171,12 +171,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 + sp_std::hash::Hash + sp_std::str::FromStr; + + Default + Bounded + Copy + sp_std::hash::Hash + sp_std::str::FromStr + MaybeMallocSizeOf; /// The output of the `Hashing` function. type Hash: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + SimpleBitOps + Ord - + Default + Copy + CheckEqual + sp_std::hash::Hash + AsRef<[u8]> + AsMut<[u8]>; + + Default + Copy + CheckEqual + sp_std::hash::Hash + AsRef<[u8]> + AsMut<[u8]> + MaybeMallocSizeOf; /// The hashing system (algorithm) being used in the runtime (e.g. Blake2). type Hashing: Hash; diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 873d607ecd..9bd30d1823 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -30,6 +30,7 @@ sp-debug-derive = { version = "2.0.0", path = "../debug-derive" } sp-externalities = { version = "0.8.0", optional = true, path = "../externalities" } sp-storage = { version = "2.0.0", default-features = false, path = "../storage" } libsecp256k1 = { version = "0.3.2", default-features = false } +parity-util-mem = { version = "0.5.1", default-features = false, features = ["primitive-types"] } # full crypto ed25519-dalek = { version = "1.0.0-pre.3", default-features = false, features = ["u64_backend", "alloc"], optional = true } diff --git a/primitives/core/src/changes_trie.rs b/primitives/core/src/changes_trie.rs index d38761ccf0..cb21ffe13d 100644 --- a/primitives/core/src/changes_trie.rs +++ b/primitives/core/src/changes_trie.rs @@ -22,7 +22,7 @@ use codec::{Encode, Decode}; use num_traits::Zero; /// Substrate changes trie configuration. -#[cfg_attr(any(feature = "std", test), derive(Serialize, Deserialize))] +#[cfg_attr(any(feature = "std", test), derive(Serialize, Deserialize, parity_util_mem::MallocSizeOf))] #[derive(Debug, Clone, PartialEq, Eq, Default, Encode, Decode)] pub struct ChangesTrieConfiguration { /// Interval (in blocks) at which level1-digests are created. Digests are not diff --git a/primitives/runtime/Cargo.toml b/primitives/runtime/Cargo.toml index 6f50a1a4d9..bf7b2b80a3 100644 --- a/primitives/runtime/Cargo.toml +++ b/primitives/runtime/Cargo.toml @@ -18,6 +18,7 @@ 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" } +parity-util-mem = { version = "0.5.1", default-features = false, features = ["primitive-types"] } [dev-dependencies] serde_json = "1.0.41" @@ -37,4 +38,5 @@ std = [ "sp-io/std", "serde", "sp-inherents/std", + "parity-util-mem/std", ] diff --git a/primitives/runtime/src/generic/block.rs b/primitives/runtime/src/generic/block.rs index 21e65d1fb5..a46396dce0 100644 --- a/primitives/runtime/src/generic/block.rs +++ b/primitives/runtime/src/generic/block.rs @@ -25,7 +25,7 @@ use serde::{Deserialize, Serialize}; 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::traits::{self, Member, Block as BlockT, Header as HeaderT, MaybeSerialize, MaybeMallocSizeOf}; use crate::Justification; /// Something to identify a block. @@ -63,7 +63,7 @@ impl fmt::Display for BlockId { /// Abstraction over a substrate block. #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, parity_util_mem::MallocSizeOf))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "std", serde(deny_unknown_fields))] pub struct Block { @@ -76,7 +76,7 @@ pub struct Block { impl traits::Block for Block where Header: HeaderT, - Extrinsic: Member + Codec + traits::Extrinsic, + Extrinsic: Member + Codec + traits::Extrinsic + MaybeMallocSizeOf, { type Extrinsic = Extrinsic; type Header = Header; diff --git a/primitives/runtime/src/generic/digest.rs b/primitives/runtime/src/generic/digest.rs index fef02d4f00..4d09b58793 100644 --- a/primitives/runtime/src/generic/digest.rs +++ b/primitives/runtime/src/generic/digest.rs @@ -27,7 +27,7 @@ use sp_core::{ChangesTrieConfiguration, RuntimeDebug}; /// Generic header digest. #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, parity_util_mem::MallocSizeOf))] pub struct Digest { /// A list of logs in the digest. pub logs: Vec>, @@ -74,6 +74,7 @@ impl Digest { /// Digest item that is able to encode/decode 'system' digest items and /// provide opaque access to other items. #[derive(PartialEq, Eq, Clone, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(parity_util_mem::MallocSizeOf))] pub enum DigestItem { /// System digest item that contains the root of changes trie at given /// block. It is created for every block iff runtime supports changes @@ -107,7 +108,7 @@ pub enum DigestItem { /// Available changes trie signals. #[derive(PartialEq, Eq, Clone, Encode, Decode)] -#[cfg_attr(feature = "std", derive(Debug))] +#[cfg_attr(feature = "std", derive(Debug, parity_util_mem::MallocSizeOf))] pub enum ChangesTrieSignal { /// New changes trie configuration is enacted, starting from **next block**. /// diff --git a/primitives/runtime/src/generic/header.rs b/primitives/runtime/src/generic/header.rs index 51f31af078..5bc7932feb 100644 --- a/primitives/runtime/src/generic/header.rs +++ b/primitives/runtime/src/generic/header.rs @@ -22,6 +22,7 @@ use crate::codec::{Decode, Encode, Codec, Input, Output, HasCompact, EncodeAsRef use crate::traits::{ self, Member, SimpleArithmetic, SimpleBitOps, Hash as HashT, MaybeSerializeDeserialize, MaybeSerialize, MaybeDisplay, + MaybeMallocSizeOf, }; use crate::generic::Digest; use sp_core::U256; @@ -51,6 +52,22 @@ pub struct Header + TryFrom, Hash: HashT> { pub digest: Digest, } +#[cfg(feature = "std")] +impl parity_util_mem::MallocSizeOf for Header +where + Number: Copy + Into + TryFrom + parity_util_mem::MallocSizeOf, + Hash: HashT, + Hash::Output: parity_util_mem::MallocSizeOf, +{ + fn size_of(&self, ops: &mut parity_util_mem::MallocSizeOfOps) -> usize { + self.parent_hash.size_of(ops) + + self.number.size_of(ops) + + self.state_root.size_of(ops) + + self.extrinsics_root.size_of(ops) + + self.digest.size_of(ops) + } +} + #[cfg(feature = "std")] pub fn serialize_number + TryFrom>( val: &T, s: S, @@ -105,10 +122,11 @@ impl codec::EncodeLike for Header where impl traits::Header for Header where Number: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + MaybeDisplay + - SimpleArithmetic + Codec + Copy + Into + TryFrom + sp_std::str::FromStr, + SimpleArithmetic + Codec + Copy + Into + TryFrom + sp_std::str::FromStr + + MaybeMallocSizeOf, Hash: HashT, Hash::Output: Default + sp_std::hash::Hash + Copy + Member + Ord + - MaybeSerialize + Debug + MaybeDisplay + SimpleBitOps + Codec, + MaybeSerialize + Debug + MaybeDisplay + SimpleBitOps + Codec + MaybeMallocSizeOf, { type Number = Number; type Hash = ::Output; diff --git a/primitives/runtime/src/generic/unchecked_extrinsic.rs b/primitives/runtime/src/generic/unchecked_extrinsic.rs index 1625d42e93..a516bc1f7f 100644 --- a/primitives/runtime/src/generic/unchecked_extrinsic.rs +++ b/primitives/runtime/src/generic/unchecked_extrinsic.rs @@ -44,6 +44,18 @@ where pub function: Call, } +#[cfg(feature = "std")] +impl parity_util_mem::MallocSizeOf + for UncheckedExtrinsic +where + Extra: SignedExtension +{ + fn size_of(&self, _ops: &mut parity_util_mem::MallocSizeOfOps) -> usize { + // Instantiated only in runtime. + 0 + } +} + impl UncheckedExtrinsic { diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index 46930c35e8..8d8effcc66 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -639,6 +639,13 @@ macro_rules! assert_eq_error_rate { #[derive(PartialEq, Eq, Clone, Default, Encode, Decode)] pub struct OpaqueExtrinsic(pub Vec); +#[cfg(feature = "std")] +impl parity_util_mem::MallocSizeOf for OpaqueExtrinsic { + fn size_of(&self, ops: &mut parity_util_mem::MallocSizeOfOps) -> usize { + self.0.size_of(ops) + } +} + impl sp_std::fmt::Debug for OpaqueExtrinsic { #[cfg(feature = "std")] fn fmt(&self, fmt: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { diff --git a/primitives/runtime/src/testing.rs b/primitives/runtime/src/testing.rs index c86638b57b..e3e94c3c9f 100644 --- a/primitives/runtime/src/testing.rs +++ b/primitives/runtime/src/testing.rs @@ -148,7 +148,7 @@ pub type DigestItem = generic::DigestItem; pub type Digest = generic::Digest; /// Block Header -#[derive(PartialEq, Eq, Clone, Serialize, Debug, Encode, Decode, Default)] +#[derive(PartialEq, Eq, Clone, Serialize, Debug, Encode, Decode, Default, parity_util_mem::MallocSizeOf)] #[serde(rename_all = "camelCase")] #[serde(deny_unknown_fields)] pub struct Header { @@ -220,10 +220,12 @@ impl<'a> Deserialize<'a> for Header { } /// An opaque extrinsic wrapper type. -#[derive(PartialEq, Eq, Clone, Debug, Encode, Decode)] +#[derive(PartialEq, Eq, Clone, Debug, Encode, Decode, parity_util_mem::MallocSizeOf)] pub struct ExtrinsicWrapper(Xt); -impl traits::Extrinsic for ExtrinsicWrapper { +impl traits::Extrinsic for ExtrinsicWrapper +where Xt: parity_util_mem::MallocSizeOf +{ type Call = (); type SignaturePayload = (); @@ -253,7 +255,7 @@ impl Deref for ExtrinsicWrapper { } /// Testing block -#[derive(PartialEq, Eq, Clone, Serialize, Debug, Encode, Decode)] +#[derive(PartialEq, Eq, Clone, Serialize, Debug, Encode, Decode, parity_util_mem::MallocSizeOf)] pub struct Block { /// Block header pub header: Header, @@ -300,6 +302,9 @@ impl<'a, Xt> Deserialize<'a> for Block where Block: Decode { #[derive(PartialEq, Eq, Clone, Encode, Decode)] pub struct TestXt(pub Option<(u64, Extra)>, pub Call); +// Non-opaque extrinsics always 0. +parity_util_mem::malloc_size_of_is_0!(any: TestXt); + impl Serialize for TestXt where TestXt: Encode { fn serialize(&self, seq: S) -> Result where S: Serializer { self.using_encoded(|bytes| seq.serialize_bytes(bytes)) diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index f8c2ed11a4..f07f4dd7ac 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -470,6 +470,9 @@ sp_core::impl_maybe_marker!( /// A type that implements Serialize, DeserializeOwned and Debug when in std environment. trait MaybeSerializeDeserialize: DeserializeOwned, Serialize; + + /// A type that implements MallocSizeOf. + trait MaybeMallocSizeOf: parity_util_mem::MallocSizeOf; ); /// A type that provides a randomness beacon. @@ -503,13 +506,18 @@ pub trait IsMember { /// `parent_hash`, as well as a `digest` and a block `number`. /// /// You can also create a `new` one from those fields. -pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + 'static { +pub trait Header: + Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + + MaybeMallocSizeOf + 'static +{ /// Header number. type Number: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash - + Copy + MaybeDisplay + SimpleArithmetic + Codec + sp_std::str::FromStr; + + Copy + MaybeDisplay + SimpleArithmetic + Codec + sp_std::str::FromStr + + MaybeMallocSizeOf; /// Header hash type type Hash: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + Ord - + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; + + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + + AsMut<[u8]> + MaybeMallocSizeOf; /// Hashing algorithm type Hashing: Hash; @@ -557,14 +565,15 @@ pub trait Header: Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + 's /// `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 { +pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + MaybeMallocSizeOf + 'static { /// Type for extrinsics. - type Extrinsic: Member + Codec + Extrinsic + MaybeSerialize; + type Extrinsic: Member + Codec + Extrinsic + MaybeSerialize + MaybeMallocSizeOf; /// Header type. - type Header: Header; + type Header: Header + MaybeMallocSizeOf; /// Block hash type. type Hash: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + Ord - + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>; + + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]> + + MaybeMallocSizeOf; /// Returns a reference to the header. fn header(&self) -> &Self::Header; @@ -583,8 +592,9 @@ pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + 'st fn encode_from(header: &Self::Header, extrinsics: &[Self::Extrinsic]) -> Vec; } + /// Something that acts like an `Extrinsic`. -pub trait Extrinsic: Sized { +pub trait Extrinsic: Sized + MaybeMallocSizeOf { /// The function call. type Call; diff --git a/primitives/test-primitives/Cargo.toml b/primitives/test-primitives/Cargo.toml index ba19eb00f3..2edd5f0575 100644 --- a/primitives/test-primitives/Cargo.toml +++ b/primitives/test-primitives/Cargo.toml @@ -11,6 +11,7 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features = 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" } +parity-util-mem = { version = "0.5.1", default-features = false, features = ["primitive-types"] } [features] default = [ diff --git a/primitives/test-primitives/src/lib.rs b/primitives/test-primitives/src/lib.rs index 74115bdb8f..302b24fcc1 100644 --- a/primitives/test-primitives/src/lib.rs +++ b/primitives/test-primitives/src/lib.rs @@ -28,6 +28,7 @@ use sp_runtime::traits::{BlakeTwo256, Verify, Extrinsic as ExtrinsicT,}; /// Extrinsic for test-runtime. #[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug)] +#[cfg_attr(feature = "std", derive(parity_util_mem::MallocSizeOf))] pub enum Extrinsic { IncludeData(Vec), StorageChange(Vec, Option>), diff --git a/primitives/transaction-pool/src/pool.rs b/primitives/transaction-pool/src/pool.rs index 2a71773996..0b23c27f82 100644 --- a/primitives/transaction-pool/src/pool.rs +++ b/primitives/transaction-pool/src/pool.rs @@ -29,7 +29,7 @@ use futures::{ use serde::{Deserialize, Serialize}; use sp_runtime::{ generic::BlockId, - traits::{Block as BlockT, Member}, + traits::{Block as BlockT, Member, MaybeMallocSizeOf}, transaction_validity::{ TransactionLongevity, TransactionPriority, TransactionTag, }, @@ -154,7 +154,7 @@ pub trait InPoolTransaction { } /// Transaction pool interface. -pub trait TransactionPool: Send + Sync { +pub trait TransactionPool: Send + Sync + MaybeMallocSizeOf { /// Block type. type Block: BlockT; /// Transaction hash type. diff --git a/test-utils/runtime/Cargo.toml b/test-utils/runtime/Cargo.toml index e0d8aa77b7..684a681554 100644 --- a/test-utils/runtime/Cargo.toml +++ b/test-utils/runtime/Cargo.toml @@ -37,6 +37,7 @@ sc-client = { version = "0.8", 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.19.2", default-features = false } +parity-util-mem = { version = "0.5.1", default-features = false, features = ["primitive-types"] } [dev-dependencies] sc-executor = { version = "0.8", path = "../../client/executor" } diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index 96387b1efc..dac232b25c 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -114,6 +114,8 @@ pub enum Extrinsic { ChangesTrieConfigUpdate(Option), } +parity_util_mem::malloc_size_of_is_0!(Extrinsic); // non-opaque extrinisic does not need this + #[cfg(feature = "std")] impl serde::Serialize for Extrinsic { fn serialize(&self, seq: S) -> Result where S: ::serde::Serializer { diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index 36f21f192b..3afa49fc25 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -16,7 +16,7 @@ console_log = "0.1.2" js-sys = "0.3.34" wasm-bindgen = "0.2.57" wasm-bindgen-futures = "0.4.7" -kvdb-web = "0.3" +kvdb-web = "0.4" service = { version = "0.8", package = "sc-service", path = "../../client/service", default-features = false } network = { package = "sc-network", path = "../../client/network" } chain-spec = { package = "sc-chain-spec", path = "../../client/chain-spec" } -- GitLab From 4944bd196ccc32f453dd87511e437b18d327e7ba Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Fri, 7 Feb 2020 11:58:31 +0100 Subject: [PATCH 103/180] pow: re-add support for algorithms where only linear verification is possible (#4843) * pow: re-add support for algorithms where only linear verification is possible * Remove unused generic parameters * Clone impl for PowBlockImport --- client/consensus/pow/src/lib.rs | 62 ++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/client/consensus/pow/src/lib.rs b/client/consensus/pow/src/lib.rs index 87f51be216..d656f71a15 100644 --- a/client/consensus/pow/src/lib.rs +++ b/client/consensus/pow/src/lib.rs @@ -63,8 +63,8 @@ pub enum Error { HeaderUnsealed(B::Hash), #[display(fmt = "PoW validation error: invalid seal")] InvalidSeal, - #[display(fmt = "PoW validation error: invalid difficulty")] - InvalidDifficulty, + #[display(fmt = "PoW validation error: preliminary verification failed")] + FailedPreliminaryVerify, #[display(fmt = "Rejecting block too far in future")] TooFarInFuture, #[display(fmt = "Fetching best header failed using select chain: {:?}", _0)] @@ -154,18 +154,23 @@ pub trait PowAlgorithm { /// This function will be called twice during the import process, so the implementation /// should be properly cached. fn difficulty(&self, parent: &BlockId) -> Result>; - /// Verify that the seal is valid against given pre hash. - fn verify_seal( + /// Verify that the seal is valid against given pre hash when parent block is not yet imported. + /// + /// None means that preliminary verify is not available for this algorithm. + fn preliminary_verify( &self, - pre_hash: &B::Hash, - seal: &Seal, - ) -> Result>; + _pre_hash: &B::Hash, + _seal: &Seal, + ) -> Result, Error> { + Ok(None) + } /// Verify that the difficulty is valid against given seal. - fn verify_difficulty( + fn verify( &self, - difficulty: Self::Difficulty, parent: &BlockId, + pre_hash: &B::Hash, seal: &Seal, + difficulty: Self::Difficulty, ) -> Result>; /// Mine a seal that satisfies the given difficulty. fn mine( @@ -187,6 +192,19 @@ pub struct PowBlockImport { check_inherents_after: <::Header as HeaderT>::Number, } +impl Clone for PowBlockImport { + fn clone(&self) -> Self { + Self { + algorithm: self.algorithm.clone(), + inner: self.inner.clone(), + select_chain: self.select_chain.clone(), + client: self.client.clone(), + inherent_data_providers: self.inherent_data_providers.clone(), + check_inherents_after: self.check_inherents_after.clone(), + } + } +} + impl PowBlockImport where B: BlockT, I: BlockImport> + Send + Sync, @@ -322,12 +340,14 @@ impl BlockImport for PowBlockImport self.algorithm.difficulty(&BlockId::hash(parent_hash))?, }; - if !self.algorithm.verify_difficulty( - difficulty, + let pre_hash = block.header.hash(); + if !self.algorithm.verify( &BlockId::hash(parent_hash), + &pre_hash, &inner_seal, + difficulty, )? { - return Err(Error::::InvalidDifficulty.into()) + return Err(Error::::InvalidSeal.into()) } aux.difficulty = difficulty; @@ -379,11 +399,8 @@ impl PowVerifier { let pre_hash = header.hash(); - if !self.algorithm.verify_seal( - &pre_hash, - &inner_seal, - )? { - return Err(Error::InvalidSeal); + if !self.algorithm.preliminary_verify(&pre_hash, &inner_seal)?.unwrap_or(true) { + return Err(Error::FailedPreliminaryVerify); } Ok((header, seal)) @@ -450,20 +467,17 @@ pub fn register_pow_inherent_data_provider( pub type PowImportQueue = BasicQueue; /// Import queue for PoW engine. -pub fn import_queue( - block_import: BoxBlockImport>, +pub fn import_queue( + block_import: BoxBlockImport, algorithm: Algorithm, inherent_data_providers: InherentDataProviders, ) -> Result< - PowImportQueue>, + PowImportQueue, sp_consensus::Error > where B: BlockT, - C: ProvideRuntimeApi + HeaderBackend + BlockOf + ProvideCache + AuxStore, - C: Send + Sync + AuxStore + 'static, - C::Api: BlockBuilderApi, + Transaction: Send + Sync + 'static, Algorithm: PowAlgorithm + Clone + Send + Sync + 'static, - S: SelectChain + 'static, { register_pow_inherent_data_provider(&inherent_data_providers)?; -- GitLab From 20d81157b831fef52949d6e34e10dd2aea6060df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 7 Feb 2020 13:21:46 +0100 Subject: [PATCH 104/180] Move tracing cli args to `ImportParams` (#4850) --- bin/node-template/node/src/command.rs | 3 +-- bin/node/cli/src/command.rs | 4 ++-- client/cli/src/lib.rs | 7 +++---- client/cli/src/params.rs | 28 +++++++++++++-------------- 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/bin/node-template/node/src/command.rs b/bin/node-template/node/src/command.rs index 585b8e1ca8..e7e386703d 100644 --- a/bin/node-template/node/src/command.rs +++ b/bin/node-template/node/src/command.rs @@ -21,8 +21,7 @@ use crate::chain_spec; use crate::cli::Cli; /// Parse and run command line arguments -pub fn run(version: VersionInfo) -> error::Result<()> -{ +pub fn run(version: VersionInfo) -> error::Result<()> { let opt = sc_cli::from_args::(&version); let config = sc_service::Configuration::new(&version); diff --git a/bin/node/cli/src/command.rs b/bin/node/cli/src/command.rs index f5d747a146..0e9b23b73e 100644 --- a/bin/node/cli/src/command.rs +++ b/bin/node/cli/src/command.rs @@ -57,9 +57,9 @@ where } // Setup tracing. - if let Some(tracing_targets) = cli_args.shared_params.tracing_targets.as_ref() { + if let Some(tracing_targets) = cli_args.import_params.tracing_targets.as_ref() { let subscriber = sc_tracing::ProfilingSubscriber::new( - cli_args.shared_params.tracing_receiver.into(), tracing_targets + cli_args.import_params.tracing_receiver.into(), tracing_targets ); if let Err(e) = tracing::subscriber::set_global_default(subscriber) { panic!("Unable to set global default subscriber {}", e); diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index 0965a79f15..735f8cb27a 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -270,8 +270,7 @@ where /// 1. set the panic handler /// 2. raise the FD limit /// 3. initialize the logger -pub fn init(shared_params: &SharedParams, version: &VersionInfo) -> error::Result<()> -{ +pub fn init(shared_params: &SharedParams, version: &VersionInfo) -> error::Result<()> { let full_version = sc_service::config::full_version_from_strs( version.version, version.commit @@ -638,8 +637,8 @@ where config.telemetry_endpoints = Some(TelemetryEndpoints::new(cli.telemetry_endpoints)); } - config.tracing_targets = cli.shared_params.tracing_targets.into(); - config.tracing_receiver = cli.shared_params.tracing_receiver.into(); + config.tracing_targets = cli.import_params.tracing_targets.into(); + config.tracing_receiver = cli.import_params.tracing_receiver.into(); // Imply forced authoring on --dev config.force_authoring = cli.shared_params.dev || cli.force_authoring; diff --git a/client/cli/src/params.rs b/client/cli/src/params.rs index 1dc6b0567c..ddded79142 100644 --- a/client/cli/src/params.rs +++ b/client/cli/src/params.rs @@ -113,20 +113,6 @@ pub struct SharedParams { /// Sets a custom logging filter. #[structopt(short = "l", long = "log", value_name = "LOG_PATTERN")] pub log: Option, - - /// Comma separated list of targets for tracing - #[structopt(long = "tracing-targets", value_name = "TARGETS")] - pub tracing_targets: Option, - - /// Receiver to process tracing messages - #[structopt( - long = "tracing-receiver", - value_name = "RECEIVER", - possible_values = &TracingReceiver::variants(), - case_insensitive = true, - default_value = "Log" - )] - pub tracing_receiver: TracingReceiver, } /// Parameters for block import. @@ -169,6 +155,20 @@ pub struct ImportParams { /// Specify the state cache size. #[structopt(long = "state-cache-size", value_name = "Bytes", default_value = "67108864")] pub state_cache_size: usize, + + /// Comma separated list of targets for tracing + #[structopt(long = "tracing-targets", value_name = "TARGETS")] + pub tracing_targets: Option, + + /// Receiver to process tracing messages + #[structopt( + long = "tracing-receiver", + value_name = "RECEIVER", + possible_values = &TracingReceiver::variants(), + case_insensitive = true, + default_value = "Log" + )] + pub tracing_receiver: TracingReceiver, } /// Parameters used to create the network configuration. -- GitLab From 4c34b6462340b04b0cf0b2c30f512ea5617fd8a6 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Fri, 7 Feb 2020 13:22:06 +0100 Subject: [PATCH 105/180] Update parity-multiaddr dependency (#4852) --- Cargo.lock | 85 +++++++++------------------------------ client/service/Cargo.toml | 2 +- 2 files changed, 21 insertions(+), 66 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca7a5d1844..9b57b0153f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -443,12 +443,6 @@ dependencies = [ "wasm-bindgen-futures", ] -[[package]] -name = "bs58" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c95ee6bba9d950218b6cc910cf62bc9e0a171d0f4537e3627b0f54d08549b188" - [[package]] name = "bs58" version = "0.3.0" @@ -2646,8 +2640,8 @@ dependencies = [ "libp2p-wasm-ext", "libp2p-websocket", "libp2p-yamux", - "parity-multiaddr 0.7.1", - "parity-multihash 0.2.1", + "parity-multiaddr", + "parity-multihash", "parking_lot 0.10.0", "pin-project", "smallvec 1.2.0", @@ -2661,7 +2655,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbafb2706b8082233f66dc13e196f9cf9b4c229f2cd7c96b2b16617ad6ee330b" dependencies = [ "asn1_der", - "bs58 0.3.0", + "bs58", "ed25519-dalek", "fnv", "futures 0.3.1", @@ -2670,8 +2664,8 @@ dependencies = [ "libsecp256k1", "log 0.4.8", "multistream-select", - "parity-multiaddr 0.7.1", - "parity-multihash 0.2.1", + "parity-multiaddr", + "parity-multihash", "parking_lot 0.10.0", "pin-project", "prost", @@ -2682,7 +2676,7 @@ dependencies = [ "sha2", "smallvec 1.2.0", "thiserror", - "unsigned-varint 0.3.0", + "unsigned-varint", "untrusted", "void", "zeroize 1.1.0", @@ -2726,7 +2720,7 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bdf6fba9272ad47dde94bade89540fdb16e24ae9ff7fb714c1c80a035165f28" dependencies = [ - "bs58 0.3.0", + "bs58", "cuckoofilter", "fnv", "futures 0.3.1", @@ -2745,7 +2739,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e6ecd058bf769d27ebec530544b081e08b0a1088e3186da8cc58d59915784d0" dependencies = [ "base64 0.11.0", - "bs58 0.3.0", + "bs58", "byteorder 1.3.2", "bytes 0.5.4", "fnv", @@ -2760,7 +2754,7 @@ dependencies = [ "rand 0.7.3", "sha2", "smallvec 1.2.0", - "unsigned-varint 0.3.0", + "unsigned-varint", "wasm-timer", ] @@ -2795,14 +2789,14 @@ dependencies = [ "libp2p-core", "libp2p-swarm", "log 0.4.8", - "parity-multihash 0.2.1", + "parity-multihash", "prost", "prost-build", "rand 0.7.3", "sha2", "smallvec 1.2.0", "uint", - "unsigned-varint 0.3.0", + "unsigned-varint", "void", "wasm-timer", ] @@ -2842,7 +2836,7 @@ dependencies = [ "libp2p-core", "log 0.4.8", "parking_lot 0.10.0", - "unsigned-varint 0.3.0", + "unsigned-varint", ] [[package]] @@ -2894,7 +2888,7 @@ dependencies = [ "prost", "prost-build", "rw-stream-sink", - "unsigned-varint 0.3.0", + "unsigned-varint", "void", ] @@ -3302,7 +3296,7 @@ dependencies = [ "log 0.4.8", "smallvec 1.2.0", "tokio-io", - "unsigned-varint 0.3.0", + "unsigned-varint", ] [[package]] @@ -4510,24 +4504,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c276d76c5333b8c2579e02d49a06733a55b8282d2d9b13e8d53b6406bd7e30a" -[[package]] -name = "parity-multiaddr" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "045b3c7af871285146300da35b1932bb6e4639b66c7c98e85d06a32cbc4e8fa7" -dependencies = [ - "arrayref", - "bs58 0.2.5", - "byteorder 1.3.2", - "bytes 0.4.12", - "data-encoding", - "parity-multihash 0.1.3", - "percent-encoding 1.0.1", - "serde", - "unsigned-varint 0.2.3", - "url 1.7.2", -] - [[package]] name = "parity-multiaddr" version = "0.7.1" @@ -4535,32 +4511,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80878c27f90dd162d3143333d672e80b194d6b080f05c83440e3dfda42e409f2" dependencies = [ "arrayref", - "bs58 0.3.0", + "bs58", "byteorder 1.3.2", "data-encoding", - "parity-multihash 0.2.1", + "parity-multihash", "percent-encoding 2.1.0", "serde", "static_assertions", - "unsigned-varint 0.3.0", + "unsigned-varint", "url 2.1.1", ] -[[package]] -name = "parity-multihash" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3a17dc27848fd99e4f87eb0f8c9baba6ede0a6d555400c850ca45254ef4ce3" -dependencies = [ - "blake2", - "bytes 0.4.12", - "rand 0.6.5", - "sha-1", - "sha2", - "sha3", - "unsigned-varint 0.2.3", -] - [[package]] name = "parity-multihash" version = "0.2.1" @@ -4573,7 +4534,7 @@ dependencies = [ "sha-1", "sha2", "sha3", - "unsigned-varint 0.3.0", + "unsigned-varint", ] [[package]] @@ -6120,7 +6081,7 @@ dependencies = [ "substrate-test-client", "substrate-test-runtime-client", "tempfile", - "unsigned-varint 0.3.0", + "unsigned-varint", "void", "zeroize 1.1.0", ] @@ -6308,7 +6269,7 @@ dependencies = [ "grafana-data-source", "lazy_static", "log 0.4.8", - "parity-multiaddr 0.5.0", + "parity-multiaddr", "parity-scale-codec", "parity-util-mem 0.5.1", "parking_lot 0.10.0", @@ -8388,12 +8349,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" -[[package]] -name = "unsigned-varint" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f0023a96687fe169081e8adce3f65e3874426b7886e9234d490af2dc077959" - [[package]] name = "unsigned-varint" version = "0.3.0" diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 31408a9a96..bc246db03e 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -52,7 +52,7 @@ 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" } +parity-multiaddr = { package = "parity-multiaddr", version = "0.7.1" } grafana-data-source = { version = "0.8", path = "../../utils/grafana-data-source" } sc-tracing = { version = "2.0.0", path = "../tracing" } tracing = "0.1.10" -- GitLab From 09abd3b436ea568a47ec4fc47f933728d8cf466b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 7 Feb 2020 15:00:51 +0100 Subject: [PATCH 106/180] Fix CLI setup again (#4851) * Fix CLI setup again We need to set `config_dir` and `database_path` for almost every command. This fixes `purge-chain` and also adds a test to make sure we don't break it again. * Adds missing test files * Split methods --- bin/node/cli/src/command.rs | 2 +- bin/node/cli/tests/common.rs | 34 +++++++++ bin/node/cli/tests/purge_chain_works.rs | 53 ++++++++++++++ .../tests/running_the_node_and_interrupt.rs | 32 +++------ client/cli/src/lib.rs | 69 ++++++++++++------- client/cli/src/params.rs | 6 +- 6 files changed, 144 insertions(+), 52 deletions(-) create mode 100644 bin/node/cli/tests/common.rs create mode 100644 bin/node/cli/tests/purge_chain_works.rs diff --git a/bin/node/cli/src/command.rs b/bin/node/cli/src/command.rs index 0e9b23b73e..3bfed148f5 100644 --- a/bin/node/cli/src/command.rs +++ b/bin/node/cli/src/command.rs @@ -41,7 +41,7 @@ where ), Some(Subcommand::Factory(cli_args)) => { sc_cli::init(&cli_args.shared_params, &version)?; - sc_cli::load_spec(&mut config, &cli_args.shared_params, load_spec)?; + sc_cli::init_config(&mut config, &cli_args.shared_params, &version, load_spec)?; sc_cli::fill_import_params( &mut config, &cli_args.import_params, diff --git a/bin/node/cli/tests/common.rs b/bin/node/cli/tests/common.rs new file mode 100644 index 0000000000..96060bf85d --- /dev/null +++ b/bin/node/cli/tests/common.rs @@ -0,0 +1,34 @@ +// Copyright 2020 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::{process::{Child, ExitStatus}, thread, time::Duration}; + +/// Wait for the given `child` the given ammount of `secs`. +/// +/// Returns the `Some(exit status)` or `None` if the process did not finish in the given time. +pub fn wait_for(child: &mut Child, secs: usize) -> Option { + for _ in 0..secs { + match child.try_wait().unwrap() { + Some(status) => return Some(status), + None => thread::sleep(Duration::from_secs(1)), + } + } + eprintln!("Took to long to exit. Killing..."); + let _ = child.kill(); + child.wait().unwrap(); + + None +} diff --git a/bin/node/cli/tests/purge_chain_works.rs b/bin/node/cli/tests/purge_chain_works.rs new file mode 100644 index 0000000000..e6b71db991 --- /dev/null +++ b/bin/node/cli/tests/purge_chain_works.rs @@ -0,0 +1,53 @@ +// Copyright 2020 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 assert_cmd::cargo::cargo_bin; +use std::{convert::TryInto, process::Command, thread, time::Duration, fs, path::PathBuf}; + +mod common; + +#[test] +#[cfg(unix)] +fn purge_chain_works() { + use nix::sys::signal::{kill, Signal::SIGINT}; + use nix::unistd::Pid; + + let base_path = "purge_chain_test"; + + let _ = fs::remove_dir_all(base_path); + let mut cmd = Command::new(cargo_bin("substrate")) + .args(&["--dev", "-d", base_path]) + .spawn() + .unwrap(); + + // Let it produce some blocks. + thread::sleep(Duration::from_secs(30)); + assert!(cmd.try_wait().unwrap().is_none(), "the process should still be running"); + + // Stop the process + kill(Pid::from_raw(cmd.id().try_into().unwrap()), SIGINT).unwrap(); + assert!(common::wait_for(&mut cmd, 30).map(|x| x.success()).unwrap_or_default()); + + let status = Command::new(cargo_bin("substrate")) + .args(&["purge-chain", "--dev", "-d", base_path, "-y"]) + .status() + .unwrap(); + assert!(status.success()); + + // Make sure that the `dev` chain folder exists, but the `db` is deleted. + assert!(PathBuf::from(base_path).join("chains/dev/").exists()); + assert!(!PathBuf::from(base_path).join("chains/dev/db").exists()); +} diff --git a/bin/node/cli/tests/running_the_node_and_interrupt.rs b/bin/node/cli/tests/running_the_node_and_interrupt.rs index 6b0d696396..6ab719de91 100644 --- a/bin/node/cli/tests/running_the_node_and_interrupt.rs +++ b/bin/node/cli/tests/running_the_node_and_interrupt.rs @@ -15,10 +15,9 @@ // along with Substrate. If not, see . use assert_cmd::cargo::cargo_bin; -use std::convert::TryInto; -use std::process::{Child, Command, ExitStatus}; -use std::thread::sleep; -use std::time::Duration; +use std::{convert::TryInto, process::Command, thread, time::Duration, fs}; + +mod common; #[test] #[cfg(unix)] @@ -26,27 +25,18 @@ fn running_the_node_works_and_can_be_interrupted() { use nix::sys::signal::{kill, Signal::{self, SIGINT, SIGTERM}}; use nix::unistd::Pid; - fn wait_for(child: &mut Child, secs: usize) -> Option { - for _ in 0..secs { - match child.try_wait().unwrap() { - Some(status) => return Some(status), - None => sleep(Duration::from_secs(1)), - } - } - eprintln!("Took to long to exit. Killing..."); - let _ = child.kill(); - child.wait().unwrap(); - - None - } - fn run_command_and_kill(signal: Signal) { - let mut cmd = Command::new(cargo_bin("substrate")).spawn().unwrap(); - sleep(Duration::from_secs(30)); + let _ = fs::remove_dir_all("interrupt_test"); + let mut cmd = Command::new(cargo_bin("substrate")) + .args(&["--dev", "-d", "interrupt_test"]) + .spawn() + .unwrap(); + + thread::sleep(Duration::from_secs(30)); assert!(cmd.try_wait().unwrap().is_none(), "the process should still be running"); kill(Pid::from_raw(cmd.id().try_into().unwrap()), signal).unwrap(); assert_eq!( - wait_for(&mut cmd, 30).map(|x| x.success()), + common::wait_for(&mut cmd, 30).map(|x| x.success()), Some(true), "the pocess must exit gracefully after signal {}", signal, diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index 735f8cb27a..54a98a6ad3 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -234,7 +234,7 @@ where SF: AbstractService + Unpin, { init(&run_cmd.shared_params, version)?; - load_spec(&mut config, &run_cmd.shared_params, spec_factory)?; + init_config(&mut config, &run_cmd.shared_params, version, spec_factory)?; run_cmd.run(config, new_light, new_full, version) } @@ -257,9 +257,8 @@ where ::Hash: std::str::FromStr, { let shared_params = subcommand.get_shared_params(); - init(shared_params, version)?; - load_spec(&mut config, shared_params, spec_factory)?; + init_config(&mut config, shared_params, version, spec_factory)?; subcommand.run(config, builder) } @@ -267,9 +266,9 @@ where /// /// This method: /// -/// 1. set the panic handler -/// 2. raise the FD limit -/// 3. initialize the logger +/// 1. Set the panic handler +/// 2. Raise the FD limit +/// 3. Initialize the logger pub fn init(shared_params: &SharedParams, version: &VersionInfo) -> error::Result<()> { let full_version = sc_service::config::full_version_from_strs( version.version, @@ -283,6 +282,37 @@ pub fn init(shared_params: &SharedParams, version: &VersionInfo) -> error::Resul Ok(()) } +/// Initialize the given `config`. +/// +/// This will load the chain spec, set the `config_dir` and the `database_dir`. +pub fn init_config( + config: &mut Configuration, + shared_params: &SharedParams, + version: &VersionInfo, + spec_factory: F, +) -> error::Result<()> where + F: FnOnce(&str) -> Result>, String>, + G: RuntimeGenesis, + E: ChainSpecExtension, +{ + load_spec(config, shared_params, spec_factory)?; + + if config.config_dir.is_none() { + config.config_dir = Some(base_path(&shared_params, version)); + } + + if config.database.is_none() { + config.database = Some(DatabaseConfig::Path { + path: config + .in_chain_config_dir(DEFAULT_DB_CONFIG_PATH) + .expect("We provided a base_path/config_dir."), + cache_size: None, + }); + } + + Ok(()) +} + /// Run the node /// /// Builds and runs either a full or a light node, depending on the `role` within the `Configuration`. @@ -514,26 +544,10 @@ where pub fn update_config_for_running_node( mut config: &mut Configuration, cli: RunCmd, - version: &VersionInfo, ) -> error::Result<()> where G: RuntimeGenesis, { - if config.config_dir.is_none() { - config.config_dir = Some(base_path(&cli.shared_params, version)); - } - - if config.database.is_none() { - // NOTE: the loading of the DatabaseConfig is voluntarily delayed to here - // in case config.config_dir has been customized - config.database = Some(DatabaseConfig::Path { - path: config - .in_chain_config_dir(DEFAULT_DB_CONFIG_PATH) - .expect("We provided a base_path/config_dir."), - cache_size: None, - }); - } - fill_config_keystore_password_and_path(&mut config, &cli)?; let keyring = cli.get_keyring(); @@ -790,7 +804,6 @@ mod tests { update_config_for_running_node( &mut node_config, run_cmds.clone(), - TEST_VERSION_INFO, ).unwrap(); let expected_path = match keystore_path { @@ -843,8 +856,14 @@ mod tests { let cli = RunCmd::from_iter(args); let mut config = Configuration::new(TEST_VERSION_INFO); - config.chain_spec = Some(chain_spec); - update_config_for_running_node(&mut config, cli, TEST_VERSION_INFO).unwrap(); + init(&cli.shared_params, &TEST_VERSION_INFO).unwrap(); + init_config( + &mut config, + &cli.shared_params, + &TEST_VERSION_INFO, + |_| Ok(Some(chain_spec)), + ).unwrap(); + update_config_for_running_node(&mut config, cli).unwrap(); assert!(config.config_dir.is_some()); assert!(config.database.is_some()); diff --git a/client/cli/src/params.rs b/client/cli/src/params.rs index ddded79142..a99d887d25 100644 --- a/client/cli/src/params.rs +++ b/client/cli/src/params.rs @@ -933,11 +933,7 @@ impl RunCmd { { assert!(config.chain_spec.is_some(), "chain_spec must be present before continuing"); - crate::update_config_for_running_node( - &mut config, - self, - &version, - )?; + crate::update_config_for_running_node(&mut config, self)?; crate::run_node(config, new_light, new_full, &version) } -- GitLab From 9d55595ec1a345008b3a862c85e22837d966c8ad Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Fri, 7 Feb 2020 16:25:20 +0100 Subject: [PATCH 107/180] Implement From for '&static str (#4856) --- primitives/runtime/src/lib.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index 8d8effcc66..9494c53cc6 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -405,13 +405,13 @@ impl From<&'static str> for DispatchError { } } -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 for &'static str { + fn from(err: DispatchError) -> &'static str { + match err { + DispatchError::Other(msg) => msg, + DispatchError::CannotLookup => "Can not lookup", + DispatchError::BadOrigin => "Bad origin", + DispatchError::Module { message, .. } => message.unwrap_or("Unknown module error"), } } } -- GitLab From aa15e17a71e28eea1291f2e5d169574d4894bc38 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Fri, 7 Feb 2020 17:38:13 +0100 Subject: [PATCH 108/180] WIP: Test: does cargo update work? (#4844) * Initial commit Forked at: 099cd0f2ba2a041f087978ef9d53473d0a6d0aee Parent branch: origin/master * Update Cargo.lock * Cargo.lock * Add missing features of libsecp256k1 * Update dependencies --- Cargo.lock | 477 ++++++++++++++++------------------ primitives/core/Cargo.toml | 2 +- primitives/trie/Cargo.toml | 8 +- test-utils/runtime/Cargo.toml | 4 +- 4 files changed, 236 insertions(+), 255 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9b57b0153f..d13c45afa2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,7 +35,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" dependencies = [ "block-cipher-trait", - "byteorder 1.3.2", + "byteorder 1.3.4", "opaque-debug", ] @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f56c476256dc249def911d6f7580b5fc7e875895b5d7ee88f5d602208035744" +checksum = "743ad5a418686aad3b87fd14c43badd828cf26e214a00f92a384291cf22e1811" dependencies = [ "memchr", ] @@ -179,7 +179,7 @@ dependencies = [ "broadcaster", "crossbeam-channel", "crossbeam-deque", - "crossbeam-utils 0.7.0", + "crossbeam-utils", "futures-core", "futures-io", "futures-timer 2.0.2", @@ -211,7 +211,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce6977f57fa68da77ffe5542950d47e9c23d65f5bc7cb0a9f8700996913eec7" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", "rustls", "webpki", "webpki-roots 0.17.0", @@ -274,7 +274,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", "safemem", ] @@ -284,7 +284,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", ] [[package]] @@ -299,7 +299,7 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5753e2a71534719bf3f4e57006c3a4f0d2c672a4b676eec84161f763eca87dbf" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", "serde", ] @@ -385,7 +385,7 @@ checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" dependencies = [ "block-padding", "byte-tools", - "byteorder 1.3.2", + "byteorder 1.3.4", "generic-array", ] @@ -429,7 +429,7 @@ dependencies = [ "console_error_panic_hook", "console_log", "futures 0.1.29", - "futures 0.3.1", + "futures 0.3.4", "js-sys", "kvdb-web", "libp2p", @@ -451,9 +451,9 @@ checksum = "b170cd256a3f9fa6b9edae3e44a7dfdfc77e8124dbc3e2612d75f9c3e2396dae" [[package]] name = "bstr" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe8a65814ca90dfc9705af76bb6ba3c6e2534489a72270e797e603783bb4990b" +checksum = "502ae1441a0a5adb8fbd38a5955a6416b9493e92b465de5e4a9bde6a539c2c48" dependencies = [ "lazy_static", "memchr", @@ -496,9 +496,9 @@ checksum = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" [[package]] name = "byteorder" -version = "1.3.2" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" [[package]] name = "bytes" @@ -506,7 +506,7 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", "either", "iovec", ] @@ -731,7 +731,7 @@ version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c63d9b6ff8a94f98deabab21880d7fd54996e0e16be687b6f80a3b6bdd9c188d" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", @@ -873,7 +873,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76f9212ddf2f4a9eb2d401635190600656a1f88a932ef53d06e7fa4c7e02fb8e" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", "cast", "itertools", ] @@ -894,7 +894,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c" dependencies = [ - "crossbeam-utils 0.7.0", + "crossbeam-utils", ] [[package]] @@ -904,7 +904,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca" dependencies = [ "crossbeam-epoch", - "crossbeam-utils 0.7.0", + "crossbeam-utils", ] [[package]] @@ -915,21 +915,12 @@ checksum = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" dependencies = [ "autocfg 0.1.7", "cfg-if", - "crossbeam-utils 0.7.0", + "crossbeam-utils", "lazy_static", "memoffset", "scopeguard 1.0.0", ] -[[package]] -name = "crossbeam-queue" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" -dependencies = [ - "crossbeam-utils 0.6.6", -] - [[package]] name = "crossbeam-queue" version = "0.2.1" @@ -937,17 +928,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db" dependencies = [ "cfg-if", - "crossbeam-utils 0.7.0", -] - -[[package]] -name = "crossbeam-utils" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" -dependencies = [ - "cfg-if", - "lazy_static", + "crossbeam-utils", ] [[package]] @@ -1044,7 +1025,7 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b7dcd30ba50cdf88b55b033456138b7c0ac4afdc436d82e1b79f370f24cc66d" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", "clear_on_drop", "digest", "rand_core 0.3.1", @@ -1057,7 +1038,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26778518a7f6cffa1d25a44b602b62b979bd88adb9e99ffec546998cf3404839" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", "digest", "rand_core 0.5.1", "subtle 2.2.2", @@ -1124,7 +1105,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", "quick-error", ] @@ -1298,7 +1279,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", ] [[package]] @@ -1376,7 +1357,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cbb25bef9fcad97fb31e817da280b1c9174435b8769c770ee190a330dd181ea" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", "futures-timer 2.0.2", "log 0.4.8", "num-traits", @@ -1391,7 +1372,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", "libc", "rand 0.7.3", "rustc-hex", @@ -1622,9 +1603,9 @@ checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" [[package]] name = "futures" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6f16056ecbb57525ff698bb955162d0cd03bee84e6241c27ff75c08d8ca5987" +checksum = "5c329ae8753502fb44ae4fc2b622fa2a94652c41e795143765ba0927f92ab780" dependencies = [ "futures-channel", "futures-core", @@ -1637,9 +1618,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcae98ca17d102fd8a3603727b9259fcf7fa4239b603d2142926189bc8999b86" +checksum = "f0c77d04ce8edd9cb903932b608268b3fffec4163dc053b3b402bf47eac1f1a8" dependencies = [ "futures-core", "futures-sink", @@ -1656,9 +1637,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79564c427afefab1dfb3298535b21eda083ef7935b4f0ecbfcb121f0aec10866" +checksum = "f25592f769825e89b92358db00d26f965761e094951ac44d3663ef25b7ac464a" [[package]] name = "futures-core-preview" @@ -1678,12 +1659,12 @@ dependencies = [ [[package]] name = "futures-diagnose" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebbb8371dd6ee87aa2aeaa8458a372fd82fe216032387b766255754c92dd7271" +checksum = "fdcef58a173af8148b182684c9f2d5250875adbcaff7b5794073894f9d8634a9" dependencies = [ "futures 0.1.29", - "futures 0.3.1", + "futures 0.3.4", "lazy_static", "log 0.4.8", "parking_lot 0.9.0", @@ -1694,9 +1675,9 @@ dependencies = [ [[package]] name = "futures-executor" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e274736563f686a837a0568b478bdabfeaec2dca794b5649b04e2fe1627c231" +checksum = "f674f3e1bcb15b37284a90cedf55afdba482ab061c407a9c0ebbd0f3109741ba" dependencies = [ "futures-core", "futures-task", @@ -1706,15 +1687,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e676577d229e70952ab25f3945795ba5b16d63ca794ca9d2c860e5595d20b5ff" +checksum = "a638959aa96152c7a4cddf50fcb1e3fede0583b27157c26e67d6f99904090dc6" [[package]] name = "futures-macro" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e7c56c15537adb4f76d0b7a76ad131cb4d2f4f32d3b0bcabcbe1c7c5e87764" +checksum = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7" dependencies = [ "proc-macro-hack", "proc-macro2 1.0.8", @@ -1724,15 +1705,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171be33efae63c2d59e6dbba34186fe0d6394fb378069a76dfd80fdcffd43c16" +checksum = "3466821b4bc114d95b087b850a724c6f83115e929bc88f1fa98a3304a944c8a6" [[package]] name = "futures-task" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bae52d6b29cf440e298856fec3965ee6fa71b06aa7495178615953fd669e5f9" +checksum = "7b0a34e53cf6cdcd0178aa573aed466b646eb3db769570841fda0c7ede375a27" [[package]] name = "futures-timer" @@ -1753,9 +1734,9 @@ checksum = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6" [[package]] name = "futures-util" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76" +checksum = "22766cf25d64306bedf0384da004d05c9974ab104fcc4528f1236181c18004c5" dependencies = [ "futures 0.1.29", "futures-channel", @@ -1791,7 +1772,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0a73299e4718f5452e45980fc1d6957a070abe308d3700b63b8673f47e1c2b3" dependencies = [ "bytes 0.5.4", - "futures 0.3.1", + "futures 0.3.4", "memchr", "pin-project", ] @@ -1802,7 +1783,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", ] [[package]] @@ -1861,7 +1842,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "162d18ae5f2e3b90a993d202f1ba17a5633c2484426f8bcae201f86194bacd00" dependencies = [ "arrayvec 0.4.12", - "byteorder 1.3.2", + "byteorder 1.3.4", "fallible-iterator", "indexmap", "stable_deref_trait", @@ -1925,7 +1906,7 @@ dependencies = [ name = "grafana-data-source-test" version = "2.0.0" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", "futures-timer 2.0.2", "grafana-data-source", "rand 0.7.3", @@ -1937,7 +1918,7 @@ version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", "bytes 0.4.12", "fnv", "futures 0.1.29", @@ -1989,7 +1970,7 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", "scopeguard 0.3.3", ] @@ -2172,7 +2153,7 @@ dependencies = [ "time", "tokio 0.1.22", "tokio-buf", - "tokio-executor 0.1.9", + "tokio-executor 0.1.10", "tokio-io", "tokio-reactor", "tokio-tcp", @@ -2305,9 +2286,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b54058f0a6ff80b6803da8faf8997cde53872b38f4023728f6830b06cd3c0dc" +checksum = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292" dependencies = [ "autocfg 1.0.0", ] @@ -2526,7 +2507,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03080afe6f42cd996da9f568d6add5d7fb5ee2ea7fb7802d2d2cbd836958fd87" dependencies = [ "parity-bytes", - "parity-util-mem 0.5.1", + "parity-util-mem", "smallvec 1.2.0", ] @@ -2537,7 +2518,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9355274e5a9e0a7e8ef43916950eae3949024de2a8dffe4d5a6c13974a37c8e" dependencies = [ "kvdb", - "parity-util-mem 0.5.1", + "parity-util-mem", "parking_lot 0.10.0", ] @@ -2553,7 +2534,7 @@ dependencies = [ "log 0.4.8", "num_cpus", "owning_ref", - "parity-util-mem 0.5.1", + "parity-util-mem", "parking_lot 0.10.0", "regex", "rocksdb", @@ -2566,12 +2547,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a985c47b4c46429e96033ebf6eaed784a81ceccb4e5df13d63f3b9078a4df81" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", "js-sys", "kvdb", "kvdb-memorydb", "log 0.4.8", - "parity-util-mem 0.5.1", + "parity-util-mem", "send_wrapper 0.3.0", "wasm-bindgen", "web-sys", @@ -2618,7 +2599,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f84847789ab24b3fc5971a68656ac85886df640986d9ce3264c0327694eae471" dependencies = [ "bytes 0.5.4", - "futures 0.3.1", + "futures 0.3.4", "lazy_static", "libp2p-core", "libp2p-core-derive", @@ -2658,7 +2639,7 @@ dependencies = [ "bs58", "ed25519-dalek", "fnv", - "futures 0.3.1", + "futures 0.3.4", "futures-timer 2.0.2", "lazy_static", "libsecp256k1", @@ -2699,7 +2680,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be32697b42d040b325c3737f827ea04ede569ec956b7807700dd8d89d8210f9" dependencies = [ "flate2", - "futures 0.3.1", + "futures 0.3.4", "libp2p-core", ] @@ -2709,7 +2690,7 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f11c979b882f25d85726b15637d5bbc722dfa1be576605c54e99b8cf56906be3" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", "libp2p-core", "log 0.4.8", ] @@ -2723,7 +2704,7 @@ dependencies = [ "bs58", "cuckoofilter", "fnv", - "futures 0.3.1", + "futures 0.3.4", "libp2p-core", "libp2p-swarm", "prost", @@ -2740,10 +2721,10 @@ checksum = "6e6ecd058bf769d27ebec530544b081e08b0a1088e3186da8cc58d59915784d0" dependencies = [ "base64 0.11.0", "bs58", - "byteorder 1.3.2", + "byteorder 1.3.4", "bytes 0.5.4", "fnv", - "futures 0.3.1", + "futures 0.3.4", "futures_codec", "libp2p-core", "libp2p-swarm", @@ -2764,7 +2745,7 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d1a6261b804111c2dbf53f8ca03f66edc5ad1c29b78a61cf0cc5354052e28e9" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", "libp2p-core", "libp2p-swarm", "log 0.4.8", @@ -2784,7 +2765,7 @@ dependencies = [ "bytes 0.5.4", "either", "fnv", - "futures 0.3.1", + "futures 0.3.4", "futures_codec", "libp2p-core", "libp2p-swarm", @@ -2811,7 +2792,7 @@ dependencies = [ "data-encoding", "dns-parser", "either", - "futures 0.3.1", + "futures 0.3.4", "lazy_static", "libp2p-core", "libp2p-swarm", @@ -2831,7 +2812,7 @@ checksum = "89d0b44dfdef80cc2be4b42d127de1c793905eca2459415a5c57d6b4fbd8ec30" dependencies = [ "bytes 0.5.4", "fnv", - "futures 0.3.1", + "futures 0.3.4", "futures_codec", "libp2p-core", "log 0.4.8", @@ -2846,7 +2827,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0845e8208d814cd41c26c90a6a2f2b720c31b588209cecc49a44c881a09f417f" dependencies = [ "curve25519-dalek 1.2.3", - "futures 0.3.1", + "futures 0.3.4", "lazy_static", "libp2p-core", "log 0.4.8", @@ -2865,7 +2846,7 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16ecced2949ae93b6ff29565303ecd1bef15c4e4efb689033ee744922561a36b" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", "libp2p-core", "libp2p-swarm", "log 0.4.8", @@ -2881,7 +2862,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "195fda6b6a948a242fd30570e0e3418ae8e0a20055ea75d45458e1079a8efb05" dependencies = [ "bytes 0.5.4", - "futures 0.3.1", + "futures 0.3.4", "futures_codec", "libp2p-core", "log 0.4.8", @@ -2900,7 +2881,7 @@ checksum = "ceef68ca377b264f84d64c88739a8fa118b5db1e8f18297351dff75314504a5f" dependencies = [ "aes-ctr", "ctr", - "futures 0.3.1", + "futures 0.3.4", "hmac", "js-sys", "lazy_static", @@ -2928,7 +2909,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14ea00be81bc3985e36abad263ce2ad1b6aeb862aa743563eb70ad42880c05ae" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", "libp2p-core", "log 0.4.8", "smallvec 1.2.0", @@ -2943,7 +2924,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e65ef381570df31cb047dfbc11483ab0fe7e6abbdcf2bdc2c60b5d11133d241" dependencies = [ "async-std", - "futures 0.3.1", + "futures 0.3.4", "futures-timer 2.0.2", "get_if_addrs", "ipnet", @@ -2958,7 +2939,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e4f4f7989b35f33d4b9738aab2f031310eb20fec513cab44d12b1bc985a8074" dependencies = [ "async-std", - "futures 0.3.1", + "futures 0.3.4", "libp2p-core", "log 0.4.8", ] @@ -2969,7 +2950,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b4d457adb91a5e2212343218a554394cd8ced64a79fb8e36e7aed2a16d49495" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", "js-sys", "libp2p-core", "parity-send-wrapper", @@ -2986,7 +2967,7 @@ dependencies = [ "async-tls", "bytes 0.5.4", "either", - "futures 0.3.1", + "futures 0.3.4", "libp2p-core", "log 0.4.8", "quicksink", @@ -3004,7 +2985,7 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ca25b3aac78a3c93c2a567622abd3cfc16f96f26ae1bf6134f0056203d62d86" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", "libp2p-core", "log 0.4.8", "parking_lot 0.10.0", @@ -3026,9 +3007,9 @@ dependencies = [ [[package]] name = "libsecp256k1" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df6edf84fd62aad1c93932b39324eaeda3912c1d26bc18dfaee6293848e49a50" +checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" dependencies = [ "arrayref", "crunchy", @@ -3130,17 +3111,6 @@ dependencies = [ "libc", ] -[[package]] -name = "malloc_size_of_derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37c5d4cd9473c5f4c9c111f033f15d4df9bd378fdf615944e360a4f55a05f0b" -dependencies = [ - "proc-macro2 1.0.8", - "syn", - "synstructure", -] - [[package]] name = "matches" version = "0.1.8" @@ -3173,14 +3143,14 @@ dependencies = [ [[package]] name = "memory-db" -version = "0.18.1" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881736a0f68a6fae1b596bb066c5bd16d7b3ed645a4dd8ffaefd02f585abaf71" +checksum = "198831fe8722331a395bc199a5d08efbc197497ef354cb4c77b969c02ffc0fc4" dependencies = [ "ahash", "hash-db", "hashbrown 0.6.3", - "parity-util-mem 0.3.0", + "parity-util-mem", ] [[package]] @@ -3195,7 +3165,7 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b0942b357c1b4d0dc43ba724674ec89c3218e6ca2b3e8269e7cb53bcecd2f6e" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", "keccak", "rand_core 0.4.2", "zeroize 1.1.0", @@ -3358,7 +3328,7 @@ dependencies = [ "browser-utils", "frame-support", "frame-system", - "futures 0.3.1", + "futures 0.3.4", "hex-literal", "jsonrpc-core", "log 0.4.8", @@ -3446,7 +3416,7 @@ dependencies = [ "sp-state-machine", "sp-trie", "substrate-test-client", - "trie-root", + "trie-root 0.15.2", "wabt", ] @@ -3554,7 +3524,7 @@ dependencies = [ name = "node-template" version = "2.0.0" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", "log 0.4.8", "node-template-runtime", "sc-basic-authorship", @@ -3778,9 +3748,9 @@ checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" [[package]] name = "openssl" -version = "0.10.27" +version = "0.10.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e176a45fedd4c990e26580847a525e39e16ec32ac78957dbf62ded31b3abfd6f" +checksum = "973293749822d7dd6370d6da1e523b0d1db19f06c459134c658b2a4261378b52" dependencies = [ "bitflags", "cfg-if", @@ -4512,7 +4482,7 @@ checksum = "80878c27f90dd162d3143333d672e80b194d6b080f05c83440e3dfda42e409f2" dependencies = [ "arrayref", "bs58", - "byteorder 1.3.2", + "byteorder 1.3.4", "data-encoding", "parity-multihash", "percent-encoding 2.1.0", @@ -4524,9 +4494,9 @@ dependencies = [ [[package]] name = "parity-multihash" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a4d7b05e51bff5ae2c29c7b8c3d889985bbd8f4e15b3542fcc1f6f9666d292" +checksum = "b11f42bbd3a021c5061b77154bd3334d5a57e1a03eb162de0b962681cc25800d" dependencies = [ "blake2", "bytes 0.5.4", @@ -4568,17 +4538,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" -[[package]] -name = "parity-util-mem" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8174d85e62c4d615fddd1ef67966bdc5757528891d0742f15b131ad04667b3f9" -dependencies = [ - "cfg-if", - "malloc_size_of_derive", - "winapi 0.3.8", -] - [[package]] name = "parity-util-mem" version = "0.5.1" @@ -4611,7 +4570,7 @@ version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16ad52817c4d343339b3bc2e26861bd21478eda0b7509acf83505727000512ac" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", ] [[package]] @@ -4721,7 +4680,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", "crypto-mac", ] @@ -4999,7 +4958,7 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f7a12f176deee919f4ba55326ee17491c8b707d0987aed822682c821b660192" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", "log 0.4.8", "parity-wasm 0.41.0", ] @@ -5228,7 +5187,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03b418169fb9c46533f326efd6eed2576699c44ca92d3052a066214a8d828929" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", "rand_core 0.3.1", ] @@ -5261,8 +5220,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9" dependencies = [ "crossbeam-deque", - "crossbeam-queue 0.2.1", - "crossbeam-utils 0.7.0", + "crossbeam-queue", + "crossbeam-utils", "lazy_static", "num_cpus", ] @@ -5311,7 +5270,7 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", ] [[package]] @@ -5343,9 +5302,9 @@ dependencies = [ [[package]] name = "ring" -version = "0.16.10" +version = "0.16.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "113f53b644c5442e20ff3a299be3d6c61ba143737af5bd2ab298e248a7575b2d" +checksum = "741ba1704ae21999c00942f9f5944f801e977f54302af346b596287599ad1862" dependencies = [ "cc", "lazy_static", @@ -5394,7 +5353,7 @@ dependencies = [ "base64 0.11.0", "blake2b_simd", "constant_time_eq", - "crossbeam-utils 0.7.0", + "crossbeam-utils", ] [[package]] @@ -5448,7 +5407,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", "pin-project", "static_assertions", ] @@ -5461,9 +5420,9 @@ checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" [[package]] name = "safe-mix" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7bf422d23a88c16d5090d455f182bc99c60af4df6a345c63428acf5129e347" +checksum = "6d3d055a2582e6b00ed7a31c1524040aa391092bf636328350813f3a0605215c" dependencies = [ "rustc_version", ] @@ -5490,7 +5449,7 @@ dependencies = [ "bytes 0.4.12", "derive_more", "env_logger 0.7.1", - "futures 0.3.1", + "futures 0.3.4", "futures-timer 2.0.2", "libp2p", "log 0.4.8", @@ -5516,7 +5475,7 @@ dependencies = [ name = "sc-basic-authorship" version = "0.8.0" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.0", @@ -5587,11 +5546,11 @@ dependencies = [ "derive_more", "env_logger 0.7.1", "fdlimit", - "futures 0.3.1", + "futures 0.3.4", "lazy_static", "log 0.4.8", "names", - "parity-util-mem 0.5.1", + "parity-util-mem", "regex", "rpassword", "sc-client-api", @@ -5619,7 +5578,7 @@ dependencies = [ "derive_more", "env_logger 0.7.1", "fnv", - "futures 0.3.1", + "futures 0.3.4", "hash-db", "hex-literal", "kvdb", @@ -5655,7 +5614,7 @@ version = "2.0.0" dependencies = [ "derive_more", "fnv", - "futures 0.3.1", + "futures 0.3.4", "hash-db", "hex-literal", "kvdb", @@ -5692,7 +5651,7 @@ dependencies = [ "linked-hash-map", "log 0.4.8", "parity-scale-codec", - "parity-util-mem 0.5.1", + "parity-util-mem", "parking_lot 0.10.0", "quickcheck", "sc-client", @@ -5717,7 +5676,7 @@ dependencies = [ "derive_more", "env_logger 0.7.1", "futures 0.1.29", - "futures 0.3.1", + "futures 0.3.4", "futures-timer 0.4.0", "log 0.4.8", "parity-scale-codec", @@ -5757,7 +5716,7 @@ dependencies = [ "env_logger 0.7.1", "fork-tree", "futures 0.1.29", - "futures 0.3.1", + "futures 0.3.4", "futures-timer 0.4.0", "log 0.4.8", "merlin", @@ -5817,7 +5776,7 @@ version = "0.8.0" dependencies = [ "derive_more", "env_logger 0.7.1", - "futures 0.3.1", + "futures 0.3.4", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", @@ -5844,7 +5803,7 @@ name = "sc-consensus-pow" version = "0.8.0" dependencies = [ "derive_more", - "futures 0.3.1", + "futures 0.3.4", "log 0.4.8", "parity-scale-codec", "sc-client-api", @@ -5863,7 +5822,7 @@ dependencies = [ name = "sc-consensus-slots" version = "0.8.0" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", "futures-timer 2.0.2", "log 0.4.8", "parity-scale-codec", @@ -5989,7 +5948,7 @@ dependencies = [ "finality-grandpa", "fork-tree", "futures 0.1.29", - "futures 0.3.1", + "futures 0.3.4", "futures-timer 2.0.2", "log 0.4.8", "parity-scale-codec", @@ -6048,7 +6007,7 @@ dependencies = [ "erased-serde", "fnv", "fork-tree", - "futures 0.3.1", + "futures 0.3.4", "futures-timer 0.4.0", "futures_codec", "libp2p", @@ -6091,7 +6050,7 @@ name = "sc-network-gossip" version = "0.8.0" dependencies = [ "futures 0.1.29", - "futures 0.3.1", + "futures 0.3.4", "futures-timer 0.4.0", "libp2p", "log 0.4.8", @@ -6107,7 +6066,7 @@ version = "0.8.0" dependencies = [ "env_logger 0.7.1", "futures 0.1.29", - "futures 0.3.1", + "futures 0.3.4", "futures-timer 0.4.0", "libp2p", "log 0.4.8", @@ -6136,7 +6095,7 @@ dependencies = [ "env_logger 0.7.1", "fnv", "futures 0.1.29", - "futures 0.3.1", + "futures 0.3.4", "futures-timer 2.0.2", "hyper 0.12.35", "hyper-rustls", @@ -6164,7 +6123,7 @@ dependencies = [ name = "sc-peerset" version = "2.0.0" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", "libp2p", "log 0.4.8", "rand 0.7.3", @@ -6177,7 +6136,7 @@ version = "2.0.0" dependencies = [ "assert_matches", "futures 0.1.29", - "futures 0.3.1", + "futures 0.3.4", "hash-db", "jsonrpc-core", "jsonrpc-pubsub", @@ -6213,7 +6172,7 @@ name = "sc-rpc-api" version = "0.8.0" dependencies = [ "derive_more", - "futures 0.3.1", + "futures 0.3.4", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", @@ -6263,7 +6222,7 @@ dependencies = [ "derive_more", "exit-future", "futures 0.1.29", - "futures 0.3.1", + "futures 0.3.4", "futures-diagnose", "futures-timer 2.0.2", "grafana-data-source", @@ -6271,7 +6230,7 @@ dependencies = [ "log 0.4.8", "parity-multiaddr", "parity-scale-codec", - "parity-util-mem 0.5.1", + "parity-util-mem", "parking_lot 0.10.0", "sc-chain-spec", "sc-client", @@ -6305,7 +6264,7 @@ dependencies = [ "sysinfo", "target_info", "tokio 0.2.11", - "tokio-executor 0.1.9", + "tokio-executor 0.1.10", "tracing", ] @@ -6316,7 +6275,7 @@ dependencies = [ "env_logger 0.7.1", "fdlimit", "futures 0.1.29", - "futures 0.3.1", + "futures 0.3.4", "log 0.4.8", "sc-client", "sc-network", @@ -6345,7 +6304,7 @@ name = "sc-telemetry" version = "2.0.0" dependencies = [ "bytes 0.5.4", - "futures 0.3.1", + "futures 0.3.4", "futures-timer 2.0.2", "libp2p", "log 0.4.8", @@ -6383,10 +6342,10 @@ dependencies = [ "assert_matches", "criterion 0.3.1", "derive_more", - "futures 0.3.1", + "futures 0.3.4", "log 0.4.8", "parity-scale-codec", - "parity-util-mem 0.5.1", + "parity-util-mem", "parking_lot 0.10.0", "serde", "sp-core", @@ -6400,11 +6359,11 @@ name = "sc-transaction-pool" version = "2.0.0" dependencies = [ "derive_more", - "futures 0.3.1", + "futures 0.3.4", "futures-diagnose", "log 0.4.8", "parity-scale-codec", - "parity-util-mem 0.5.1", + "parity-util-mem", "parking_lot 0.10.0", "sc-client-api", "sc-transaction-graph", @@ -6420,9 +6379,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" +checksum = "507a9e6e8ffe0a4e0ebb9a10293e62fdf7657c06f1b8bb07a8fcf697d2abf295" dependencies = [ "lazy_static", "winapi 0.3.8", @@ -6732,7 +6691,7 @@ dependencies = [ "base64 0.11.0", "bytes 0.5.4", "flate2", - "futures 0.3.1", + "futures 0.3.4", "http 0.2.0", "httparse", "log 0.4.8", @@ -6892,7 +6851,7 @@ name = "sp-consensus" version = "0.8.0" dependencies = [ "derive_more", - "futures 0.3.1", + "futures 0.3.4", "futures-diagnose", "futures-timer 0.4.0", "libp2p", @@ -6954,7 +6913,7 @@ version = "2.0.0" dependencies = [ "base58", "blake2-rfc", - "byteorder 1.3.2", + "byteorder 1.3.4", "criterion 0.2.11", "ed25519-dalek", "hash-db", @@ -6967,7 +6926,7 @@ dependencies = [ "log 0.4.8", "num-traits", "parity-scale-codec", - "parity-util-mem 0.5.1", + "parity-util-mem", "parking_lot 0.10.0", "pretty_assertions", "primitive-types", @@ -7113,7 +7072,7 @@ dependencies = [ "impl-trait-for-tuples", "log 0.4.8", "parity-scale-codec", - "parity-util-mem 0.5.1", + "parity-util-mem", "paste", "rand 0.7.3", "serde", @@ -7235,8 +7194,8 @@ dependencies = [ "sp-externalities", "sp-panic-handler", "sp-trie", - "trie-db", - "trie-root", + "trie-db 0.19.2", + "trie-root 0.15.2", ] [[package]] @@ -7258,7 +7217,7 @@ name = "sp-test-primitives" version = "2.0.0" dependencies = [ "parity-scale-codec", - "parity-util-mem 0.5.1", + "parity-util-mem", "serde", "sp-application-crypto", "sp-core", @@ -7282,7 +7241,7 @@ name = "sp-transaction-pool" version = "2.0.0" dependencies = [ "derive_more", - "futures 0.3.1", + "futures 0.3.4", "log 0.4.8", "parity-scale-codec", "serde", @@ -7302,8 +7261,8 @@ dependencies = [ "sp-core", "sp-std", "trie-bench", - "trie-db", - "trie-root", + "trie-db 0.20.0", + "trie-root 0.16.0", "trie-standardmap", ] @@ -7474,7 +7433,7 @@ version = "2.0.0" dependencies = [ "frame-support", "frame-system", - "futures 0.3.1", + "futures 0.3.4", "jsonrpc-client-transports", "jsonrpc-core", "parity-scale-codec", @@ -7490,7 +7449,7 @@ version = "2.0.0" dependencies = [ "env_logger 0.7.1", "frame-system-rpc-runtime-api", - "futures 0.3.1", + "futures 0.3.4", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", @@ -7511,7 +7470,7 @@ dependencies = [ name = "substrate-test-client" version = "2.0.0" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", "hash-db", "parity-scale-codec", "sc-client", @@ -7540,7 +7499,7 @@ dependencies = [ "pallet-babe", "pallet-timestamp", "parity-scale-codec", - "parity-util-mem 0.5.1", + "parity-util-mem", "sc-client", "sc-executor", "serde", @@ -7564,14 +7523,14 @@ dependencies = [ "sp-version", "substrate-test-runtime-client", "substrate-wasm-builder-runner", - "trie-db", + "trie-db 0.20.0", ] [[package]] name = "substrate-test-runtime-client" version = "2.0.0" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", "parity-scale-codec", "sc-block-builder", "sc-client", @@ -7589,7 +7548,7 @@ name = "substrate-test-runtime-transaction-pool" version = "2.0.0" dependencies = [ "derive_more", - "futures 0.3.1", + "futures 0.3.4", "parity-scale-codec", "parking_lot 0.10.0", "sc-transaction-graph", @@ -7846,11 +7805,11 @@ dependencies = [ "num_cpus", "tokio-codec", "tokio-current-thread", - "tokio-executor 0.1.9", + "tokio-executor 0.1.10", "tokio-fs", "tokio-io", "tokio-reactor", - "tokio-sync 0.1.7", + "tokio-sync 0.1.8", "tokio-tcp", "tokio-threadpool", "tokio-timer", @@ -7891,9 +7850,9 @@ dependencies = [ [[package]] name = "tokio-codec" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" +checksum = "25b2998660ba0e70d18684de5d06b70b70a3a747469af9dea7618cc59e75976b" dependencies = [ "bytes 0.4.12", "futures 0.1.29", @@ -7902,21 +7861,21 @@ dependencies = [ [[package]] name = "tokio-current-thread" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" +checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e" dependencies = [ "futures 0.1.29", - "tokio-executor 0.1.9", + "tokio-executor 0.1.10", ] [[package]] name = "tokio-executor" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6df436c42b0c3330a82d855d2ef017cd793090ad550a6bc2184f4b933532ab" +checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" dependencies = [ - "crossbeam-utils 0.6.6", + "crossbeam-utils", "futures 0.1.29", ] @@ -7933,9 +7892,9 @@ dependencies = [ [[package]] name = "tokio-fs" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af" +checksum = "297a1206e0ca6302a0eed35b700d292b275256f596e2f3fea7729d5e629b6ff4" dependencies = [ "futures 0.1.29", "tokio-io", @@ -7944,9 +7903,9 @@ dependencies = [ [[package]] name = "tokio-io" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" +checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" dependencies = [ "bytes 0.4.12", "futures 0.1.29", @@ -7966,11 +7925,11 @@ dependencies = [ [[package]] name = "tokio-reactor" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6732fe6b53c8d11178dcb77ac6d9682af27fc6d4cb87789449152e5377377146" +checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351" dependencies = [ - "crossbeam-utils 0.6.6", + "crossbeam-utils", "futures 0.1.29", "lazy_static", "log 0.4.8", @@ -7978,9 +7937,9 @@ dependencies = [ "num_cpus", "parking_lot 0.9.0", "slab", - "tokio-executor 0.1.9", + "tokio-executor 0.1.10", "tokio-io", - "tokio-sync 0.1.7", + "tokio-sync 0.1.8", ] [[package]] @@ -7999,9 +7958,9 @@ dependencies = [ [[package]] name = "tokio-sync" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76" +checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee" dependencies = [ "fnv", "futures 0.1.29", @@ -8020,9 +7979,9 @@ dependencies = [ [[package]] name = "tokio-tcp" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" +checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" dependencies = [ "bytes 0.4.12", "futures 0.1.29", @@ -8034,31 +7993,31 @@ dependencies = [ [[package]] name = "tokio-threadpool" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c32ffea4827978e9aa392d2f743d973c1dfa3730a2ed3f22ce1e6984da848c" +checksum = "df720b6581784c118f0eb4310796b12b1d242a7eb95f716a8367855325c25f89" dependencies = [ "crossbeam-deque", - "crossbeam-queue 0.1.2", - "crossbeam-utils 0.6.6", + "crossbeam-queue", + "crossbeam-utils", "futures 0.1.29", "lazy_static", "log 0.4.8", "num_cpus", "slab", - "tokio-executor 0.1.9", + "tokio-executor 0.1.10", ] [[package]] name = "tokio-timer" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1739638e364e558128461fc1ad84d997702c8e31c2e6b18fb99842268199e827" +checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296" dependencies = [ - "crossbeam-utils 0.6.6", + "crossbeam-utils", "futures 0.1.29", "slab", - "tokio-executor 0.1.9", + "tokio-executor 0.1.10", ] [[package]] @@ -8074,9 +8033,9 @@ dependencies = [ [[package]] name = "tokio-udp" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f02298505547f73e60f568359ef0d016d5acd6e830ab9bc7c4a5b3403440121b" +checksum = "e2a0b10e610b39c38b031a2fcab08e4b82f16ece36504988dcbd81dbba650d82" dependencies = [ "bytes 0.4.12", "futures 0.1.29", @@ -8089,9 +8048,9 @@ dependencies = [ [[package]] name = "tokio-uds" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" +checksum = "5076db410d6fdc6523df7595447629099a1fdc47b3d9f896220780fa48faf798" dependencies = [ "bytes 0.4.12", "futures 0.1.29", @@ -8178,17 +8137,17 @@ checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" [[package]] name = "trie-bench" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fd042d57ee9c987c562811162a78db78b5340ab674ac76056c85dca49b26bc" +checksum = "6dcd9bac85703d8f974ee1e6dfe668784b105d3385c174ad729adb7427ad5d81" dependencies = [ "criterion 0.2.11", "hash-db", "keccak-hasher", "memory-db", "parity-scale-codec", - "trie-db", - "trie-root", + "trie-db 0.20.0", + "trie-root 0.16.0", "trie-standardmap", ] @@ -8206,6 +8165,19 @@ dependencies = [ "smallvec 1.2.0", ] +[[package]] +name = "trie-db" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de9222c50cc325855621271157c973da27a0dcd26fa06f8edf81020bd2333df0" +dependencies = [ + "hash-db", + "hashbrown 0.6.3", + "log 0.4.8", + "rustc-hex", + "smallvec 1.2.0", +] + [[package]] name = "trie-root" version = "0.15.2" @@ -8215,6 +8187,15 @@ dependencies = [ "hash-db", ] +[[package]] +name = "trie-root" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "652931506d2c1244d7217a70b99f56718a7b4161b37f04e7cd868072a99f68cd" +dependencies = [ + "hash-db", +] + [[package]] name = "trie-standardmap" version = "0.15.2" @@ -8252,7 +8233,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712d261e83e727c8e2dbb75dacac67c36e35db36a958ee504f2164fc052434e1" dependencies = [ "block-cipher-trait", - "byteorder 1.3.2", + "byteorder 1.3.4", "opaque-debug", ] @@ -8283,7 +8264,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e75a4cdd7b87b28840dba13c483b9a88ee6bbf16ba5c951ee1ecfcf723078e0d" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", "crunchy", "rustc-hex", "static_assertions", @@ -8589,7 +8570,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "324c5e65a08699c9c4334ba136597ab22b85dccd4b65dd1e36ccf8f723a95b54" dependencies = [ - "futures 0.3.1", + "futures 0.3.4", "js-sys", "parking_lot 0.9.0", "pin-utils", @@ -8791,7 +8772,7 @@ checksum = "5e3810f0d00c4dccb54c30a4eee815e703232819dec7b007db115791c42aa374" dependencies = [ "base64 0.10.1", "bitflags", - "byteorder 1.3.2", + "byteorder 1.3.4", "bytes 0.4.12", "futures 0.1.29", "native-tls", @@ -8880,7 +8861,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c51a2c47b5798ccc774ffb93ff536aec7c4275d722fd9c740c83cdd1af1f2d94" dependencies = [ - "byteorder 1.3.2", + "byteorder 1.3.4", "bytes 0.4.12", "httparse", "log 0.4.8", @@ -8921,12 +8902,12 @@ checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" [[package]] name = "yamux" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f937668802a2e862a4fed05267e10b20c310bf771adc89687710706d55a9a65" +checksum = "902f4cee32c401c211b6b69f4a3f6f4cf3515644db5bd822cf685a7dbd6201f9" dependencies = [ "bytes 0.5.4", - "futures 0.3.1", + "futures 0.3.4", "log 0.4.8", "nohash-hasher", "parking_lot 0.10.0", diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 9bd30d1823..6f1ce2f080 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -29,7 +29,7 @@ parking_lot = { version = "0.10.0", optional = true } sp-debug-derive = { version = "2.0.0", path = "../debug-derive" } sp-externalities = { version = "0.8.0", optional = true, path = "../externalities" } sp-storage = { version = "2.0.0", default-features = false, path = "../storage" } -libsecp256k1 = { version = "0.3.2", default-features = false } +libsecp256k1 = { version = "0.3.2", default-features = false, features = ["hmac"] } parity-util-mem = { version = "0.5.1", default-features = false, features = ["primitive-types"] } # full crypto diff --git a/primitives/trie/Cargo.toml b/primitives/trie/Cargo.toml index a78a26db73..361ddb186c 100644 --- a/primitives/trie/Cargo.toml +++ b/primitives/trie/Cargo.toml @@ -15,13 +15,13 @@ harness = false codec = { package = "parity-scale-codec", version = "1.0.0", 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.19.2", default-features = false } -trie-root = { version = "0.15.2", default-features = false } -memory-db = { version = "0.18.1", default-features = false } +trie-db = { version = "0.20.0", default-features = false } +trie-root = { version = "0.16.0", default-features = false } +memory-db = { version = "0.19.0", default-features = false } sp-core = { version = "2.0.0", default-features = false, path = "../core" } [dev-dependencies] -trie-bench = "0.19.0" +trie-bench = "0.20.0" trie-standardmap = "0.15.2" criterion = "0.2.11" hex-literal = "0.2.1" diff --git a/test-utils/runtime/Cargo.toml b/test-utils/runtime/Cargo.toml index 684a681554..01244d8c6f 100644 --- a/test-utils/runtime/Cargo.toml +++ b/test-utils/runtime/Cargo.toml @@ -17,7 +17,7 @@ frame-executive = { version = "2.0.0", default-features = false, path = "../../f 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.18.0", default-features = false } +memory-db = { version = "0.19.0", 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" } @@ -36,7 +36,7 @@ pallet-timestamp = { version = "2.0.0", default-features = false, path = "../../ sc-client = { version = "0.8", 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.19.2", default-features = false } +trie-db = { version = "0.20.0", default-features = false } parity-util-mem = { version = "0.5.1", default-features = false, features = ["primitive-types"] } [dev-dependencies] -- GitLab From f123c297de9f9159d034f1af1f132b16f302ab74 Mon Sep 17 00:00:00 2001 From: Alexander Popiak Date: Sat, 8 Feb 2020 20:31:35 +0100 Subject: [PATCH 109/180] Rename StorageMap::exists to ::contains_key (Resolves #4839) (#4847) * rename StorageMap::exists(key) to ::contains_key(key) * bump impl_version --- bin/node/runtime/src/lib.rs | 2 +- frame/balances/src/lib.rs | 2 +- frame/collective/src/lib.rs | 2 +- frame/contracts/src/account_db.rs | 2 +- frame/contracts/src/tests.rs | 2 +- frame/democracy/src/lib.rs | 18 ++--- frame/elections-phragmen/src/lib.rs | 2 +- frame/elections/src/lib.rs | 4 +- frame/generic-asset/src/lib.rs | 2 +- frame/identity/src/lib.rs | 2 +- frame/im-online/src/lib.rs | 6 +- frame/offences/src/lib.rs | 2 +- frame/recovery/src/lib.rs | 6 +- frame/recovery/src/tests.rs | 6 +- frame/scored-pool/src/lib.rs | 2 +- frame/society/src/lib.rs | 12 ++-- frame/staking/src/lib.rs | 6 +- frame/staking/src/tests.rs | 72 +++++++++---------- .../src/storage/generator/double_map.rs | 2 +- .../src/storage/generator/linked_map.rs | 2 +- frame/support/src/storage/generator/map.rs | 2 +- frame/support/src/storage/mod.rs | 12 ++-- frame/support/test/tests/instance.rs | 18 ++--- frame/system/src/lib.rs | 2 +- frame/treasury/src/lib.rs | 8 +-- frame/vesting/src/lib.rs | 4 +- 26 files changed, 100 insertions(+), 100 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 7b718ca21f..f0e2c79743 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -80,7 +80,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 214, - impl_version: 1, + impl_version: 2, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index 4b3e88eb9f..64932fb256 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -1381,6 +1381,6 @@ where { fn is_dead_account(who: &T::AccountId) -> bool { // this should always be exactly equivalent to `Self::account(who).total().is_zero()` - !Account::::exists(who) + !Account::::contains_key(who) } } diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index 8d811b8dec..ffc62d976a 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -191,7 +191,7 @@ decl_module! { let proposal_hash = T::Hashing::hash_of(&proposal); - ensure!(!>::exists(proposal_hash), Error::::DuplicateProposal); + ensure!(!>::contains_key(proposal_hash), Error::::DuplicateProposal); if threshold < 2 { let seats = Self::members().len() as MemberCount; diff --git a/frame/contracts/src/account_db.rs b/frame/contracts/src/account_db.rs index 814983c586..efef02222d 100644 --- a/frame/contracts/src/account_db.rs +++ b/frame/contracts/src/account_db.rs @@ -137,7 +137,7 @@ impl AccountDb for DirectAccountDb { >::get(account).and_then(|i| i.as_alive().map(|i| i.rent_allowance)) } fn contract_exists(&self, account: &T::AccountId) -> bool { - >::exists(account) + >::contains_key(account) } fn get_balance(&self, account: &T::AccountId) -> BalanceOf { T::Currency::free_balance(account) diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 5eb7bce48a..783eca02ca 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -460,7 +460,7 @@ fn instantiate_and_call_and_deposit_event() { ]); assert_ok!(creation); - assert!(ContractInfoOf::::exists(BOB)); + assert!(ContractInfoOf::::contains_key(BOB)); }); } diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index da0cccb1d0..9bf08840f4 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -294,7 +294,7 @@ decl_storage! { /// Get the vote in a given referendum of a particular voter. The result is meaningful only /// if `voters_for` includes the voter when called with the referendum (you'll get the /// default `Vote` value otherwise). If you don't want to check `voters_for`, then you can - /// also check for simple existence with `VoteOf::exists` first. + /// also check for simple existence with `VoteOf::contains_key` first. pub VoteOf get(fn vote_of): map hasher(blake2_256) (ReferendumIndex, T::AccountId) => Vote; /// Who is able to vote for whom. Value is the fund-holding account, key is the @@ -537,7 +537,7 @@ decl_module! { let info = Self::referendum_info(ref_index).ok_or(Error::::BadIndex)?; let h = info.proposal_hash; - ensure!(!>::exists(h), Error::::AlreadyCanceled); + ensure!(!>::contains_key(h), Error::::AlreadyCanceled); >::insert(h, true); Self::clear_referendum(ref_index); @@ -667,7 +667,7 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(100_000)] fn set_proxy(origin, proxy: T::AccountId) { let who = ensure_signed(origin)?; - ensure!(!>::exists(&proxy), Error::::AlreadyProxy); + ensure!(!>::contains_key(&proxy), Error::::AlreadyProxy); >::insert(proxy, who) } @@ -725,7 +725,7 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(500_000)] fn undelegate(origin) { let who = ensure_signed(origin)?; - ensure!(>::exists(&who), Error::::NotDelegated); + ensure!(>::contains_key(&who), Error::::NotDelegated); let (_, conviction) = >::take(&who); // Indefinite lock is reduced to the maximum voting lock that could be possible. let now = >::block_number(); @@ -754,7 +754,7 @@ decl_module! { 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); + ensure!(!>::contains_key(&proposal_hash), Error::::DuplicatePreimage); let deposit = >::from(encoded_proposal.len() as u32) .saturating_mul(T::PreimageByteDeposit::get()); @@ -772,7 +772,7 @@ decl_module! { 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); + ensure!(!>::contains_key(&proposal_hash), Error::::DuplicatePreimage); let queue = >::get(); ensure!(queue.iter().any(|item| &item.1 == &proposal_hash), Error::::NotImminent); @@ -832,7 +832,7 @@ impl Module { /// Return true if `ref_index` is an on-going referendum. pub fn is_active_referendum(ref_index: ReferendumIndex) -> bool { - >::exists(ref_index) + >::contains_key(ref_index) } /// Get all referenda currently active. @@ -913,7 +913,7 @@ impl Module { if recursion_limit == 0 { return (Zero::zero(), Zero::zero()); } >::enumerate() .filter(|(delegator, (delegate, _))| - *delegate == to && !>::exists(&(ref_index, delegator.clone())) + *delegate == to && !>::contains_key(&(ref_index, delegator.clone())) ).fold( (Zero::zero(), Zero::zero()), |(votes_acc, turnout_acc), (delegator, (_delegate, max_conviction))| { @@ -963,7 +963,7 @@ impl Module { /// Actually enact a vote, if legit. 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)) { + if !>::contains_key((ref_index, &who)) { >::append_or_insert(ref_index, &[&who][..]); } >::insert((ref_index, &who), vote); diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 33d4c46e91..b3dc05fe7b 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -520,7 +520,7 @@ impl Module { /// /// State: O(1). fn is_voter(who: &T::AccountId) -> bool { - >::exists(who) + >::contains_key(who) } /// Check if `who` is currently an active member. diff --git a/frame/elections/src/lib.rs b/frame/elections/src/lib.rs index 899fcfac8a..eb87057f95 100644 --- a/frame/elections/src/lib.rs +++ b/frame/elections/src/lib.rs @@ -525,7 +525,7 @@ decl_module! { let who = ensure_signed(origin)?; ensure!(!Self::presentation_active(), Error::::CannotRetractPresenting); - ensure!(>::exists(&who), Error::::RetractNonVoter); + ensure!(>::contains_key(&who), Error::::RetractNonVoter); let index = index as usize; let voter = Self::voter_at(index).ok_or(Error::::InvalidRetractionIndex)?; ensure!(voter == who, Error::::InvalidRetractionIndex); @@ -730,7 +730,7 @@ impl Module { /// If `who` a candidate at the moment? pub fn is_a_candidate(who: &T::AccountId) -> bool { - >::exists(who) + >::contains_key(who) } /// Iff the member `who` still has a seat at blocknumber `n` returns `true`. diff --git a/frame/generic-asset/src/lib.rs b/frame/generic-asset/src/lib.rs index 3b8ebe0535..5d246a8afd 100644 --- a/frame/generic-asset/src/lib.rs +++ b/frame/generic-asset/src/lib.rs @@ -580,7 +580,7 @@ impl Module { options: AssetOptions, ) -> DispatchResult { let asset_id = if let Some(asset_id) = asset_id { - ensure!(!>::exists(&asset_id), Error::::IdAlreadyTaken); + ensure!(!>::contains_key(&asset_id), Error::::IdAlreadyTaken); ensure!(asset_id < Self::next_asset_id(), Error::::IdUnavailable); asset_id } else { diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index 56960b2d1d..80a200e808 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -553,7 +553,7 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(50_000)] fn set_subs(origin, subs: Vec<(T::AccountId, Data)>) { let sender = ensure_signed(origin)?; - ensure!(>::exists(&sender), Error::::NotFound); + ensure!(>::contains_key(&sender), Error::::NotFound); ensure!(subs.len() <= T::MaxSubAccounts::get() as usize, Error::::TooManySubAccounts); let (old_deposit, old_ids) = >::get(&sender); diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index ff06cb37d4..f7067a5843 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -315,7 +315,7 @@ decl_module! { ensure_none(origin)?; let current_session = >::current_index(); - let exists = ::exists( + let exists = ::contains_key( ¤t_session, &heartbeat.authority_index ); @@ -398,7 +398,7 @@ impl Module { fn is_online_aux(authority_index: AuthIndex, authority: &T::ValidatorId) -> bool { let current_session = >::current_index(); - ::exists(¤t_session, &authority_index) || + ::contains_key(¤t_session, &authority_index) || >::get( ¤t_session, authority, @@ -409,7 +409,7 @@ impl Module { /// 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(); - ::exists(¤t_session, &authority_index) + ::contains_key(¤t_session, &authority_index) } /// Note that the given authority has authored a block in the current session. diff --git a/frame/offences/src/lib.rs b/frame/offences/src/lib.rs index 2b625873f0..ea6f96cbc3 100644 --- a/frame/offences/src/lib.rs +++ b/frame/offences/src/lib.rs @@ -150,7 +150,7 @@ impl Module { for offender in offenders { let report_id = Self::report_id::(time_slot, &offender); - if !>::exists(&report_id) { + if !>::contains_key(&report_id) { any_new = true; >::insert( &report_id, diff --git a/frame/recovery/src/lib.rs b/frame/recovery/src/lib.rs index 0309fec12a..668608c892 100644 --- a/frame/recovery/src/lib.rs +++ b/frame/recovery/src/lib.rs @@ -401,7 +401,7 @@ decl_module! { ) { let who = ensure_signed(origin)?; // Check account is not already set up for recovery - ensure!(!>::exists(&who), Error::::AlreadyRecoverable); + ensure!(!>::contains_key(&who), Error::::AlreadyRecoverable); // Check user input is valid ensure!(threshold >= 1, Error::::ZeroThreshold); ensure!(!friends.is_empty(), Error::::NotEnoughFriends); @@ -456,9 +456,9 @@ decl_module! { fn initiate_recovery(origin, account: T::AccountId) { let who = ensure_signed(origin)?; // Check that the account is recoverable - ensure!(>::exists(&account), Error::::NotRecoverable); + ensure!(>::contains_key(&account), Error::::NotRecoverable); // Check that the recovery process has not already been started - ensure!(!>::exists(&account, &who), Error::::AlreadyStarted); + ensure!(!>::contains_key(&account, &who), Error::::AlreadyStarted); // Take recovery deposit let recovery_deposit = T::RecoveryDeposit::get(); T::Currency::reserve(&who, recovery_deposit)?; diff --git a/frame/recovery/src/tests.rs b/frame/recovery/src/tests.rs index cfc8e25b12..af4eadb58f 100644 --- a/frame/recovery/src/tests.rs +++ b/frame/recovery/src/tests.rs @@ -92,9 +92,9 @@ fn recovery_lifecycle_works() { assert_eq!(Balances::free_balance(1), 200); assert_eq!(Balances::free_balance(5), 0); // All storage items are removed from the module - assert!(!>::exists(&5, &1)); - assert!(!>::exists(&5)); - assert!(!>::exists(&5)); + assert!(!>::contains_key(&5, &1)); + assert!(!>::contains_key(&5)); + assert!(!>::contains_key(&5)); }); } diff --git a/frame/scored-pool/src/lib.rs b/frame/scored-pool/src/lib.rs index 2a73c4bb68..98a7ed217e 100644 --- a/frame/scored-pool/src/lib.rs +++ b/frame/scored-pool/src/lib.rs @@ -265,7 +265,7 @@ decl_module! { /// the index of the transactor in the `Pool`. pub fn submit_candidacy(origin) { let who = ensure_signed(origin)?; - ensure!(!>::exists(&who), Error::::AlreadyInPool); + ensure!(!>::contains_key(&who), Error::::AlreadyInPool); let deposit = T::CandidateDeposit::get(); T::Currency::reserve(&who, deposit)?; diff --git a/frame/society/src/lib.rs b/frame/society/src/lib.rs index e45ac30bce..c1e1803c64 100644 --- a/frame/society/src/lib.rs +++ b/frame/society/src/lib.rs @@ -530,8 +530,8 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(50_000)] pub fn bid(origin, value: BalanceOf) -> DispatchResult { let who = ensure_signed(origin)?; - ensure!(!>::exists(&who), Error::::Suspended); - ensure!(!>::exists(&who), Error::::Suspended); + ensure!(!>::contains_key(&who), Error::::Suspended); + ensure!(!>::contains_key(&who), Error::::Suspended); let bids = >::get(); ensure!(!Self::is_bid(&bids, &who), Error::::AlreadyBid); let candidates = >::get(); @@ -640,8 +640,8 @@ decl_module! { pub fn vouch(origin, who: T::AccountId, value: BalanceOf, tip: BalanceOf) -> DispatchResult { let voucher = ensure_signed(origin)?; // Check user is not suspended. - ensure!(!>::exists(&who), Error::::Suspended); - ensure!(!>::exists(&who), Error::::Suspended); + ensure!(!>::contains_key(&who), Error::::Suspended); + ensure!(!>::contains_key(&who), Error::::Suspended); // Check user is not a bid or candidate. let bids = >::get(); ensure!(!Self::is_bid(&bids, &who), Error::::AlreadyBid); @@ -652,7 +652,7 @@ decl_module! { ensure!(!Self::is_member(&members, &who), Error::::AlreadyMember); // Check sender can vouch. ensure!(Self::is_member(&members, &voucher), Error::::NotMember); - ensure!(!>::exists(&voucher), Error::::AlreadyVouching); + ensure!(!>::contains_key(&voucher), Error::::AlreadyVouching); >::insert(&voucher, VouchingStatus::Vouching); Self::put_bid(bids, &who, value.clone(), BidKind::Vouch(voucher.clone(), tip)); @@ -892,7 +892,7 @@ decl_module! { #[weight = SimpleDispatchInfo::FixedNormal(30_000)] fn judge_suspended_member(origin, who: T::AccountId, forgive: bool) { T::SuspensionJudgementOrigin::ensure_origin(origin)?; - ensure!(>::exists(&who), Error::::NotSuspended); + ensure!(>::contains_key(&who), Error::::NotSuspended); if forgive { // Try to add member back to society. Can fail with `MaxMembers` limit. diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index ca2a2bf092..0c1c9a4942 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -887,13 +887,13 @@ decl_module! { ) { let stash = ensure_signed(origin)?; - if >::exists(&stash) { + if >::contains_key(&stash) { Err(Error::::AlreadyBonded)? } let controller = T::Lookup::lookup(controller)?; - if >::exists(&controller) { + if >::contains_key(&controller) { Err(Error::::AlreadyPaired)? } @@ -1139,7 +1139,7 @@ decl_module! { let stash = ensure_signed(origin)?; let old_controller = Self::bonded(&stash).ok_or(Error::::NotStash)?; let controller = T::Lookup::lookup(controller)?; - if >::exists(&controller) { + if >::contains_key(&controller) { Err(Error::::AlreadyPaired)? } if controller != old_controller { diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index a9b6e16598..f62a58e20b 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -977,7 +977,7 @@ fn bond_extra_works() { // See `bond_extra_and_withdraw_unbonded_works` for more details and updates on `Exposure`. ExtBuilder::default().build().execute_with(|| { // Check that account 10 is a validator - assert!(>::exists(11)); + assert!(>::contains_key(11)); // Check that account 10 is bonded to account 11 assert_eq!(Staking::bonded(&11), Some(10)); // Check how much is at stake @@ -1375,7 +1375,7 @@ fn slot_stake_is_least_staked_validator_and_exposure_defines_maximum_punishment( // Confirm validator count is 2 assert_eq!(Staking::validator_count(), 2); // Confirm account 10 and 20 are validators - assert!(>::exists(&11) && >::exists(&21)); + assert!(>::contains_key(&11) && >::contains_key(&21)); assert_eq!(Staking::stakers(&11).total, 1000); assert_eq!(Staking::stakers(&21).total, 2000); @@ -1433,10 +1433,10 @@ fn on_free_balance_zero_stash_removes_validator() { assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Stash)); // Check storage items that should be cleaned up - assert!(>::exists(&10)); - assert!(>::exists(&11)); - assert!(>::exists(&11)); - assert!(>::exists(&11)); + assert!(>::contains_key(&10)); + assert!(>::contains_key(&11)); + assert!(>::contains_key(&11)); + assert!(>::contains_key(&11)); // Reduce free_balance of controller to 0 let _ = Balances::slash(&10, u64::max_value()); @@ -1447,10 +1447,10 @@ fn on_free_balance_zero_stash_removes_validator() { assert_eq!(Staking::bonded(&11), Some(10)); // Check storage items have not changed - assert!(>::exists(&10)); - assert!(>::exists(&11)); - assert!(>::exists(&11)); - assert!(>::exists(&11)); + assert!(>::contains_key(&10)); + assert!(>::contains_key(&11)); + assert!(>::contains_key(&11)); + assert!(>::contains_key(&11)); // Reduce free_balance of stash to 0 let _ = Balances::slash(&11, u64::max_value()); @@ -1458,11 +1458,11 @@ fn on_free_balance_zero_stash_removes_validator() { assert_eq!(Balances::total_balance(&11), 0); // Check storage items do not exist - assert!(!>::exists(&10)); - assert!(!>::exists(&11)); - assert!(!>::exists(&11)); - assert!(!>::exists(&11)); - assert!(!>::exists(&11)); + assert!(!>::contains_key(&10)); + assert!(!>::contains_key(&11)); + assert!(!>::contains_key(&11)); + assert!(!>::contains_key(&11)); + assert!(!>::contains_key(&11)); }); } @@ -1474,7 +1474,7 @@ fn on_free_balance_zero_stash_removes_nominator() { // Make 10 a nominator assert_ok!(Staking::nominate(Origin::signed(10), vec![20])); // Check that account 10 is a nominator - assert!(>::exists(11)); + assert!(>::contains_key(11)); // Check the balance of the nominator account assert_eq!(Balances::free_balance(10), 256); // Check the balance of the stash account @@ -1484,10 +1484,10 @@ fn on_free_balance_zero_stash_removes_nominator() { assert_ok!(Staking::set_payee(Origin::signed(10), RewardDestination::Stash)); // Check storage items that should be cleaned up - assert!(>::exists(&10)); - assert!(>::exists(&11)); - assert!(>::exists(&11)); - assert!(>::exists(&11)); + assert!(>::contains_key(&10)); + assert!(>::contains_key(&11)); + assert!(>::contains_key(&11)); + assert!(>::contains_key(&11)); // Reduce free_balance of controller to 0 let _ = Balances::slash(&10, u64::max_value()); @@ -1500,10 +1500,10 @@ fn on_free_balance_zero_stash_removes_nominator() { assert_eq!(Staking::bonded(&11), Some(10)); // Check storage items have not changed - assert!(>::exists(&10)); - assert!(>::exists(&11)); - assert!(>::exists(&11)); - assert!(>::exists(&11)); + assert!(>::contains_key(&10)); + assert!(>::contains_key(&11)); + assert!(>::contains_key(&11)); + assert!(>::contains_key(&11)); // Reduce free_balance of stash to 0 let _ = Balances::slash(&11, u64::max_value()); @@ -1511,11 +1511,11 @@ fn on_free_balance_zero_stash_removes_nominator() { assert_eq!(Balances::total_balance(&11), 0); // Check storage items do not exist - assert!(!>::exists(&10)); - assert!(!>::exists(&11)); - assert!(!>::exists(&11)); - assert!(!>::exists(&11)); - assert!(!>::exists(&11)); + assert!(!>::contains_key(&10)); + assert!(!>::contains_key(&11)); + assert!(!>::contains_key(&11)); + assert!(!>::contains_key(&11)); + assert!(!>::contains_key(&11)); }); } @@ -1968,7 +1968,7 @@ fn offence_ensures_new_era_without_clobbering() { #[test] fn offence_deselects_validator_when_slash_is_zero() { ExtBuilder::default().build().execute_with(|| { - assert!(>::exists(11)); + assert!(>::contains_key(11)); on_offence_now( &[OffenceDetails { offender: ( @@ -1980,7 +1980,7 @@ fn offence_deselects_validator_when_slash_is_zero() { &[Perbill::from_percent(0)], ); assert_eq!(Staking::force_era(), Forcing::ForceNew); - assert!(!>::exists(11)); + assert!(!>::contains_key(11)); }); } @@ -2017,7 +2017,7 @@ fn slash_in_old_span_does_not_deselect() { ExtBuilder::default().build().execute_with(|| { start_era(1); - assert!(>::exists(11)); + assert!(>::contains_key(11)); on_offence_now( &[OffenceDetails { offender: ( @@ -2029,13 +2029,13 @@ fn slash_in_old_span_does_not_deselect() { &[Perbill::from_percent(0)], ); assert_eq!(Staking::force_era(), Forcing::ForceNew); - assert!(!>::exists(11)); + assert!(!>::contains_key(11)); start_era(2); Staking::validate(Origin::signed(10), Default::default()).unwrap(); assert_eq!(Staking::force_era(), Forcing::NotForcing); - assert!(>::exists(11)); + assert!(>::contains_key(11)); start_era(3); @@ -2056,7 +2056,7 @@ fn slash_in_old_span_does_not_deselect() { // not for zero-slash. assert_eq!(Staking::force_era(), Forcing::NotForcing); - assert!(>::exists(11)); + assert!(>::contains_key(11)); on_offence_in_era( &[OffenceDetails { @@ -2072,7 +2072,7 @@ fn slash_in_old_span_does_not_deselect() { // or non-zero. assert_eq!(Staking::force_era(), Forcing::NotForcing); - assert!(>::exists(11)); + assert!(>::contains_key(11)); assert_ledger_consistent(11); }); } diff --git a/frame/support/src/storage/generator/double_map.rs b/frame/support/src/storage/generator/double_map.rs index 947235c4bd..ff73fdbedf 100644 --- a/frame/support/src/storage/generator/double_map.rs +++ b/frame/support/src/storage/generator/double_map.rs @@ -110,7 +110,7 @@ where Self::storage_double_map_final_key(k1, k2) } - fn exists(k1: KArg1, k2: KArg2) -> bool + fn contains_key(k1: KArg1, k2: KArg2) -> bool where KArg1: EncodeLike, KArg2: EncodeLike, diff --git a/frame/support/src/storage/generator/linked_map.rs b/frame/support/src/storage/generator/linked_map.rs index face87edf9..2d0df8fcc8 100644 --- a/frame/support/src/storage/generator/linked_map.rs +++ b/frame/support/src/storage/generator/linked_map.rs @@ -326,7 +326,7 @@ where type Enumerator = Enumerator; - fn exists>(key: KeyArg) -> bool { + fn contains_key>(key: KeyArg) -> bool { unhashed::exists(Self::storage_linked_map_final_key(key).as_ref()) } diff --git a/frame/support/src/storage/generator/map.rs b/frame/support/src/storage/generator/map.rs index 78f261e7da..c1d9f1b149 100644 --- a/frame/support/src/storage/generator/map.rs +++ b/frame/support/src/storage/generator/map.rs @@ -95,7 +95,7 @@ impl> storage::StorageMap } } - fn exists>(key: KeyArg) -> bool { + fn contains_key>(key: KeyArg) -> bool { unhashed::exists(Self::storage_map_final_key(key).as_ref()) } diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index f629ac3eb9..3eb1a6f116 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -126,7 +126,7 @@ pub trait StorageMap { fn hashed_key_for>(key: KeyArg) -> Vec; /// Does the value (explicitly) exist in storage? - fn exists>(key: KeyArg) -> bool; + fn contains_key>(key: KeyArg) -> bool; /// Load the value associated with the given key from the map. fn get>(key: KeyArg) -> Self::Query; @@ -176,7 +176,7 @@ pub trait StorageMap { /// `T` 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()` + /// Therefore, this function cannot be used as a sign of _existence_. use the `::contains_key()` /// function for this purpose. fn decode_len>(key: KeyArg) -> Result where V: codec::DecodeLength + Len; @@ -196,7 +196,7 @@ pub trait StorageLinkedMap { type Enumerator: Iterator; /// Does the value (explicitly) exist in storage? - fn exists>(key: KeyArg) -> bool; + fn contains_key>(key: KeyArg) -> bool; /// Load the value associated with the given key from the map. fn get>(key: KeyArg) -> Self::Query; @@ -227,7 +227,7 @@ pub trait StorageLinkedMap { /// `T` 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()` + /// Therefore, this function cannot be used as a sign of _existence_. use the `::contains_key()` /// function for this purpose. fn decode_len>(key: KeyArg) -> Result where V: codec::DecodeLength + Len; @@ -270,7 +270,7 @@ pub trait StorageDoubleMap { KArg1: EncodeLike, KArg2: EncodeLike; - fn exists(k1: KArg1, k2: KArg2) -> bool + fn contains_key(k1: KArg1, k2: KArg2) -> bool where KArg1: EncodeLike, KArg2: EncodeLike; @@ -348,7 +348,7 @@ pub trait StorageDoubleMap { /// `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()` + /// Therefore, this function cannot be used as a sign of _existence_. use the `::contains_key()` /// function for this purpose. fn decode_len(key1: KArg1, key2: KArg2) -> Result where diff --git a/frame/support/test/tests/instance.rs b/frame/support/test/tests/instance.rs index 2c761ca43e..4c509ae18f 100644 --- a/frame/support/test/tests/instance.rs +++ b/frame/support/test/tests/instance.rs @@ -348,8 +348,8 @@ fn storage_with_instance_basic_operation() { assert_eq!(Value::get(), 0); let key = 1; - assert_eq!(Map::exists(0), true); - assert_eq!(Map::exists(key), false); + assert_eq!(Map::contains_key(0), true); + assert_eq!(Map::contains_key(key), false); Map::insert(key, 1); assert_eq!(Map::get(key), 1); assert_eq!(Map::take(key), 1); @@ -357,11 +357,11 @@ fn storage_with_instance_basic_operation() { Map::mutate(key, |a| *a=2); assert_eq!(Map::get(key), 2); Map::remove(key); - assert_eq!(Map::exists(key), false); + assert_eq!(Map::contains_key(key), false); assert_eq!(Map::get(key), 0); - assert_eq!(LinkedMap::exists(0), true); - assert_eq!(LinkedMap::exists(key), false); + assert_eq!(LinkedMap::contains_key(0), true); + assert_eq!(LinkedMap::contains_key(key), false); LinkedMap::insert(key, vec![1]); assert_eq!(LinkedMap::enumerate().count(), 2); assert_eq!(LinkedMap::get(key), vec![1]); @@ -373,17 +373,17 @@ fn storage_with_instance_basic_operation() { assert_eq!(LinkedMap::get(key), vec![2]); LinkedMap::remove(key); assert_eq!(LinkedMap::enumerate().count(), 1); - assert_eq!(LinkedMap::exists(key), false); + assert_eq!(LinkedMap::contains_key(key), false); assert_eq!(LinkedMap::get(key), vec![]); - assert_eq!(LinkedMap::exists(key), false); + assert_eq!(LinkedMap::contains_key(key), false); assert_eq!(LinkedMap::enumerate().count(), 1); LinkedMap::insert(key, &vec![1]); assert_eq!(LinkedMap::enumerate().count(), 2); let key1 = 1; let key2 = 1; - assert_eq!(DoubleMap::exists(&0, &0), true); - assert_eq!(DoubleMap::exists(&key1, &key2), false); + assert_eq!(DoubleMap::contains_key(&0, &0), true); + assert_eq!(DoubleMap::contains_key(&key1, &key2), false); DoubleMap::insert(&key1, &key2, &1); assert_eq!(DoubleMap::get(&key1, &key2), 1); assert_eq!(DoubleMap::take(&key1, &key2), 1); diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index a0f3700c9d..03b5d48aad 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -1146,7 +1146,7 @@ impl SignedExtension for CheckEra { fn additional_signed(&self) -> Result { let current_u64 = >::block_number().saturated_into::(); let n = (self.0).0.birth(current_u64).saturated_into::(); - if !>::exists(n) { + if !>::contains_key(n) { Err(InvalidTransaction::AncientBirthBlock.into()) } else { Ok(>::block_hash(n)) diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index 0872bc718c..ef37cc12ee 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -371,7 +371,7 @@ decl_module! { fn approve_proposal(origin, #[compact] proposal_id: ProposalIndex) { T::ApproveOrigin::ensure_origin(origin)?; - ensure!(>::exists(proposal_id), Error::::InvalidProposalIndex); + ensure!(>::contains_key(proposal_id), Error::::InvalidProposalIndex); Approvals::mutate(|v| v.push(proposal_id)); } @@ -403,9 +403,9 @@ decl_module! { ensure!(reason.len() <= MAX_SENSIBLE_REASON_LENGTH, Error::::ReasonTooBig); let reason_hash = T::Hashing::hash(&reason[..]); - ensure!(!Reasons::::exists(&reason_hash), Error::::AlreadyKnown); + ensure!(!Reasons::::contains_key(&reason_hash), Error::::AlreadyKnown); let hash = T::Hashing::hash_of(&(&reason_hash, &who)); - ensure!(!Tips::::exists(&hash), Error::::AlreadyKnown); + ensure!(!Tips::::contains_key(&hash), Error::::AlreadyKnown); let deposit = T::TipReportDepositBase::get() + T::TipReportDepositPerByte::get() * (reason.len() as u32).into(); @@ -474,7 +474,7 @@ decl_module! { let tipper = ensure_signed(origin)?; ensure!(T::Tippers::contains(&tipper), BadOrigin); let reason_hash = T::Hashing::hash(&reason[..]); - ensure!(!Reasons::::exists(&reason_hash), Error::::AlreadyKnown); + ensure!(!Reasons::::contains_key(&reason_hash), Error::::AlreadyKnown); let hash = T::Hashing::hash_of(&(&reason_hash, &who)); Reasons::::insert(&reason_hash, &reason); diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index 4a079e7693..2a1ff12716 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -212,7 +212,7 @@ impl Module { /// (Re)set or remove the module's currency lock on `who`'s account in accordance with their /// current unvested amount. fn update_lock(who: T::AccountId) -> DispatchResult { - ensure!(Vesting::::exists(&who), Error::::NotVesting); + ensure!(Vesting::::contains_key(&who), Error::::NotVesting); let unvested = Self::vesting_balance(&who); if unvested.is_zero() { T::Currency::remove_lock(VESTING_ID, &who); @@ -257,7 +257,7 @@ impl VestingSchedule for Module where starting_block: T::BlockNumber ) -> DispatchResult { if locked.is_zero() { return Ok(()) } - if Vesting::::exists(who) { + if Vesting::::contains_key(who) { Err(Error::::ExistingVestingSchedule)? } let vesting_schedule = VestingInfo { -- GitLab From 0a894803c73175e08944e6032098deded1e65755 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Sun, 9 Feb 2020 15:11:22 +0300 Subject: [PATCH 110/180] Alter usage collection a bit (#4863) * alter usage collection a bit * replace with mutex --- client/db/src/lib.rs | 20 ++++++++++---------- client/db/src/light.rs | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index be56919497..36cf7dacf4 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -699,7 +699,7 @@ impl sp_state_machine::Storage> for DbGenesisSto /// Used as inner structure under lock in `FrozenForDuration`. struct Frozen { at: std::time::Instant, - value: T, + value: Option, } /// Some value frozen for period of time. @@ -709,26 +709,26 @@ struct Frozen { /// a new value which will be again frozen for `duration`. pub(crate) struct FrozenForDuration { duration: std::time::Duration, - value: RwLock>, + value: parking_lot::Mutex>, } impl FrozenForDuration { - fn new(duration: std::time::Duration, initial: T) -> Self { + fn new(duration: std::time::Duration) -> Self { Self { duration, - value: Frozen { at: std::time::Instant::now(), value: initial }.into(), + value: Frozen { at: std::time::Instant::now(), value: None }.into(), } } fn take_or_else(&self, f: F) -> T where F: FnOnce() -> T { - if self.value.read().at.elapsed() > self.duration { - let mut write_lock = self.value.write(); + let mut lock = self.value.lock(); + if lock.at.elapsed() > self.duration || lock.value.is_none() { let new_value = f(); - write_lock.at = std::time::Instant::now(); - write_lock.value = new_value.clone(); + lock.at = std::time::Instant::now(); + lock.value = Some(new_value.clone()); new_value } else { - self.value.read().value.clone() + lock.value.as_ref().expect("checked with lock above").clone() } } } @@ -818,7 +818,7 @@ impl Backend { ), import_lock: Default::default(), is_archive: is_archive_pruning, - io_stats: FrozenForDuration::new(std::time::Duration::from_secs(1), (kvdb::IoStats::empty(), StateUsageInfo::empty())), + io_stats: FrozenForDuration::new(std::time::Duration::from_secs(1)), state_usage: StateUsageStats::new(), }) } diff --git a/client/db/src/light.rs b/client/db/src/light.rs index e663fc5699..8fb220973f 100644 --- a/client/db/src/light.rs +++ b/client/db/src/light.rs @@ -102,7 +102,7 @@ impl LightStorage { cache: Arc::new(DbCacheSync(RwLock::new(cache))), header_metadata_cache: HeaderMetadataCache::default(), #[cfg(not(target_os = "unknown"))] - io_stats: FrozenForDuration::new(std::time::Duration::from_secs(1), kvdb::IoStats::empty()), + io_stats: FrozenForDuration::new(std::time::Duration::from_secs(1)), }) } -- GitLab From 3b21fb5020679236a8fe6d6b7a3a009a810d13a2 Mon Sep 17 00:00:00 2001 From: h4x3rotab Date: Mon, 10 Feb 2020 03:11:53 +0800 Subject: [PATCH 111/180] Wrap runtime_print! macro in its own scope (#4867) * Wrap runtime_print! macro in its own scope Before this fix runtime_print! can be used only once in a scope because of the name pollution. * Bump runtime impl versioin (no logic change) --- bin/node/runtime/src/lib.rs | 2 +- frame/support/src/debug.rs | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index f0e2c79743..76241eb5e7 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -80,7 +80,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 214, - impl_version: 2, + impl_version: 3, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/support/src/debug.rs b/frame/support/src/debug.rs index 0316fb9797..29847b70e5 100644 --- a/frame/support/src/debug.rs +++ b/frame/support/src/debug.rs @@ -129,10 +129,12 @@ pub mod native { #[macro_export] macro_rules! runtime_print { ($($arg:tt)+) => { - use core::fmt::Write; - let mut w = $crate::debug::Writer::default(); - let _ = core::write!(&mut w, $($arg)+); - w.print(); + { + use core::fmt::Write; + let mut w = $crate::debug::Writer::default(); + let _ = core::write!(&mut w, $($arg)+); + w.print(); + } } } -- GitLab From 8d822dad74598d924612c9cf915933ddc6345089 Mon Sep 17 00:00:00 2001 From: h4x3rotab Date: Mon, 10 Feb 2020 03:29:45 +0800 Subject: [PATCH 112/180] Remove the unnecessary std dependency from 'blake2-rfc' (#4868) --- primitives/api/proc-macro/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primitives/api/proc-macro/Cargo.toml b/primitives/api/proc-macro/Cargo.toml index cb9f2e4599..66c2c5dba8 100644 --- a/primitives/api/proc-macro/Cargo.toml +++ b/primitives/api/proc-macro/Cargo.toml @@ -12,7 +12,7 @@ proc-macro = true 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" +blake2-rfc = { version = "0.2.18", default-features = false } proc-macro-crate = "0.1.4" # Required for the doc tests -- GitLab From 19b67cd93b56396e8921b5227add3f7de18c60f4 Mon Sep 17 00:00:00 2001 From: h4x3rotab Date: Mon, 10 Feb 2020 16:26:09 +0800 Subject: [PATCH 113/180] Export GRANDPA AuthorityPair when full_crypto is enabled (#4872) * Export crypto_full feature in primitives/finality-grandpa * Export GRANDPA AuthorityPair when full_crypto is enabled --- primitives/finality-grandpa/Cargo.toml | 3 +++ primitives/finality-grandpa/src/lib.rs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/primitives/finality-grandpa/Cargo.toml b/primitives/finality-grandpa/Cargo.toml index dfa6b572d8..6498763e4c 100644 --- a/primitives/finality-grandpa/Cargo.toml +++ b/primitives/finality-grandpa/Cargo.toml @@ -23,3 +23,6 @@ std = [ "sp-api/std", "sp-runtime/std", ] +full_crypto = [ + "app-crypto/full_crypto" +] diff --git a/primitives/finality-grandpa/src/lib.rs b/primitives/finality-grandpa/src/lib.rs index f1481c0aed..98fce45081 100644 --- a/primitives/finality-grandpa/src/lib.rs +++ b/primitives/finality-grandpa/src/lib.rs @@ -34,7 +34,7 @@ mod app { } /// The grandpa crypto scheme defined via the keypair type. -#[cfg(feature = "std")] +#[cfg(any(feature = "std", feature = "full_crypto"))] pub type AuthorityPair = app::Pair; /// Identity of a Grandpa authority. -- GitLab From 8b6b093dd9a84547fa1fbbfd88fbf45b545a9855 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Mon, 10 Feb 2020 10:23:08 +0100 Subject: [PATCH 114/180] Create Benchmarking Setup for Identity Pallet #4695 (#4818) * Starting * closer * Compiles! * comments * Create seperate mock * Remove changes to test env * Fix step calculation * Add host function * Add runtime api * compiles * Update to use offchain timestamp * Gives a result * added some CLI wip * make generic * Update instance * Remove CLI stuff * Remove last cli stuff * undo more changes * Update benchmarks * Update Cargo.lock * remove test * Move loop out of runtime * Benchmarking externalities * Benchmarking state * Implemented commit * Make CLI work, move loop back into runtime * Wipe resets to genesis * Speedup benchmarks * Use enum to select extrinsic within pallet * CLI controls which module and extrinsic to call * Select a pallet with cli * Add steps and repeats to cli * Output as CSV format * Introduce benchmark pallet * Append bench * Use Results * fix merge * Clear Identity benchmark * Bench request judgment and cancel request * Add final benchmarks * Fix CSV output * Start cleaning up for PR * Bump numbers in `wasmtime` integration tests. * More docs * Add rockdb feature to bench * Fix formatting issues * Add test feature to bench * Add test feature to bench * Add rocksdb feature flag * Update bench.rs Co-authored-by: Arkadiy Paronyan Co-authored-by: Gavin Wood --- Cargo.lock | 1 + bin/node/runtime/src/lib.rs | 25 +- client/cli/src/lib.rs | 1 + client/cli/src/params.rs | 77 +++ client/db/Cargo.toml | 1 + client/db/src/bench.rs | 286 ++++++++ client/db/src/lib.rs | 6 + client/executor/src/integration_tests/mod.rs | 4 +- client/service/src/builder.rs | 2 + client/service/src/chain_ops.rs | 73 +- client/service/src/lib.rs | 1 + client/src/lib.rs | 2 +- frame/identity/src/benchmarking.rs | 630 ++++++++++++++++++ frame/identity/src/lib.rs | 4 +- primitives/externalities/src/lib.rs | 8 + primitives/io/src/lib.rs | 25 + primitives/runtime/src/lib.rs | 12 + primitives/runtime/src/traits.rs | 21 + primitives/state-machine/src/backend.rs | 10 + primitives/state-machine/src/ext.rs | 19 + .../state-machine/src/overlayed_changes.rs | 28 +- 21 files changed, 1217 insertions(+), 19 deletions(-) create mode 100644 client/db/src/bench.rs create mode 100644 frame/identity/src/benchmarking.rs diff --git a/Cargo.lock b/Cargo.lock index d13c45afa2..b59da69bfe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5654,6 +5654,7 @@ dependencies = [ "parity-util-mem", "parking_lot 0.10.0", "quickcheck", + "rand 0.7.3", "sc-client", "sc-client-api", "sc-executor", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 76241eb5e7..c9528a3c3e 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -30,12 +30,14 @@ use sp_core::u32_trait::{_1, _2, _3, _4}; use node_primitives::{AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, Moment, Signature}; use sp_api::impl_runtime_apis; use sp_runtime::{ - Permill, Perbill, Percent, ApplyExtrinsicResult, impl_opaque_keys, generic, create_runtime_str + Permill, Perbill, Percent, ApplyExtrinsicResult, impl_opaque_keys, generic, create_runtime_str, + BenchmarkResults, }; use sp_runtime::curve::PiecewiseLinear; use sp_runtime::transaction_validity::TransactionValidity; use sp_runtime::traits::{ - self, BlakeTwo256, Block as BlockT, StaticLookup, SaturatedConversion, ConvertInto, OpaqueKeys, + self, BlakeTwo256, Block as BlockT, StaticLookup, SaturatedConversion, + ConvertInto, OpaqueKeys, Benchmarking, }; use sp_version::RuntimeVersion; #[cfg(any(feature = "std", test))] @@ -804,6 +806,25 @@ impl_runtime_apis! { SessionKeys::decode_into_raw_public_keys(&encoded) } } + + impl crate::Benchmark for Runtime { + fn dispatch_benchmark(module: Vec, extrinsic: Vec, steps: u32, repeat: u32) + -> Option> + { + match module.as_slice() { + b"pallet-identity" | b"identity" => Identity::run_benchmark(extrinsic, steps, repeat).ok(), + _ => return None, + } + } + } +} + +sp_api::decl_runtime_apis! { + pub trait Benchmark + { + fn dispatch_benchmark(module: Vec, extrinsic: Vec, steps: u32, repeat: u32) + -> Option>; + } } #[cfg(test)] diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index 54a98a6ad3..5649232c37 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -58,6 +58,7 @@ use params::{ pub use params::{ SharedParams, ImportParams, ExecutionStrategy, Subcommand, RunCmd, BuildSpecCmd, ExportBlocksCmd, ImportBlocksCmd, CheckBlockCmd, PurgeChainCmd, RevertCmd, + BenchmarkCmd, }; pub use traits::GetSharedParams; use app_dirs::{AppInfo, AppDataType}; diff --git a/client/cli/src/params.rs b/client/cli/src/params.rs index a99d887d25..0881247b07 100644 --- a/client/cli/src/params.rs +++ b/client/cli/src/params.rs @@ -845,6 +845,49 @@ pub struct PurgeChainCmd { pub shared_params: SharedParams, } +/// The `benchmark` command used to benchmark FRAME Pallets. +#[derive(Debug, StructOpt, Clone)] +pub struct BenchmarkCmd { + /// Select a FRAME Pallet to benchmark. + #[structopt(short, long)] + pub pallet: String, + + /// Select an extrinsic to benchmark. + #[structopt(short, long)] + pub extrinsic: String, + + /// Select how many samples we should take across the variable components. + #[structopt(short, long, default_value = "1")] + pub steps: u32, + + /// Select how many repetitions of this benchmark should run. + #[structopt(short, long, default_value = "1")] + pub repeat: u32, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub shared_params: SharedParams, + + /// The execution strategy that should be used for benchmarks + #[structopt( + long = "execution", + value_name = "STRATEGY", + possible_values = &ExecutionStrategy::variants(), + case_insensitive = true, + )] + pub execution: Option, + + /// 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, +} + /// All core commands that are provided by default. /// /// The core commands are split into multiple subcommands and `Run` is the default subcommand. From @@ -869,6 +912,9 @@ pub enum Subcommand { /// Remove the whole chain data. PurgeChain(PurgeChainCmd), + + /// Run runtime benchmarks. + Benchmark(BenchmarkCmd), } impl Subcommand { @@ -883,6 +929,7 @@ impl Subcommand { CheckBlock(params) => ¶ms.shared_params, Revert(params) => ¶ms.shared_params, PurgeChain(params) => ¶ms.shared_params, + Benchmark(params) => ¶ms.shared_params, } } @@ -909,6 +956,7 @@ impl Subcommand { Subcommand::ImportBlocks(cmd) => cmd.run(config, builder), Subcommand::CheckBlock(cmd) => cmd.run(config, builder), Subcommand::PurgeChain(cmd) => cmd.run(config), + Subcommand::Benchmark(cmd) => cmd.run(config, builder), Subcommand::Revert(cmd) => cmd.run(config, builder), } } @@ -1186,3 +1234,32 @@ impl RevertCmd { Ok(()) } } + +impl BenchmarkCmd { + /// Runs the command and benchmarks the chain. + pub fn run( + self, + config: Configuration, + _builder: B, + ) -> error::Result<()> + where + B: FnOnce(Configuration) -> Result, + G: RuntimeGenesis, + E: ChainSpecExtension, + BC: ServiceBuilderCommand + Unpin, + BB: sp_runtime::traits::Block + Debug, + <<::Header as HeaderT>::Number as std::str::FromStr>::Err: std::fmt::Debug, + ::Hash: std::str::FromStr, + { + let spec = config.chain_spec.expect("chain_spec is always Some"); + let execution_strategy = self.execution.unwrap_or(ExecutionStrategy::Native).into(); + let wasm_method = self.wasm_method.into(); + let pallet = self.pallet; + let extrinsic = self.extrinsic; + let steps = self.steps; + let repeat = self.repeat; + sc_service::chain_ops::benchmark_runtime::(spec, execution_strategy, wasm_method, pallet, extrinsic, steps, repeat)?; + Ok(()) + } +} + diff --git a/client/db/Cargo.toml b/client/db/Cargo.toml index d35a554d3f..ef418d43ef 100644 --- a/client/db/Cargo.toml +++ b/client/db/Cargo.toml @@ -8,6 +8,7 @@ license = "GPL-3.0" [dependencies] parking_lot = "0.10.0" log = "0.4.8" +rand = "0.7" kvdb = "0.4.0" kvdb-rocksdb = { version = "0.5", optional = true } kvdb-memorydb = "0.4.0" diff --git a/client/db/src/bench.rs b/client/db/src/bench.rs new file mode 100644 index 0000000000..9858a5c148 --- /dev/null +++ b/client/db/src/bench.rs @@ -0,0 +1,286 @@ +// Copyright 2020 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 . + +//! State backend that's useful for benchmarking + +use std::sync::Arc; +use std::path::PathBuf; +use std::cell::{Cell, RefCell}; +use rand::Rng; + +use hash_db::{Prefix, Hasher}; +use sp_trie::{MemoryDB, prefixed_key}; +use sp_core::storage::ChildInfo; +use sp_runtime::traits::{Block as BlockT, HasherFor}; +use sp_runtime::Storage; +use sp_state_machine::{DBValue, backend::Backend as StateBackend}; +use kvdb::{KeyValueDB, DBTransaction}; +use kvdb_rocksdb::{Database, DatabaseConfig}; + +type DbState = sp_state_machine::TrieBackend< + Arc>>, HasherFor +>; + +struct StorageDb { + db: Arc, + _block: std::marker::PhantomData, +} + +impl sp_state_machine::Storage> for StorageDb { + fn get(&self, key: &Block::Hash, prefix: Prefix) -> Result, String> { + let key = prefixed_key::>(key, prefix); + self.db.get(0, &key) + .map_err(|e| format!("Database backend error: {:?}", e)) + } +} + +/// State that manages the backend database reference. Allows runtime to control the database. +pub struct BenchmarkingState { + path: PathBuf, + root: Cell, + state: RefCell>>, + db: Cell>>, + genesis: as StateBackend>>::Transaction, +} + +impl BenchmarkingState { + /// Create a new instance that creates a database in a temporary dir. + pub fn new(genesis: Storage) -> Result { + let temp_dir = PathBuf::from(std::env::temp_dir()); + let name: String = rand::thread_rng().sample_iter(&rand::distributions::Alphanumeric).take(10).collect(); + let path = temp_dir.join(&name); + + let mut root = B::Hash::default(); + let mut mdb = MemoryDB::>::default(); + sp_state_machine::TrieDBMut::>::new(&mut mdb, &mut root); + + std::fs::create_dir(&path).map_err(|_| String::from("Error creating temp dir"))?; + let mut state = BenchmarkingState { + state: RefCell::new(None), + db: Cell::new(None), + path, + root: Cell::new(root), + genesis: Default::default(), + }; + + state.reopen()?; + let child_delta = genesis.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) = state.state.borrow_mut().as_mut().unwrap().full_storage_root( + genesis.top.into_iter().map(|(k, v)| (k, Some(v))), + child_delta, + ); + state.genesis = transaction.clone(); + state.commit(root, transaction)?; + Ok(state) + } + + fn reopen(&self) -> Result<(), String> { + *self.state.borrow_mut() = None; + self.db.set(None); + let db_config = DatabaseConfig::with_columns(1); + let path = self.path.to_str() + .ok_or_else(|| String::from("Invalid database path"))?; + let db = Arc::new(Database::open(&db_config, &path).map_err(|e| format!("Error opening database: {:?}", e))?); + self.db.set(Some(db.clone())); + let storage_db = Arc::new(StorageDb:: { db, _block: Default::default() }); + *self.state.borrow_mut() = Some(DbState::::new(storage_db, self.root.get())); + Ok(()) + } + + fn kill(&self) -> Result<(), String> { + self.db.set(None); + *self.state.borrow_mut() = None; + let mut root = B::Hash::default(); + let mut mdb = MemoryDB::>::default(); + sp_state_machine::TrieDBMut::>::new(&mut mdb, &mut root); + self.root.set(root); + + std::fs::remove_dir_all(&self.path).map_err(|_| "Error removing database dir".into()) + } +} + +impl Drop for BenchmarkingState { + fn drop(&mut self) { + self.kill().ok(); + } +} + +fn state_err() -> String { + "State is not open".into() +} + +impl StateBackend> for BenchmarkingState { + type Error = as StateBackend>>::Error; + type Transaction = as StateBackend>>::Transaction; + type TrieBackendStorage = as StateBackend>>::TrieBackendStorage; + + fn storage(&self, key: &[u8]) -> Result>, Self::Error> { + self.state.borrow().as_ref().ok_or_else(state_err)?.storage(key) + } + + fn storage_hash(&self, key: &[u8]) -> Result, Self::Error> { + self.state.borrow().as_ref().ok_or_else(state_err)?.storage_hash(key) + } + + fn child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result>, Self::Error> { + self.state.borrow().as_ref().ok_or_else(state_err)?.child_storage(storage_key, child_info, key) + } + + fn exists_storage(&self, key: &[u8]) -> Result { + self.state.borrow().as_ref().ok_or_else(state_err)?.exists_storage(key) + } + + fn exists_child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result { + self.state.borrow().as_ref().ok_or_else(state_err)?.exists_child_storage(storage_key, child_info, key) + } + + fn next_storage_key(&self, key: &[u8]) -> Result>, Self::Error> { + self.state.borrow().as_ref().ok_or_else(state_err)?.next_storage_key(key) + } + + fn next_child_storage_key( + &self, + storage_key: &[u8], + child_info: ChildInfo, + key: &[u8], + ) -> Result>, Self::Error> { + self.state.borrow().as_ref().ok_or_else(state_err)?.next_child_storage_key(storage_key, child_info, key) + } + + fn for_keys_with_prefix(&self, prefix: &[u8], f: F) { + if let Some(ref state) = *self.state.borrow() { + state.for_keys_with_prefix(prefix, f) + } + } + + fn for_key_values_with_prefix(&self, prefix: &[u8], f: F) { + if let Some(ref state) = *self.state.borrow() { + state.for_key_values_with_prefix(prefix, f) + } + } + + fn for_keys_in_child_storage( + &self, + storage_key: &[u8], + child_info: ChildInfo, + f: F, + ) { + if let Some(ref state) = *self.state.borrow() { + state.for_keys_in_child_storage(storage_key, child_info, f) + } + } + + fn for_child_keys_with_prefix( + &self, + storage_key: &[u8], + child_info: ChildInfo, + prefix: &[u8], + f: F, + ) { + if let Some(ref state) = *self.state.borrow() { + state.for_child_keys_with_prefix(storage_key, child_info, prefix, f) + } + } + + fn storage_root(&self, delta: I) -> (B::Hash, Self::Transaction) where + I: IntoIterator, Option>)> + { + self.state.borrow().as_ref().map_or(Default::default(), |s| s.storage_root(delta)) + } + + fn child_storage_root( + &self, + storage_key: &[u8], + child_info: ChildInfo, + delta: I, + ) -> (B::Hash, bool, Self::Transaction) where + I: IntoIterator, Option>)>, + { + self.state.borrow().as_ref().map_or(Default::default(), |s| s.child_storage_root(storage_key, child_info, delta)) + } + + fn pairs(&self) -> Vec<(Vec, Vec)> { + self.state.borrow().as_ref().map_or(Default::default(), |s| s.pairs()) + } + + fn keys(&self, prefix: &[u8]) -> Vec> { + self.state.borrow().as_ref().map_or(Default::default(), |s| s.keys(prefix)) + } + + fn child_keys( + &self, + storage_key: &[u8], + child_info: ChildInfo, + prefix: &[u8], + ) -> Vec> { + self.state.borrow().as_ref().map_or(Default::default(), |s| s.child_keys(storage_key, child_info, prefix)) + } + + fn as_trie_backend(&mut self) + -> Option<&sp_state_machine::TrieBackend>> + { + None + } + + fn commit(&self, storage_root: as Hasher>::Out, mut transaction: Self::Transaction) + -> Result<(), Self::Error> + { + if let Some(db) = self.db.take() { + let mut db_transaction = DBTransaction::new(); + + for (key, (val, rc)) in transaction.drain() { + if rc > 0 { + db_transaction.put(0, &key, &val); + } else if rc < 0 { + db_transaction.delete(0, &key); + } + } + db.write(db_transaction).map_err(|_| String::from("Error committing transaction"))?; + self.root.set(storage_root); + } else { + return Err("Trying to commit to a closed db".into()) + } + self.reopen() + } + + fn wipe(&self) -> Result<(), Self::Error> { + self.kill()?; + self.reopen()?; + self.commit(self.root.get(), self.genesis.clone())?; + Ok(()) + } +} + +impl std::fmt::Debug for BenchmarkingState { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "DB at {:?}", self.path) + } +} + diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index 36cf7dacf4..20998a57f9 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -29,6 +29,9 @@ pub mod light; pub mod offchain; +#[cfg(any(feature = "kvdb-rocksdb", test))] +pub mod bench; + mod children; mod cache; mod changes_tries_storage; @@ -80,6 +83,9 @@ use crate::stats::StateUsageStats; use log::{trace, debug, warn}; pub use sc_state_db::PruningMode; +#[cfg(any(feature = "kvdb-rocksdb", test))] +pub use bench::BenchmarkingState; + #[cfg(feature = "test-helpers")] use sc_client::in_mem::Backend as InMemoryBackend; diff --git a/client/executor/src/integration_tests/mod.rs b/client/executor/src/integration_tests/mod.rs index 3f3d9f69e1..2ac67215a8 100644 --- a/client/executor/src/integration_tests/mod.rs +++ b/client/executor/src/integration_tests/mod.rs @@ -88,7 +88,7 @@ fn call_not_existing_function(wasm_method: WasmExecutionMethod) { #[cfg(feature = "wasmtime")] WasmExecutionMethod::Compiled => assert_eq!( &format!("{:?}", e), - "Other(\"call to undefined external function with index 68\")" + "Other(\"call to undefined external function with index 71\")" ), } } @@ -117,7 +117,7 @@ fn call_yet_another_not_existing_function(wasm_method: WasmExecutionMethod) { #[cfg(feature = "wasmtime")] WasmExecutionMethod::Compiled => assert_eq!( &format!("{:?}", e), - "Other(\"call to undefined external function with index 69\")" + "Other(\"call to undefined external function with index 72\")" ), } } diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 2c10804675..71749ac308 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -673,6 +673,8 @@ impl(spec: ChainSpec, raw: bool) -> error::Result ( + spec: ChainSpec, + strategy: ExecutionStrategy, + wasm_method: WasmExecutionMethod, + pallet: String, + extrinsic: String, + steps: u32, + repeat: u32, +) -> error::Result<()> where + TBl: BlockT, + TExecDisp: NativeExecutionDispatch + 'static, + G: RuntimeGenesis, + E: Extension, +{ + let genesis_storage = spec.build_storage()?; + let mut changes = Default::default(); + let state = BenchmarkingState::::new(genesis_storage)?; + let executor = NativeExecutor::::new( + wasm_method, + None, // heap pages + ); + let result = StateMachine::<_, _, NumberFor, _>::new( + &state, + None, + &mut changes, + &executor, + "Benchmark_dispatch_benchmark", + &(&pallet, &extrinsic, steps, repeat).encode(), + Default::default(), + ).execute(strategy).map_err(|e| format!("Error executing runtime benchmark: {:?}", e))?; + let results = > as Decode>::decode(&mut &result[..]).unwrap_or(None); + if let Some(results) = results { + // Print benchmark metadata + println!("Pallet: {:?}, Extrinsic: {:?}, Steps: {:?}, Repeat: {:?}", pallet, extrinsic, steps, repeat); + // Print the table header + results[0].0.iter().for_each(|param| print!("{:?},", param.0)); + print!("time\n"); + // Print the values + results.iter().for_each(|result| { + let parameters = &result.0; + parameters.iter().for_each(|param| print!("{:?},", param.1)); + print!("{:?}\n", result.1); + }); + info!("Done."); + } else { + info!("No Results."); + } + Ok(()) +} + + impl< TBl, TRtApi, TGen, TCSExt, TBackend, - TExec, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, + TExecDisp, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, Backend > ServiceBuilderCommand for ServiceBuilder< - TBl, TRtApi, TGen, TCSExt, Client, + TBl, TRtApi, TGen, TCSExt, + Client>, TBl, TRtApi>, TFchr, TSc, TImpQu, TFprb, TFpp, TNetP, TExPool, TRpc, Backend > where TBl: BlockT, TBackend: 'static + sc_client_api::backend::Backend + Send, - TExec: 'static + sc_client::CallExecutor + Send + Sync + Clone, + TExecDisp: 'static + NativeExecutionDispatch, TImpQu: 'static + ImportQueue, TRtApi: 'static + Send + Sync, { type Block = TBl; + type NativeDispatch = TExecDisp; fn import_blocks( self, diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 577f36572a..920cdc5c4c 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -65,6 +65,7 @@ pub use sp_transaction_pool::{TransactionPool, InPoolTransaction, error::IntoPoo pub use sc_transaction_pool::txpool::Options as TransactionPoolOptions; pub use sc_client::FinalityNotifications; pub use sc_rpc::Metadata as RpcMetadata; +pub use sc_executor::NativeExecutionDispatch; #[doc(hidden)] pub use std::{ops::Deref, result::Result, sync::Arc}; #[doc(hidden)] diff --git a/client/src/lib.rs b/client/src/lib.rs index 4caabfa201..d97246d478 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -104,4 +104,4 @@ pub use crate::{ }, leaves::LeafSet, }; -pub use sp_state_machine::{ExecutionStrategy, StorageProof}; +pub use sp_state_machine::{ExecutionStrategy, StorageProof, StateMachine}; diff --git a/frame/identity/src/benchmarking.rs b/frame/identity/src/benchmarking.rs new file mode 100644 index 0000000000..0a4a143ea9 --- /dev/null +++ b/frame/identity/src/benchmarking.rs @@ -0,0 +1,630 @@ +// Copyright 2020 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 pallet benchmarking. + +use super::*; + +use frame_system::RawOrigin; +use sp_io::hashing::blake2_256; +use sp_runtime::{BenchmarkResults, BenchmarkParameter}; +use sp_runtime::traits::{Bounded, Benchmarking, BenchmarkingSetup, Dispatchable}; + +use crate::Module as Identity; + +// The maximum number of identity registrars we will test. +const MAX_REGISTRARS: u32 = 50; + +// Support Functions +fn account(name: &'static str, index: u32) -> T::AccountId { + let entropy = (name, index).using_encoded(blake2_256); + T::AccountId::decode(&mut &entropy[..]).unwrap_or_default() +} + +// Adds `r` registrars to the Identity Pallet. These registrars will have set fees and fields. +fn add_registrars(r: u32) -> Result<(), &'static str> { + for i in 0..r { + let _ = T::Currency::make_free_balance_be(&account::("registrar", i), BalanceOf::::max_value()); + Identity::::add_registrar(RawOrigin::Root.into(), account::("registrar", i))?; + Identity::::set_fee(RawOrigin::Signed(account::("registrar", i)).into(), i.into(), 10.into())?; + let fields = IdentityFields( + IdentityField::Display | IdentityField::Legal | IdentityField::Web | IdentityField::Riot + | IdentityField::Email | IdentityField::PgpFingerprint | IdentityField::Image | IdentityField::Twitter + ); + Identity::::set_fields(RawOrigin::Signed(account::("registrar", i)).into(), i.into(), fields)?; + } + + assert_eq!(Registrars::::get().len(), r as usize); + Ok(()) +} + +// Adds `s` sub-accounts to the identity of `who`. Each wil have 32 bytes of raw data added to it. +// This additionally returns the vector of sub-accounts to it can be modified if needed. +fn add_sub_accounts(who: T::AccountId, s: u32) -> Result, &'static str> { + let mut subs = Vec::new(); + let who_origin = RawOrigin::Signed(who.clone()); + let data = Data::Raw(vec![0; 32]); + + for i in 0..s { + let sub_account = account::("sub", i); + subs.push((sub_account, data.clone())); + } + Identity::::set_subs(who_origin.into(), subs.clone())?; + + return Ok(subs) +} + +// This creates an `IdentityInfo` object with `num_fields` extra fields. +// All data is pre-populated with some arbitrary bytes. +fn create_identity_info(num_fields: u32) -> IdentityInfo { + let data = Data::Raw(vec![0; 32]); + + let info = IdentityInfo { + additional: vec![(data.clone(), data.clone()); num_fields as usize], + display: data.clone(), + legal: data.clone(), + web: data.clone(), + riot: data.clone(), + email: data.clone(), + pgp_fingerprint: Some([0; 20]), + image: data.clone(), + twitter: data.clone(), + }; + + return info +} + +// Benchmark `add_registrar` extrinsic. +struct AddRegistrar; +impl BenchmarkingSetup, RawOrigin> for AddRegistrar { + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + vec![ + // Registrar Count + (BenchmarkParameter::R, 1, MAX_REGISTRARS), + ] + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(crate::Call, RawOrigin), &'static str> + { + // Add r registrars + let r = components.iter().find(|&c| c.0 == BenchmarkParameter::R).unwrap().1; + benchmarking::add_registrars::(r)?; + + // Return the `add_registrar` r + 1 call + Ok((crate::Call::::add_registrar(account::("registrar", r + 1)), RawOrigin::Root)) + } +} + +// Benchmark `set_identity` extrinsic. +struct SetIdentity; +impl BenchmarkingSetup, RawOrigin> for SetIdentity { + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + vec![ + // Registrar Count + (BenchmarkParameter::R, 1, MAX_REGISTRARS), + // Additional Field Count + (BenchmarkParameter::X, 1, T::MaxAdditionalFields::get()) + ] + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(crate::Call, RawOrigin), &'static str> + { + // Add r registrars + let r = components.iter().find(|&c| c.0 == BenchmarkParameter::R).unwrap().1; + benchmarking::add_registrars::(r)?; + + // The target user + let caller = account::("caller", r); + let caller_lookup: ::Source = T::Lookup::unlookup(caller.clone()); + let caller_origin: ::Origin = RawOrigin::Signed(caller.clone()).into(); + let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + + // Add an initial identity + let initial_info = benchmarking::create_identity_info::(1); + Identity::::set_identity(caller_origin.clone(), initial_info)?; + + // User requests judgement from all the registrars, and they approve + for i in 0..r { + Identity::::request_judgement(caller_origin.clone(), i, 10.into())?; + Identity::::provide_judgement( + RawOrigin::Signed(account::("registrar", i)).into(), + i, + caller_lookup.clone(), + Judgement::Reasonable + )?; + } + + // Create identity info with x additional fields + let x = components.iter().find(|&c| c.0 == BenchmarkParameter::X).unwrap().1; + // 32 byte data that we reuse below + let info = benchmarking::create_identity_info::(x); + + // Return the `set_identity` call + Ok((crate::Call::::set_identity(info), RawOrigin::Signed(caller))) + } +} + +// Benchmark `set_subs` extrinsic. +struct SetSubs; +impl BenchmarkingSetup, RawOrigin> for SetSubs { + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + vec![ + // Subs Count + (BenchmarkParameter::S, 1, T::MaxSubAccounts::get()), + ] + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(crate::Call, RawOrigin), &'static str> + { + // Generic data to be used. + let data = Data::Raw(vec![0; 32]); + + // The target user + let caller = account::("caller", 0); + let caller_origin: ::Origin = RawOrigin::Signed(caller.clone()).into(); + let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + + // Create their main identity + let info = benchmarking::create_identity_info::(1); + Identity::::set_identity(caller_origin.clone(), info)?; + + // Give them s many sub accounts + let s = components.iter().find(|&c| c.0 == BenchmarkParameter::S).unwrap().1; + let mut subs = add_sub_accounts::(caller.clone(), s)?; + + // Create an s+1 sub account to add + subs.push((account::("sub", s+1), data)); + + // Return the `set_subs` call + Ok((crate::Call::::set_subs(subs), RawOrigin::Signed(caller))) + } +} + +// Benchmark `clear_identity` extrinsic. +struct ClearIdentity; +impl BenchmarkingSetup, RawOrigin> for ClearIdentity { + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + vec![ + // Registrar Count + (BenchmarkParameter::R, 1, MAX_REGISTRARS), + // Subs Count + (BenchmarkParameter::S, 1, T::MaxSubAccounts::get()), + // Additional Field Count + (BenchmarkParameter::X, 1, T::MaxAdditionalFields::get()), + ] + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(crate::Call, RawOrigin), &'static str> + { + // The target user + let caller = account::("caller", 0); + let caller_origin: ::Origin = RawOrigin::Signed(caller.clone()).into(); + let caller_lookup: ::Source = T::Lookup::unlookup(caller.clone()); + let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + + // Register r registrars + let r = components.iter().find(|&c| c.0 == BenchmarkParameter::R).unwrap().1; + benchmarking::add_registrars::(r)?; + + // Create their main identity with x additional fields + let x = components.iter().find(|&c| c.0 == BenchmarkParameter::X).unwrap().1; + let info = benchmarking::create_identity_info::(x); + Identity::::set_identity(caller_origin.clone(), info)?; + + // Give them s many sub accounts + let s = components.iter().find(|&c| c.0 == BenchmarkParameter::S).unwrap().1; + let _ = benchmarking::add_sub_accounts::(caller.clone(), s)?; + + // User requests judgement from all the registrars, and they approve + for i in 0..r { + Identity::::request_judgement(caller_origin.clone(), i, 10.into())?; + Identity::::provide_judgement( + RawOrigin::Signed(account::("registrar", i)).into(), + i, + caller_lookup.clone(), + Judgement::Reasonable + )?; + } + + // Return the `clear_identity` call + Ok((crate::Call::::clear_identity(), RawOrigin::Signed(caller))) + } +} + +// Benchmark `request_judgement` extrinsic. +struct RequestJudgement; +impl BenchmarkingSetup, RawOrigin> for RequestJudgement { + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + vec![ + // Registrar Count + (BenchmarkParameter::R, 1, MAX_REGISTRARS), + // Additional Field Count + (BenchmarkParameter::X, 1, T::MaxAdditionalFields::get()), + ] + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(crate::Call, RawOrigin), &'static str> + { + // The target user + let caller = account::("caller", 0); + let caller_origin: ::Origin = RawOrigin::Signed(caller.clone()).into(); + let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + + // Register r registrars + let r = components.iter().find(|&c| c.0 == BenchmarkParameter::R).unwrap().1; + benchmarking::add_registrars::(r)?; + + // Create their main identity with x additional fields + let x = components.iter().find(|&c| c.0 == BenchmarkParameter::X).unwrap().1; + let info = benchmarking::create_identity_info::(x); + Identity::::set_identity(caller_origin.clone(), info)?; + + // Return the `request_judgement` call + Ok((crate::Call::::request_judgement(r-1, 10.into()), RawOrigin::Signed(caller))) + } +} + +// Benchmark `cancel_request` extrinsic. +struct CancelRequest; +impl BenchmarkingSetup, RawOrigin> for CancelRequest { + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + vec![ + // Registrar Count + (BenchmarkParameter::R, 1, MAX_REGISTRARS), + // Additional Field Count + (BenchmarkParameter::X, 1, T::MaxAdditionalFields::get()), + ] + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(crate::Call, RawOrigin), &'static str> + { + // The target user + let caller = account::("caller", 0); + let caller_origin: ::Origin = RawOrigin::Signed(caller.clone()).into(); + let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + + // Register r registrars + let r = components.iter().find(|&c| c.0 == BenchmarkParameter::R).unwrap().1; + benchmarking::add_registrars::(r)?; + + // Create their main identity with x additional fields + let x = components.iter().find(|&c| c.0 == BenchmarkParameter::X).unwrap().1; + let info = benchmarking::create_identity_info::(x); + Identity::::set_identity(caller_origin.clone(), info)?; + + // Request judgement + Identity::::request_judgement(caller_origin.clone(), r-1, 10.into())?; + + Ok((crate::Call::::cancel_request(r-1), RawOrigin::Signed(caller))) + } +} + +// Benchmark `set_fee` extrinsic. +struct SetFee; +impl BenchmarkingSetup, RawOrigin> for SetFee { + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + vec![ + // Registrar Count + (BenchmarkParameter::R, 1, MAX_REGISTRARS), + ] + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(crate::Call, RawOrigin), &'static str> + { + // The target user + let caller = account::("caller", 0); + let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + + // Register r registrars + let r = components.iter().find(|&c| c.0 == BenchmarkParameter::R).unwrap().1; + benchmarking::add_registrars::(r)?; + + // Add caller as registrar + Identity::::add_registrar(RawOrigin::Root.into(), caller.clone())?; + + // Return `set_fee` call + Ok((crate::Call::::set_fee(r, 10.into()), RawOrigin::Signed(caller))) + } +} + +// Benchmark `set_account_id` extrinsic. +struct SetAccountId; +impl BenchmarkingSetup, RawOrigin> for SetAccountId { + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + vec![ + // Registrar Count + (BenchmarkParameter::R, 1, MAX_REGISTRARS), + ] + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(crate::Call, RawOrigin), &'static str> + { + // The target user + let caller = account::("caller", 0); + let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + + // Register r registrars + let r = components.iter().find(|&c| c.0 == BenchmarkParameter::R).unwrap().1; + benchmarking::add_registrars::(r)?; + + // Add caller as registrar + Identity::::add_registrar(RawOrigin::Root.into(), caller.clone())?; + + // Return `set_account_id` call + Ok((crate::Call::::set_account_id(r, account::("new", 0)), RawOrigin::Signed(caller))) + } +} + +// Benchmark `set_fields` extrinsic. +struct SetFields; +impl BenchmarkingSetup, RawOrigin> for SetFields { + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + vec![ + // Registrar Count + (BenchmarkParameter::R, 1, MAX_REGISTRARS), + ] + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(crate::Call, RawOrigin), &'static str> + { + // The target user + let caller = account::("caller", 0); + let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + + // Register r registrars + let r = components.iter().find(|&c| c.0 == BenchmarkParameter::R).unwrap().1; + benchmarking::add_registrars::(r)?; + + // Add caller as registrar + Identity::::add_registrar(RawOrigin::Root.into(), caller.clone())?; + + let fields = IdentityFields( + IdentityField::Display | IdentityField::Legal | IdentityField::Web | IdentityField::Riot + | IdentityField::Email | IdentityField::PgpFingerprint | IdentityField::Image | IdentityField::Twitter + ); + + // Return `set_account_id` call + Ok((crate::Call::::set_fields(r, fields), RawOrigin::Signed(caller))) + } +} + +// Benchmark `provide_judgement` extrinsic. +struct ProvideJudgement; +impl BenchmarkingSetup, RawOrigin> for ProvideJudgement { + + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + vec![ + // Registrar Count + (BenchmarkParameter::R, 1, MAX_REGISTRARS), + // Additional Field Count + (BenchmarkParameter::X, 1, T::MaxAdditionalFields::get()), + ] + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(crate::Call, RawOrigin), &'static str> + { + // Add r registrars + let r = components.iter().find(|&c| c.0 == BenchmarkParameter::R).unwrap().1; + benchmarking::add_registrars::(r)?; + + // The user + let user = account::("user", r); + let user_origin: ::Origin = RawOrigin::Signed(user.clone()).into(); + let user_lookup: ::Source = T::Lookup::unlookup(user.clone()); + let _ = T::Currency::make_free_balance_be(&user, BalanceOf::::max_value()); + + // Create their main identity with x additional fields + let x = components.iter().find(|&c| c.0 == BenchmarkParameter::X).unwrap().1; + let info = benchmarking::create_identity_info::(x); + Identity::::set_identity(user_origin.clone(), info)?; + + // The caller registrar + let caller = account::("caller", r); + let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + + // Add caller as registrar + Identity::::add_registrar(RawOrigin::Root.into(), caller.clone())?; + + // User requests judgement from caller registrar + Identity::::request_judgement(user_origin.clone(), r, 10.into())?; + + // Return `provide_judgement` call + Ok((crate::Call::::provide_judgement( + r, + user_lookup.clone(), + Judgement::Reasonable + ), RawOrigin::Signed(caller))) + } +} + +// Benchmark `kill_identity` extrinsic. +struct KillIdentity; +impl BenchmarkingSetup, RawOrigin> for KillIdentity { + + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + vec![ + // Registrar Count + (BenchmarkParameter::R, 1, MAX_REGISTRARS), + // Subs Count + (BenchmarkParameter::S, 1, T::MaxSubAccounts::get()), + // Additional Field Count + (BenchmarkParameter::X, 1, T::MaxAdditionalFields::get()), + ] + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(crate::Call, RawOrigin), &'static str> + { + // The target user + let caller = account::("caller", 0); + let caller_origin: ::Origin = RawOrigin::Signed(caller.clone()).into(); + let caller_lookup: ::Source = T::Lookup::unlookup(caller.clone()); + let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + + // Register r registrars + let r = components.iter().find(|&c| c.0 == BenchmarkParameter::R).unwrap().1; + benchmarking::add_registrars::(r)?; + + // Create their main identity with x additional fields + let x = components.iter().find(|&c| c.0 == BenchmarkParameter::X).unwrap().1; + let info = benchmarking::create_identity_info::(x); + Identity::::set_identity(caller_origin.clone(), info)?; + + // Give them s many sub accounts + let s = components.iter().find(|&c| c.0 == BenchmarkParameter::S).unwrap().1; + let _ = benchmarking::add_sub_accounts::(caller.clone(), s)?; + + // User requests judgement from all the registrars, and they approve + for i in 0..r { + Identity::::request_judgement(caller_origin.clone(), i, 10.into())?; + Identity::::provide_judgement( + RawOrigin::Signed(account::("registrar", i)).into(), + i, + caller_lookup.clone(), + Judgement::Reasonable + )?; + } + + // Return the `kill_identity` call + Ok((crate::Call::::kill_identity(caller_lookup), RawOrigin::Root)) + } +} + +// The list of available benchmarks for this pallet. +enum SelectedBenchmark { + AddRegistrar, + SetIdentity, + SetSubs, + ClearIdentity, + RequestJudgement, + CancelRequest, + SetFee, + SetAccountId, + SetFields, + ProvideJudgement, + KillIdentity, +} + +// Allow us to select a benchmark from the list of available benchmarks. + +impl BenchmarkingSetup, RawOrigin> for SelectedBenchmark { + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + match self { + Self::AddRegistrar => , RawOrigin>>::components(&AddRegistrar), + Self::SetIdentity => , RawOrigin>>::components(&SetIdentity), + Self::SetSubs => , RawOrigin>>::components(&SetSubs), + Self::ClearIdentity => , RawOrigin>>::components(&ClearIdentity), + Self::RequestJudgement => , RawOrigin>>::components(&RequestJudgement), + Self::CancelRequest => , RawOrigin>>::components(&CancelRequest), + Self::SetFee => , RawOrigin>>::components(&SetFee), + Self::SetAccountId => , RawOrigin>>::components(&SetAccountId), + Self::SetFields => , RawOrigin>>::components(&SetFields), + Self::ProvideJudgement => , RawOrigin>>::components(&ProvideJudgement), + Self::KillIdentity => , RawOrigin>>::components(&KillIdentity), + } + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(crate::Call, RawOrigin), &'static str> + { + match self { + Self::AddRegistrar => , RawOrigin>>::instance(&AddRegistrar, components), + Self::SetIdentity => , RawOrigin>>::instance(&SetIdentity, components), + Self::SetSubs => , RawOrigin>>::instance(&SetSubs, components), + Self::ClearIdentity => , RawOrigin>>::instance(&ClearIdentity, components), + Self::RequestJudgement => , RawOrigin>>::instance(&RequestJudgement, components), + Self::CancelRequest => , RawOrigin>>::instance(&CancelRequest, components), + Self::SetFee => , RawOrigin>>::instance(&SetFee, components), + Self::SetAccountId => , RawOrigin>>::instance(&SetAccountId, components), + Self::SetFields => , RawOrigin>>::instance(&SetFields, components), + Self::ProvideJudgement => , RawOrigin>>::instance(&ProvideJudgement, components), + Self::KillIdentity => , RawOrigin>>::instance(&KillIdentity, components), + } + } +} + +impl Benchmarking for Module { + fn run_benchmark(extrinsic: Vec, steps: u32, repeat: u32) -> Result, &'static str> { + // Map the input to the selected benchmark. + let selected_benchmark = match extrinsic.as_slice() { + b"add_registrar" => SelectedBenchmark::AddRegistrar, + b"set_identity" => SelectedBenchmark::SetIdentity, + b"set_subs" => SelectedBenchmark::SetSubs, + b"clear_identity" => SelectedBenchmark::ClearIdentity, + b"request_judgement" => SelectedBenchmark::RequestJudgement, + b"cancel_request" => SelectedBenchmark::CancelRequest, + b"set_fee" => SelectedBenchmark::SetFee, + b"set_account_id" => SelectedBenchmark::SetAccountId, + b"set_fields" => SelectedBenchmark::SetFields, + b"provide_judgement" => SelectedBenchmark::ProvideJudgement, + b"kill_identity" => SelectedBenchmark::KillIdentity, + _ => return Err("Could not find extrinsic."), + }; + + // Warm up the DB + sp_io::benchmarking::commit_db(); + sp_io::benchmarking::wipe_db(); + + // first one is set_identity. + let components = , RawOrigin>>::components(&selected_benchmark); + // results go here + let mut results: Vec = Vec::new(); + // Select the component we will be benchmarking. Each component will be benchmarked. + for (name, low, high) in components.iter() { + // Create up to `STEPS` steps for that component between high and low. + let step_size = ((high - low) / steps).max(1); + let num_of_steps = (high - low) / step_size; + for s in 0..num_of_steps { + // This is the value we will be testing for component `name` + let component_value = low + step_size * s; + + // Select the mid value for all the other components. + let c: Vec<(BenchmarkParameter, u32)> = components.iter() + .map(|(n, l, h)| + (*n, if n == name { component_value } else { (h - l) / 2 + l }) + ).collect(); + + // Run the benchmark `repeat` times. + for _ in 0..repeat { + // Set up the externalities environment for the setup we want to benchmark. + let (call, caller) = , RawOrigin>>::instance(&selected_benchmark, &c)?; + // Commit the externalities to the database, flushing the DB cache. + // This will enable worst case scenario for reading from the database. + sp_io::benchmarking::commit_db(); + // Run the benchmark. + let start = sp_io::benchmarking::current_time(); + call.dispatch(caller.into())?; + let finish = sp_io::benchmarking::current_time(); + let elapsed = finish - start; + results.push((c.clone(), elapsed)); + // Wipe the DB back to the genesis state. + sp_io::benchmarking::wipe_db(); + } + } + } + return Ok(results); + } +} diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index 80a200e808..c6fc0062be 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -78,6 +78,8 @@ use frame_support::{ }; use frame_system::{self as system, ensure_signed, ensure_root}; +pub mod benchmarking; + type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; @@ -880,7 +882,7 @@ mod tests { use sp_runtime::traits::BadOrigin; use frame_support::{ assert_ok, assert_noop, impl_outer_origin, parameter_types, weights::Weight, - ord_parameter_types + ord_parameter_types, }; use sp_core::H256; use frame_system::EnsureSignedBy; diff --git a/primitives/externalities/src/lib.rs b/primitives/externalities/src/lib.rs index 350b65d190..75193a4b9c 100644 --- a/primitives/externalities/src/lib.rs +++ b/primitives/externalities/src/lib.rs @@ -202,6 +202,14 @@ pub trait Externalities: ExtensionStore { /// /// Returns the SCALE encoded hash. fn storage_changes_root(&mut self, parent: &[u8]) -> Result>, ()>; + + fn wipe(&mut self) { + unimplemented!() + } + + fn commit(&mut self) { + unimplemented!() + } } /// Extension for the [`Externalities`] trait. diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index 1b531725fe..ea45b580ce 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -771,6 +771,30 @@ pub trait Logging { } } +/// Interface that provides functions for benchmarking the runtime. +#[runtime_interface] +pub trait Benchmarking { + /// Get the number of nanoseconds passed since the UNIX epoch + /// + /// WARNING! This is a non-deterministic call. Do not use this within + /// consensus critical logic. + fn current_time() -> u128 { + std::time::SystemTime::now().duration_since(std::time::SystemTime::UNIX_EPOCH) + .expect("Unix time doesn't go backwards; qed") + .as_nanos() + } + + /// Reset the trie database to the genesis state. + fn wipe_db(&mut self) { + self.wipe() + } + + /// Commit pending storage changes to the trie database and clear the database cache. + fn commit_db(&mut self) { + self.commit() + } +} + /// Wasm-only interface that provides functions for interacting with the sandbox. #[runtime_interface(wasm_only)] pub trait Sandbox { @@ -923,6 +947,7 @@ pub type SubstrateHostFunctions = ( logging::HostFunctions, sandbox::HostFunctions, crate::trie::HostFunctions, + benchmarking::HostFunctions, ); #[cfg(test)] diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index 9494c53cc6..f525f91ff6 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -685,6 +685,18 @@ pub fn print(print: impl traits::Printable) { print.print(); } +/// An alphabet of possible parameters to use for benchmarking. +#[derive(Encode, Decode, Clone, Copy, PartialEq, Debug)] +#[allow(missing_docs)] +pub enum BenchmarkParameter { + A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, +} + +/// Results from running benchmarks on a FRAME pallet. +/// Contains duration of the function call in nanoseconds along with the benchmark parameters +/// used for that benchmark result. +pub type BenchmarkResults = (Vec<(BenchmarkParameter, u32)>, u128); + #[cfg(test)] mod tests { use super::*; diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index f07f4dd7ac..e95fc073eb 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -24,6 +24,7 @@ use std::fmt::Display; #[cfg(feature = "std")] use serde::{Serialize, Deserialize, de::DeserializeOwned}; use sp_core::{self, Hasher, Blake2Hasher, TypeId, RuntimeDebug}; +use crate::BenchmarkParameter; use crate::codec::{Codec, Encode, Decode}; use crate::transaction_validity::{ ValidTransaction, TransactionValidity, TransactionValidityError, UnknownTransaction, @@ -1328,6 +1329,26 @@ pub trait BlockIdTo { ) -> Result>, Self::Error>; } +/// The pallet benchmarking trait. +pub trait Benchmarking { + /// Run the benchmarks for this pallet. + /// + /// Parameters + /// - `extrinsic`: The name of extrinsic function you want to benchmark encoded as bytes. + /// - `steps`: The number of sample points you want to take across the range of parameters. + /// - `repeat`: The number of times you want to repeat a benchmark. + fn run_benchmark(extrinsic: Vec, steps: u32, repeat: u32) -> Result, &'static str>; +} + +/// The required setup for creating a benchmark. +pub trait BenchmarkingSetup { + /// Return the components and their ranges which should be tested in this benchmark. + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)>; + + /// Set up the storage, and prepare a call and caller to test in a single run of the benchmark. + fn instance(&self, components: &[(BenchmarkParameter, u32)]) -> Result<(Call, RawOrigin), &'static str>; +} + #[cfg(test)] mod tests { use super::*; diff --git a/primitives/state-machine/src/backend.rs b/primitives/state-machine/src/backend.rs index 4ef9b970ae..396ef6575a 100644 --- a/primitives/state-machine/src/backend.rs +++ b/primitives/state-machine/src/backend.rs @@ -213,6 +213,16 @@ pub trait Backend: std::fmt::Debug { fn usage_info(&self) -> UsageInfo { UsageInfo::empty() } + + /// Wipe the state database. + fn wipe(&self) -> Result<(), Self::Error> { + unimplemented!() + } + + /// Commit given transaction to storage. + fn commit(&self, _storage_root: H::Out, _transaction: Self::Transaction) -> Result<(), Self::Error> { + unimplemented!() + } } impl<'a, T: Backend, H: Hasher> Backend for &'a T { diff --git a/primitives/state-machine/src/ext.rs b/primitives/state-machine/src/ext.rs index 38a2e70262..53156cb186 100644 --- a/primitives/state-machine/src/ext.rs +++ b/primitives/state-machine/src/ext.rs @@ -583,6 +583,25 @@ where root.map(|r| r.map(|o| o.encode())) } + + fn wipe(&mut self) { + self.overlay.discard_prospective(); + self.overlay.drain_storage_changes(&self.backend, None, Default::default(), self.storage_transaction_cache) + .expect(EXT_NOT_ALLOWED_TO_FAIL); + self.storage_transaction_cache.reset(); + self.backend.wipe().expect(EXT_NOT_ALLOWED_TO_FAIL) + } + + fn commit(&mut self) { + self.overlay.commit_prospective(); + let changes = self.overlay.drain_storage_changes(&self.backend, None, Default::default(), self.storage_transaction_cache) + .expect(EXT_NOT_ALLOWED_TO_FAIL); + self.backend.commit( + changes.transaction_storage_root, + changes.transaction, + ).expect(EXT_NOT_ALLOWED_TO_FAIL); + self.storage_transaction_cache.reset(); + } } impl<'a, H, B, N> sp_externalities::ExtensionStore for Ext<'a, H, N, B> diff --git a/primitives/state-machine/src/overlayed_changes.rs b/primitives/state-machine/src/overlayed_changes.rs index ed6f30a4f5..37187e163f 100644 --- a/primitives/state-machine/src/overlayed_changes.rs +++ b/primitives/state-machine/src/overlayed_changes.rs @@ -428,15 +428,18 @@ impl OverlayedChanges { /// /// Panics: /// Will panic if there are any uncommitted prospective changes. - pub fn into_committed(self) -> ( + fn drain_committed(&mut self) -> ( impl Iterator)>, impl Iterator)>, 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, ci))| (sk, (v.into_iter().map(|(k, v)| (k, v.value)), ci))) + std::mem::replace(&mut self.committed.top, Default::default()) + .into_iter() + .map(|(k, v)| (k, v.value)), + std::mem::replace(&mut self.committed.children, Default::default()) + .into_iter() + .map(|(sk, (v, ci))| (sk, (v.into_iter().map(|(k, v)| (k, v.value)), ci))), ) } @@ -444,11 +447,22 @@ impl OverlayedChanges { pub fn into_storage_changes< B: Backend, H: Hasher, N: BlockNumber >( - self, + mut self, backend: &B, changes_trie_state: Option<&ChangesTrieState>, parent_hash: H::Out, mut cache: StorageTransactionCache, + ) -> Result, String> where H::Out: Ord + Encode + 'static { + self.drain_storage_changes(backend, changes_trie_state, parent_hash, &mut cache) + } + + /// Drain all changes into a [`StorageChanges`] instance. Leave empty overlay in place. + pub fn drain_storage_changes, H: Hasher, N: BlockNumber>( + &mut self, + backend: &B, + changes_trie_state: Option<&ChangesTrieState>, + parent_hash: H::Out, + mut cache: &mut StorageTransactionCache, ) -> Result, String> where H::Out: Ord + Encode + 'static { // If the transaction does not exist, we generate it. if cache.transaction.is_none() { @@ -474,7 +488,7 @@ impl OverlayedChanges { .take() .expect("Changes trie transaction was generated by `changes_trie_root`; qed"); - let (main_storage_changes, child_storage_changes) = self.into_committed(); + let (main_storage_changes, child_storage_changes) = self.drain_committed(); Ok(StorageChanges { main_storage_changes: main_storage_changes.collect(), -- GitLab From f735d3e2491d347825ec9560e8916decd72a4f11 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Mon, 10 Feb 2020 10:30:42 +0100 Subject: [PATCH 115/180] Fix vesting logic (#4864) * Fix vesting logic * Bump runtime version * Docs. --- bin/node/runtime/src/lib.rs | 4 ++-- frame/support/src/traits.rs | 6 ++++++ frame/vesting/src/lib.rs | 18 ++++++++++++------ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index c9528a3c3e..0435755d19 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -81,8 +81,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 214, - impl_version: 3, + spec_version: 215, + impl_version: 0, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index ecfababfc0..f7701b4cd5 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -620,6 +620,10 @@ pub trait VestingSchedule { /// /// If there already exists a vesting schedule for the given account, an `Err` is returned /// and nothing is updated. + /// + /// Is a no-op if the amount to be vested is zero. + /// + /// NOTE: This doesn't alter the free balance of the account. fn add_vesting_schedule( who: &AccountId, locked: >::Balance, @@ -628,6 +632,8 @@ pub trait VestingSchedule { ) -> DispatchResult; /// Remove a vesting schedule for a given account. + /// + /// NOTE: This doesn't alter the free balance of the account. fn remove_vesting_schedule(who: &AccountId); } diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index 2a1ff12716..dd12f28ec4 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -52,7 +52,7 @@ use codec::{Encode, Decode}; use sp_runtime::{DispatchResult, RuntimeDebug, traits::{ StaticLookup, Zero, SimpleArithmetic, MaybeSerializeDeserialize, Saturating, Convert }}; -use frame_support::{decl_module, decl_event, decl_storage, ensure, decl_error}; +use frame_support::{decl_module, decl_event, decl_storage, decl_error}; use frame_support::traits::{ Currency, LockableCurrency, VestingSchedule, WithdrawReason, LockIdentifier }; @@ -212,16 +212,18 @@ impl Module { /// (Re)set or remove the module's currency lock on `who`'s account in accordance with their /// current unvested amount. fn update_lock(who: T::AccountId) -> DispatchResult { - ensure!(Vesting::::contains_key(&who), Error::::NotVesting); - let unvested = Self::vesting_balance(&who); - if unvested.is_zero() { + let vesting = Self::vesting(&who).ok_or(Error::::NotVesting)?; + let now = >::block_number(); + let locked_now = vesting.locked_at::(now); + + if locked_now.is_zero() { T::Currency::remove_lock(VESTING_ID, &who); Vesting::::remove(&who); Self::deposit_event(RawEvent::VestingCompleted(who)); } else { let reasons = WithdrawReason::Transfer | WithdrawReason::Reserve; - T::Currency::set_lock(VESTING_ID, &who, unvested, reasons); - Self::deposit_event(RawEvent::VestingUpdated(who, unvested)); + T::Currency::set_lock(VESTING_ID, &who, locked_now, reasons); + Self::deposit_event(RawEvent::VestingUpdated(who, locked_now)); } Ok(()) } @@ -249,6 +251,10 @@ impl VestingSchedule for Module where /// If there already exists a vesting schedule for the given account, an `Err` is returned /// and nothing is updated. /// + /// On success, a linearly reducing amount of funds will be locked. In order to realise any + /// reduction of the lock over time as it diminishes, the account owner must use `vest` or + /// `vest_other`. + /// /// Is a no-op if the amount to be vested is zero. fn add_vesting_schedule( who: &T::AccountId, -- GitLab From 7e8ac2eb0df9a4a6154dc1ba6029caabcf5e7191 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Mon, 10 Feb 2020 11:51:56 +0100 Subject: [PATCH 116/180] Update trie-db to the latest (#4874) --- Cargo.lock | 69 ++++++++++------------------- bin/node/executor/Cargo.toml | 2 +- primitives/state-machine/Cargo.toml | 4 +- 3 files changed, 26 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b59da69bfe..7d5d3c641a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -472,9 +472,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.1.2" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb8038c1ddc0a5f73787b130f4cc75151e96ed33e417fde765eb5a81e3532f4" +checksum = "1f359dc14ff8911330a51ef78022d376f25ed00248912803b58f00cb1c27f742" [[package]] name = "byte-slice-cast" @@ -2010,9 +2010,9 @@ dependencies = [ [[package]] name = "hex" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e" +checksum = "76cdda6bf525062a0c9e8f14ee2b37935c86b8efb6c8b69b3c83dfb518a914af" [[package]] name = "hex-literal" @@ -2409,28 +2409,28 @@ dependencies = [ [[package]] name = "jsonrpc-http-server" -version = "14.0.5" +version = "14.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d83d348120edee487c560b7cdd2565055d61cda053aa0d0ef0f8b6a18429048" +checksum = "816d63997ea45d3634608edbef83ddb35e661f7c0b27b5b72f237e321f0e9807" dependencies = [ "hyper 0.12.35", "jsonrpc-core", "jsonrpc-server-utils", "log 0.4.8", "net2", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "unicase 2.6.0", ] [[package]] name = "jsonrpc-pubsub" -version = "14.0.5" +version = "14.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3453625f0f0f5cd6d6776d389d73b7d70fcc98620b7cbb1cbbb1f6a36e95f39a" +checksum = "5b31c9b90731276fdd24d896f31bb10aecf2e5151733364ae81123186643d939" dependencies = [ "jsonrpc-core", "log 0.4.8", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "serde", ] @@ -2452,14 +2452,14 @@ dependencies = [ [[package]] name = "jsonrpc-ws-server" -version = "14.0.5" +version = "14.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b34faa167c3ac9705aeecb986c0da6056529f348425dbe0441db60a2c4cc41d1" +checksum = "b94e5773b2ae66e0e02c80775ce6bbba6f15d5bb47c14ec36a36fcf94f8df851" dependencies = [ "jsonrpc-core", "jsonrpc-server-utils", "log 0.4.8", - "parking_lot 0.9.0", + "parking_lot 0.10.0", "slab", "ws", ] @@ -3416,7 +3416,7 @@ dependencies = [ "sp-state-machine", "sp-trie", "substrate-test-client", - "trie-root 0.15.2", + "trie-root", "wabt", ] @@ -6527,9 +6527,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.46" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b01d7f0288608a01dca632cf1df859df6fd6ffa885300fc275ce2ba6221953" +checksum = "15913895b61e0be854afd32fd4163fcd2a3df34142cf2cb961b310ce694cbf90" dependencies = [ "itoa", "ryu", @@ -7195,8 +7195,8 @@ dependencies = [ "sp-externalities", "sp-panic-handler", "sp-trie", - "trie-db 0.19.2", - "trie-root 0.15.2", + "trie-db", + "trie-root", ] [[package]] @@ -7262,8 +7262,8 @@ dependencies = [ "sp-core", "sp-std", "trie-bench", - "trie-db 0.20.0", - "trie-root 0.16.0", + "trie-db", + "trie-root", "trie-standardmap", ] @@ -7524,7 +7524,7 @@ dependencies = [ "sp-version", "substrate-test-runtime-client", "substrate-wasm-builder-runner", - "trie-db 0.20.0", + "trie-db", ] [[package]] @@ -8147,25 +8147,11 @@ dependencies = [ "keccak-hasher", "memory-db", "parity-scale-codec", - "trie-db 0.20.0", - "trie-root 0.16.0", + "trie-db", + "trie-root", "trie-standardmap", ] -[[package]] -name = "trie-db" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d747ae5b6f078df7e46477fcc7df66df9eb4f27a031cf4a7c890a8dd03d8e6" -dependencies = [ - "hash-db", - "hashbrown 0.6.3", - "log 0.4.8", - "rand 0.6.5", - "rustc-hex", - "smallvec 1.2.0", -] - [[package]] name = "trie-db" version = "0.20.0" @@ -8179,15 +8165,6 @@ dependencies = [ "smallvec 1.2.0", ] -[[package]] -name = "trie-root" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b779f7c1c8fe9276365d9d5be5c4b5adeacf545117bb3f64c974305789c5c0b" -dependencies = [ - "hash-db", -] - [[package]] name = "trie-root" version = "0.16.0" diff --git a/bin/node/executor/Cargo.toml b/bin/node/executor/Cargo.toml index 0d68b70522..1d894e39fa 100644 --- a/bin/node/executor/Cargo.toml +++ b/bin/node/executor/Cargo.toml @@ -15,7 +15,7 @@ sp-core = { version = "2.0.0", path = "../../../primitives/core" } sp-io = { version = "2.0.0", path = "../../../primitives/io" } sp-state-machine = { version = "0.8", path = "../../../primitives/state-machine" } sp-trie = { version = "2.0.0", path = "../../../primitives/trie" } -trie-root = "0.15.2" +trie-root = "0.16.0" [dev-dependencies] criterion = "0.3.0" diff --git a/primitives/state-machine/Cargo.toml b/primitives/state-machine/Cargo.toml index 3752e95695..2408cce099 100644 --- a/primitives/state-machine/Cargo.toml +++ b/primitives/state-machine/Cargo.toml @@ -10,8 +10,8 @@ license = "GPL-3.0" log = "0.4.8" parking_lot = "0.10.0" hash-db = "0.15.2" -trie-db = "0.19.2" -trie-root = "0.15.2" +trie-db = "0.20.0" +trie-root = "0.16.0" 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" } -- GitLab From ae03ee918e6338a3afc5dbd3742f5b8d7fa35271 Mon Sep 17 00:00:00 2001 From: Ashley Date: Mon, 10 Feb 2020 12:23:55 +0100 Subject: [PATCH 117/180] Fix timer panics in the wasm light client (#4561) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Make WASM browser thing compile * Fix * updated exit-future (github repo) * Switch to broadcast crate * Migrate client/cli * Switch exit-future to modernize branch * Small changes * Switch to cargo version and fix fg tests * fix basic-authorship * Fix crash on grafana macro * Fix grafana macro * Switch node python version * Disable record_metrics_slice in grafana macro on wasm * Update client/grafana-data-source/src/lib.rs * Revert "Update client/grafana-data-source/src/lib.rs" This reverts commit 888009a8e0b7051bd4bfbbfdb0448bcf2e2aae93. * Add wasm support for state machine * Switch to my own libp2p version * Revert "Switch to my own libp2p version" This reverts commit ce613871b59264b3165b45c37943e6560240daa7. * Revert "Add wasm support for state machine" This reverts commit de7eaa0694d9534fc3b164621737968e9a6a7c5f. * Add sc-browser * Squash * remove sc-browser * Fix keystore on wasm * stubs for removed functions to make env compatible with old runtimes * Add test (that doesn't work) * Fix build scripts * Revert basic-authorship due to no panics * Revert cli/informant * Revert consensus * revert offchain * Update utils/browser/Cargo.toml Co-Authored-By: Benjamin Kampmann * export console functions * Add new chainspec * Fix ws in chain spec * revert chainspec * Fix chainspec * Use an Option in keystore instead of cfg flags * Remove crud * Only use wasm-timer for instant and systemtime * Remove telemetry changes * Assuming this is ok * Add a KeystoreConfig * Add stubs back in * Update libp2p * Revert "Add stubs back in" This reverts commit 4690cf1882aa0f99f7f00a58c4080c8aa9b77c36. * Remove commented js again * Bump kvdb-web version * Fix cli * Switch branch on futures-timer * Fix tests * Remove sc-client test build in check-web-wasm because there isn't a good way to build futures-timer with wasm-bindgen support in the build * Remove more things ^^ * Switch branch on futures-timer back * Put DB io stats behind a cfg flag * Fix things * Don't timeout transports on wasm * Update branch of futures-timer and fix bad merge * Spawn informant * Fix network test * Fix delay resets * Changes * Fix tests * use wasm_timer for transaction pool * Fixes * Switch futures-timer to crates * Only diagnose futures on native * Fix sc-network-test tests * Select log level in js * Fix syncing ;^) * Allow disabling colours in the informant * Use OutputFormat enum for informant * MallocSizeOf impl on transaction pool broke stuff because wasm_timer::Instant doesnt impl it so just revert the transaction pool to master * Update futures-diagnose * Revert "MallocSizeOf impl on transaction pool broke stuff because wasm_timer::Instant doesnt impl it so just revert the transaction pool to master" This reverts commit baa4ffc94fd968b6660a2c17ba8113e06af15548. * Pass whole chain spec in start_client * Get Instant::now to work in transaction pool again * Informant dep reordering Co-authored-by: Pierre Krieger Co-authored-by: Bastian Köcher Co-authored-by: Svyatoslav Nikolsky Co-authored-by: Benjamin Kampmann Co-authored-by: Demi Obenour <48690212+DemiMarie-parity@users.noreply.github.com> --- Cargo.lock | 94 ++++++++++++++----- Cargo.toml | 1 + bin/node/cli/browser-demo/index.html | 7 +- bin/node/cli/src/browser.rs | 14 +-- client/authority-discovery/Cargo.toml | 2 +- client/cli/Cargo.toml | 1 + client/cli/src/lib.rs | 1 - client/cli/src/runtime.rs | 3 +- client/consensus/aura/Cargo.toml | 2 +- client/consensus/babe/Cargo.toml | 2 +- client/consensus/slots/Cargo.toml | 2 +- client/finality-grandpa/Cargo.toml | 2 +- .../src/communication/periodic.rs | 10 +- client/informant/Cargo.toml | 19 ++++ .../informant => informant/src}/display.rs | 61 ++++++++---- .../src/informant.rs => informant/src/lib.rs} | 12 ++- client/network-gossip/Cargo.toml | 3 +- client/network-gossip/src/state_machine.rs | 9 +- client/network/Cargo.toml | 3 +- client/network/src/debug_info.rs | 3 +- client/network/src/protocol.rs | 13 +-- .../src/protocol/legacy_proto/behaviour.rs | 7 +- .../src/protocol/legacy_proto/handler.rs | 11 +-- .../src/protocol/legacy_proto/tests.rs | 2 +- client/network/src/protocol/light_dispatch.rs | 3 +- .../src/protocol/sync/extra_requests.rs | 3 +- client/network/src/transport.rs | 15 ++- client/network/test/Cargo.toml | 2 +- client/network/test/src/sync.rs | 4 +- client/offchain/Cargo.toml | 2 +- client/peerset/Cargo.toml | 1 + client/peerset/src/lib.rs | 3 +- client/service/Cargo.toml | 3 +- client/service/src/builder.rs | 13 ++- client/service/src/lib.rs | 18 +++- client/telemetry/Cargo.toml | 3 +- client/telemetry/src/lib.rs | 3 +- client/telemetry/src/worker.rs | 4 +- client/transaction-pool/Cargo.toml | 1 + client/transaction-pool/graph/Cargo.toml | 1 + .../transaction-pool/graph/src/base_pool.rs | 3 +- client/transaction-pool/graph/src/future.rs | 11 ++- client/transaction-pool/graph/src/pool.rs | 11 +-- client/transaction-pool/graph/src/rotator.rs | 3 +- .../graph/src/validated_pool.rs | 15 +-- client/transaction-pool/src/lib.rs | 6 +- primitives/consensus/common/Cargo.toml | 2 +- primitives/timestamp/Cargo.toml | 1 + primitives/timestamp/src/lib.rs | 2 +- primitives/transaction-pool/src/pool.rs | 6 +- utils/browser/Cargo.toml | 9 +- utils/browser/src/lib.rs | 14 ++- utils/grafana-data-source/Cargo.toml | 2 +- utils/grafana-data-source/test/Cargo.toml | 2 +- 54 files changed, 297 insertions(+), 153 deletions(-) create mode 100644 client/informant/Cargo.toml rename client/{cli/src/informant => informant/src}/display.rs (76%) rename client/{cli/src/informant.rs => informant/src/lib.rs} (90%) diff --git a/Cargo.lock b/Cargo.lock index 7d5d3c641a..b93b32fd93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -425,11 +425,13 @@ dependencies = [ name = "browser-utils" version = "0.8.0" dependencies = [ + "chrono", "clear_on_drop", "console_error_panic_hook", "console_log", "futures 0.1.29", "futures 0.3.4", + "futures-timer 3.0.1", "js-sys", "kvdb-web", "libp2p", @@ -437,6 +439,7 @@ dependencies = [ "rand 0.6.5", "rand 0.7.3", "sc-chain-spec", + "sc-informant", "sc-network", "sc-service", "wasm-bindgen", @@ -595,10 +598,12 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" dependencies = [ + "js-sys", "num-integer", "num-traits", "serde", "time", + "wasm-bindgen", ] [[package]] @@ -1717,20 +1722,19 @@ checksum = "7b0a34e53cf6cdcd0178aa573aed466b646eb3db769570841fda0c7ede375a27" [[package]] name = "futures-timer" -version = "0.4.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "878f1d2fc31355fa02ed2372e741b0c17e58373341e6a122569b4623a14a7d33" -dependencies = [ - "futures-core-preview", - "futures-util-preview", - "pin-utils", -] +checksum = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6" [[package]] name = "futures-timer" -version = "2.0.2" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6" +checksum = "3de1a2b2a2a33d9e60e17980b60ee061eeaae96a5abe9121db0fdb9af167a1c5" +dependencies = [ + "gloo-timers", + "send_wrapper 0.4.0", +] [[package]] name = "futures-util" @@ -1873,6 +1877,19 @@ dependencies = [ "regex", ] +[[package]] +name = "gloo-timers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2d17dbd803c2fc86cb1b613adf63192046a7176f383a8302594654752c4c4a" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "goblin" version = "0.1.3" @@ -1891,7 +1908,7 @@ dependencies = [ "async-std", "chrono", "derive_more", - "futures-timer 2.0.2", + "futures-timer 3.0.1", "futures-util", "hyper 0.13.2", "lazy_static", @@ -1907,7 +1924,7 @@ name = "grafana-data-source-test" version = "2.0.0" dependencies = [ "futures 0.3.4", - "futures-timer 2.0.2", + "futures-timer 3.0.1", "grafana-data-source", "rand 0.7.3", ] @@ -5450,7 +5467,7 @@ dependencies = [ "derive_more", "env_logger 0.7.1", "futures 0.3.4", - "futures-timer 2.0.2", + "futures-timer 3.0.1", "libp2p", "log 0.4.8", "parity-scale-codec", @@ -5554,6 +5571,7 @@ dependencies = [ "regex", "rpassword", "sc-client-api", + "sc-informant", "sc-network", "sc-service", "sc-telemetry", @@ -5678,7 +5696,7 @@ dependencies = [ "env_logger 0.7.1", "futures 0.1.29", "futures 0.3.4", - "futures-timer 0.4.0", + "futures-timer 3.0.1", "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.0", @@ -5718,7 +5736,7 @@ dependencies = [ "fork-tree", "futures 0.1.29", "futures 0.3.4", - "futures-timer 0.4.0", + "futures-timer 3.0.1", "log 0.4.8", "merlin", "num-bigint", @@ -5824,7 +5842,7 @@ name = "sc-consensus-slots" version = "0.8.0" dependencies = [ "futures 0.3.4", - "futures-timer 2.0.2", + "futures-timer 3.0.1", "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.0", @@ -5950,7 +5968,7 @@ dependencies = [ "fork-tree", "futures 0.1.29", "futures 0.3.4", - "futures-timer 2.0.2", + "futures-timer 3.0.1", "log 0.4.8", "parity-scale-codec", "parking_lot 0.10.0", @@ -5981,6 +5999,22 @@ dependencies = [ "tokio 0.1.22", ] +[[package]] +name = "sc-informant" +version = "0.8.0" +dependencies = [ + "ansi_term 0.12.1", + "futures 0.3.4", + "log 0.4.8", + "parity-util-mem", + "sc-client-api", + "sc-network", + "sc-service", + "sp-blockchain", + "sp-runtime", + "wasm-timer", +] + [[package]] name = "sc-keystore" version = "2.0.0" @@ -6009,7 +6043,7 @@ dependencies = [ "fnv", "fork-tree", "futures 0.3.4", - "futures-timer 0.4.0", + "futures-timer 3.0.1", "futures_codec", "libp2p", "linked-hash-map", @@ -6043,6 +6077,7 @@ dependencies = [ "tempfile", "unsigned-varint", "void", + "wasm-timer", "zeroize 1.1.0", ] @@ -6052,13 +6087,14 @@ version = "0.8.0" dependencies = [ "futures 0.1.29", "futures 0.3.4", - "futures-timer 0.4.0", + "futures-timer 3.0.1", "libp2p", "log 0.4.8", "lru 0.1.17", "parking_lot 0.10.0", "sc-network", "sp-runtime", + "wasm-timer", ] [[package]] @@ -6068,7 +6104,7 @@ dependencies = [ "env_logger 0.7.1", "futures 0.1.29", "futures 0.3.4", - "futures-timer 0.4.0", + "futures-timer 3.0.1", "libp2p", "log 0.4.8", "parking_lot 0.10.0", @@ -6097,7 +6133,7 @@ dependencies = [ "fnv", "futures 0.1.29", "futures 0.3.4", - "futures-timer 2.0.2", + "futures-timer 3.0.1", "hyper 0.12.35", "hyper-rustls", "log 0.4.8", @@ -6129,6 +6165,7 @@ dependencies = [ "log 0.4.8", "rand 0.7.3", "serde_json", + "wasm-timer", ] [[package]] @@ -6225,7 +6262,7 @@ dependencies = [ "futures 0.1.29", "futures 0.3.4", "futures-diagnose", - "futures-timer 2.0.2", + "futures-timer 3.0.1", "grafana-data-source", "lazy_static", "log 0.4.8", @@ -6267,6 +6304,7 @@ dependencies = [ "tokio 0.2.11", "tokio-executor 0.1.10", "tracing", + "wasm-timer", ] [[package]] @@ -6306,7 +6344,7 @@ version = "2.0.0" dependencies = [ "bytes 0.5.4", "futures 0.3.4", - "futures-timer 2.0.2", + "futures-timer 3.0.1", "libp2p", "log 0.4.8", "parking_lot 0.10.0", @@ -6318,6 +6356,7 @@ dependencies = [ "slog-scope", "take_mut", "void", + "wasm-timer", ] [[package]] @@ -6353,6 +6392,7 @@ dependencies = [ "sp-runtime", "sp-transaction-pool", "substrate-test-runtime", + "wasm-timer", ] [[package]] @@ -6376,6 +6416,7 @@ dependencies = [ "sp-transaction-pool", "substrate-test-runtime-client", "substrate-test-runtime-transaction-pool", + "wasm-timer", ] [[package]] @@ -6505,6 +6546,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "686ef91cf020ad8d4aca9a7047641fd6add626b7b89e14546c2b6a76781cf822" +[[package]] +name = "send_wrapper" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" + [[package]] name = "serde" version = "1.0.104" @@ -6854,7 +6901,7 @@ dependencies = [ "derive_more", "futures 0.3.4", "futures-diagnose", - "futures-timer 0.4.0", + "futures-timer 3.0.1", "libp2p", "log 0.4.8", "parity-scale-codec", @@ -7235,6 +7282,7 @@ dependencies = [ "sp-inherents", "sp-runtime", "sp-std", + "wasm-timer", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 47e3fe3f0e..0c620d251d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ members = [ "client/executor/wasmtime", "client/executor/runtime-test", "client/finality-grandpa", + "client/informant", "client/tracing", "client/keystore", "client/network", diff --git a/bin/node/cli/browser-demo/index.html b/bin/node/cli/browser-demo/index.html index 0b66b612f1..f40863c46e 100644 --- a/bin/node/cli/browser-demo/index.html +++ b/bin/node/cli/browser-demo/index.html @@ -15,11 +15,12 @@ function log(msg) { async function start() { log('Loading WASM'); await init('./pkg/node_cli_bg.wasm'); - log('Successfully loaded WASM'); + log('Fetching chain spec'); + const chain_spec_response = await fetch("https://raw.githubusercontent.com/paritytech/substrate/master/bin/node/cli/res/flaming-fir.json"); + const chain_spec_text = await chain_spec_response.text(); // Build our client. - log('Starting client'); - let client = await start_client(ws()); + let client = await start_client(chain_spec_text, 'info', ws()); log('Client started'); client.rpcSubscribe('{"method":"chain_subscribeNewHead","params":[],"id":1,"jsonrpc":"2.0"}', diff --git a/bin/node/cli/src/browser.rs b/bin/node/cli/src/browser.rs index e05238b82d..80ca963445 100644 --- a/bin/node/cli/src/browser.rs +++ b/bin/node/cli/src/browser.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::ChainSpec; +use crate::chain_spec::ChainSpec; use log::info; use wasm_bindgen::prelude::*; use sc_service::Configuration; @@ -22,20 +22,20 @@ use browser_utils::{ Transport, Client, browser_configuration, set_console_error_panic_hook, init_console_log, }; +use std::str::FromStr; /// Starts the client. #[wasm_bindgen] -pub async fn start_client(wasm_ext: Transport) -> Result { - start_inner(wasm_ext) +pub async fn start_client(chain_spec: String, log_level: String, wasm_ext: Transport) -> Result { + start_inner(chain_spec, log_level, wasm_ext) .await .map_err(|err| JsValue::from_str(&err.to_string())) } -async fn start_inner(wasm_ext: Transport) -> Result> { +async fn start_inner(chain_spec: String, log_level: String, wasm_ext: Transport) -> Result> { set_console_error_panic_hook(); - init_console_log(log::Level::Info)?; - - let chain_spec = ChainSpec::FlamingFir.load() + init_console_log(log::Level::from_str(&log_level)?)?; + let chain_spec = ChainSpec::from_json_bytes(chain_spec.as_bytes().to_vec()) .map_err(|e| format!("{:?}", e))?; let config: Configuration<_, _> = browser_configuration(wasm_ext, chain_spec) diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index 68144625b3..40b1b30173 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -14,7 +14,7 @@ bytes = "0.4.12" codec = { package = "parity-scale-codec", default-features = false, version = "1.0.3" } derive_more = "0.99.2" futures = "0.3.1" -futures-timer = "2.0" +futures-timer = "3.0.1" libp2p = { version = "0.15.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } log = "0.4.8" prost = "0.6.1" diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index e302d53d55..e176894d64 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -21,6 +21,7 @@ tokio = { version = "0.2.9", features = [ "signal", "rt-core", "rt-threaded" ] } futures = "0.3.1" fdlimit = "0.1.1" serde_json = "1.0.41" +sc-informant = { version = "0.8", path = "../informant" } 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" } diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index 5649232c37..a2e9fa96da 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -24,7 +24,6 @@ mod traits; mod params; mod execution_strategy; pub mod error; -pub mod informant; mod runtime; mod node_key; diff --git a/client/cli/src/runtime.rs b/client/cli/src/runtime.rs index 62a2245c9e..157b75f205 100644 --- a/client/cli/src/runtime.rs +++ b/client/cli/src/runtime.rs @@ -21,7 +21,6 @@ use futures::select; use futures::pin_mut; use sc_service::{AbstractService, Configuration}; use crate::error; -use crate::informant; #[cfg(target_family = "unix")] async fn main(func: F) -> Result<(), Box> @@ -124,7 +123,7 @@ where let service = service_builder(config)?; - let informant_future = informant::build(&service); + let informant_future = sc_informant::build(&service, sc_informant::OutputFormat::Coloured); let _informant_handle = runtime.spawn(informant_future); // we eagerly drop the service so that the internal exit future is fired, diff --git a/client/consensus/aura/Cargo.toml b/client/consensus/aura/Cargo.toml index 142b10b9da..e67f1e15a3 100644 --- a/client/consensus/aura/Cargo.toml +++ b/client/consensus/aura/Cargo.toml @@ -16,7 +16,7 @@ codec = { package = "parity-scale-codec", version = "1.0.0" } sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" } derive_more = "0.99.2" futures = "0.3.1" -futures-timer = "0.4.0" +futures-timer = "3.0.1" sp-inherents = { version = "2.0.0", path = "../../../primitives/inherents" } sc-keystore = { version = "2.0.0", path = "../../keystore" } log = "0.4.8" diff --git a/client/consensus/babe/Cargo.toml b/client/consensus/babe/Cargo.toml index 23bf9cea28..c36b5216c2 100644 --- a/client/consensus/babe/Cargo.toml +++ b/client/consensus/babe/Cargo.toml @@ -32,7 +32,7 @@ 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 = "0.3.1" -futures-timer = "0.4.0" +futures-timer = "3.0.1" parking_lot = "0.10.0" log = "0.4.8" schnorrkel = { version = "0.8.5", features = ["preaudit_deprecated"] } diff --git a/client/consensus/slots/Cargo.toml b/client/consensus/slots/Cargo.toml index d500a0fdc7..67de0a54ed 100644 --- a/client/consensus/slots/Cargo.toml +++ b/client/consensus/slots/Cargo.toml @@ -19,7 +19,7 @@ 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" +futures-timer = "3.0.1" parking_lot = "0.10.0" log = "0.4.8" diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index 1249bff751..e96792258a 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -8,7 +8,7 @@ license = "GPL-3.0" [dependencies] fork-tree = { version = "2.0.0", path = "../../utils/fork-tree" } futures = "0.3.1" -futures-timer = "2.0.2" +futures-timer = "3.0.1" log = "0.4.8" parking_lot = "0.10.0" rand = "0.7.2" diff --git a/client/finality-grandpa/src/communication/periodic.rs b/client/finality-grandpa/src/communication/periodic.rs index 4635899690..f2e79e8f14 100644 --- a/client/finality-grandpa/src/communication/periodic.rs +++ b/client/finality-grandpa/src/communication/periodic.rs @@ -19,7 +19,7 @@ use futures_timer::Delay; use futures::{channel::mpsc, future::{FutureExt as _}, prelude::*, ready, stream::Stream}; use log::debug; -use std::{pin::Pin, task::{Context, Poll}, time::{Instant, Duration}}; +use std::{pin::Pin, task::{Context, Poll}, time::Duration}; use sc_network::PeerId; use sp_runtime::traits::{NumberFor, Block as BlockT}; @@ -28,10 +28,6 @@ use super::gossip::{NeighborPacket, GossipMessage}; // How often to rebroadcast, in cases where no new packets are created. const REBROADCAST_AFTER: Duration = Duration::from_secs(2 * 60); -fn rebroadcast_instant() -> Instant { - Instant::now() + REBROADCAST_AFTER -} - /// A sender used to send neighbor packets to a background job. #[derive(Clone)] pub(super) struct NeighborPacketSender( @@ -85,7 +81,7 @@ impl Stream for NeighborPacketWorker { match this.rx.poll_next_unpin(cx) { Poll::Ready(None) => return Poll::Ready(None), Poll::Ready(Some((to, packet))) => { - this.delay.reset(rebroadcast_instant()); + this.delay.reset(REBROADCAST_AFTER); this.last = Some((to.clone(), packet.clone())); return Poll::Ready(Some((to, GossipMessage::::from(packet.clone())))); @@ -98,7 +94,7 @@ impl Stream for NeighborPacketWorker { // Getting this far here implies that the timer fired. - this.delay.reset(rebroadcast_instant()); + this.delay.reset(REBROADCAST_AFTER); // Make sure the underlying task is scheduled for wake-up. // diff --git a/client/informant/Cargo.toml b/client/informant/Cargo.toml new file mode 100644 index 0000000000..197f320889 --- /dev/null +++ b/client/informant/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "sc-informant" +version = "0.8.0" +authors = ["Parity Technologies "] +description = "Substrate informant." +edition = "2018" +license = "GPL-3.0" + +[dependencies] +ansi_term = "0.12.1" +futures = "0.3.1" +log = "0.4.8" +parity-util-mem = { version = "0.5.1", default-features = false, features = ["primitive-types"] } +wasm-timer = "0.2" +sc-client-api = { version = "2.0.0", path = "../api" } +sc-network = { version = "0.8", path = "../network" } +sc-service = { version = "0.8", default-features = false, path = "../service" } +sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" } +sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } diff --git a/client/cli/src/informant/display.rs b/client/informant/src/display.rs similarity index 76% rename from client/cli/src/informant/display.rs rename to client/informant/src/display.rs index 199635e7c7..53c9697868 100644 --- a/client/cli/src/informant/display.rs +++ b/client/informant/src/display.rs @@ -20,7 +20,9 @@ use log::info; 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}; +use std::{convert::{TryFrom, TryInto}, fmt}; +use wasm_timer::Instant; +use crate::OutputFormat; /// State of the informant display system. /// @@ -40,15 +42,18 @@ pub struct InformantDisplay { /// `None` if `display` has never been called. last_number: Option>, /// The last time `display` or `new` has been called. - last_update: time::Instant, + last_update: Instant, + /// The format to print output in. + format: OutputFormat, } impl InformantDisplay { /// Builds a new informant display system. - pub fn new() -> InformantDisplay { + pub fn new(format: OutputFormat) -> InformantDisplay { InformantDisplay { last_number: None, - last_update: time::Instant::now(), + last_update: Instant::now(), + format, } } @@ -56,8 +61,10 @@ impl InformantDisplay { pub fn display(&mut self, info: &ClientInfo, net_status: NetworkStatus) { let best_number = info.chain.best_number; let best_hash = info.chain.best_hash; + let finalized_number = info.chain.finalized_number; + let num_connected_peers = net_status.num_connected_peers; let speed = speed::(best_number, self.last_number, self.last_update); - self.last_update = time::Instant::now(); + self.last_update = Instant::now(); self.last_number = Some(best_number); let (status, target) = match (net_status.sync_state, net_status.best_seen_block) { @@ -66,19 +73,35 @@ impl InformantDisplay { (SyncState::Downloading, Some(n)) => (format!("Syncing{}", speed), format!(", target=#{}", n)), }; - info!( - target: "substrate", - "{}{} ({} peers), best: #{} ({}), finalized #{} ({}), ⬇ {} ⬆ {}", - Colour::White.bold().paint(&status), - target, - Colour::White.bold().paint(format!("{}", net_status.num_connected_peers)), - Colour::White.paint(format!("{}", best_number)), - best_hash, - Colour::White.paint(format!("{}", info.chain.finalized_number)), - info.chain.finalized_hash, - TransferRateFormat(net_status.average_download_per_sec), - TransferRateFormat(net_status.average_upload_per_sec), - ); + if self.format == OutputFormat::Coloured { + info!( + target: "substrate", + "{}{} ({} peers), best: #{} ({}), finalized #{} ({}), ⬇ {} ⬆ {}", + Colour::White.bold().paint(&status), + target, + Colour::White.bold().paint(format!("{}", num_connected_peers)), + Colour::White.paint(format!("{}", best_number)), + best_hash, + Colour::White.paint(format!("{}", finalized_number)), + info.chain.finalized_hash, + TransferRateFormat(net_status.average_download_per_sec), + TransferRateFormat(net_status.average_upload_per_sec), + ); + } else { + info!( + target: "substrate", + "{}{} ({} peers), best: #{} ({}), finalized #{} ({}), ⬇ {} ⬆ {}", + status, + target, + num_connected_peers, + best_number, + best_hash, + finalized_number, + info.chain.finalized_hash, + TransferRateFormat(net_status.average_download_per_sec), + TransferRateFormat(net_status.average_upload_per_sec), + ); + } } } @@ -87,7 +110,7 @@ impl InformantDisplay { fn speed( best_number: NumberFor, last_number: Option>, - last_update: time::Instant + last_update: Instant ) -> String { // Number of milliseconds elapsed since last time. let elapsed_ms = { diff --git a/client/cli/src/informant.rs b/client/informant/src/lib.rs similarity index 90% rename from client/cli/src/informant.rs rename to client/informant/src/lib.rs index 9e7c5044e0..699dcfdd74 100644 --- a/client/cli/src/informant.rs +++ b/client/informant/src/lib.rs @@ -25,12 +25,19 @@ use std::time::Duration; mod display; +/// The format to print telemetry output in. +#[derive(PartialEq)] +pub enum OutputFormat { + Coloured, + Plain, +} + /// Creates an informant in the form of a `Future` that must be polled regularly. -pub fn build(service: &impl AbstractService) -> impl futures::Future { +pub fn build(service: &impl AbstractService, format: OutputFormat) -> impl futures::Future { let client = service.client(); let pool = service.transaction_pool(); - let mut display = display::InformantDisplay::new(); + let mut display = display::InformantDisplay::new(format); let display_notifications = service .network_status(Duration::from_millis(5000)) @@ -41,6 +48,7 @@ pub fn build(service: &impl AbstractService) -> impl futures::Future { messages: Vec>, known_messages: LruCache, validators: HashMap>>, - next_broadcast: time::Instant, + next_broadcast: Instant, } impl ConsensusGossip { @@ -177,7 +178,7 @@ impl ConsensusGossip { messages: Default::default(), known_messages: LruCache::new(KNOWN_MESSAGES_CACHE_SIZE), validators: Default::default(), - next_broadcast: time::Instant::now() + REBROADCAST_INTERVAL, + next_broadcast: Instant::now() + REBROADCAST_INTERVAL, } } @@ -260,9 +261,9 @@ impl ConsensusGossip { /// Perform periodic maintenance pub fn tick(&mut self, network: &mut dyn Network) { self.collect_garbage(); - if time::Instant::now() >= self.next_broadcast { + if Instant::now() >= self.next_broadcast { self.rebroadcast(network); - self.next_broadcast = time::Instant::now() + REBROADCAST_INTERVAL; + self.next_broadcast = Instant::now() + REBROADCAST_INTERVAL; } } diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index e506a61c75..10d5f1ce9b 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -17,7 +17,8 @@ fnv = "1.0.6" fork-tree = { version = "2.0.0", path = "../../utils/fork-tree" } futures = "0.3.1" futures_codec = "0.3.3" -futures-timer = "0.4.0" +futures-timer = "3.0.1" +wasm-timer = "0.2" libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] } linked-hash-map = "0.5.2" linked_hash_set = "0.1.3" diff --git a/client/network/src/debug_info.rs b/client/network/src/debug_info.rs index b06e275d1d..a3d63333fa 100644 --- a/client/network/src/debug_info.rs +++ b/client/network/src/debug_info.rs @@ -28,7 +28,8 @@ use std::error; use std::collections::hash_map::Entry; use std::pin::Pin; use std::task::{Context, Poll}; -use std::time::{Duration, Instant}; +use std::time::Duration; +use wasm_timer::Instant; use crate::utils::interval; /// Time after we disconnect from a node before we purge its information from the cache. diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 5e8df2831b..99b0117882 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -52,6 +52,7 @@ use crate::chain::{Client, FinalityProofProvider}; use sc_client_api::{FetchChecker, ChangesProof, StorageProof}; use crate::error; use util::LruHashSet; +use wasm_timer::Instant; mod legacy_proto; mod util; @@ -158,7 +159,7 @@ struct PacketStats { /// A peer that we are connected to /// and from whom we have not yet received a Status message. struct HandshakingPeer { - timestamp: time::Instant, + timestamp: Instant, } /// Peer information @@ -166,9 +167,9 @@ struct HandshakingPeer { struct Peer { info: PeerInfo, /// Current block request, if any. - block_request: Option<(time::Instant, message::BlockRequest)>, + block_request: Option<(Instant, message::BlockRequest)>, /// Requests we are no longer insterested in. - obsolete_requests: HashMap, + obsolete_requests: HashMap, /// Holds a set of transactions known to this peer. known_extrinsics: LruHashSet, /// Holds a set of blocks known to this peer. @@ -701,7 +702,7 @@ impl, H: ExHashT> Protocol { /// Called when a new peer is connected pub fn on_peer_connected(&mut self, who: PeerId) { trace!(target: "sync", "Connecting {}", who); - self.handshaking_peers.insert(who.clone(), HandshakingPeer { timestamp: time::Instant::now() }); + self.handshaking_peers.insert(who.clone(), HandshakingPeer { timestamp: Instant::now() }); self.send_status(who); } @@ -890,7 +891,7 @@ impl, H: ExHashT> Protocol { } fn maintain_peers(&mut self) { - let tick = time::Instant::now(); + let tick = Instant::now(); let mut aborting = Vec::new(); { for (who, peer) in self.context_data.peers.iter() { @@ -1833,7 +1834,7 @@ fn send_request( trace!(target: "sync", "Request {} for {} is now obsolete.", request.id, who); peer.obsolete_requests.insert(request.id, timestamp); } - peer.block_request = Some((time::Instant::now(), r.clone())); + peer.block_request = Some((Instant::now(), r.clone())); } } send_message::(behaviour, stats, who, message) diff --git a/client/network/src/protocol/legacy_proto/behaviour.rs b/client/network/src/protocol/legacy_proto/behaviour.rs index b4047f320a..1eb6b157dd 100644 --- a/client/network/src/protocol/legacy_proto/behaviour.rs +++ b/client/network/src/protocol/legacy_proto/behaviour.rs @@ -26,7 +26,8 @@ use log::{debug, error, trace, warn}; use rand::distributions::{Distribution as _, Uniform}; use smallvec::SmallVec; use std::{borrow::Cow, collections::hash_map::Entry, cmp, error, marker::PhantomData, mem, pin::Pin}; -use std::time::{Duration, Instant}; +use std::time::Duration; +use wasm_timer::Instant; use std::task::{Context, Poll}; /// Network behaviour that handles opening substreams for custom protocols with other nodes. @@ -387,7 +388,7 @@ impl LegacyProto { debug!(target: "sub-libp2p", "PSM => Connect({:?}): Will start to connect at \ until {:?}", occ_entry.key(), until); *occ_entry.into_mut() = PeerState::PendingRequest { - timer: futures_timer::Delay::new_at(until.clone()), + timer: futures_timer::Delay::new(until.clone() - Instant::now()), timer_deadline: until.clone(), }; }, @@ -406,7 +407,7 @@ impl LegacyProto { *occ_entry.into_mut() = PeerState::DisabledPendingEnable { connected_point: connected_point.clone(), open, - timer: futures_timer::Delay::new_at(banned.clone()), + timer: futures_timer::Delay::new(banned.clone() - Instant::now()), timer_deadline: banned.clone(), }; }, diff --git a/client/network/src/protocol/legacy_proto/handler.rs b/client/network/src/protocol/legacy_proto/handler.rs index fc3b64b968..66fb0dca13 100644 --- a/client/network/src/protocol/legacy_proto/handler.rs +++ b/client/network/src/protocol/legacy_proto/handler.rs @@ -348,13 +348,12 @@ where ProtocolState::Init { substreams, mut init_deadline } => { match Pin::new(&mut init_deadline).poll(cx) { - Poll::Ready(Ok(())) => { + Poll::Ready(()) => { init_deadline = Delay::new(Duration::from_secs(60)); error!(target: "sub-libp2p", "Handler initialization process is too long \ with {:?}", self.remote_peer_id) }, Poll::Pending => {} - Poll::Ready(Err(_)) => error!(target: "sub-libp2p", "Tokio timer has errored") } self.state = ProtocolState::Init { substreams, init_deadline }; @@ -363,7 +362,7 @@ where ProtocolState::Opening { mut deadline } => { match Pin::new(&mut deadline).poll(cx) { - Poll::Ready(Ok(())) => { + Poll::Ready(()) => { deadline = Delay::new(Duration::from_secs(60)); let event = CustomProtoHandlerOut::ProtocolError { is_severe: true, @@ -376,12 +375,6 @@ where self.state = ProtocolState::Opening { deadline }; None }, - Poll::Ready(Err(_)) => { - error!(target: "sub-libp2p", "Tokio timer has errored"); - deadline = Delay::new(Duration::from_secs(60)); - self.state = ProtocolState::Opening { deadline }; - None - }, } } diff --git a/client/network/src/protocol/legacy_proto/tests.rs b/client/network/src/protocol/legacy_proto/tests.rs index 18e32f1d01..4f523fa31d 100644 --- a/client/network/src/protocol/legacy_proto/tests.rs +++ b/client/network/src/protocol/legacy_proto/tests.rs @@ -409,7 +409,7 @@ fn reconnect_after_disconnect() { _ => panic!() } - if let Poll::Ready(Ok(_)) = delay.poll_unpin(cx) { + if let Poll::Ready(()) = delay.poll_unpin(cx) { Poll::Ready(Ok(())) } else { Poll::Pending diff --git a/client/network/src/protocol/light_dispatch.rs b/client/network/src/protocol/light_dispatch.rs index bfa8daa181..5b587d2045 100644 --- a/client/network/src/protocol/light_dispatch.rs +++ b/client/network/src/protocol/light_dispatch.rs @@ -21,7 +21,8 @@ use std::collections::{HashMap, VecDeque}; use std::sync::Arc; -use std::time::{Instant, Duration}; +use std::time::Duration; +use wasm_timer::Instant; use log::{trace, info}; use futures::channel::oneshot::{Sender as OneShotSender}; use linked_hash_map::{Entry, LinkedHashMap}; diff --git a/client/network/src/protocol/sync/extra_requests.rs b/client/network/src/protocol/sync/extra_requests.rs index 44b42b154f..a5fb232b8d 100644 --- a/client/network/src/protocol/sync/extra_requests.rs +++ b/client/network/src/protocol/sync/extra_requests.rs @@ -21,7 +21,8 @@ use libp2p::PeerId; use log::{debug, trace, warn}; use sp_runtime::traits::{Block as BlockT, NumberFor, Zero}; use std::collections::{HashMap, HashSet, VecDeque}; -use std::time::{Duration, Instant}; +use std::time::Duration; +use wasm_timer::Instant; // Time to wait before trying to get the same extra data from the same peer. const EXTRA_RETRY_WAIT: Duration = Duration::from_secs(10); diff --git a/client/network/src/transport.rs b/client/network/src/transport.rs index b11b187051..6b5c18cf33 100644 --- a/client/network/src/transport.rs +++ b/client/network/src/transport.rs @@ -118,11 +118,18 @@ pub fn build_transport( core::upgrade::apply(stream, upgrade, endpoint, upgrade::Version::V1) .map_ok(|(id, muxer)| (id, core::muxing::StreamMuxerBox::new(muxer))) - }) + }); - .timeout(Duration::from_secs(20)) - .map_err(|err| io::Error::new(io::ErrorKind::Other, err)) - .boxed(); + let transport = if cfg!(not(target_os = "unknown")) { + transport + .timeout(Duration::from_secs(20)) + .map_err(|err| io::Error::new(io::ErrorKind::Other, err)) + .boxed() + } else { + transport + .map_err(|err| io::Error::new(io::ErrorKind::Other, err)) + .boxed() + }; (transport, sinks) } diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index 3f1d1d5867..ca4b0237cf 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -12,7 +12,7 @@ log = "0.4.8" parking_lot = "0.10.0" futures = "0.1.29" futures03 = { package = "futures", version = "0.3.1", features = ["compat"] } -futures-timer = "0.4.0" +futures-timer = "3.0.1" rand = "0.7.2" libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] } sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" } diff --git a/client/network/test/src/sync.rs b/client/network/test/src/sync.rs index 2140de0973..210a4fb38b 100644 --- a/client/network/test/src/sync.rs +++ b/client/network/test/src/sync.rs @@ -405,7 +405,7 @@ fn blocks_are_not_announced_by_light_nodes() { net.peers.remove(0); // Poll for a few seconds and make sure 1 and 2 (now 0 and 1) don't sync together. - let mut delay = futures_timer::Delay::new(Duration::from_secs(5)).compat(); + let mut delay = futures_timer::Delay::new(Duration::from_secs(5)).unit_error().compat(); runtime.block_on(futures::future::poll_fn::<(), (), _>(|| { net.poll(); delay.poll().map_err(|_| ()) @@ -504,7 +504,7 @@ fn can_not_sync_from_light_peer() { net.peers.remove(0); // ensure that the #2 (now #1) fails to sync block #1 even after 5 seconds - let mut test_finished = futures_timer::Delay::new(Duration::from_secs(5)).compat(); + let mut test_finished = futures_timer::Delay::new(Duration::from_secs(5)).unit_error().compat(); runtime.block_on(futures::future::poll_fn::<(), (), _>(|| -> Result<_, ()> { net.poll(); test_finished.poll().map_err(|_| ()) diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index bdbf3fa199..ed5db3f2c7 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -13,7 +13,7 @@ sp-api = { version = "2.0.0", path = "../../primitives/api" } fnv = "1.0.6" futures01 = { package = "futures", version = "0.1" } futures = "0.3.1" -futures-timer = "2.0" +futures-timer = "3.0.1" log = "0.4.8" threadpool = "1.7" num_cpus = "1.10" diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index 85c988d048..2527b86795 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -12,6 +12,7 @@ futures = "0.3.1" libp2p = { version = "0.15.0", default-features = false } log = "0.4.8" serde_json = "1.0.41" +wasm-timer = "0.2" [dev-dependencies] rand = "0.7.2" diff --git a/client/peerset/src/lib.rs b/client/peerset/src/lib.rs index c958912727..7c7bbc6b36 100644 --- a/client/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -19,12 +19,13 @@ mod peersstate; -use std::{collections::{HashSet, HashMap}, collections::VecDeque, time::Instant}; +use std::{collections::{HashSet, HashMap}, collections::VecDeque}; use futures::{prelude::*, channel::mpsc}; use libp2p::PeerId; use log::{debug, error, trace}; use serde_json::json; use std::{pin::Pin, task::Context, task::Poll}; +use wasm_timer::Instant; /// We don't accept nodes whose reputation is under this value. const BANNED_THRESHOLD: i32 = 82 * (i32::min_value() / 100); diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index bc246db03e..7f7ef80b16 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -24,7 +24,8 @@ lazy_static = "1.4.0" log = "0.4.8" slog = { version = "2.5.2", features = ["nested-values"] } tokio-executor = "0.1.8" -futures-timer = "2" +futures-timer = "3.0.1" +wasm-timer = "0.2" exit-future = "0.2.0" serde = "1.0.101" serde_json = "1.0.41" diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 71749ac308..4d672006b8 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.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::{Service, NetworkStatus, NetworkState, error::Error, DEFAULT_PROTOCOL_ID}; +use crate::{Service, NetworkStatus, NetworkState, error::Error, DEFAULT_PROTOCOL_ID, MallocSizeOfWasm}; use crate::{SpawnTaskHandle, start_rpc_servers, build_network_future, TransactionPoolAdapter}; use crate::status_sinks; use crate::config::{Configuration, DatabaseConfig, KeystoreConfig}; @@ -46,8 +46,9 @@ use sc_executor::{NativeExecutor, NativeExecutionDispatch}; use std::{ borrow::Cow, io::{Read, Write, Seek}, - marker::PhantomData, sync::Arc, time::SystemTime, pin::Pin + marker::PhantomData, sync::Arc, pin::Pin }; +use wasm_timer::SystemTime; use sysinfo::{get_current_pid, ProcessExt, System, SystemExt}; use sc_telemetry::{telemetry, SUBSTRATE_INFO}; use sp_transaction_pool::MaintainedTransactionPool; @@ -738,7 +739,7 @@ ServiceBuilder< TSc: Clone, TImpQu: 'static + ImportQueue, TNetP: NetworkSpecialization, - TExPool: MaintainedTransactionPool::Hash> + 'static, + TExPool: MaintainedTransactionPool::Hash> + MallocSizeOfWasm + 'static, TRpc: sc_rpc::RpcExtension + Clone, { @@ -984,6 +985,10 @@ ServiceBuilder< "disk_read_per_sec" => info.usage.as_ref().map(|usage| usage.io.bytes_read).unwrap_or(0), "disk_write_per_sec" => info.usage.as_ref().map(|usage| usage.io.bytes_written).unwrap_or(0), ); + #[cfg(not(target_os = "unknown"))] + let memory_transaction_pool = parity_util_mem::malloc_size(&*transaction_pool_); + #[cfg(target_os = "unknown")] + let memory_transaction_pool = 0; let _ = record_metrics!( "peers" => num_peers, "height" => best_number, @@ -997,7 +1002,7 @@ ServiceBuilder< "used_db_cache_size" => info.usage.as_ref().map(|usage| usage.memory.database_cache).unwrap_or(0), "disk_read_per_sec" => info.usage.as_ref().map(|usage| usage.io.bytes_read).unwrap_or(0), "disk_write_per_sec" => info.usage.as_ref().map(|usage| usage.io.bytes_written).unwrap_or(0), - "memory_transaction_pool" => parity_util_mem::malloc_size(&*transaction_pool_), + "memory_transaction_pool" => memory_transaction_pool, ); ready(()) diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 920cdc5c4c..8c2f57dd7c 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -31,7 +31,8 @@ use std::{borrow::Cow, io, pin::Pin}; use std::marker::PhantomData; use std::net::SocketAddr; use std::collections::HashMap; -use std::time::{Duration, Instant}; +use std::time::Duration; +use wasm_timer::Instant; use std::task::{Poll, Context}; use parking_lot::Mutex; @@ -52,6 +53,7 @@ use log::{log, warn, debug, error, Level}; use codec::{Encode, Decode}; use sp_runtime::generic::BlockId; use sp_runtime::traits::{NumberFor, Block as BlockT}; +use parity_util_mem::MallocSizeOf; pub use self::error::Error; pub use self::builder::{ @@ -73,6 +75,16 @@ pub use sc_network::{FinalityProofProvider, OnDemand, config::BoxFinalityProofRe const DEFAULT_PROTOCOL_ID: &str = "sup"; +/// A type that implements `MallocSizeOf` on native but not wasm. +#[cfg(not(target_os = "unknown"))] +pub trait MallocSizeOfWasm: MallocSizeOf {} +#[cfg(target_os = "unknown")] +pub trait MallocSizeOfWasm {} +#[cfg(not(target_os = "unknown"))] +impl MallocSizeOfWasm for T {} +#[cfg(target_os = "unknown")] +impl MallocSizeOfWasm for T {} + /// Substrate service. pub struct Service { client: Arc, @@ -163,7 +175,7 @@ pub trait AbstractService: 'static + Future> + /// Chain selection algorithm. type SelectChain: sp_consensus::SelectChain; /// Transaction pool. - type TransactionPool: TransactionPool; + type TransactionPool: TransactionPool + MallocSizeOfWasm; /// Network specialization. type NetworkSpecialization: NetworkSpecialization; @@ -227,7 +239,7 @@ where TExec: 'static + sc_client::CallExecutor + Send + Sync + Clone, TRtApi: 'static + Send + Sync, TSc: sp_consensus::SelectChain + 'static + Clone + Send + Unpin, - TExPool: 'static + TransactionPool, + TExPool: 'static + TransactionPool + MallocSizeOfWasm, TOc: 'static + Send + Sync, TNetSpec: NetworkSpecialization, { diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index 44e332b9d7..f75c6dd44e 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -10,7 +10,8 @@ license = "GPL-3.0" bytes = "0.5" parking_lot = "0.10.0" futures = "0.3.1" -futures-timer = "2.0.0" +futures-timer = "3.0.1" +wasm-timer = "0.2.0" libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] } log = "0.4.8" pin-project = "0.4.6" diff --git a/client/telemetry/src/lib.rs b/client/telemetry/src/lib.rs index 906df545e2..1c6f1425d6 100644 --- a/client/telemetry/src/lib.rs +++ b/client/telemetry/src/lib.rs @@ -63,7 +63,8 @@ use libp2p::{Multiaddr, wasm_ext}; use log::{error, warn}; use parking_lot::Mutex; use serde::{Serialize, Deserialize}; -use std::{pin::Pin, sync::Arc, task::{Context, Poll}, time::{Duration, Instant}}; +use std::{pin::Pin, sync::Arc, task::{Context, Poll}, time::Duration}; +use wasm_timer::Instant; pub use libp2p::wasm_ext::ExtTransport; pub use slog_scope::with_logger; diff --git a/client/telemetry/src/worker.rs b/client/telemetry/src/worker.rs index 8f43bb612a..ef1f9fa067 100644 --- a/client/telemetry/src/worker.rs +++ b/client/telemetry/src/worker.rs @@ -98,10 +98,10 @@ impl TelemetryWorker { .map_ok(|data| BytesMut::from(data.as_ref())); future::ready(Ok::<_, io::Error>(connec)) }) - }); + }) + .timeout(CONNECT_TIMEOUT); let transport = transport - .timeout(CONNECT_TIMEOUT) .map_err(|err| io::Error::new(io::ErrorKind::Other, err)) .map(|out, _| { let out = out diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index 524e9a98a0..27aec1b92e 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -12,6 +12,7 @@ futures = { version = "0.3.1", features = ["compat"] } futures-diagnose = "1.0" log = "0.4.8" parking_lot = "0.10.0" +wasm-timer = "0.2" 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" } diff --git a/client/transaction-pool/graph/Cargo.toml b/client/transaction-pool/graph/Cargo.toml index 2d3172fc91..3bbe46bc50 100644 --- a/client/transaction-pool/graph/Cargo.toml +++ b/client/transaction-pool/graph/Cargo.toml @@ -11,6 +11,7 @@ futures = "0.3.1" log = "0.4.8" parking_lot = "0.10.0" serde = { version = "1.0.101", features = ["derive"] } +wasm-timer = "0.2" 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" } diff --git a/client/transaction-pool/graph/src/base_pool.rs b/client/transaction-pool/graph/src/base_pool.rs index 52e00df363..8a33d8244e 100644 --- a/client/transaction-pool/graph/src/base_pool.rs +++ b/client/transaction-pool/graph/src/base_pool.rs @@ -209,7 +209,8 @@ const RECENTLY_PRUNED_TAGS: usize = 2; /// as-is for the second time will fail or produce unwanted results. /// Most likely it is required to revalidate them and recompute set of /// required tags. -#[derive(Debug, parity_util_mem::MallocSizeOf)] +#[derive(Debug)] +#[cfg_attr(not(target_os = "unknown"), derive(parity_util_mem::MallocSizeOf))] pub struct BasePool { reject_future_transactions: bool, future: FutureTransactions, diff --git a/client/transaction-pool/graph/src/future.rs b/client/transaction-pool/graph/src/future.rs index bda26fe34f..a84a5fbe68 100644 --- a/client/transaction-pool/graph/src/future.rs +++ b/client/transaction-pool/graph/src/future.rs @@ -19,17 +19,17 @@ use std::{ fmt, hash, sync::Arc, - time, }; use sp_core::hexdisplay::HexDisplay; use sp_runtime::transaction_validity::{ TransactionTag as Tag, }; +use wasm_timer::Instant; use crate::base_pool::Transaction; -#[derive(parity_util_mem::MallocSizeOf)] +#[cfg_attr(not(target_os = "unknown"), derive(parity_util_mem::MallocSizeOf))] /// Transaction with partially satisfied dependencies. pub struct WaitingTransaction { /// Transaction details. @@ -37,7 +37,7 @@ pub struct WaitingTransaction { /// Tags that are required and have not been satisfied yet by other transactions in the pool. pub missing_tags: HashSet, /// Time of import to the Future Queue. - pub imported_at: time::Instant, + pub imported_at: Instant, } impl fmt::Debug for WaitingTransaction { @@ -91,7 +91,7 @@ impl WaitingTransaction { WaitingTransaction { transaction: Arc::new(transaction), missing_tags, - imported_at: time::Instant::now(), + imported_at: Instant::now(), } } @@ -110,7 +110,8 @@ impl WaitingTransaction { /// /// Contains transactions that are still awaiting for some other transactions that /// could provide a tag that they require. -#[derive(Debug, parity_util_mem::MallocSizeOf)] +#[derive(Debug)] +#[cfg_attr(not(target_os = "unknown"), derive(parity_util_mem::MallocSizeOf))] pub struct FutureTransactions { /// tags that are not yet provided by any transaction and we await for them wanted_tags: HashMap>, diff --git a/client/transaction-pool/graph/src/pool.rs b/client/transaction-pool/graph/src/pool.rs index ab4e3a5a79..edcd211df9 100644 --- a/client/transaction-pool/graph/src/pool.rs +++ b/client/transaction-pool/graph/src/pool.rs @@ -34,6 +34,7 @@ use sp_runtime::{ transaction_validity::{TransactionValidity, TransactionTag as Tag, TransactionValidityError}, }; use sp_transaction_pool::{error, PoolStatus}; +use wasm_timer::Instant; use crate::validated_pool::{ValidatedPool, ValidatedTransaction}; @@ -122,6 +123,7 @@ pub struct Pool { validated_pool: Arc>, } +#[cfg(not(target_os = "unknown"))] impl parity_util_mem::MallocSizeOf for Pool where B::Hash: parity_util_mem::MallocSizeOf, @@ -189,7 +191,6 @@ impl Pool { at: &BlockId, max: Option, ) -> Result<(), B::Error> { - use std::time::Instant; log::debug!(target: "txpool", "Fetching ready transactions (up to: {})", max.map(|x| format!("{}", x)).unwrap_or_else(|| "all".into()) @@ -317,7 +318,7 @@ impl Pool { // Make sure that we don't revalidate extrinsics that were part of the recently // imported block. This is especially important for UTXO-like chains cause the // inputs are pruned so such transaction would go to future again. - self.validated_pool.ban(&std::time::Instant::now(), known_imported_hashes.clone().into_iter()); + self.validated_pool.ban(&Instant::now(), known_imported_hashes.clone().into_iter()); // Try to re-validate pruned transactions since some of them might be still valid. // note that `known_imported_hashes` will be rejected here due to temporary ban. @@ -469,10 +470,7 @@ impl Clone for Pool { #[cfg(test)] mod tests { - use std::{ - collections::{HashMap, HashSet}, - time::Instant, - }; + use std::collections::{HashMap, HashSet}; use parking_lot::Mutex; use futures::executor::block_on; use super::*; @@ -481,6 +479,7 @@ mod tests { use codec::Encode; use substrate_test_runtime::{Block, Extrinsic, Transfer, H256, AccountId}; use assert_matches::assert_matches; + use wasm_timer::Instant; use crate::base_pool::Limit; const INVALID_NONCE: u64 = 254; diff --git a/client/transaction-pool/graph/src/rotator.rs b/client/transaction-pool/graph/src/rotator.rs index e1c852f95a..55a9230522 100644 --- a/client/transaction-pool/graph/src/rotator.rs +++ b/client/transaction-pool/graph/src/rotator.rs @@ -23,9 +23,10 @@ use std::{ collections::HashMap, hash, iter, - time::{Duration, Instant}, + time::Duration, }; use parking_lot::RwLock; +use wasm_timer::Instant; use crate::base_pool::Transaction; diff --git a/client/transaction-pool/graph/src/validated_pool.rs b/client/transaction-pool/graph/src/validated_pool.rs index 9524284064..d02bc0ec72 100644 --- a/client/transaction-pool/graph/src/validated_pool.rs +++ b/client/transaction-pool/graph/src/validated_pool.rs @@ -19,7 +19,6 @@ use std::{ fmt, hash, sync::Arc, - time, }; use crate::base_pool as base; @@ -37,6 +36,7 @@ use sp_runtime::{ transaction_validity::TransactionTag as Tag, }; use sp_transaction_pool::{error, PoolStatus}; +use wasm_timer::Instant; use crate::base_pool::PruneStatus; use crate::pool::{EventStream, Options, ChainApi, BlockHash, ExHash, ExtrinsicFor, TransactionFor}; @@ -74,6 +74,7 @@ pub(crate) struct ValidatedPool { rotator: PoolRotator>, } +#[cfg(not(target_os = "unknown"))] impl parity_util_mem::MallocSizeOf for ValidatedPool where B::Hash: parity_util_mem::MallocSizeOf, @@ -100,7 +101,7 @@ impl ValidatedPool { } /// Bans given set of hashes. - pub fn ban(&self, now: &std::time::Instant, hashes: impl IntoIterator>) { + pub fn ban(&self, now: &Instant, hashes: impl IntoIterator>) { self.rotator.ban(now, hashes) } @@ -145,7 +146,7 @@ impl ValidatedPool { Ok(imported.hash().clone()) } ValidatedTransaction::Invalid(hash, err) => { - self.rotator.ban(&std::time::Instant::now(), std::iter::once(hash)); + self.rotator.ban(&Instant::now(), std::iter::once(hash)); Err(err.into()) }, ValidatedTransaction::Unknown(hash, err) => { @@ -177,7 +178,7 @@ impl ValidatedPool { let removed = pool.enforce_limits(ready_limit, future_limit) .into_iter().map(|x| x.hash.clone()).collect::>(); // ban all removed transactions - self.rotator.ban(&std::time::Instant::now(), removed.iter().map(|x| x.clone())); + self.rotator.ban(&Instant::now(), removed.iter().map(|x| x.clone())); removed }; // run notifications @@ -208,7 +209,7 @@ impl ValidatedPool { .map(|_| watcher) }, ValidatedTransaction::Invalid(hash, err) => { - self.rotator.ban(&std::time::Instant::now(), std::iter::once(hash)); + self.rotator.ban(&Instant::now(), std::iter::once(hash)); Err(err.into()) }, ValidatedTransaction::Unknown(_, err) => Err(err.into()), @@ -430,7 +431,7 @@ impl ValidatedPool { let block_number = self.api.block_id_to_number(at)? .ok_or_else(|| error::Error::InvalidBlockId(format!("{:?}", at)).into())? .saturated_into::(); - let now = time::Instant::now(); + let now = Instant::now(); let to_remove = { self.ready() .filter(|tx| self.rotator.ban_if_stale(&now, block_number, &tx)) @@ -497,7 +498,7 @@ impl ValidatedPool { debug!(target: "txpool", "Removing invalid transactions: {:?}", hashes); // temporarily ban invalid transactions - self.rotator.ban(&time::Instant::now(), hashes.iter().cloned()); + self.rotator.ban(&Instant::now(), hashes.iter().cloned()); let invalid = self.pool.write().remove_subtree(hashes); diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index 7084e1c4a0..139efcd59e 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -28,7 +28,7 @@ pub mod testing; pub use sc_transaction_graph as txpool; pub use crate::api::{FullChainApi, LightChainApi}; -use std::{collections::HashMap, sync::Arc, pin::Pin, time::Instant}; +use std::{collections::HashMap, sync::Arc, pin::Pin}; use futures::{Future, FutureExt, future::ready}; use parking_lot::Mutex; @@ -41,6 +41,7 @@ use sp_transaction_pool::{ TxHash, TransactionFor, TransactionStatusStreamFor, BlockHash, MaintainedTransactionPool, PoolFuture, }; +use wasm_timer::Instant; /// Basic implementation of transaction pool that can be customized by providing PoolApi. pub struct BasicPool @@ -53,6 +54,7 @@ pub struct BasicPool revalidation_strategy: Arc>>>, } +#[cfg(not(target_os = "unknown"))] impl parity_util_mem::MallocSizeOf for BasicPool where PoolApi: sc_transaction_graph::ChainApi, @@ -205,7 +207,7 @@ enum RevalidationStatus { /// The revalidation has never been completed. NotScheduled, /// The revalidation is scheduled. - Scheduled(Option, Option), + Scheduled(Option, Option), /// The revalidation is in progress. InProgress, } diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index 1b5c54b7e9..2abc6f5617 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -14,7 +14,7 @@ sp-core = { path= "../../core" } sp-inherents = { version = "2.0.0", path = "../../inherents" } sp-state-machine = { version = "0.8.0", path = "../../../primitives/state-machine" } futures = { version = "0.3.1", features = ["thread-pool"] } -futures-timer = "0.4.0" +futures-timer = "3.0.1" futures-diagnose = "1.0" sp-std = { version = "2.0.0", path = "../../std" } sp-version = { version = "2.0.0", path = "../../version" } diff --git a/primitives/timestamp/Cargo.toml b/primitives/timestamp/Cargo.toml index fa146ebd6f..815aaf5305 100644 --- a/primitives/timestamp/Cargo.toml +++ b/primitives/timestamp/Cargo.toml @@ -12,6 +12,7 @@ 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"] } sp-inherents = { version = "2.0.0", default-features = false, path = "../inherents" } impl-trait-for-tuples = "0.1.3" +wasm-timer = "0.2" [features] default = [ "std" ] diff --git a/primitives/timestamp/src/lib.rs b/primitives/timestamp/src/lib.rs index 50b871d73e..979b98b495 100644 --- a/primitives/timestamp/src/lib.rs +++ b/primitives/timestamp/src/lib.rs @@ -90,7 +90,7 @@ impl ProvideInherentData for InherentDataProvider { &self, inherent_data: &mut InherentData, ) -> Result<(), sp_inherents::Error> { - use std::time::SystemTime; + use wasm_timer::SystemTime; let now = SystemTime::now(); now.duration_since(SystemTime::UNIX_EPOCH) diff --git a/primitives/transaction-pool/src/pool.rs b/primitives/transaction-pool/src/pool.rs index 0b23c27f82..d4e6a5caf2 100644 --- a/primitives/transaction-pool/src/pool.rs +++ b/primitives/transaction-pool/src/pool.rs @@ -29,7 +29,7 @@ use futures::{ use serde::{Deserialize, Serialize}; use sp_runtime::{ generic::BlockId, - traits::{Block as BlockT, Member, MaybeMallocSizeOf}, + traits::{Block as BlockT, Member}, transaction_validity::{ TransactionLongevity, TransactionPriority, TransactionTag, }, @@ -154,7 +154,7 @@ pub trait InPoolTransaction { } /// Transaction pool interface. -pub trait TransactionPool: Send + Sync + MaybeMallocSizeOf { +pub trait TransactionPool: Send + Sync { /// Block type. type Block: BlockT; /// Transaction hash type. @@ -263,4 +263,4 @@ impl OffchainSubmitTransaction for TPool { e )) } -} \ No newline at end of file +} diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index 3afa49fc25..e52f630cb5 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -17,12 +17,15 @@ js-sys = "0.3.34" wasm-bindgen = "0.2.57" wasm-bindgen-futures = "0.4.7" kvdb-web = "0.4" -service = { version = "0.8", package = "sc-service", path = "../../client/service", default-features = false } -network = { package = "sc-network", path = "../../client/network" } -chain-spec = { package = "sc-chain-spec", path = "../../client/chain-spec" } +sc-informant = { version = "0.8", path = "../../client/informant" } +sc-service = { version = "0.8", path = "../../client/service", default-features = false } +sc-network = { path = "../../client/network" } +sc-chain-spec = { path = "../../client/chain-spec" } # Imported just for the `no_cc` feature clear_on_drop = { version = "0.2.3", features = ["no_cc"] } # Imported just for the `wasm-bindgen` feature rand6 = { package = "rand", version = "0.6", features = ["wasm-bindgen"] } rand = { version = "0.7", features = ["wasm-bindgen"] } +futures-timer = { version = "3.0.1", features = ["wasm-bindgen"]} +chrono = { version = "0.4", features = ["wasmbind"] } diff --git a/utils/browser/src/lib.rs b/utils/browser/src/lib.rs index d7ffdca1aa..b054d73ac9 100644 --- a/utils/browser/src/lib.rs +++ b/utils/browser/src/lib.rs @@ -17,7 +17,7 @@ use futures01::sync::mpsc as mpsc01; use log::{debug, info}; use std::sync::Arc; -use service::{ +use sc_service::{ AbstractService, RpcSession, Roles, Configuration, config::{DatabaseConfig, KeystoreConfig}, ChainSpec, RuntimeGenesis }; @@ -25,7 +25,7 @@ use wasm_bindgen::prelude::*; use futures::{prelude::*, channel::{oneshot, mpsc}, future::{poll_fn, ok}, compat::*}; use std::task::Poll; use std::pin::Pin; -use chain_spec::Extension; +use sc_chain_spec::Extension; pub use libp2p::wasm_ext::{ExtTransport, ffi::Transport}; pub use console_error_panic_hook::set_once as set_console_error_panic_hook; @@ -46,7 +46,10 @@ where let transport = ExtTransport::new(transport); let mut config = Configuration::default(); - config.network.transport = network::config::TransportConfig::Normal { + config.network.boot_nodes = chain_spec.boot_nodes().to_vec(); + config.telemetry_endpoints = chain_spec.telemetry_endpoints().clone(); + config.chain_spec = Some(chain_spec); + config.network.transport = sc_network::config::TransportConfig::Normal { wasm_external_transport: Some(transport.clone()), allow_private_ipv4: true, enable_mdns: false, @@ -82,6 +85,11 @@ struct RpcMessage { /// Create a Client object that connects to a service. pub fn start_client(mut service: impl AbstractService) -> Client { + // Spawn informant + wasm_bindgen_futures::spawn_local( + sc_informant::build(&service, sc_informant::OutputFormat::Plain).map(drop) + ); + // We dispatch a background task responsible for processing the service. // // The main action performed by the code below consists in polling the service with diff --git a/utils/grafana-data-source/Cargo.toml b/utils/grafana-data-source/Cargo.toml index ab4251ef57..e1bd037009 100644 --- a/utils/grafana-data-source/Cargo.toml +++ b/utils/grafana-data-source/Cargo.toml @@ -16,7 +16,7 @@ serde = { version = "1", features = ["derive"] } chrono = { version = "0.4", features = ["serde"] } lazy_static = "1.4" parking_lot = "0.10.0" -futures-timer = "2.0" +futures-timer = "3.0.1" derive_more = "0.99" [target.'cfg(not(target_os = "unknown"))'.dependencies] diff --git a/utils/grafana-data-source/test/Cargo.toml b/utils/grafana-data-source/test/Cargo.toml index 9575866fa8..18c080c8d1 100644 --- a/utils/grafana-data-source/test/Cargo.toml +++ b/utils/grafana-data-source/test/Cargo.toml @@ -9,5 +9,5 @@ edition = "2018" [dependencies] grafana-data-source = { version = "0.8", path = ".." } futures = "0.3" -futures-timer = "2.0" +futures-timer = "3.0.1" rand = "0.7" -- GitLab From 0d4586b13f176ca35c65f288b59e4ecccd099313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 10 Feb 2020 13:13:04 +0100 Subject: [PATCH 118/180] Don't expose `Benchmarking` host functions by default (#4875) * Don't expose `Benchmarking` host functions by default * Fix tests Co-authored-by: Shawn Tabrizi --- bin/node/executor/src/lib.rs | 3 +- client/executor/src/integration_tests/mod.rs | 4 +-- primitives/io/src/lib.rs | 35 ++++++++++---------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/bin/node/executor/src/lib.rs b/bin/node/executor/src/lib.rs index 812c018502..72f40b7c1f 100644 --- a/bin/node/executor/src/lib.rs +++ b/bin/node/executor/src/lib.rs @@ -25,5 +25,6 @@ use sc_executor::native_executor_instance; native_executor_instance!( pub Executor, node_runtime::api::dispatch, - node_runtime::native_version + node_runtime::native_version, + sp_io::benchmarking::HostFunctions, ); diff --git a/client/executor/src/integration_tests/mod.rs b/client/executor/src/integration_tests/mod.rs index 2ac67215a8..3f3d9f69e1 100644 --- a/client/executor/src/integration_tests/mod.rs +++ b/client/executor/src/integration_tests/mod.rs @@ -88,7 +88,7 @@ fn call_not_existing_function(wasm_method: WasmExecutionMethod) { #[cfg(feature = "wasmtime")] WasmExecutionMethod::Compiled => assert_eq!( &format!("{:?}", e), - "Other(\"call to undefined external function with index 71\")" + "Other(\"call to undefined external function with index 68\")" ), } } @@ -117,7 +117,7 @@ fn call_yet_another_not_existing_function(wasm_method: WasmExecutionMethod) { #[cfg(feature = "wasmtime")] WasmExecutionMethod::Compiled => assert_eq!( &format!("{:?}", e), - "Other(\"call to undefined external function with index 72\")" + "Other(\"call to undefined external function with index 69\")" ), } } diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index ea45b580ce..ce8a546e86 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -774,25 +774,25 @@ pub trait Logging { /// Interface that provides functions for benchmarking the runtime. #[runtime_interface] pub trait Benchmarking { - /// Get the number of nanoseconds passed since the UNIX epoch - /// - /// WARNING! This is a non-deterministic call. Do not use this within - /// consensus critical logic. - fn current_time() -> u128 { - std::time::SystemTime::now().duration_since(std::time::SystemTime::UNIX_EPOCH) - .expect("Unix time doesn't go backwards; qed") - .as_nanos() - } + /// Get the number of nanoseconds passed since the UNIX epoch + /// + /// WARNING! This is a non-deterministic call. Do not use this within + /// consensus critical logic. + fn current_time() -> u128 { + std::time::SystemTime::now().duration_since(std::time::SystemTime::UNIX_EPOCH) + .expect("Unix time doesn't go backwards; qed") + .as_nanos() + } - /// Reset the trie database to the genesis state. - fn wipe_db(&mut self) { - self.wipe() - } + /// Reset the trie database to the genesis state. + fn wipe_db(&mut self) { + self.wipe() + } - /// Commit pending storage changes to the trie database and clear the database cache. - fn commit_db(&mut self) { - self.commit() - } + /// Commit pending storage changes to the trie database and clear the database cache. + fn commit_db(&mut self) { + self.commit() + } } /// Wasm-only interface that provides functions for interacting with the sandbox. @@ -947,7 +947,6 @@ pub type SubstrateHostFunctions = ( logging::HostFunctions, sandbox::HostFunctions, crate::trie::HostFunctions, - benchmarking::HostFunctions, ); #[cfg(test)] -- GitLab From 571e3c4d9cdcf55a7c09b7040061f6e096dd3b08 Mon Sep 17 00:00:00 2001 From: Marcio Diaz Date: Mon, 10 Feb 2020 13:25:20 +0100 Subject: [PATCH 119/180] Add trace on import block. (#4871) --- client/src/client.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/src/client.rs b/client/src/client.rs index 9e30c7b2ea..d085b92025 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -1599,6 +1599,9 @@ impl sp_consensus::BlockImport for &Client>, new_cache: HashMap>, ) -> Result { + let span = tracing::span!(tracing::Level::DEBUG, "import_block"); + let _enter = span.enter(); + if let Some(res) = self.prepare_block_storage_changes(&mut import_block).map_err(|e| { warn!("Block prepare storage changes error:\n{:?}", e); ConsensusError::ClientImport(e.to_string()) -- GitLab From 1fa3f7f607351e008ec6d817ca218d9aade576f7 Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Mon, 10 Feb 2020 13:37:10 +0100 Subject: [PATCH 120/180] Refactor and document allocator (#4855) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Clarify code a bit. * Move code around. * Introduce `Order`. * Introduce `Link` structure. * Get rid of ptr_offset This is beneficial since ptr_offset is essentially makes us handle two different address spaces, global (i.e. `mem`) and heap local and without it things are becoming simpler. * Rename PREFIX_SIZE to HEADER_SIZE. This will come in the next commits. * Introduce a separate `Memory` trait. This is not necessary, but will come in handy for the upcoming changes. * Rename `ptr` to `header_ptr` where makes sense. * Introduce a `Header` type. * Make `bump` dumber. This allows us to pull `HEADER_SIZE` to see that we actually allocate `order.size() + HEADER_SIZE`. * Clean up. * Introduce a freelists struct. * Update documentation. * Make Sized requirement optional to make the PR truly back-compatible. * Apply suggestions from code review Co-Authored-By: Gavin Wood * Apply suggestions from code review Co-Authored-By: Bastian Köcher Co-authored-by: Gavin Wood Co-authored-by: Bastian Köcher --- primitives/allocator/src/freeing_bump.rs | 524 ++++++++++++++++------- 1 file changed, 369 insertions(+), 155 deletions(-) diff --git a/primitives/allocator/src/freeing_bump.rs b/primitives/allocator/src/freeing_bump.rs index f51dc222a2..caac9dd6c4 100644 --- a/primitives/allocator/src/freeing_bump.rs +++ b/primitives/allocator/src/freeing_bump.rs @@ -16,42 +16,40 @@ //! This module implements a freeing-bump allocator. //! -//! The algorithm is as follows: -//! We store `N` linked list heads, where `N` is the total number of sizes -//! of allocations to support. A simple set is powers of two from 8 bytes -//! to 16,777,216 bytes (2^3 - 2^24 inclusive), resulting in `N = 22`: +//! The heap is a continuous linear memory and chunks are allocated using a bump allocator. //! //! ```ignore -//! let mut heads [u64; N] = [0; N]; -//! fn size(n: u64) -> u64 { 8 << n } -//! let mut bumper = 0; -//! fn bump(n: u64) -> u64 { let res = bumper; bumper += n; res } +//! +-------------+-------------------------------------------------+ +//! | | | +//! +-------------+-------------------------------------------------+ +//! ^ +//! |_ bumper //! ``` //! -//! We assume there is a slab of heap to be allocated: +//! Only allocations with sizes of power of two can be allocated. If the incoming request has a non +//! power of two size it is increased to the nearest power of two. The power of two of size is +//! referred as **an order**. //! -//! ```ignore -//! let mut heap = [0u8; HEAP_SIZE]; -//! ``` +//! Each allocation has a header immediately preceding to it. The header is always 8 bytes and can +//! be of two types: free and occupied. //! -//! Whenever we allocate, we select the lowest linked list item size that -//! will fit the allocation (i.e. the next highest power of two). -//! We then check to see if the linked list is empty. If empty, we use -//! the bump allocator to get the allocation with an extra 8 bytes -//! preceding it. We initialise those preceding 8 bytes to identify the -//! list to which it belongs. If it is not empty, we unlink the first item from -//! the linked list and then reset the 8 preceding bytes so they now record -//! the identity of the linked list. +//! For implementing freeing we maintain a linked lists for each order. The maximum supported +//! allocation size is capped, therefore the number of orders and thus the linked lists is as well +//! limited. //! -//! To deallocate we use the preceding 8 bytes of the allocation to knit -//! back the allocation into the linked list from the head. +//! When the allocater serves an allocation request it first checks the linked list for the respective +//! order. If it doesn't have any free chunks, the allocator requests memory from the bump allocator. +//! In any case the order is stored in the header of the allocation. +//! +//! Upon deallocation we get the order of the allocation from its header and then add that +//! allocation to the linked list for the respective order. use crate::Error; -use sp_std::{convert::{TryFrom, TryInto}, ops::Range}; +use sp_std::{convert::{TryFrom, TryInto}, ops::{Range, Index, IndexMut}}; 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. +/// The minimal alignment guaranteed by this allocator. The alignment of 8 is choosen because it is +/// the alignment guaranteed by wasm32. const ALIGNMENT: u32 = 8; // The pointer returned by `allocate()` needs to fulfill the alignment @@ -65,17 +63,7 @@ const MIN_POSSIBLE_ALLOCATION: u32 = 8; // Each pointer is prefixed with 8 bytes, which identify the list index // to which it belongs. -const PREFIX_SIZE: u32 = 8; - -/// An implementation of freeing bump allocator. -/// -/// Refer to the module-level documentation for further details. -pub struct FreeingBumpHeapAllocator { - bumper: u32, - heads: [u32; N], - ptr_offset: u32, - total_size: u32, -} +const HEADER_SIZE: u32 = 8; /// Create an allocator error. fn error(msg: &'static str) -> Error { @@ -93,6 +81,219 @@ macro_rules! trace { } } +/// The exponent for the power of two sized block adjusted to the minimum size. +/// +/// This way, if `MIN_POSSIBLE_ALLOCATION == 8`, we would get: +/// +/// power_of_two_size | order +/// 8 | 0 +/// 16 | 1 +/// 32 | 2 +/// 64 | 3 +/// +/// and so on. +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +struct Order(u32); + +impl Order { + /// Create `Order` object from a raw order. + /// + /// Returns `Err` if it is greater than the maximum supported order. + fn from_raw(order: u32) -> Result { + if order < N as u32 { + Ok(Self(order)) + } else { + Err(error("invalid order")) + } + } + + /// Compute the order by the given size + /// + /// The size is clamped, so that the following holds: + /// + /// `MIN_POSSIBLE_ALLOCATION <= size <= MAX_POSSIBLE_ALLOCATION` + fn from_size(size: u32) -> Result { + let clamped_size = if size > MAX_POSSIBLE_ALLOCATION { + return Err(Error::RequestedAllocationTooLarge); + } else if size < MIN_POSSIBLE_ALLOCATION { + MIN_POSSIBLE_ALLOCATION + } else { + size + }; + + // Round the clamped size to the next power of two. + // + // It returns the unchanged value if the value is already a power of two. + let power_of_two_size = clamped_size.next_power_of_two(); + + // Compute the number of trailing zeroes to get the order. We adjust it by the number of + // trailing zeroes in the minimum possible allocation. + let order = power_of_two_size.trailing_zeros() - MIN_POSSIBLE_ALLOCATION.trailing_zeros(); + + Ok(Self(order)) + } + + /// Returns the corresponding size for this order. + /// + /// Note that it is always a power of two. + fn size(&self) -> u32 { + MIN_POSSIBLE_ALLOCATION << self.0 + } + + /// Extract the order as `u32`. + fn into_raw(self) -> u32 { + self.0 + } +} + +/// A marker for denoting the end of the linked list. +const EMPTY_MARKER: u32 = u32::max_value(); + +/// A link between headers in the free list. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +enum Link { + /// Null, denotes that there is no next element. + Null, + /// Link to the next element represented as a pointer to the a header. + Ptr(u32), +} + +impl Link { + /// Creates a link from raw value. + fn from_raw(raw: u32) -> Self { + if raw != EMPTY_MARKER { + Self::Ptr(raw) + } else { + Self::Null + } + } + + /// Converts this link into a raw u32. + fn into_raw(self) -> u32 { + match self { + Self::Null => EMPTY_MARKER, + Self::Ptr(ptr) => ptr, + } + } +} + +/// A header of an allocation. +/// +/// The header is encoded in memory as follows. +/// +/// ## Free header +/// +/// ```ignore +/// 64 32 0 +// +--------------+-------------------+ +/// | 0 | next element link | +/// +--------------+-------------------+ +/// ``` +/// +/// ## Occupied header +/// +/// ```ignore +/// 64 32 0 +// +--------------+-------------------+ +/// | 1 | order | +/// +--------------+-------------------+ +/// ``` +#[derive(Clone, Debug, PartialEq, Eq)] +enum Header { + /// A free header contains a link to the next element to form a free linked list. + Free(Link), + /// An occupied header has attached order to know in which free list we should put the + /// allocation upon deallocation. + Occupied(Order), +} + +impl Header { + fn read_from(memory: &M, header_ptr: u32) -> Result { + let raw_header = memory.read_le_u64(header_ptr)?; + + // Check if the header represents an occupied or free allocation and extract the header data + // by trimming (and discarding) the high bits. + let occupied = raw_header & 0x00000001_00000000 != 0; + let header_data = raw_header as u32; + + Ok(if occupied { + Self::Occupied(Order::from_raw(header_data)?) + } else { + Self::Free(Link::from_raw(header_data)) + }) + } + + /// Write out this header to memory. + fn write_into(&self, memory: &mut M, header_ptr: u32) -> Result<(), Error> { + let (header_data, occupied_mask) = match *self { + Self::Occupied(order) => (order.into_raw(), 0x00000001_00000000), + Self::Free(link) => (link.into_raw(), 0x00000000_00000000), + }; + let raw_header = header_data as u64 | occupied_mask; + memory.write_le_u64(header_ptr, raw_header)?; + Ok(()) + } + + /// Returns the order of the allocation if this is an occupied header. + fn into_occupied(self) -> Option { + match self { + Self::Occupied(order) => Some(order), + _ => None, + } + } + + /// Returns the link to the next element in the free list if this is a free header. + fn into_free(self) -> Option { + match self { + Self::Free(link) => Some(link), + _ => None, + } + } +} + +/// This struct represents a collection of intrusive linked lists for each order. +struct FreeLists { + heads: [Link; N], +} + +impl FreeLists { + /// Creates the free empty lists. + fn new() -> Self { + Self { + heads: [Link::Null; N] + } + } + + /// Replaces a given link for the specified order and returns the old one. + fn replace(&mut self, order: Order, new: Link) -> Link { + let prev = self[order]; + self[order] = new; + prev + } +} + +impl Index for FreeLists { + type Output = Link; + fn index(&self, index: Order) -> &Link { + &self.heads[index.0 as usize] + } +} + +impl IndexMut for FreeLists { + fn index_mut(&mut self, index: Order) -> &mut Link { + &mut self.heads[index.0 as usize] + } +} + +/// An implementation of freeing bump allocator. +/// +/// Refer to the module-level documentation for further details. +pub struct FreeingBumpHeapAllocator { + bumper: u32, + free_lists: FreeLists, + total_size: u32, +} + impl FreeingBumpHeapAllocator { /// Creates a new allocation heap which follows a freeing-bump strategy. /// The maximum size which can be allocated at once is 16 MiB. @@ -101,13 +302,11 @@ impl FreeingBumpHeapAllocator { /// /// - `heap_base` - the offset from the beginning of the linear memory where the heap starts. pub fn new(heap_base: u32) -> Self { - // ptr_offset is the next alignment boundary on or after heap_base. - let ptr_offset = (heap_base + ALIGNMENT - 1) / ALIGNMENT * ALIGNMENT; + let aligned_heap_base = (heap_base + ALIGNMENT - 1) / ALIGNMENT * ALIGNMENT; FreeingBumpHeapAllocator { - bumper: 0, - heads: [u32::max_value(); N], - ptr_offset, + bumper: aligned_heap_base, + free_lists: FreeLists::new(), total_size: 0, } } @@ -122,46 +321,42 @@ impl FreeingBumpHeapAllocator { /// /// - `mem` - a slice representing the linear memory on which this allocator operates. /// - `size` - size in bytes of the allocation request - pub fn allocate(&mut self, mem: &mut [u8], size: WordSize) -> Result, Error> { - let mem_size = u32::try_from(mem.len()) - .expect("size of Wasm linear memory is <2^32; qed"); - let max_heap_size = mem_size - self.ptr_offset; - - if size > MAX_POSSIBLE_ALLOCATION { - return Err(Error::RequestedAllocationTooLarge); - } - - let size = size.max(MIN_POSSIBLE_ALLOCATION); - let item_size = size.next_power_of_two(); - if item_size + PREFIX_SIZE + self.total_size > max_heap_size { - return Err(Error::AllocatorOutOfSpace); - } - - let list_index = (item_size.trailing_zeros() - 3) as usize; - let ptr: u32 = if self.heads[list_index] != u32::max_value() { - // Something from the free list - let ptr = self.heads[list_index]; - assert!( - ptr + item_size + PREFIX_SIZE <= max_heap_size, - "Pointer is looked up in list of free entries, into which - only valid values are inserted; qed" - ); - - self.heads[list_index] = self.get_heap_u64(mem, ptr)? - .try_into() - .map_err(|_| error("read invalid free list pointer"))?; - ptr - } else { - // Nothing to be freed. Bump. - self.bump(item_size, max_heap_size)? + pub fn allocate( + &mut self, + mem: &mut M, + size: WordSize, + ) -> Result, Error> { + let order = Order::from_size(size)?; + + let header_ptr: u32 = match self.free_lists[order] { + Link::Ptr(header_ptr) => { + assert!( + header_ptr + order.size() + HEADER_SIZE <= mem.size(), + "Pointer is looked up in list of free entries, into which + only valid values are inserted; qed" + ); + + // Remove this header from the free list. + let next_free = Header::read_from(mem, header_ptr)? + .into_free() + .ok_or_else(|| error("free list points to a occupied header"))?; + self.free_lists[order] = next_free; + + header_ptr + } + Link::Null => { + // Corresponding free list is empty. Allocate a new item. + self.bump(order.size() + HEADER_SIZE, mem.size())? + } }; - self.set_heap_u64(mem, ptr, list_index as u64)?; + // Write the order in the occupied header. + Header::Occupied(order).write_into(mem, header_ptr)?; - self.total_size = self.total_size + item_size + PREFIX_SIZE; + self.total_size += order.size() + HEADER_SIZE; trace!("Heap size is {} bytes after allocation", self.total_size); - Ok(Pointer::new(self.ptr_offset + ptr + PREFIX_SIZE)) + Ok(Pointer::new(header_ptr + HEADER_SIZE)) } /// Deallocates the space which was allocated for a pointer. @@ -170,80 +365,83 @@ impl FreeingBumpHeapAllocator { /// /// - `mem` - a slice representing the linear memory on which this allocator operates. /// - `ptr` - pointer to the allocated chunk - pub fn deallocate(&mut self, mem: &mut [u8], ptr: Pointer) -> Result<(), Error> { - let ptr = u32::from(ptr) - self.ptr_offset; - let ptr = ptr.checked_sub(PREFIX_SIZE).ok_or_else(|| - error("Invalid pointer for deallocation") - )?; - - let list_index: usize = self.get_heap_u64(mem, ptr)? - .try_into() - .map_err(|_| error("read invalid list index"))?; - if list_index > self.heads.len() { - return Err(error("read invalid list index")); - } - self.set_heap_u64(mem, ptr, self.heads[list_index] as u64)?; - self.heads[list_index] = ptr; - - let item_size = Self::get_item_size_from_index(list_index); - self.total_size = self.total_size.checked_sub(item_size as u32 + PREFIX_SIZE) + pub fn deallocate(&mut self, mem: &mut M, ptr: Pointer) -> Result<(), Error> { + let header_ptr = u32::from(ptr) + .checked_sub(HEADER_SIZE) + .ok_or_else(|| error("Invalid pointer for deallocation"))?; + + let order = Header::read_from(mem, header_ptr)? + .into_occupied() + .ok_or_else(|| error("the allocation points to an empty header"))?; + + // Update the just freed header and knit it back to the free list. + let prev_head = self.free_lists.replace(order, Link::Ptr(header_ptr)); + Header::Free(prev_head).write_into(mem, header_ptr)?; + + // Do the total_size book keeping. + self.total_size = self + .total_size + .checked_sub(order.size() + HEADER_SIZE) .ok_or_else(|| error("Unable to subtract from total heap size without overflow"))?; trace!("Heap size is {} bytes after deallocation", self.total_size); Ok(()) } - /// Increases the `bumper` by `item_size + PREFIX_SIZE`. + /// Increases the `bumper` by `size`. /// /// Returns the `bumper` from before the increase. /// Returns an `Error::AllocatorOutOfSpace` if the operation /// would exhaust the heap. - fn bump(&mut self, item_size: u32, max_heap_size: u32) -> Result { - if self.bumper + PREFIX_SIZE + item_size > max_heap_size { + fn bump(&mut self, size: u32, heap_end: u32) -> Result { + if self.bumper + size > heap_end { return Err(Error::AllocatorOutOfSpace); } let res = self.bumper; - self.bumper += item_size + PREFIX_SIZE; + self.bumper += size; Ok(res) } +} - fn get_item_size_from_index(index: usize) -> usize { - // we shift 1 by three places, since the first possible item size is 8 - 1 << 3 << index - } +/// A trait for abstraction of accesses to linear memory. +pub trait Memory { + /// Read a u64 from the heap in LE form. Used to read heap allocation prefixes. + fn read_le_u64(&self, ptr: u32) -> Result; + /// Write a u64 to the heap in LE form. Used to write heap allocation prefixes. + fn write_le_u64(&mut self, ptr: u32, val: u64) -> Result<(), Error>; + /// Returns the full size of the memory. + fn size(&self) -> u32; +} - // Read a u64 from the heap in LE form. Used to read heap allocation prefixes. - fn get_heap_u64(&self, heap: &[u8], offset: u32) -> Result { - let range = self.heap_range(offset, 8, heap.len()) - .ok_or_else(|| error("read out of heap bounds"))?; - let bytes = heap[range].try_into() +impl Memory for [u8] { + fn read_le_u64(&self, ptr: u32) -> Result { + let range = + heap_range(ptr, 8, self.len()).ok_or_else(|| error("read out of heap bounds"))?; + let bytes = self[range] + .try_into() .expect("[u8] slice of length 8 must be convertible to [u8; 8]"); Ok(u64::from_le_bytes(bytes)) } - - // Write a u64 to the heap in LE form. Used to write heap allocation prefixes. - fn set_heap_u64(&self, heap: &mut [u8], offset: u32, val: u64) -> Result<(), Error> { - let range = self.heap_range(offset, 8, heap.len()) - .ok_or_else(|| error("write out of heap bounds"))?; + fn write_le_u64(&mut self, ptr: u32, val: u64) -> Result<(), Error> { + let range = + heap_range(ptr, 8, self.len()).ok_or_else(|| error("write out of heap bounds"))?; let bytes = val.to_le_bytes(); - &mut heap[range].copy_from_slice(&bytes[..]); + &mut self[range].copy_from_slice(&bytes[..]); Ok(()) } + fn size(&self) -> u32 { + u32::try_from(self.len()).expect("size of Wasm linear memory is <2^32; qed") + } +} - fn heap_range(&self, offset: u32, length: u32, heap_len: usize) -> Option> { - let start = offset - .checked_add(self.ptr_offset)? - as usize; - let end = offset - .checked_add(self.ptr_offset)? - .checked_add(length)? - as usize; - if end <= heap_len { - Some(start..end) - } else { - None - } +fn heap_range(offset: u32, length: u32, heap_len: usize) -> Option> { + let start = offset as usize; + let end = offset.checked_add(length)? as usize; + if end <= heap_len { + Some(start..end) + } else { + None } } @@ -268,8 +466,8 @@ mod tests { let ptr = heap.allocate(&mut mem[..], 1).unwrap(); // then - // returned pointer must start right after `PREFIX_SIZE` - assert_eq!(ptr, to_pointer(PREFIX_SIZE)); + // returned pointer must start right after `HEADER_SIZE` + assert_eq!(ptr, to_pointer(HEADER_SIZE)); } #[test] @@ -300,14 +498,14 @@ mod tests { // then // a prefix of 8 bytes is prepended to each pointer - assert_eq!(ptr1, to_pointer(PREFIX_SIZE)); + assert_eq!(ptr1, to_pointer(HEADER_SIZE)); // the prefix of 8 bytes + the content of ptr1 padded to the lowest possible // item size of 8 bytes + the prefix of ptr1 assert_eq!(ptr2, to_pointer(24)); // ptr2 + its content of 16 bytes + the prefix of 8 bytes - assert_eq!(ptr3, to_pointer(24 + 16 + PREFIX_SIZE)); + assert_eq!(ptr3, to_pointer(24 + 16 + HEADER_SIZE)); } #[test] @@ -317,7 +515,7 @@ mod tests { let mut heap = FreeingBumpHeapAllocator::new(0); let ptr1 = heap.allocate(&mut mem[..], 1).unwrap(); // the prefix of 8 bytes is prepended to the pointer - assert_eq!(ptr1, to_pointer(PREFIX_SIZE)); + assert_eq!(ptr1, to_pointer(HEADER_SIZE)); let ptr2 = heap.allocate(&mut mem[..], 1).unwrap(); // the prefix of 8 bytes + the content of ptr 1 is prepended to the pointer @@ -329,7 +527,7 @@ mod tests { // then // then the heads table should contain a pointer to the // prefix of ptr2 in the leftmost entry - assert_eq!(heap.heads[0], u32::from(ptr2) - PREFIX_SIZE); + assert_eq!(heap.free_lists.heads[0], Link::Ptr(u32::from(ptr2) - HEADER_SIZE)); } #[test] @@ -341,13 +539,13 @@ mod tests { let ptr1 = heap.allocate(&mut mem[..], 1).unwrap(); // the prefix of 8 bytes is prepended to the pointer - assert_eq!(ptr1, to_pointer(padded_offset + PREFIX_SIZE)); + assert_eq!(ptr1, to_pointer(padded_offset + HEADER_SIZE)); let ptr2 = heap.allocate(&mut mem[..], 9).unwrap(); // the padded_offset + the previously allocated ptr (8 bytes prefix + // 8 bytes content) + the prefix of 8 bytes which is prepended to the // current pointer - assert_eq!(ptr2, to_pointer(padded_offset + 16 + PREFIX_SIZE)); + assert_eq!(ptr2, to_pointer(padded_offset + 16 + HEADER_SIZE)); // when heap.deallocate(&mut mem[..], ptr2).unwrap(); @@ -355,8 +553,8 @@ mod tests { // then // should have re-allocated - assert_eq!(ptr3, to_pointer(padded_offset + 16 + PREFIX_SIZE)); - assert_eq!(heap.heads, [u32::max_value(); N]); + assert_eq!(ptr3, to_pointer(padded_offset + 16 + HEADER_SIZE)); + assert_eq!(heap.free_lists.heads, [Link::Null; N]); } #[test] @@ -375,12 +573,12 @@ mod tests { heap.deallocate(&mut mem[..], ptr3).unwrap(); // then - assert_eq!(heap.heads[0], u32::from(ptr3) - PREFIX_SIZE); + assert_eq!(heap.free_lists.heads[0], Link::Ptr(u32::from(ptr3) - HEADER_SIZE)); let ptr4 = heap.allocate(&mut mem[..], 8).unwrap(); assert_eq!(ptr4, ptr3); - assert_eq!(heap.heads[0], u32::from(ptr2) - PREFIX_SIZE); + assert_eq!(heap.free_lists.heads[0], Link::Ptr(u32::from(ptr2) - HEADER_SIZE)); } #[test] @@ -404,8 +602,8 @@ mod tests { // given let mut mem = [0u8; PAGE_SIZE as usize]; let mut heap = FreeingBumpHeapAllocator::new(0); - let ptr1 = heap.allocate(&mut mem[..], (PAGE_SIZE / 2) - PREFIX_SIZE).unwrap(); - assert_eq!(ptr1, to_pointer(PREFIX_SIZE)); + let ptr1 = heap.allocate(&mut mem[..], (PAGE_SIZE / 2) - HEADER_SIZE).unwrap(); + assert_eq!(ptr1, to_pointer(HEADER_SIZE)); // when let ptr2 = heap.allocate(&mut mem[..], PAGE_SIZE / 2); @@ -428,7 +626,7 @@ mod tests { let ptr = heap.allocate(&mut mem[..], MAX_POSSIBLE_ALLOCATION).unwrap(); // then - assert_eq!(ptr, to_pointer(PREFIX_SIZE)); + assert_eq!(ptr, to_pointer(HEADER_SIZE)); } #[test] @@ -454,7 +652,7 @@ mod tests { let mut heap = FreeingBumpHeapAllocator::new(0); let ptr1 = heap.allocate(&mut mem[..], 32).unwrap(); - assert_eq!(ptr1, to_pointer(PREFIX_SIZE)); + assert_eq!(ptr1, to_pointer(HEADER_SIZE)); heap.deallocate(&mut mem[..], ptr1).expect("failed freeing ptr1"); assert_eq!(heap.total_size, 0); assert_eq!(heap.bumper, 40); @@ -466,7 +664,7 @@ mod tests { assert_eq!(heap.bumper, 64); // when - // the `bumper` value is equal to `max_heap_size` here and any + // the `bumper` value is equal to `size` here and any // further allocation which would increment the bumper must fail. // we try to allocate 8 bytes here, which will increment the // bumper since no 8 byte item has been allocated+freed before. @@ -490,7 +688,7 @@ mod tests { heap.allocate(&mut mem[..], 9).unwrap(); // then - assert_eq!(heap.total_size, PREFIX_SIZE + 16); + assert_eq!(heap.total_size, HEADER_SIZE + 16); } #[test] @@ -501,7 +699,7 @@ mod tests { // when let ptr = heap.allocate(&mut mem[..], 42).unwrap(); - assert_eq!(ptr, to_pointer(16 + PREFIX_SIZE)); + assert_eq!(ptr, to_pointer(16 + HEADER_SIZE)); heap.deallocate(&mut mem[..], ptr).unwrap(); // then @@ -528,23 +726,22 @@ mod tests { fn should_read_and_write_u64_correctly() { // given let mut mem = [0u8; PAGE_SIZE as usize]; - let heap = FreeingBumpHeapAllocator::new(16); // when - heap.set_heap_u64(&mut mem[..], 40, 4480113).unwrap(); + Memory::write_le_u64(mem.as_mut(), 40, 4480113).unwrap(); // then - let value = heap.get_heap_u64(&mut mem[..], 40).unwrap(); + let value = Memory::read_le_u64(mem.as_mut(), 40).unwrap(); assert_eq!(value, 4480113); } #[test] - fn should_get_item_size_from_index() { + fn should_get_item_size_from_order() { // given - let index = 0; + let raw_order = 0; // when - let item_size = FreeingBumpHeapAllocator::get_item_size_from_index(index); + let item_size = Order::from_raw(raw_order).unwrap().size(); // then assert_eq!(item_size, 8); @@ -553,10 +750,10 @@ mod tests { #[test] fn should_get_max_item_size_from_index() { // given - let index = 21; + let raw_order = 21; // when - let item_size = FreeingBumpHeapAllocator::get_item_size_from_index(index); + let item_size = Order::from_raw(raw_order).unwrap().size(); // then assert_eq!(item_size as u32, MAX_POSSIBLE_ALLOCATION); @@ -568,10 +765,27 @@ mod tests { let mut heap = FreeingBumpHeapAllocator::new(0); // Allocate and free some pointers - let ptrs = (0..4).map(|_| heap.allocate(&mut mem, 8).unwrap()).collect::>(); - ptrs.into_iter().for_each(|ptr| heap.deallocate(&mut mem, ptr).unwrap()); + let ptrs = (0..4).map(|_| heap.allocate(&mut mem[..], 8).unwrap()).collect::>(); + ptrs.into_iter().for_each(|ptr| heap.deallocate(&mut mem[..], ptr).unwrap()); // Second time we should be able to allocate all of them again. - let _ = (0..4).map(|_| heap.allocate(&mut mem, 8).unwrap()).collect::>(); + let _ = (0..4).map(|_| heap.allocate(&mut mem[..], 8).unwrap()).collect::>(); + } + + #[test] + fn header_read_write() { + let roundtrip = |header: Header| { + let mut memory = [0u8; 32]; + header.write_into(memory.as_mut(), 0).unwrap(); + + let read_header = Header::read_from(memory.as_mut(), 0).unwrap(); + assert_eq!(header, read_header); + }; + + roundtrip(Header::Occupied(Order(0))); + roundtrip(Header::Occupied(Order(1))); + roundtrip(Header::Free(Link::Null)); + roundtrip(Header::Free(Link::Ptr(0))); + roundtrip(Header::Free(Link::Ptr(4))); } } -- GitLab From d472cd6ef27c93a3f58b0c1efd0927fc49394387 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Mon, 10 Feb 2020 14:04:50 +0100 Subject: [PATCH 121/180] Avoid challenging those that can't be suspended anyway (#4804) * Merge branch 'gav-split-balanecs-vesting' into gav-upsub # Conflicts: # Cargo.lock # cli/Cargo.toml # collator/Cargo.toml # primitives/Cargo.toml # runtime/common/Cargo.toml # runtime/common/src/claims.rs # runtime/kusama/Cargo.toml # runtime/polkadot/Cargo.toml # service/Cargo.toml * Fix tests --- frame/society/src/lib.rs | 30 ++++++++++++++++++------------ frame/society/src/tests.rs | 14 +++++++------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/frame/society/src/lib.rs b/frame/society/src/lib.rs index c1e1803c64..28220f1063 100644 --- a/frame/society/src/lib.rs +++ b/frame/society/src/lib.rs @@ -1536,18 +1536,24 @@ impl, I: Instance> Module { >::remove_all(); } - // Start a new defender rotation - let phrase = b"society_challenge"; - // we'll need a random seed here. - let seed = T::Randomness::random(phrase); - // seed needs to be guaranteed to be 32 bytes. - let seed = <[u8; 32]>::decode(&mut TrailingZeroInput::new(seed.as_ref())) - .expect("input is padded with zeroes; qed"); - let mut rng = ChaChaRng::from_seed(seed); - let chosen = pick_item(&mut rng, &members).expect("exited if members empty; qed"); - - >::put(&chosen); - Self::deposit_event(RawEvent::Challenged(chosen.clone())); + // Avoid challenging if there's only two members since we never challenge the Head or + // the Founder. + if members.len() > 2 { + // Start a new defender rotation + let phrase = b"society_challenge"; + // we'll need a random seed here. + let seed = T::Randomness::random(phrase); + // seed needs to be guaranteed to be 32 bytes. + let seed = <[u8; 32]>::decode(&mut TrailingZeroInput::new(seed.as_ref())) + .expect("input is padded with zeroes; qed"); + let mut rng = ChaChaRng::from_seed(seed); + let chosen = pick_item(&mut rng, &members[1..members.len() - 1]) + .expect("exited if members empty; qed"); + >::put(&chosen); + Self::deposit_event(RawEvent::Challenged(chosen.clone())); + } else { + >::kill(); + } } } diff --git a/frame/society/src/tests.rs b/frame/society/src/tests.rs index 3e5afc47f5..47d13d8361 100644 --- a/frame/society/src/tests.rs +++ b/frame/society/src/tests.rs @@ -577,14 +577,14 @@ fn challenges_work() { assert_eq!(Society::defender(), None); // 20 will be challenged during the challenge rotation run_to_block(8); - assert_eq!(Society::defender(), Some(20)); + assert_eq!(Society::defender(), Some(30)); // They can always free vote for themselves - assert_ok!(Society::defender_vote(Origin::signed(20), true)); + assert_ok!(Society::defender_vote(Origin::signed(30), true)); // If no one else votes, nothing happens run_to_block(16); assert_eq!(Society::members(), vec![10, 20, 30, 40]); // New challenge period - assert_eq!(Society::defender(), Some(20)); + assert_eq!(Society::defender(), Some(30)); // Non-member cannot challenge assert_noop!(Society::defender_vote(Origin::signed(1), true), Error::::NotMember); // 3 people say accept, 1 reject @@ -601,7 +601,7 @@ fn challenges_work() { assert_eq!(>::get(30), None); assert_eq!(>::get(40), None); // One more time - assert_eq!(Society::defender(), Some(20)); + assert_eq!(Society::defender(), Some(30)); // 2 people say accept, 2 reject assert_ok!(Society::defender_vote(Origin::signed(10), true)); assert_ok!(Society::defender_vote(Origin::signed(20), true)); @@ -609,10 +609,10 @@ fn challenges_work() { assert_ok!(Society::defender_vote(Origin::signed(40), false)); run_to_block(32); // 20 is suspended - assert_eq!(Society::members(), vec![10, 30, 40]); - assert_eq!(Society::suspended_member(20), true); + assert_eq!(Society::members(), vec![10, 20, 40]); + assert_eq!(Society::suspended_member(30), true); // New defender is chosen - assert_eq!(Society::defender(), Some(40)); + assert_eq!(Society::defender(), Some(20)); // Votes are reset assert_eq!(>::get(10), None); assert_eq!(>::get(20), None); -- GitLab From b388338814c5040f6a6b84018430f799445b4876 Mon Sep 17 00:00:00 2001 From: Marcio Diaz Date: Mon, 10 Feb 2020 14:27:40 +0100 Subject: [PATCH 122/180] Add trait to get module and call names. (#4854) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add trait to get module and call names. Co-authored-by: Bastian Köcher --- bin/node/runtime/src/lib.rs | 2 +- frame/support/src/dispatch.rs | 38 +++++++++++++++++++++++++++++++++++ frame/support/src/traits.rs | 6 ++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 0435755d19..be9dbb9686 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -82,7 +82,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 215, - impl_version: 0, + impl_version: 1, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index 85cf8d6ede..c2f42fd561 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -1346,6 +1346,14 @@ macro_rules! decl_module { $call_type::__PhantomItem(_, _) => unreachable!("__PhantomItem should never be used."), } } + + fn get_call_names() -> &'static [&'static str] { + &[ + $( + stringify!($fn_name), + )* + ] + } } // manual implementation of clone/eq/partialeq because using derive erroneously requires @@ -1518,6 +1526,24 @@ macro_rules! impl_outer_dispatch { }, )* } } + + fn get_module_names() -> &'static [&'static str] { + &[$( + stringify!($camelcase), + )*] + } + + fn get_call_names(module: &str) -> &'static [&'static str] { + use $crate::dispatch::{Callable, GetCallName}; + match module { + $( + stringify!($camelcase) => + <<$camelcase as Callable<$runtime>>::Call + as GetCallName>::get_call_names(), + )* + _ => unreachable!(), + } + } } impl $crate::dispatch::Dispatchable for $call_type { type Origin = $origin; @@ -2118,4 +2144,16 @@ mod tests { let expected = CallMetadata { function_name: "aux_3".into(), pallet_name: "Test".into() }; assert_eq!(metadata, expected); } + + #[test] + fn get_call_names() { + let call_names = Call::::get_call_names(); + assert_eq!(["aux_0", "aux_1", "aux_2", "aux_3", "aux_4", "aux_5", "operational"], call_names); + } + + #[test] + fn get_module_names() { + let module_names = OuterCall::get_module_names(); + assert_eq!(["Test"], module_names); + } } diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index f7701b4cd5..ba8a0d7ded 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -819,12 +819,18 @@ pub struct CallMetadata { /// Gets the function name of the Call. pub trait GetCallName { + /// Return all function names. + fn get_call_names() -> &'static [&'static str]; /// Return the function name of the Call. fn get_call_name(&self) -> &'static str; } /// Gets the metadata for the Call - function name and pallet name. pub trait GetCallMetadata { + /// Return all module names. + fn get_module_names() -> &'static [&'static str]; + /// Return all function names for the given `module`. + fn get_call_names(module: &str) -> &'static [&'static str]; /// Return a [`CallMetadata`], containing function and pallet name of the Call. fn get_call_metadata(&self) -> CallMetadata; } -- GitLab From 26a4b73931e636157a38a26a92f9103fe1b644c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Mon, 10 Feb 2020 14:49:42 +0100 Subject: [PATCH 123/180] Fix runtime-interface tests on windows (#4805) --- primitives/runtime-interface/test-wasm/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/primitives/runtime-interface/test-wasm/src/lib.rs b/primitives/runtime-interface/test-wasm/src/lib.rs index c6e2c9909f..467f58cb30 100644 --- a/primitives/runtime-interface/test-wasm/src/lib.rs +++ b/primitives/runtime-interface/test-wasm/src/lib.rs @@ -108,6 +108,7 @@ pub trait TestApi { /// Two random external functions from the old runtime interface. /// This ensures that we still inherently export these functions from the host and that we are still /// compatible with old wasm runtimes. +#[cfg(not(feature = "std"))] extern "C" { pub fn ext_clear_storage(key_data: *const u8, key_len: u32); pub fn ext_keccak_256(data: *const u8, len: u32, out: *mut u8); @@ -115,6 +116,7 @@ extern "C" { /// Make sure the old runtime interface needs to be imported. #[no_mangle] +#[cfg(not(feature = "std"))] pub fn force_old_runtime_interface_import() { unsafe { ext_clear_storage(sp_std::ptr::null(), 0); } unsafe { ext_keccak_256(sp_std::ptr::null(), 0, sp_std::ptr::null_mut()); } -- GitLab From 613a3bc895f1031e7ede7c7232ae256efe11d8b2 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Mon, 10 Feb 2020 22:21:38 +0300 Subject: [PATCH 124/180] update primitive types to 0.6.2 (#4866) --- Cargo.lock | 2 +- frame/evm/Cargo.toml | 2 +- primitives/arithmetic/Cargo.toml | 2 +- primitives/arithmetic/fuzzer/Cargo.toml | 2 +- primitives/core/Cargo.toml | 2 +- primitives/runtime-interface/Cargo.toml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b93b32fd93..76d3d004c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8269,7 +8269,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" dependencies = [ - "rand 0.7.3", + "rand 0.3.23", ] [[package]] diff --git a/frame/evm/Cargo.toml b/frame/evm/Cargo.toml index b45bf6e31e..50d7b03672 100644 --- a/frame/evm/Cargo.toml +++ b/frame/evm/Cargo.toml @@ -16,7 +16,7 @@ sp-core = { version = "2.0.0", default-features = false, path = "../../primitive 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"] } +primitive-types = { version = "0.6.2", default-features = false, features = ["rlp"] } rlp = { version = "0.4", default-features = false } evm = { version = "0.14", default-features = false } sha3 = { version = "0.8", default-features = false } diff --git a/primitives/arithmetic/Cargo.toml b/primitives/arithmetic/Cargo.toml index 1b6d36ca37..995e36d5c9 100644 --- a/primitives/arithmetic/Cargo.toml +++ b/primitives/arithmetic/Cargo.toml @@ -14,7 +14,7 @@ serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-debug-derive = { version = "2.0.0", default-features = false, path = "../../primitives/debug-derive" } [dev-dependencies] -primitive-types = "0.6.0" +primitive-types = "0.6.2" rand = "0.7.2" criterion = "0.3" diff --git a/primitives/arithmetic/fuzzer/Cargo.toml b/primitives/arithmetic/fuzzer/Cargo.toml index 56e789f3e4..19d677f744 100644 --- a/primitives/arithmetic/fuzzer/Cargo.toml +++ b/primitives/arithmetic/fuzzer/Cargo.toml @@ -8,7 +8,7 @@ license = "GPL-3.0" [dependencies] sp-arithmetic = { version = "2.0.0", path = ".." } honggfuzz = "0.5" -primitive-types = "0.6" +primitive-types = "0.6.2" num-bigint = "0.2" num-traits = "0.2" diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 6f1ce2f080..574b9aa9cb 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -12,7 +12,7 @@ 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"] } byteorder = { version = "1.3.2", default-features = false } -primitive-types = { version = "0.6", default-features = false, features = ["codec"] } +primitive-types = { version = "0.6.2", 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 } diff --git a/primitives/runtime-interface/Cargo.toml b/primitives/runtime-interface/Cargo.toml index 3f20de1288..cef3acdbfb 100644 --- a/primitives/runtime-interface/Cargo.toml +++ b/primitives/runtime-interface/Cargo.toml @@ -12,7 +12,7 @@ sp-runtime-interface-proc-macro = { version = "2.0.0", path = "proc-macro" } sp-externalities = { version = "0.8.0", optional = true, path = "../externalities" } codec = { package = "parity-scale-codec", version = "1.0.6", default-features = false } static_assertions = "1.0.0" -primitive-types = { version = "0.6.1", default-features = false } +primitive-types = { version = "0.6.2", default-features = false } [dev-dependencies] sp-runtime-interface-test-wasm = { version = "2.0.0", path = "test-wasm" } -- GitLab From 671cb85238ce18b23392e3298a399ee8ee64e98d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 11 Feb 2020 00:41:59 +0100 Subject: [PATCH 125/180] Run offchain workers at hash, not number. (#4878) * Run offchain workers at particular hash, not number. * Don't run if not new best. * Don't run if not new best. * Update client/service/src/builder.rs Co-Authored-By: Nikolay Volf * Update client/service/src/builder.rs Co-Authored-By: Nikolay Volf * Update client/service/src/builder.rs Co-authored-by: Nikolay Volf --- client/db/src/utils.rs | 4 +++- client/offchain/src/lib.rs | 11 ++--------- client/service/src/builder.rs | 28 ++++++++++++++++++---------- primitives/blockchain/src/backend.rs | 10 +++++++--- 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/client/db/src/utils.rs b/client/db/src/utils.rs index f7f51d7f6d..534cbb2197 100644 --- a/client/db/src/utils.rs +++ b/client/db/src/utils.rs @@ -320,7 +320,9 @@ pub fn require_header( id: BlockId, ) -> sp_blockchain::Result { read_header(db, col_index, col, id) - .and_then(|header| header.ok_or_else(|| sp_blockchain::Error::UnknownBlock(format!("{}", id)))) + .and_then(|header| header.ok_or_else(|| + sp_blockchain::Error::UnknownBlock(format!("Require header: {}", id)) + )) } /// Read meta from the database. diff --git a/client/offchain/src/lib.rs b/client/offchain/src/lib.rs index f0a10a5409..fadfaa0134 100644 --- a/client/offchain/src/lib.rs +++ b/client/offchain/src/lib.rs @@ -97,7 +97,7 @@ impl OffchainWorkers< is_validator: bool, ) -> impl Future { let runtime = self.client.runtime_api(); - let at = BlockId::number(*header.number()); + let at = BlockId::hash(header.hash()); let has_api_v1 = runtime.has_api_with::, _>( &at, |v| v == 1 ); @@ -169,7 +169,6 @@ mod tests { use substrate_test_runtime_client::runtime::Block; use sc_transaction_pool::{BasicPool, FullChainApi}; use sp_transaction_pool::{TransactionPool, InPoolTransaction}; - use sp_runtime::{generic::Header, traits::Header as _}; struct MockNetworkStateInfo(); @@ -210,13 +209,7 @@ mod tests { .register_transaction_pool(Arc::downgrade(&pool.clone()) as _); let db = sc_client_db::offchain::LocalStorage::new_test(); let network_state = Arc::new(MockNetworkStateInfo()); - let header = Header::new( - 0u64, - Default::default(), - Default::default(), - Default::default(), - Default::default(), - ); + let header = client.header(&BlockId::number(0)).unwrap().unwrap(); // when let offchain = OffchainWorkers::new(client, db); diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 4d672006b8..e29c503402 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -898,16 +898,24 @@ ServiceBuilder< } let offchain = offchain.as_ref().and_then(|o| o.upgrade()); - if let Some(offchain) = offchain { - let future = offchain.on_block_imported( - ¬ification.header, - network_state_info.clone(), - is_validator - ); - let _ = to_spawn_tx_.unbounded_send(( - Box::pin(future), - From::from("offchain-on-block") - )); + match offchain { + Some(offchain) if notification.is_new_best => { + let future = offchain.on_block_imported( + ¬ification.header, + network_state_info.clone(), + is_validator, + ); + let _ = to_spawn_tx_.unbounded_send(( + Box::pin(future), + From::from("offchain-on-block"), + )); + }, + Some(_) => log::debug!( + target: "sc_offchain", + "Skipping offchain workers for non-canon block: {:?}", + notification.header, + ), + _ => {}, } ready(()) diff --git a/primitives/blockchain/src/backend.rs b/primitives/blockchain/src/backend.rs index 101dcd1443..35cac1e481 100644 --- a/primitives/blockchain/src/backend.rs +++ b/primitives/blockchain/src/backend.rs @@ -59,19 +59,23 @@ pub trait HeaderBackend: Send + Sync { /// Get block header. Returns `UnknownBlock` error if block is not found. fn expect_header(&self, id: BlockId) -> Result { - self.header(id)?.ok_or_else(|| Error::UnknownBlock(format!("{}", id))) + self.header(id)?.ok_or_else(|| Error::UnknownBlock(format!("Expect header: {}", id))) } /// Convert an arbitrary block ID into a block number. Returns `UnknownBlock` error if block is not found. fn expect_block_number_from_id(&self, id: &BlockId) -> Result> { self.block_number_from_id(id) - .and_then(|n| n.ok_or_else(|| Error::UnknownBlock(format!("{}", id)))) + .and_then(|n| n.ok_or_else(|| + Error::UnknownBlock(format!("Expect block number from id: {}", id)) + )) } /// Convert an arbitrary block ID into a block hash. Returns `UnknownBlock` error if block is not found. fn expect_block_hash_from_id(&self, id: &BlockId) -> Result { self.block_hash_from_id(id) - .and_then(|n| n.ok_or_else(|| Error::UnknownBlock(format!("{}", id)))) + .and_then(|n| n.ok_or_else(|| + Error::UnknownBlock(format!("Expect block hash from id: {}", id)) + )) } } -- GitLab From 50bb62fff79bb5c437634302d23fd97528369261 Mon Sep 17 00:00:00 2001 From: cheme Date: Tue, 11 Feb 2020 10:00:56 +0100 Subject: [PATCH 126/180] Use prefixed iterator from trie. (#4858) --- primitives/state-machine/src/trie_backend_essence.rs | 11 +++-------- primitives/trie/src/lib.rs | 2 +- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/primitives/state-machine/src/trie_backend_essence.rs b/primitives/state-machine/src/trie_backend_essence.rs index 2598682ae0..125a823f57 100644 --- a/primitives/state-machine/src/trie_backend_essence.rs +++ b/primitives/state-machine/src/trie_backend_essence.rs @@ -23,7 +23,7 @@ use log::{debug, warn}; use hash_db::{self, Hasher, EMPTY_PREFIX, Prefix}; use sp_trie::{Trie, MemoryDB, PrefixedMemoryDB, DBValue, default_child_trie_root, read_trie_value, read_child_trie_value, - for_keys_in_child_trie, KeySpacedDB}; + for_keys_in_child_trie, KeySpacedDB, TrieDBIterator}; use sp_trie::trie_types::{TrieDB, TrieError, Layout}; use crate::{backend::Consolidate, StorageKey, StorageValue}; use sp_core::storage::ChildInfo; @@ -252,16 +252,11 @@ impl, H: Hasher> TrieBackendEssence where H::Out: let mut iter = move |db| -> Result<(), Box>> { let trie = TrieDB::::new(db, root)?; - let mut iter = trie.iter()?; - iter.seek(prefix)?; - - for x in iter { + for x in TrieDBIterator::new_prefixed(&trie, prefix)? { let (key, value) = x?; - if !key.starts_with(prefix) { - break; - } + debug_assert!(key.starts_with(prefix)); f(&key, &value); } diff --git a/primitives/trie/src/lib.rs b/primitives/trie/src/lib.rs index c71d3fb84c..0cf268856b 100644 --- a/primitives/trie/src/lib.rs +++ b/primitives/trie/src/lib.rs @@ -37,7 +37,7 @@ pub use trie_stream::TrieStream; pub use node_codec::NodeCodec; /// Various re-exports from the `trie-db` crate. pub use trie_db::{ - Trie, TrieMut, DBValue, Recorder, CError, Query, TrieLayout, TrieConfiguration, nibble_ops, + Trie, TrieMut, DBValue, Recorder, CError, Query, TrieLayout, TrieConfiguration, nibble_ops, TrieDBIterator, }; /// Various re-exports from the `memory-db` crate. pub use memory_db::KeyFunction; -- GitLab From a5a61df9c442339a8b67fc467ea990867431f355 Mon Sep 17 00:00:00 2001 From: Hayden Bakkum <53467950+hbakkum-dotstar@users.noreply.github.com> Date: Tue, 11 Feb 2020 22:35:58 +1300 Subject: [PATCH 127/180] Add support for json output in subkey (#4882) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add support for json output in subkey * Updates as per code review * Apply suggestions from code review Co-Authored-By: Nikolay Volf * Apply suggestions from code review Co-Authored-By: Bastian Köcher * Clean up error handler as per code review * Apply suggestions from code review Co-Authored-By: Marcio Diaz * Fix compilation error * Remove accidental file commit Co-authored-by: Nikolay Volf Co-authored-by: Bastian Köcher Co-authored-by: Marcio Diaz --- Cargo.lock | 1 + bin/utils/subkey/Cargo.toml | 1 + bin/utils/subkey/src/main.rs | 146 ++++++++++++++++++++++++++--------- 3 files changed, 112 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 76d3d004c5..7564a72a01 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7454,6 +7454,7 @@ dependencies = [ "rpassword", "rustc-hex", "sc-rpc", + "serde_json", "sp-core", "sp-runtime", "substrate-bip39", diff --git a/bin/utils/subkey/Cargo.toml b/bin/utils/subkey/Cargo.toml index 9b7db6699f..d352cf28fa 100644 --- a/bin/utils/subkey/Cargo.toml +++ b/bin/utils/subkey/Cargo.toml @@ -28,6 +28,7 @@ derive_more = { version = "0.99.2" } sc-rpc = { version = "2.0.0", path = "../../../client/rpc" } jsonrpc-core-client = { version = "14.0.3", features = ["http"] } hyper = "0.12.35" +serde_json = "1.0" [features] bench = [] diff --git a/bin/utils/subkey/src/main.rs b/bin/utils/subkey/src/main.rs index c2fd7e28c2..52bacea384 100644 --- a/bin/utils/subkey/src/main.rs +++ b/bin/utils/subkey/src/main.rs @@ -25,6 +25,7 @@ use hex_literal::hex; use itertools::Itertools; use node_primitives::{Balance, Hash, Index, AccountId, Signature}; use node_runtime::{BalancesCall, Call, Runtime, SignedPayload, UncheckedExtrinsic, VERSION}; +use serde_json::json; use sp_core::{ crypto::{set_default_ss58_version, Ss58AddressFormat, Ss58Codec}, ed25519, sr25519, ecdsa, Pair, Public, H256, hexdisplay::HexDisplay, @@ -37,6 +38,24 @@ use std::{ mod rpc; mod vanity; +enum OutputType { + Json, + Text, +} + +impl<'a> TryFrom<&'a str> for OutputType { + type Error = (); + + fn try_from(s: &'a str) -> Result { + match s { + "json" => Ok(OutputType::Json), + "text" => Ok(OutputType::Text), + _ => Err(()), + } + } + +} + trait Crypto: Sized { type Pair: Pair; type Public: Public + Ss58Codec + AsRef<[u8]> + std::hash::Hash; @@ -55,50 +74,97 @@ trait Crypto: Sized { uri: &str, password: Option<&str>, network_override: Option, + output: OutputType, ) where ::Public: PublicT, { if let Ok((pair, seed)) = Self::Pair::from_phrase(uri, password) { let public_key = Self::public_from_pair(&pair); - println!("Secret phrase `{}` is account:\n \ - Secret seed: {}\n \ - Public key (hex): {}\n \ - Account ID: {}\n \ - SS58 Address: {}", - uri, - format_seed::(seed), - format_public_key::(public_key.clone()), - format_account_id::(public_key), - Self::ss58_from_pair(&pair) - ); + + match output { + OutputType::Json => { + let json = json!({ + "secretPhrase": uri, + "secretSeed": format_seed::(seed), + "publicKey": format_public_key::(public_key.clone()), + "accountId": format_account_id::(public_key), + "ss58Address": Self::ss58_from_pair(&pair), + }); + println!("{}", serde_json::to_string_pretty(&json).expect("Json pretty print failed")); + }, + OutputType::Text => { + println!("Secret phrase `{}` is account:\n \ + Secret seed: {}\n \ + Public key (hex): {}\n \ + Account ID: {}\n \ + SS58 Address: {}", + uri, + format_seed::(seed), + format_public_key::(public_key.clone()), + format_account_id::(public_key), + Self::ss58_from_pair(&pair), + ); + }, + } } else if let Ok((pair, seed)) = Self::Pair::from_string_with_seed(uri, password) { let public_key = Self::public_from_pair(&pair); - println!("Secret Key URI `{}` is account:\n \ - Secret seed: {}\n \ - Public key (hex): {}\n \ - Account ID: {}\n \ - SS58 Address: {}", - uri, - if let Some(seed) = seed { format_seed::(seed) } else { "n/a".into() }, - format_public_key::(public_key.clone()), - format_account_id::(public_key), - Self::ss58_from_pair(&pair) - ); + + match output { + OutputType::Json => { + let json = json!({ + "secretKeyUri": uri, + "secretSeed": if let Some(seed) = seed { format_seed::(seed) } else { "n/a".into() }, + "publicKey": format_public_key::(public_key.clone()), + "accountId": format_account_id::(public_key), + "ss58Address": Self::ss58_from_pair(&pair), + }); + println!("{}", serde_json::to_string_pretty(&json).expect("Json pretty print failed")); + }, + OutputType::Text => { + println!("Secret Key URI `{}` is account:\n \ + Secret seed: {}\n \ + Public key (hex): {}\n \ + Account ID: {}\n \ + SS58 Address: {}", + uri, + if let Some(seed) = seed { format_seed::(seed) } else { "n/a".into() }, + format_public_key::(public_key.clone()), + format_account_id::(public_key), + Self::ss58_from_pair(&pair), + ); + }, + } + } else if let Ok((public_key, v)) = ::Public::from_string_with_version(uri) { let v = network_override.unwrap_or(v); - println!("Public Key URI `{}` is account:\n \ - Network ID/version: {}\n \ - Public key (hex): {}\n \ - Account ID: {}\n \ - SS58 Address: {}", - uri, - String::from(v), - format_public_key::(public_key.clone()), - format_account_id::(public_key.clone()), - public_key.to_ss58check_with_version(v) - ); + + match output { + OutputType::Json => { + let json = json!({ + "publicKeyUri": uri, + "networkId": String::from(v), + "publicKey": format_public_key::(public_key.clone()), + "accountId": format_account_id::(public_key.clone()), + "ss58Address": public_key.to_ss58check_with_version(v), + }); + println!("{}", serde_json::to_string_pretty(&json).expect("Json pretty print failed")); + }, + OutputType::Text => { + println!("Public Key URI `{}` is account:\n \ + Network ID/version: {}\n \ + Public key (hex): {}\n \ + Account ID: {}\n \ + SS58 Address: {}", + uri, + String::from(v), + format_public_key::(public_key.clone()), + format_account_id::(public_key.clone()), + public_key.to_ss58check_with_version(v), + ); + }, + } } else { println!("Invalid phrase/URI given"); } @@ -165,6 +231,7 @@ fn get_usage() -> String { [network] -n, --network 'Specify a network. One of {}. Default is {}' [password] -p, --password 'The password for the key' --password-interactive 'You will be prompted for the password for the key.' + [output] -o, --output 'Specify an output format. One of text, json. Default is text.' ", networks, default_network) } @@ -329,13 +396,20 @@ where if let Some(network) = maybe_network { set_default_ss58_version(network); } + + let output: OutputType = match matches.value_of("output").map(TryInto::try_into) { + Some(Err(_)) => return Err(Error::Static("Invalid output name. See --help for available outputs.")), + Some(Ok(v)) => v, + None => OutputType::Text, + }; + match matches.subcommand() { ("generate", Some(matches)) => { let mnemonic = generate_mnemonic(matches)?; - C::print_from_uri(mnemonic.phrase(), password, maybe_network); + C::print_from_uri(mnemonic.phrase(), password, maybe_network, output); } ("inspect", Some(matches)) => { - C::print_from_uri(&get_uri("uri", &matches)?, password, maybe_network); + C::print_from_uri(&get_uri("uri", &matches)?, password, maybe_network, output); } ("sign", Some(matches)) => { let suri = get_uri("suri", &matches)?; @@ -364,7 +438,7 @@ where .unwrap_or_default(); let result = vanity::generate_key::(&desired)?; let formated_seed = format_seed::(result.seed); - C::print_from_uri(&formated_seed, None, maybe_network); + C::print_from_uri(&formated_seed, None, maybe_network, output); } ("transfer", Some(matches)) => { let signer = read_pair::(matches.value_of("from"), password)?; -- GitLab From 1dd662b5439841468a1f827a53731cb5ee91165b Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Tue, 11 Feb 2020 11:07:14 +0100 Subject: [PATCH 128/180] impl Randomness trait for Babe and remove unused RandomBeacon trait (#4886) * impl Randomness trait for Babe and remove unused RandomBeacon trait * bump runtime version --- bin/node/runtime/src/lib.rs | 2 +- frame/babe/src/lib.rs | 14 +++++++++----- frame/support/src/traits.rs | 5 ++++- primitives/runtime/src/traits.rs | 16 ---------------- 4 files changed, 14 insertions(+), 23 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index be9dbb9686..ca6ce955e6 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -82,7 +82,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 215, - impl_version: 1, + impl_version: 2, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index 1578d5c556..e707b9a10b 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -23,10 +23,10 @@ pub use pallet_timestamp; use sp_std::{result, prelude::*}; -use frame_support::{decl_storage, decl_module, traits::FindAuthor, traits::Get}; +use frame_support::{decl_storage, decl_module, traits::{FindAuthor, Get, Randomness as RandomnessT}}; use sp_timestamp::OnTimestampSet; use sp_runtime::{generic::DigestItem, ConsensusEngineId, Perbill}; -use sp_runtime::traits::{IsMember, SaturatedConversion, Saturating, RandomnessBeacon}; +use sp_runtime::traits::{IsMember, SaturatedConversion, Saturating, Hash}; use sp_staking::{ SessionIndex, offence::{Offence, Kind}, @@ -191,9 +191,13 @@ decl_module! { } } -impl RandomnessBeacon for Module { - fn random() -> [u8; VRF_OUTPUT_LENGTH] { - Self::randomness() +impl RandomnessT<::Hash> for Module { + fn random(subject: &[u8]) -> T::Hash { + let mut subject = subject.to_vec(); + subject.reserve(VRF_OUTPUT_LENGTH); + subject.extend_from_slice(&Self::randomness()[..]); + + ::Hashing::hash(&subject[..]) } } diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index ba8a0d7ded..f456ef5bec 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -767,7 +767,10 @@ pub trait Randomness { /// Get a "random" value /// /// Being a deterministic blockchain, real randomness is difficult to come by. This gives you - /// something that approximates it. `subject` is a context identifier and allows you to get a + /// something that approximates it. At best, this will be randomness which was + /// hard to predict a long time ago, but that has become easy to predict recently. + /// + /// `subject` is a context identifier and allows you to get a /// different result to other callers of this function; use it like /// `random(&b"my context"[..])`. fn random(subject: &[u8]) -> Output; diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index e95fc073eb..645725e1bf 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -476,22 +476,6 @@ sp_core::impl_maybe_marker!( trait MaybeMallocSizeOf: parity_util_mem::MallocSizeOf; ); -/// A type that provides a randomness beacon. -pub trait RandomnessBeacon { - /// Returns 32 bytes of random data. The output will change eventually, but - /// is not guaranteed to be different between any two calls. - /// - /// # 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 - /// cryptographic protocols, however, so long as one remembers that this - /// (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]; -} - /// A type that can be used in runtime structures. pub trait Member: Send + Sync + Sized + Debug + Eq + PartialEq + Clone + 'static {} impl Member for T {} -- GitLab From 60f05698c9fefe7efe38e8d7508190f10a4fde7b Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 11 Feb 2020 12:22:25 +0100 Subject: [PATCH 129/180] Pause Kademlia if too many connections (#4828) * Pause Kademlia if too many connections * Fix test * Update client/network/src/discovery.rs Co-Authored-By: Toralf Wittner * Change the limit Co-authored-by: Toralf Wittner --- client/network/src/behaviour.rs | 4 +++- client/network/src/discovery.rs | 26 +++++++++++++++++++++----- client/network/src/service.rs | 1 + 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index 8b903cec35..a1f54654b3 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -65,6 +65,7 @@ impl, H: ExHashT> Behaviour { known_addresses: Vec<(PeerId, Multiaddr)>, enable_mdns: bool, allow_private_ipv4: bool, + discovery_only_if_under_num: u64, ) -> Self { Behaviour { substrate, @@ -73,7 +74,8 @@ impl, H: ExHashT> Behaviour { local_public_key, known_addresses, enable_mdns, - allow_private_ipv4 + allow_private_ipv4, + discovery_only_if_under_num, ).await, events: Vec::new(), } diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index de49913b26..2da69e1894 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -87,6 +87,8 @@ pub struct DiscoveryBehaviour { /// If false, `addresses_of_peer` won't return any private IPv4 address, except for the ones /// stored in `user_defined`. allow_private_ipv4: bool, + /// Number of active connections over which we interrupt the discovery process. + discovery_only_if_under_num: u64, } impl DiscoveryBehaviour { @@ -98,6 +100,7 @@ impl DiscoveryBehaviour { user_defined: Vec<(PeerId, Multiaddr)>, enable_mdns: bool, allow_private_ipv4: bool, + discovery_only_if_under_num: u64, ) -> Self { if enable_mdns { #[cfg(target_os = "unknown")] @@ -120,6 +123,7 @@ impl DiscoveryBehaviour { local_peer_id: local_public_key.into_peer_id(), num_connections: 0, allow_private_ipv4, + discovery_only_if_under_num, #[cfg(not(target_os = "unknown"))] mdns: if enable_mdns { match Mdns::new() { @@ -331,11 +335,19 @@ where // Poll the stream that fires when we need to start a random Kademlia query. while let Poll::Ready(_) = self.next_kad_random_query.poll_unpin(cx) { - let random_peer_id = PeerId::random(); - debug!(target: "sub-libp2p", "Libp2p <= Starting random Kademlia request for \ - {:?}", random_peer_id); + if self.num_connections < self.discovery_only_if_under_num { + let random_peer_id = PeerId::random(); + debug!(target: "sub-libp2p", "Libp2p <= Starting random Kademlia request for \ + {:?}", random_peer_id); - self.kademlia.get_closest_peers(random_peer_id); + self.kademlia.get_closest_peers(random_peer_id); + } else { + debug!( + target: "sub-libp2p", + "Kademlia paused due to high number of connections ({})", + self.num_connections + ); + } // Schedule the next random query with exponentially increasing delay, // capped at 60 seconds. @@ -435,6 +447,10 @@ where NetworkBehaviourAction::GenerateEvent(event) => { match event { MdnsEvent::Discovered(list) => { + if self.num_connections >= self.discovery_only_if_under_num { + continue; + } + self.discoveries.extend(list.into_iter().map(|(peer_id, _)| peer_id)); if let Some(peer_id) = self.discoveries.pop_front() { let ev = DiscoveryOut::Discovered(peer_id); @@ -502,7 +518,7 @@ mod tests { let user_defined = user_defined.clone(); let keypair_public = keypair.public(); async move { - DiscoveryBehaviour::new(keypair_public, user_defined, false, true).await + DiscoveryBehaviour::new(keypair_public, user_defined, false, true, 50).await } }); let mut swarm = Swarm::new(transport, behaviour, keypair.public().into_peer_id()); diff --git a/client/network/src/service.rs b/client/network/src/service.rs index e3eaf6c31d..b4281112f6 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -232,6 +232,7 @@ impl, H: ExHashT> NetworkWorker TransportConfig::MemoryOnly => false, TransportConfig::Normal { allow_private_ipv4, .. } => allow_private_ipv4, }, + u64::from(params.network_config.out_peers) + 15, )); let (transport, bandwidth) = { let (config_mem, config_wasm) = match params.network_config.transport { -- GitLab From 657484a45b1f941b695c01ff3b944a4d81bd1849 Mon Sep 17 00:00:00 2001 From: Marcio Diaz Date: Tue, 11 Feb 2020 13:59:52 +0100 Subject: [PATCH 130/180] Refactor tx factory 1 (#4870) * Remove modes. * Refactor. --- bin/node/cli/src/cli.rs | 33 +--- bin/node/cli/src/command.rs | 5 +- bin/node/cli/src/factory_impl.rs | 124 +++--------- .../transaction-factory/src/complex_mode.rs | 157 --------------- bin/node/transaction-factory/src/lib.rs | 182 ++++++++---------- bin/node/transaction-factory/src/modes.rs | 40 ---- .../transaction-factory/src/simple_modes.rs | 112 ----------- 7 files changed, 113 insertions(+), 540 deletions(-) delete mode 100644 bin/node/transaction-factory/src/complex_mode.rs delete mode 100644 bin/node/transaction-factory/src/modes.rs delete mode 100644 bin/node/transaction-factory/src/simple_modes.rs diff --git a/bin/node/cli/src/cli.rs b/bin/node/cli/src/cli.rs index dd3ee4a596..7844c2c0a5 100644 --- a/bin/node/cli/src/cli.rs +++ b/bin/node/cli/src/cli.rs @@ -52,34 +52,13 @@ pub enum Subcommand { /// Please note: this command currently only works on an empty database! #[derive(Debug, StructOpt, Clone)] pub struct FactoryCmd { - /// How often to repeat. This option only has an effect in mode `MasterToNToM`. - #[structopt(long="rounds", default_value = "1")] - pub rounds: u64, + /// Number of blocks to generate. + #[structopt(long="blocks", default_value = "1")] + pub blocks: u32, - /// MasterToN: Manufacture `num` transactions from the master account - /// to `num` randomly created accounts, one each. - /// - /// MasterTo1: Manufacture `num` transactions from the master account - /// to exactly one other randomly created account. - /// - /// MasterToNToM: Manufacture `num` transactions from the master account - /// to `num` randomly created accounts. - /// From each of these randomly created accounts manufacture - /// a transaction to another randomly created account. - /// Repeat this `rounds` times. If `rounds` = 1 the behavior - /// is the same as `MasterToN`.{n} - /// A -> B, A -> C, A -> D, ... x `num`{n} - /// B -> E, C -> F, D -> G, ...{n} - /// ... x `rounds` - /// - /// These three modes control manufacturing. - #[structopt(long="mode", default_value = "MasterToN")] - pub mode: node_transaction_factory::Mode, - - /// Number of transactions to generate. In mode `MasterNToNToM` this is - /// the number of transactions per round. - #[structopt(long="num", default_value = "8")] - pub num: u64, + /// Number of transactions to push per block. + #[structopt(long="transactions", default_value = "8")] + pub transactions: u32, #[allow(missing_docs)] #[structopt(flatten)] diff --git a/bin/node/cli/src/command.rs b/bin/node/cli/src/command.rs index 3bfed148f5..61d1051796 100644 --- a/bin/node/cli/src/command.rs +++ b/bin/node/cli/src/command.rs @@ -67,9 +67,8 @@ where } let factory_state = FactoryState::new( - cli_args.mode.clone(), - cli_args.num, - cli_args.rounds, + cli_args.blocks, + cli_args.transactions, ); let service_builder = new_full_start!(config).0; diff --git a/bin/node/cli/src/factory_impl.rs b/bin/node/cli/src/factory_impl.rs index a1c5a5f4e0..1d1eabe29c 100644 --- a/bin/node/cli/src/factory_impl.rs +++ b/bin/node/cli/src/factory_impl.rs @@ -33,7 +33,6 @@ use sp_runtime::{ generic::Era, traits::{Block as BlockT, Header as HeaderT, SignedExtension, Verify, IdentifyAccount} }; use node_transaction_factory::RuntimeAdapter; -use node_transaction_factory::modes::Mode; use sp_inherents::InherentData; use sp_timestamp; use sp_finality_tracker; @@ -41,14 +40,10 @@ use sp_finality_tracker; type AccountPublic = ::Signer; pub struct FactoryState { - block_no: N, - - mode: Mode, - start_number: u32, - rounds: u32, - round: u32, - block_in_round: u32, - num: u32, + blocks: u32, + transactions: u32, + block_number: N, + index: u32, } type Number = <::Header as HeaderT>::Number; @@ -78,63 +73,35 @@ impl RuntimeAdapter for FactoryState { type Number = Number; fn new( - mode: Mode, - num: u64, - rounds: u64, + blocks: u32, + transactions: u32, ) -> FactoryState { FactoryState { - mode, - num: num as u32, - round: 0, - rounds: rounds as u32, - block_in_round: 0, - block_no: 0, - start_number: 0, + blocks, + transactions, + block_number: 0, + index: 0, } } - fn block_no(&self) -> Self::Number { - self.block_no - } - - fn block_in_round(&self) -> Self::Number { - self.block_in_round - } - - fn rounds(&self) -> Self::Number { - self.rounds - } - - fn num(&self) -> Self::Number { - self.num - } - - fn round(&self) -> Self::Number { - self.round - } - - fn start_number(&self) -> Self::Number { - self.start_number - } - - fn mode(&self) -> &Mode { - &self.mode + fn block_number(&self) -> u32 { + self.block_number } - fn set_block_no(&mut self, val: Self::Number) { - self.block_no = val; + fn blocks(&self) -> u32 { + self.blocks } - fn set_block_in_round(&mut self, val: Self::Number) { - self.block_in_round = val; + fn transactions(&self) -> u32 { + self.transactions } - fn set_round(&mut self, val: Self::Number) { - self.round = val; + fn set_block_number(&mut self, value: u32) { + self.block_number = value; } fn transfer_extrinsic( - &self, + &mut self, sender: &Self::AccountId, key: &Self::Secret, destination: &Self::AccountId, @@ -143,10 +110,12 @@ impl RuntimeAdapter for FactoryState { genesis_hash: &::Hash, prior_block_hash: &::Hash, ) -> ::Extrinsic { - let index = self.extract_index(&sender, prior_block_hash); - let phase = self.extract_phase(*prior_block_hash); + let phase = self.block_number() as Self::Phase; + let extra = Self::build_extra(self.index, phase); + self.index += 1; + sign::(CheckedExtrinsic { - signed: Some((sender.clone(), Self::build_extra(index, phase))), + signed: Some((sender.clone(), extra)), function: Call::Balances( BalancesCall::transfer( pallet_indices::address::Address::Id(destination.clone().into()), @@ -157,12 +126,12 @@ impl RuntimeAdapter for FactoryState { } fn inherent_extrinsics(&self) -> InherentData { - let timestamp = (self.block_no as u64 + 1) * MinimumPeriod::get(); + let timestamp = (self.block_number as u64 + 1) * MinimumPeriod::get(); let mut inherent = InherentData::new(); inherent.put_data(sp_timestamp::INHERENT_IDENTIFIER, ×tamp) .expect("Failed putting timestamp inherent"); - inherent.put_data(sp_finality_tracker::INHERENT_IDENTIFIER, &self.block_no) + inherent.put_data(sp_finality_tracker::INHERENT_IDENTIFIER, &self.block_number) .expect("Failed putting finalized number inherent"); inherent } @@ -180,49 +149,16 @@ impl RuntimeAdapter for FactoryState { } /// Generates a random `AccountId` from `seed`. - fn gen_random_account_id(seed: &Self::Number) -> Self::AccountId { - let pair: sr25519::Pair = sr25519::Pair::from_seed(&gen_seed_bytes(*seed)); + fn gen_random_account_id(seed: u32) -> Self::AccountId { + let pair: sr25519::Pair = sr25519::Pair::from_seed(&gen_seed_bytes(seed)); AccountPublic::from(pair.public()).into_account() } /// Generates a random `Secret` from `seed`. - fn gen_random_account_secret(seed: &Self::Number) -> Self::Secret { - let pair: sr25519::Pair = sr25519::Pair::from_seed(&gen_seed_bytes(*seed)); + fn gen_random_account_secret(seed: u32) -> Self::Secret { + let pair: sr25519::Pair = sr25519::Pair::from_seed(&gen_seed_bytes(seed)); pair } - - fn extract_index( - &self, - _account_id: &Self::AccountId, - _block_hash: &::Hash, - ) -> Self::Index { - // TODO get correct index for account via api. See #2587. - // This currently prevents the factory from being used - // without a preceding purge of the database. - if self.mode == Mode::MasterToN || self.mode == Mode::MasterTo1 { - self.block_no() as Self::Index - } else { - match self.round() { - 0 => - // if round is 0 all transactions will be done with master as a sender - self.block_no() as Self::Index, - _ => - // if round is e.g. 1 every sender account will be new and not yet have - // any transactions done - 0 - } - } - } - - fn extract_phase( - &self, - _block_hash: ::Hash - ) -> Self::Phase { - // TODO get correct phase via api. See #2587. - // This currently prevents the factory from being used - // without a preceding purge of the database. - self.block_no() as Self::Phase - } } fn gen_seed_bytes(seed: u32) -> [u8; 32] { diff --git a/bin/node/transaction-factory/src/complex_mode.rs b/bin/node/transaction-factory/src/complex_mode.rs deleted file mode 100644 index 6d7e60c8d3..0000000000 --- a/bin/node/transaction-factory/src/complex_mode.rs +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright 2019-2020 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 . - -/// This module implements the `MasterToNToM` mode: -/// -/// Manufacture `num` transactions from the master account to `num` -/// randomly created accounts. From each of these randomly created -/// accounts manufacture a transaction to another randomly created -/// account. -/// Repeat this round `rounds` times. If `rounds` = 1 the behavior -/// is the same as `MasterToN`. -/// -/// A -> B -/// A -> C -/// A -> D -/// ... x `num` -/// -/// B -> E -/// C -> F -/// D -> G -/// ... -/// E -> H -/// F -> I -/// G -> J -/// ... -/// ... x `rounds` - -use std::sync::Arc; - -use log::info; -use sc_client::Client; -use sp_block_builder::BlockBuilder; -use sp_api::{ConstructRuntimeApi, ProvideRuntimeApi}; -use sp_runtime::generic::BlockId; -use sp_runtime::traits::{Block as BlockT, One, Zero}; - -use crate::{RuntimeAdapter, create_block}; - -pub fn next( - factory_state: &mut RA, - client: &Arc>, - version: u32, - genesis_hash: ::Hash, - prior_block_hash: ::Hash, - prior_block_id: BlockId, -) -> Option -where - Block: BlockT, - Exec: sc_client::CallExecutor + Send + Sync + Clone, - Backend: sc_client_api::backend::Backend + Send, - Client: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: - BlockBuilder + - sp_api::ApiExt, - RtApi: ConstructRuntimeApi> + Send + Sync, - RA: RuntimeAdapter, -{ - let total = factory_state.start_number() + factory_state.num() * factory_state.rounds(); - - if factory_state.block_no() >= total || factory_state.round() >= factory_state.rounds() { - return None; - } - - info!( - "Round {}: Creating {} transactions in total, {} per round. {} rounds in total.", - factory_state.round() + RA::Number::one(), - factory_state.num() * factory_state.rounds(), - factory_state.num(), - factory_state.rounds(), - ); - - let from = from::(factory_state); - - let seed = factory_state.start_number() + factory_state.block_no(); - let to = RA::gen_random_account_id(&seed); - - let rounds_left = factory_state.rounds() - factory_state.round(); - let amount = RA::minimum_balance() * rounds_left.into(); - - let transfer = factory_state.transfer_extrinsic( - &from.0, - &from.1, - &to, - &amount, - version, - &genesis_hash, - &prior_block_hash, - ); - - let inherents = factory_state.inherent_extrinsics(); - let inherents = client.runtime_api().inherent_extrinsics(&prior_block_id, inherents) - .expect("Failed to create inherent extrinsics"); - - let block = create_block::(&client, transfer, inherents); - info!( - "Created block {} with hash {}. Transferring {} from {} to {}.", - factory_state.block_no() + RA::Number::one(), - prior_block_hash, - amount, - from.0, - to - ); - - factory_state.set_block_no(factory_state.block_no() + RA::Number::one()); - - let new_round = factory_state.block_no() > RA::Number::zero() - && factory_state.block_no() % factory_state.num() == RA::Number::zero(); - if new_round { - factory_state.set_round(factory_state.round() + RA::Number::one()); - factory_state.set_block_in_round(RA::Number::zero()); - } else { - factory_state.set_block_in_round(factory_state.block_in_round() + RA::Number::one()); - } - - Some(block) -} - -/// Return the account which received tokens at this point in the previous round. -fn from( - factory_state: &mut RA -) -> (::AccountId, ::Secret) -where RA: RuntimeAdapter -{ - let is_first_round = factory_state.round() == RA::Number::zero(); - match is_first_round { - true => { - // first round always uses master account - (RA::master_account_id(), RA::master_account_secret()) - }, - _ => { - // the account to which was sent in the last round - let is_round_one = factory_state.round() == RA::Number::one(); - let seed = match is_round_one { - true => factory_state.start_number() + factory_state.block_in_round(), - _ => { - let block_no_in_prior_round = - factory_state.num() * (factory_state.round() - RA::Number::one()) + factory_state.block_in_round(); - factory_state.start_number() + block_no_in_prior_round - } - }; - (RA::gen_random_account_id(&seed), RA::gen_random_account_secret(&seed)) - }, - } -} diff --git a/bin/node/transaction-factory/src/lib.rs b/bin/node/transaction-factory/src/lib.rs index a0c6a4f663..12c24e4f2f 100644 --- a/bin/node/transaction-factory/src/lib.rs +++ b/bin/node/transaction-factory/src/lib.rs @@ -39,11 +39,6 @@ use sp_runtime::generic::BlockId; use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, SimpleArithmetic, One, Zero, }; -pub use crate::modes::Mode; - -pub mod modes; -mod complex_mode; -mod simple_modes; pub trait RuntimeAdapter { type AccountId: Display; @@ -54,22 +49,16 @@ pub trait RuntimeAdapter { type Phase: Copy; type Secret; - fn new(mode: Mode, rounds: u64, start_number: u64) -> Self; + fn new(blocks: u32, transactions: u32) -> Self; - fn block_no(&self) -> Self::Number; - fn block_in_round(&self) -> Self::Number; - fn mode(&self) -> &Mode; - fn num(&self) -> Self::Number; - fn rounds(&self) -> Self::Number; - fn round(&self) -> Self::Number; - fn start_number(&self) -> Self::Number; + fn blocks(&self) -> u32; + fn transactions(&self) -> u32; - fn set_block_in_round(&mut self, val: Self::Number); - fn set_block_no(&mut self, val: Self::Number); - fn set_round(&mut self, val: Self::Number); + fn block_number(&self) -> u32; + fn set_block_number(&mut self, value: u32); fn transfer_extrinsic( - &self, + &mut self, sender: &Self::AccountId, key: &Self::Secret, destination: &Self::AccountId, @@ -84,14 +73,12 @@ pub trait RuntimeAdapter { fn minimum_balance() -> Self::Balance; fn master_account_id() -> Self::AccountId; fn master_account_secret() -> Self::Secret; - fn extract_index(&self, account_id: &Self::AccountId, block_hash: &::Hash) -> Self::Index; - fn extract_phase(&self, block_hash: ::Hash) -> Self::Phase; - fn gen_random_account_id(seed: &Self::Number) -> Self::AccountId; - fn gen_random_account_secret(seed: &Self::Number) -> Self::Secret; + + fn gen_random_account_id(seed: u32) -> Self::AccountId; + fn gen_random_account_secret(seed: u32) -> Self::Secret; } -/// Manufactures transactions. The exact amount depends on -/// `mode`, `num` and `rounds`. +/// Manufactures transactions. The exact amount depends on `num` and `rounds`. pub fn factory( mut factory_state: RA, client: &Arc>, @@ -110,11 +97,6 @@ where RA: RuntimeAdapter, Block::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(sc_cli::error::Error::Input(msg)); - } - 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(); @@ -123,89 +105,75 @@ where let genesis_hash = client.block_hash(Zero::zero())? .expect("Genesis block always exists; qed").into(); - while let Some(block) = match factory_state.mode() { - Mode::MasterToNToM => complex_mode::next::( - &mut factory_state, - &client, - version, - genesis_hash, - best_hash.into(), - best_block_id, - ), - _ => simple_modes::next::( - &mut factory_state, - &client, - version, - genesis_hash, - best_hash.into(), - best_block_id, - ), - } { + while factory_state.block_number() < factory_state.blocks() { + let from = (RA::master_account_id(), RA::master_account_secret()); + let amount = RA::minimum_balance(); + + let inherents = RA::inherent_extrinsics(&factory_state); + let inherents = client.runtime_api().inherent_extrinsics(&best_block_id, inherents) + .expect("Failed to create inherent extrinsics"); + + let tx_per_block = factory_state.transactions(); + + let mut block = client.new_block(Default::default()).expect("Failed to create new block"); + + for tx_num in 0..tx_per_block { + let seed = tx_num * (factory_state.block_number() + 1); + let to = RA::gen_random_account_id(seed); + + let transfer = factory_state.transfer_extrinsic( + &from.0, + &from.1, + &to, + &amount, + version, + &genesis_hash, + &best_hash, + ); + + info!("Pushing transfer {}/{} to {} into block.", tx_num + 1, tx_per_block, to); + + block.push( + Decode::decode(&mut &transfer.encode()[..]) + .expect("Failed to decode transfer extrinsic") + ).expect("Failed to push transfer extrinsic into block"); + } + + for inherent in inherents { + block.push(inherent).expect("Failed ..."); + } + + let block = block.build().expect("Failed to bake block").block; + + factory_state.set_block_number(factory_state.block_number() + 1); + + info!( + "Created block {} with hash {}.", + factory_state.block_number(), + best_hash, + ); + best_hash = block.header().hash(); best_block_id = BlockId::::hash(best_hash); - import_block(client.clone(), block); - info!("Imported block at {}", factory_state.block_no()); + let import = BlockImportParams { + origin: BlockOrigin::File, + header: block.header().clone(), + post_digests: Vec::new(), + body: Some(block.extrinsics().to_vec()), + storage_changes: None, + finalized: false, + justification: None, + auxiliary: Vec::new(), + intermediates: Default::default(), + fork_choice: Some(ForkChoiceStrategy::LongestChain), + allow_missing_state: false, + import_existing: false, + }; + client.clone().import_block(import, HashMap::new()).expect("Failed to import block"); + + info!("Imported block at {}", factory_state.block_number()); } Ok(()) } - -/// Create a baked block from a transfer extrinsic and timestamp inherent. -pub fn create_block( - client: &Arc>, - transfer: ::Extrinsic, - inherent_extrinsics: Vec<::Extrinsic>, -) -> Block -where - Block: BlockT, - Exec: sc_client::CallExecutor + Send + Sync + Clone, - Backend: sc_client_api::backend::Backend + Send, - Client: ProvideRuntimeApi, - RtApi: ConstructRuntimeApi> + Send + Sync, - as ProvideRuntimeApi>::Api: - BlockBuilder + - ApiExt, - RA: RuntimeAdapter, -{ - let mut block = client.new_block(Default::default()).expect("Failed to create new block"); - block.push( - Decode::decode(&mut &transfer.encode()[..]) - .expect("Failed to decode transfer extrinsic") - ).expect("Failed to push transfer extrinsic into block"); - - for inherent in inherent_extrinsics { - block.push(inherent).expect("Failed ..."); - } - - block.build().expect("Failed to bake block").block -} - -fn import_block( - mut client: Arc>, - block: Block -) -> () where - Block: BlockT, - Exec: sc_client::CallExecutor + Send + Sync + Clone, - Backend: sc_client_api::backend::Backend + Send, - Client: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: - sp_api::Core + - ApiExt, -{ - let import = BlockImportParams { - origin: BlockOrigin::File, - header: block.header().clone(), - post_digests: Vec::new(), - body: Some(block.extrinsics().to_vec()), - storage_changes: None, - finalized: false, - justification: None, - auxiliary: Vec::new(), - intermediates: Default::default(), - fork_choice: Some(ForkChoiceStrategy::LongestChain), - allow_missing_state: false, - import_existing: false, - }; - client.import_block(import, HashMap::new()).expect("Failed to import block"); -} diff --git a/bin/node/transaction-factory/src/modes.rs b/bin/node/transaction-factory/src/modes.rs deleted file mode 100644 index 5deab7635e..0000000000 --- a/bin/node/transaction-factory/src/modes.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2019-2020 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 . - -//! The transaction factory can operate in different modes. See -//! the `simple_mode` and `complex_mode` modules for details. - -use std::str::FromStr; - -/// Token distribution modes. -#[derive(Debug, Clone, PartialEq)] -pub enum Mode { - MasterToN, - MasterTo1, - MasterToNToM -} - -impl FromStr for Mode { - type Err = String; - fn from_str(mode: &str) -> Result { - match mode { - "MasterToN" => Ok(Mode::MasterToN), - "MasterTo1" => Ok(Mode::MasterTo1), - "MasterToNToM" => Ok(Mode::MasterToNToM), - _ => Err(format!("Invalid mode: {}", mode)), - } - } -} diff --git a/bin/node/transaction-factory/src/simple_modes.rs b/bin/node/transaction-factory/src/simple_modes.rs deleted file mode 100644 index fba328731a..0000000000 --- a/bin/node/transaction-factory/src/simple_modes.rs +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2019-2020 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 . - -/// This module implements two manufacturing modes: -/// -/// # MasterToN -/// Manufacture `num` transactions from the master account -/// to `num` randomly created accounts, one each. -/// -/// A -> B -/// A -> C -/// ... x `num` -/// -/// -/// # MasterTo1 -/// Manufacture `num` transactions from the master account -/// to exactly one other randomly created account. -/// -/// A -> B -/// A -> B -/// ... x `num` - -use std::sync::Arc; - -use log::info; -use sc_client::Client; -use sp_block_builder::BlockBuilder; -use sp_api::{ConstructRuntimeApi, ProvideRuntimeApi}; -use sp_runtime::traits::{Block as BlockT, One}; -use sp_runtime::generic::BlockId; - -use crate::{Mode, RuntimeAdapter, create_block}; - -pub fn next( - factory_state: &mut RA, - client: &Arc>, - version: u32, - genesis_hash: ::Hash, - prior_block_hash: ::Hash, - prior_block_id: BlockId, -) -> Option -where - Block: BlockT, - Exec: sc_client::CallExecutor + Send + Sync + Clone, - Backend: sc_client_api::backend::Backend + Send, - Client: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: - BlockBuilder + - sp_api::ApiExt, - RtApi: ConstructRuntimeApi> + Send + Sync, - RA: RuntimeAdapter, -{ - if factory_state.block_no() >= factory_state.num() { - return None; - } - - let from = (RA::master_account_id(), RA::master_account_secret()); - - let seed = match factory_state.mode() { - // choose the same receiver for all transactions - Mode::MasterTo1 => factory_state.start_number(), - - // different receiver for each transaction - Mode::MasterToN => factory_state.start_number() + factory_state.block_no(), - _ => unreachable!("Mode not covered!"), - }; - let to = RA::gen_random_account_id(&seed); - - let amount = RA::minimum_balance(); - - let transfer = factory_state.transfer_extrinsic( - &from.0, - &from.1, - &to, - &amount, - version, - &genesis_hash, - &prior_block_hash, - ); - - let inherents = RA::inherent_extrinsics(&factory_state); - let inherents = client.runtime_api().inherent_extrinsics(&prior_block_id, inherents) - .expect("Failed to create inherent extrinsics"); - - let block = create_block::(&client, transfer, inherents); - - factory_state.set_block_no(factory_state.block_no() + RA::Number::one()); - - info!( - "Created block {} with hash {}. Transferring {} from {} to {}.", - factory_state.block_no(), - prior_block_hash, - amount, - from.0, - to - ); - - Some(block) -} -- GitLab From 7647c39259553926c07f2a0ec20a597dae4613fe Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Tue, 11 Feb 2020 18:52:59 +0100 Subject: [PATCH 131/180] pallet-evm: optional nonce parameter (#4893) * pallet-evm: optional nonce parameter * Consume all gases when nonce mismatches * Bump node runtime version --- bin/node/runtime/src/lib.rs | 4 ++-- frame/evm/src/lib.rs | 36 ++++++++++++++++++++++-------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index ca6ce955e6..6c5b75482d 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -81,8 +81,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 215, - impl_version: 2, + spec_version: 216, + impl_version: 0, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index edd3d46a9a..7413292cd5 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -117,19 +117,19 @@ impl Precompiles for () { struct WeightForCallCreate; -impl WeighData<(&H160, &Vec, &U256, &u32, &U256)> for WeightForCallCreate { +impl WeighData<(&H160, &Vec, &U256, &u32, &U256, &Option)> for WeightForCallCreate { fn weigh_data( &self, - (_, _, _, gas_provided, gas_price): (&H160, &Vec, &U256, &u32, &U256) + (_, _, _, gas_provided, gas_price, _): (&H160, &Vec, &U256, &u32, &U256, &Option) ) -> Weight { (*gas_price).saturated_into::().saturating_mul(*gas_provided) } } -impl WeighData<(&Vec, &U256, &u32, &U256)> for WeightForCallCreate { +impl WeighData<(&Vec, &U256, &u32, &U256, &Option)> for WeightForCallCreate { fn weigh_data( &self, - (_, _, gas_provided, gas_price): (&Vec, &U256, &u32, &U256) + (_, _, gas_provided, gas_price, _): (&Vec, &U256, &u32, &U256, &Option) ) -> Weight { (*gas_price).saturated_into::().saturating_mul(*gas_provided) } @@ -197,6 +197,8 @@ decl_error! { ExitReasonRevert, /// Call returned VM fatal error ExitReasonFatal, + /// Nonce is invalid + InvalidNonce, } } @@ -258,6 +260,7 @@ decl_module! { value: U256, gas_limit: u32, gas_price: U256, + nonce: Option, ) -> DispatchResult { let sender = ensure_signed(origin)?; ensure!(gas_price >= T::FeeCalculator::min_gas_price(), Error::::GasPriceTooLow); @@ -278,13 +281,15 @@ decl_module! { let total_fee = gas_price.checked_mul(U256::from(gas_limit)) .ok_or(Error::::FeeOverflow)?; - if Accounts::get(&source).balance < - value.checked_add(total_fee).ok_or(Error::::PaymentOverflow)? - { - Err(Error::::BalanceLow)? - } + let total_payment = value.checked_add(total_fee).ok_or(Error::::PaymentOverflow)?; + let source_account = Accounts::get(&source); + ensure!(source_account.balance >= total_payment, Error::::BalanceLow); executor.withdraw(source, total_fee).map_err(|_| Error::::WithdrawFailed)?; + if let Some(nonce) = nonce { + ensure!(source_account.nonce == nonce, Error::::InvalidNonce); + } + let reason = executor.transact_call( source, target, @@ -317,6 +322,7 @@ decl_module! { value: U256, gas_limit: u32, gas_price: U256, + nonce: Option, ) -> DispatchResult { let sender = ensure_signed(origin)?; ensure!(gas_price >= T::FeeCalculator::min_gas_price(), Error::::GasPriceTooLow); @@ -338,13 +344,15 @@ decl_module! { let total_fee = gas_price.checked_mul(U256::from(gas_limit)) .ok_or(Error::::FeeOverflow)?; - if Accounts::get(&source).balance < - value.checked_add(total_fee).ok_or(Error::::PaymentOverflow)? - { - Err(Error::::BalanceLow)? - } + let total_payment = value.checked_add(total_fee).ok_or(Error::::PaymentOverflow)?; + let source_account = Accounts::get(&source); + ensure!(source_account.balance >= total_payment, Error::::BalanceLow); executor.withdraw(source, total_fee).map_err(|_| Error::::WithdrawFailed)?; + if let Some(nonce) = nonce { + ensure!(source_account.nonce == nonce, Error::::InvalidNonce); + } + let create_address = executor.create_address(source, evm::CreateScheme::Dynamic); let reason = executor.transact_create( source, -- GitLab From d0e354ad93630208f5f7c65a8f851d5d4b85d14d Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 11 Feb 2020 20:38:56 +0100 Subject: [PATCH 132/180] Increase the penality for being offline (#4889) --- client/peerset/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/peerset/src/lib.rs b/client/peerset/src/lib.rs index 7c7bbc6b36..bd2b6bb110 100644 --- a/client/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -30,7 +30,7 @@ use wasm_timer::Instant; /// We don't accept nodes whose reputation is under this value. const BANNED_THRESHOLD: i32 = 82 * (i32::min_value() / 100); /// Reputation change for a node when we get disconnected from it. -const DISCONNECT_REPUTATION_CHANGE: i32 = -10; +const DISCONNECT_REPUTATION_CHANGE: i32 = -256; /// Reserved peers group ID const RESERVED_NODES: &'static str = "reserved"; -- GitLab From 00a400f82539e2f78e8ddbcd98aea512c87c5f3c Mon Sep 17 00:00:00 2001 From: Hayden Bakkum <53467950+hbakkum-dotstar@users.noreply.github.com> Date: Wed, 12 Feb 2020 09:17:08 +1300 Subject: [PATCH 133/180] Add a sub command to generate a node key file (#4884) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add a sub command to generate a node key file in the format required by a substrate node * Update lock file * Apply suggestions from code review Co-Authored-By: Bastian Köcher * Updates as per code review Co-authored-by: Bastian Köcher --- Cargo.lock | 1 + bin/utils/subkey/Cargo.toml | 1 + bin/utils/subkey/src/main.rs | 15 +++++++++++++++ 3 files changed, 17 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 7564a72a01..0f214fe87a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7445,6 +7445,7 @@ dependencies = [ "hyper 0.12.35", "itertools", "jsonrpc-core-client", + "libp2p", "node-primitives", "node-runtime", "pallet-balances", diff --git a/bin/utils/subkey/Cargo.toml b/bin/utils/subkey/Cargo.toml index d352cf28fa..e29ee9a6c5 100644 --- a/bin/utils/subkey/Cargo.toml +++ b/bin/utils/subkey/Cargo.toml @@ -28,6 +28,7 @@ derive_more = { version = "0.99.2" } sc-rpc = { version = "2.0.0", path = "../../../client/rpc" } jsonrpc-core-client = { version = "14.0.3", features = ["http"] } hyper = "0.12.35" +libp2p = "0.15.0" serde_json = "1.0" [features] diff --git a/bin/utils/subkey/src/main.rs b/bin/utils/subkey/src/main.rs index 52bacea384..4d7e220642 100644 --- a/bin/utils/subkey/src/main.rs +++ b/bin/utils/subkey/src/main.rs @@ -23,6 +23,7 @@ use clap::{App, ArgMatches, SubCommand}; use codec::{Decode, Encode}; use hex_literal::hex; use itertools::Itertools; +use libp2p::identity::{ed25519 as libp2p_ed25519, PublicKey}; use node_primitives::{Balance, Hash, Index, AccountId, Signature}; use node_runtime::{BalancesCall, Call, Runtime, SignedPayload, UncheckedExtrinsic, VERSION}; use serde_json::json; @@ -248,6 +249,9 @@ fn get_app<'a, 'b>(usage: &'a str) -> App<'a, 'b> { 'The number of words in the phrase to generate. One of 12 \ (default), 15, 18, 21 and 24.' "), + SubCommand::with_name("generate-node-key") + .about("Generate a random node libp2p key, save it to file and print its peer ID") + .args_from_usage("[file] 'Name of file to save secret key to'"), SubCommand::with_name("inspect") .about("Gets a public key and a SS58 address from the provided Secret URI") .args_from_usage("[uri] 'A Key URI to be inspected. May be a secret seed, \ @@ -408,6 +412,17 @@ where let mnemonic = generate_mnemonic(matches)?; C::print_from_uri(mnemonic.phrase(), password, maybe_network, output); } + ("generate-node-key", Some(matches)) => { + let file = matches.value_of("file").ok_or(Error::Static("Output file name is required"))?; + + let keypair = libp2p_ed25519::Keypair::generate(); + let secret = keypair.secret(); + let peer_id = PublicKey::Ed25519(keypair.public()).into_peer_id(); + + fs::write(file, secret.as_ref())?; + + println!("{}", peer_id); + } ("inspect", Some(matches)) => { C::print_from_uri(&get_uri("uri", &matches)?, password, maybe_network, output); } -- GitLab From 10332c9a0ed4dfc3e32e9a8a13492fd6ff758c29 Mon Sep 17 00:00:00 2001 From: Marcio Diaz Date: Wed, 12 Feb 2020 11:00:08 +0100 Subject: [PATCH 134/180] Benchmark Timestamp Pallet (#4891) * Add selected_benchmark! macro. * Use selected_benchmark! in Identity pallet. * Implement timestamp pallet benchmark. * Fix some nits. * Bump impl_version. --- bin/node/runtime/src/lib.rs | 3 +- frame/identity/src/benchmarking.rs | 46 ++---------- frame/timestamp/Cargo.toml | 1 + frame/timestamp/src/benchmarking.rs | 105 ++++++++++++++++++++++++++++ frame/timestamp/src/lib.rs | 2 + primitives/runtime/src/traits.rs | 49 +++++++++++++ 6 files changed, 163 insertions(+), 43 deletions(-) create mode 100644 frame/timestamp/src/benchmarking.rs diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 6c5b75482d..209208c58f 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -82,7 +82,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 216, - impl_version: 0, + impl_version: 1, apis: RUNTIME_API_VERSIONS, }; @@ -813,6 +813,7 @@ impl_runtime_apis! { { match module.as_slice() { b"pallet-identity" | b"identity" => Identity::run_benchmark(extrinsic, steps, repeat).ok(), + b"pallet-timestamp" | b"timestamp" => Timestamp::run_benchmark(extrinsic, steps, repeat).ok(), _ => return None, } } diff --git a/frame/identity/src/benchmarking.rs b/frame/identity/src/benchmarking.rs index 0a4a143ea9..86ec6b30c9 100644 --- a/frame/identity/src/benchmarking.rs +++ b/frame/identity/src/benchmarking.rs @@ -20,7 +20,7 @@ use super::*; use frame_system::RawOrigin; use sp_io::hashing::blake2_256; -use sp_runtime::{BenchmarkResults, BenchmarkParameter}; +use sp_runtime::{BenchmarkResults, BenchmarkParameter, selected_benchmark}; use sp_runtime::traits::{Bounded, Benchmarking, BenchmarkingSetup, Dispatchable}; use crate::Module as Identity; @@ -514,7 +514,7 @@ impl BenchmarkingSetup, RawOrigin> for } // The list of available benchmarks for this pallet. -enum SelectedBenchmark { +selected_benchmark!( AddRegistrar, SetIdentity, SetSubs, @@ -525,46 +525,8 @@ enum SelectedBenchmark { SetAccountId, SetFields, ProvideJudgement, - KillIdentity, -} - -// Allow us to select a benchmark from the list of available benchmarks. - -impl BenchmarkingSetup, RawOrigin> for SelectedBenchmark { - fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { - match self { - Self::AddRegistrar => , RawOrigin>>::components(&AddRegistrar), - Self::SetIdentity => , RawOrigin>>::components(&SetIdentity), - Self::SetSubs => , RawOrigin>>::components(&SetSubs), - Self::ClearIdentity => , RawOrigin>>::components(&ClearIdentity), - Self::RequestJudgement => , RawOrigin>>::components(&RequestJudgement), - Self::CancelRequest => , RawOrigin>>::components(&CancelRequest), - Self::SetFee => , RawOrigin>>::components(&SetFee), - Self::SetAccountId => , RawOrigin>>::components(&SetAccountId), - Self::SetFields => , RawOrigin>>::components(&SetFields), - Self::ProvideJudgement => , RawOrigin>>::components(&ProvideJudgement), - Self::KillIdentity => , RawOrigin>>::components(&KillIdentity), - } - } - - fn instance(&self, components: &[(BenchmarkParameter, u32)]) - -> Result<(crate::Call, RawOrigin), &'static str> - { - match self { - Self::AddRegistrar => , RawOrigin>>::instance(&AddRegistrar, components), - Self::SetIdentity => , RawOrigin>>::instance(&SetIdentity, components), - Self::SetSubs => , RawOrigin>>::instance(&SetSubs, components), - Self::ClearIdentity => , RawOrigin>>::instance(&ClearIdentity, components), - Self::RequestJudgement => , RawOrigin>>::instance(&RequestJudgement, components), - Self::CancelRequest => , RawOrigin>>::instance(&CancelRequest, components), - Self::SetFee => , RawOrigin>>::instance(&SetFee, components), - Self::SetAccountId => , RawOrigin>>::instance(&SetAccountId, components), - Self::SetFields => , RawOrigin>>::instance(&SetFields, components), - Self::ProvideJudgement => , RawOrigin>>::instance(&ProvideJudgement, components), - Self::KillIdentity => , RawOrigin>>::instance(&KillIdentity, components), - } - } -} + KillIdentity +); impl Benchmarking for Module { fn run_benchmark(extrinsic: Vec, steps: u32, repeat: u32) -> Result, &'static str> { diff --git a/frame/timestamp/Cargo.toml b/frame/timestamp/Cargo.toml index f2d6f40582..e68392f9e9 100644 --- a/frame/timestamp/Cargo.toml +++ b/frame/timestamp/Cargo.toml @@ -9,6 +9,7 @@ license = "GPL-3.0" serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } 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-inherents = { version = "2.0.0", default-features = false, path = "../../primitives/inherents" } frame-support = { version = "2.0.0", default-features = false, path = "../support" } diff --git a/frame/timestamp/src/benchmarking.rs b/frame/timestamp/src/benchmarking.rs new file mode 100644 index 0000000000..55d6d7e046 --- /dev/null +++ b/frame/timestamp/src/benchmarking.rs @@ -0,0 +1,105 @@ +// Copyright 2020 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 . + +//! Timestamp pallet benchmarking. + +use super::*; + +use sp_std::prelude::*; + +use frame_system::RawOrigin; +use sp_runtime::{BenchmarkResults, BenchmarkParameter, selected_benchmark}; +use sp_runtime::traits::{Benchmarking, BenchmarkingSetup, Dispatchable}; + +/// Benchmark `set` extrinsic. +struct Set; +impl BenchmarkingSetup, RawOrigin> for Set { + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + vec![ + // Current time ("Now") + (BenchmarkParameter::N, 1, 100), + ] + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(Call, RawOrigin), &'static str> + { + let user_origin = RawOrigin::None; + let now = components.iter().find(|&c| c.0 == BenchmarkParameter::N).unwrap().1; + + // Return the `set` call + Ok((Call::::set(now.into()), user_origin)) + } +} + +selected_benchmark!(Set); + +impl Benchmarking for Module { + fn run_benchmark(extrinsic: Vec, steps: u32, repeat: u32) -> Result, &'static str> { + // Map the input to the selected benchmark. + let selected_benchmark = match extrinsic.as_slice() { + b"set" => SelectedBenchmark::Set, + _ => return Err("Could not find extrinsic."), + }; + + // Warm up the DB + sp_io::benchmarking::commit_db(); + sp_io::benchmarking::wipe_db(); + + let components = , RawOrigin>>::components(&selected_benchmark); + let mut results: Vec = Vec::new(); + + // Select the component we will be benchmarking. Each component will be benchmarked. + for (name, low, high) in components.iter() { + // Create up to `STEPS` steps for that component between high and low. + let step_size = ((high - low) / steps).max(1); + let num_of_steps = (high - low) / step_size; + for s in 0..num_of_steps { + // This is the value we will be testing for component `name` + let component_value = low + step_size * s; + + // Select the mid value for all the other components. + let c: Vec<(BenchmarkParameter, u32)> = components.iter() + .map(|(n, l, h)| + (*n, if n == name { component_value } else { (h - l) / 2 + l }) + ).collect(); + + // Run the benchmark `repeat` times. + for _ in 0..repeat { + // Set up the externalities environment for the setup we want to benchmark. + let (call, caller) = , + RawOrigin, + >>::instance(&selected_benchmark, &c)?; + // Commit the externalities to the database, flushing the DB cache. + // This will enable worst case scenario for reading from the database. + sp_io::benchmarking::commit_db(); + // Run the benchmark. + let start = sp_io::benchmarking::current_time(); + call.dispatch(caller.into())?; + let finish = sp_io::benchmarking::current_time(); + let elapsed = finish - start; + results.push((c.clone(), elapsed)); + // Wipe the DB back to the genesis state. + sp_io::benchmarking::wipe_db(); + } + } + } + + return Ok(results); + } +} diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index 1c16ed6380..c437c325cd 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -90,6 +90,8 @@ #![cfg_attr(not(feature = "std"), no_std)] +mod benchmarking; + use sp_std::{result, cmp}; use sp_inherents::{ProvideInherent, InherentData, InherentIdentifier}; use frame_support::{Parameter, decl_storage, decl_module}; diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 645725e1bf..c28fe555f7 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -1333,6 +1333,55 @@ pub trait BenchmarkingSetup { fn instance(&self, components: &[(BenchmarkParameter, u32)]) -> Result<(Call, RawOrigin), &'static str>; } +/// Creates a `SelectedBenchmark` enum implementing `BenchmarkingSetup`. +/// +/// Every variant must implement [`BenchmarkingSetup`](crate::traits::BenchmarkingSetup). +/// +/// ```nocompile +/// +/// struct Transfer; +/// impl BenchmarkingSetup for Transfer { ... } +/// +/// struct SetBalance; +/// impl BenchmarkingSetup for SetBalance { ... } +/// +/// selected_benchmark!(Transfer, SetBalance); +/// ``` +#[macro_export] +macro_rules! selected_benchmark { + ($($bench:ident),*) => { + // The list of available benchmarks for this pallet. + enum SelectedBenchmark { + $( $bench, )* + } + + // Allow us to select a benchmark from the list of available benchmarks. + impl $crate::traits::BenchmarkingSetup, RawOrigin> for SelectedBenchmark { + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + match self { + $( Self::$bench => <$bench as $crate::traits::BenchmarkingSetup< + T, + Call, + RawOrigin, + >>::components(&$bench), )* + } + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(Call, RawOrigin), &'static str> + { + match self { + $( Self::$bench => <$bench as $crate::traits::BenchmarkingSetup< + T, + Call, + RawOrigin, + >>::instance(&$bench, components), )* + } + } + } + }; +} + #[cfg(test)] mod tests { use super::*; -- GitLab From f5f7852af88a1008c5ade88bcadf003b8e3aff3d Mon Sep 17 00:00:00 2001 From: Toralf Wittner Date: Wed, 12 Feb 2020 11:24:25 +0100 Subject: [PATCH 135/180] Add command-line flag to enable yamux flow control. (#4892) * Add command-line flag to enable yamux flow control. We never enabled proper flow-control for yamux streams which may cause stream buffers to exceed their configured limit when the stream producer outpaces the stream consumer. By switching the window update mode to on-read, producers will only receive more sending credit when all data has been consumed from the stream buffer. Using this option creates backpressure on producers. However depending on the protocol there is a risk of deadlock, if both endpoints concurrently attempt to send more data than they have credit for and neither side reads before finishing their writes. To facilitate proper testing, this PR adds a command-line flag `use-yamux-flow-control`. * Replace comment with generic message. --- Cargo.lock | 1 + client/cli/src/lib.rs | 1 + client/cli/src/params.rs | 4 ++++ client/network/Cargo.toml | 1 + client/network/src/config.rs | 3 +++ client/network/src/service.rs | 10 +++++----- client/network/src/transport.rs | 18 +++++++++++++++--- client/service/test/src/lib.rs | 1 + utils/browser/src/lib.rs | 1 + 9 files changed, 32 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f214fe87a..8ac3012df7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6078,6 +6078,7 @@ dependencies = [ "unsigned-varint", "void", "wasm-timer", + "yamux", "zeroize 1.1.0", ] diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index a2e9fa96da..7495ad8e75 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -424,6 +424,7 @@ fn fill_network_configuration( enable_mdns: !is_dev && !cli.no_mdns, allow_private_ipv4: !cli.no_private_ipv4, wasm_external_transport: None, + use_yamux_flow_control: cli.use_yamux_flow_control }; config.max_parallel_downloads = cli.max_parallel_downloads; diff --git a/client/cli/src/params.rs b/client/cli/src/params.rs index 0881247b07..2ffa8bd61b 100644 --- a/client/cli/src/params.rs +++ b/client/cli/src/params.rs @@ -238,6 +238,10 @@ pub struct NetworkConfigurationParams { #[allow(missing_docs)] #[structopt(flatten)] pub node_key_params: NodeKeyParams, + + /// Experimental feature flag. + #[structopt(long = "use-yamux-flow-control")] + pub use_yamux_flow_control: bool, } arg_enum! { diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index 10d5f1ce9b..db3e32393d 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -48,6 +48,7 @@ substrate-test-runtime-client = { version = "2.0.0", optional = true, path = ".. unsigned-varint = { version = "0.3.0", features = ["codec"] } void = "1.0.2" zeroize = "1.0.0" +yamux = "0.4.2" [dev-dependencies] env_logger = "0.7.0" diff --git a/client/network/src/config.rs b/client/network/src/config.rs index 6cf2587fe4..87c77fee9f 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -292,6 +292,7 @@ impl Default for NetworkConfiguration { enable_mdns: false, allow_private_ipv4: true, wasm_external_transport: None, + use_yamux_flow_control: false, }, max_parallel_downloads: 5, } @@ -348,6 +349,8 @@ pub enum TransportConfig { /// This parameter exists whatever the target platform is, but it is expected to be set to /// `Some` only when compiling for WASM. wasm_external_transport: Option, + /// Use flow control for yamux streams if set to true. + use_yamux_flow_control: bool, }, /// Only allow connections within the same process. diff --git a/client/network/src/service.rs b/client/network/src/service.rs index b4281112f6..3dc8a49764 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -235,12 +235,12 @@ impl, H: ExHashT> NetworkWorker u64::from(params.network_config.out_peers) + 15, )); let (transport, bandwidth) = { - let (config_mem, config_wasm) = match params.network_config.transport { - TransportConfig::MemoryOnly => (true, None), - TransportConfig::Normal { wasm_external_transport, .. } => - (false, wasm_external_transport) + let (config_mem, config_wasm, flowctrl) = match params.network_config.transport { + TransportConfig::MemoryOnly => (true, None, false), + TransportConfig::Normal { wasm_external_transport, use_yamux_flow_control, .. } => + (false, wasm_external_transport, use_yamux_flow_control) }; - transport::build_transport(local_identity, config_mem, config_wasm) + transport::build_transport(local_identity, config_mem, config_wasm, flowctrl) }; let mut builder = SwarmBuilder::new(transport, behaviour, local_peer_id.clone()); if let Some(spawner) = params.executor { diff --git a/client/network/src/transport.rs b/client/network/src/transport.rs index 6b5c18cf33..e2c95824f8 100644 --- a/client/network/src/transport.rs +++ b/client/network/src/transport.rs @@ -17,7 +17,7 @@ use futures::prelude::*; use libp2p::{ InboundUpgradeExt, OutboundUpgradeExt, PeerId, Transport, - mplex, identity, yamux, bandwidth, wasm_ext + mplex, identity, bandwidth, wasm_ext }; #[cfg(not(target_os = "unknown"))] use libp2p::{tcp, dns, websocket, noise}; @@ -36,7 +36,8 @@ pub use self::bandwidth::BandwidthSinks; pub fn build_transport( keypair: identity::Keypair, memory_only: bool, - wasm_external_transport: Option + wasm_external_transport: Option, + use_yamux_flow_control: bool ) -> (Boxed<(PeerId, StreamMuxerBox), io::Error>, Arc) { // Build configuration objects for encryption mechanisms. #[cfg(not(target_os = "unknown"))] @@ -55,7 +56,18 @@ pub fn build_transport( let mut mplex_config = mplex::MplexConfig::new(); mplex_config.max_buffer_len_behaviour(mplex::MaxBufferBehaviour::Block); mplex_config.max_buffer_len(usize::MAX); - let yamux_config = yamux::Config::default(); + + let yamux_config = { + let mut c = yamux::Config::default(); + // Only set SYN flag on first data frame sent to the remote. + c.set_lazy_open(true); + if use_yamux_flow_control { + // Enable proper flow-control: window updates are only sent when + // buffered data has been consumed. + c.set_window_update_mode(yamux::WindowUpdateMode::OnRead); + } + libp2p::yamux::Config::new(c) + }; // Build the base layer of the transport. let transport = if let Some(t) = wasm_external_transport { diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 2976e66a29..723c13ec82 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -166,6 +166,7 @@ fn node_config ( enable_mdns: false, allow_private_ipv4: true, wasm_external_transport: None, + use_yamux_flow_control: true, }, max_parallel_downloads: NetworkConfiguration::default().max_parallel_downloads, }; diff --git a/utils/browser/src/lib.rs b/utils/browser/src/lib.rs index b054d73ac9..d82f982e14 100644 --- a/utils/browser/src/lib.rs +++ b/utils/browser/src/lib.rs @@ -53,6 +53,7 @@ where wasm_external_transport: Some(transport.clone()), allow_private_ipv4: true, enable_mdns: false, + use_yamux_flow_control: true, }; config.task_executor = Some(Arc::new(move |fut| { wasm_bindgen_futures::spawn_local(fut) -- GitLab From 2723b9cca8d6eaa5dedbfe15ba259d1009e1dcf2 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Wed, 12 Feb 2020 11:29:30 +0100 Subject: [PATCH 136/180] Do not allow zero Existential Deposit when using Balances (#4894) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add non-zero ed check on Balances genesis * Update ED from 0 to 1 * bump impl * bump spec * Found remove more ed = 0 * Fix some contract tests * Use ctx.overlay.set_balance for contracts * Fix staking test * Remove obsolete logic * Allow death of payout account in society * Update frame/balances/src/lib.rs Co-Authored-By: Bastian Köcher * Dont create genesis balances if balance is zero in transaction payment pallet Co-authored-by: Bastian Köcher Co-authored-by: Gavin Wood --- frame/balances/src/lib.rs | 4 ++++ frame/balances/src/mock.rs | 5 +---- frame/contracts/src/exec.rs | 11 ++++++++--- frame/contracts/src/tests.rs | 2 +- frame/democracy/src/lib.rs | 2 +- frame/elections/src/mock.rs | 2 +- frame/example/src/lib.rs | 2 +- frame/executive/src/lib.rs | 2 +- frame/identity/src/lib.rs | 2 +- frame/nicks/src/lib.rs | 2 +- frame/scored-pool/src/mock.rs | 2 +- frame/society/src/lib.rs | 4 ++-- frame/society/src/mock.rs | 2 +- frame/staking/src/mock.rs | 4 ++-- frame/staking/src/tests.rs | 5 +++-- frame/transaction-payment/src/lib.rs | 22 +++++++++++++--------- frame/utility/src/lib.rs | 2 +- 17 files changed, 43 insertions(+), 32 deletions(-) diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index 64932fb256..ac651a5c24 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -394,6 +394,10 @@ decl_storage! { config(balances): Vec<(T::AccountId, T::Balance)>; // ^^ begin, length, amount liquid at genesis build(|config: &GenesisConfig| { + assert!( + >::ExistentialDeposit::get() > Zero::zero(), + "The existential deposit should be greater than zero." + ); for (_, balance) in &config.balances { assert!( *balance >= >::ExistentialDeposit::get(), diff --git a/frame/balances/src/mock.rs b/frame/balances/src/mock.rs index 5eb722733f..8a651a0ff7 100644 --- a/frame/balances/src/mock.rs +++ b/frame/balances/src/mock.rs @@ -103,7 +103,7 @@ pub struct ExtBuilder { impl Default for ExtBuilder { fn default() -> Self { Self { - existential_deposit: 0, + existential_deposit: 1, creation_fee: 0, monied: false, } @@ -120,9 +120,6 @@ impl ExtBuilder { } pub fn monied(mut self, monied: bool) -> Self { self.monied = monied; - if self.existential_deposit == 0 { - self.existential_deposit = 1; - } self } pub fn set_associated_consts(&self) { diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index d0033e0bd1..e84fded920 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -1009,7 +1009,7 @@ mod tests { let mut gas_meter = GasMeter::::with_limit(1000, 1); - let result = ctx.instantiate(0, &mut gas_meter, &code, vec![]); + let result = ctx.instantiate(1, &mut gas_meter, &code, vec![]); assert_matches!(result, Ok(_)); let mut toks = gas_meter.tokens().iter(); @@ -1302,8 +1302,10 @@ mod tests { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ctx.overlay.set_balance(&ALICE, 1); + let result = ctx.instantiate( - 0, + 1, &mut GasMeter::::with_limit(10000, 1), &input_data_ch, vec![1, 2, 3, 4], @@ -1348,6 +1350,7 @@ mod tests { ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ctx.overlay.set_balance(&BOB, 1); ctx.overlay.instantiate_contract(&BOB, recurse_ch).unwrap(); let result = ctx.call( @@ -1661,8 +1664,10 @@ mod tests { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); + ctx.overlay.set_balance(&ALICE, 1); + let result = ctx.instantiate( - 0, + 1, &mut GasMeter::::with_limit(10000, 1), &rent_allowance_ch, vec![], diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 783eca02ca..9ee44a767a 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -235,7 +235,7 @@ pub struct ExtBuilder { impl Default for ExtBuilder { fn default() -> Self { Self { - existential_deposit: 0, + existential_deposit: 1, gas_price: 2, block_gas_limit: 100_000_000, transfer_fee: 0, diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index 9bf08840f4..d2033fa8b3 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -1229,7 +1229,7 @@ mod tests { type ModuleToIndex = (); } parameter_types! { - pub const ExistentialDeposit: u64 = 0; + pub const ExistentialDeposit: u64 = 1; pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Test { diff --git a/frame/elections/src/mock.rs b/frame/elections/src/mock.rs index 3274dd57b4..7cef8e3bdb 100644 --- a/frame/elections/src/mock.rs +++ b/frame/elections/src/mock.rs @@ -57,7 +57,7 @@ impl frame_system::Trait for Test { } parameter_types! { - pub const ExistentialDeposit: u64 = 0; + pub const ExistentialDeposit: u64 = 1; pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Test { diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index b3a86b6acd..b4e0f3d657 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -689,7 +689,7 @@ mod tests { type ModuleToIndex = (); } parameter_types! { - pub const ExistentialDeposit: u64 = 0; + pub const ExistentialDeposit: u64 = 1; pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Test { diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 93db141856..72411c904b 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -453,7 +453,7 @@ mod tests { type ModuleToIndex = (); } parameter_types! { - pub const ExistentialDeposit: u64 = 0; + pub const ExistentialDeposit: u64 = 1; pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Runtime { diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index c6fc0062be..c69239350c 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -926,7 +926,7 @@ mod tests { type ModuleToIndex = (); } parameter_types! { - pub const ExistentialDeposit: u64 = 0; + pub const ExistentialDeposit: u64 = 1; pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Test { diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index 82aea43ad4..814673a6ff 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -287,7 +287,7 @@ mod tests { type ModuleToIndex = (); } parameter_types! { - pub const ExistentialDeposit: u64 = 0; + pub const ExistentialDeposit: u64 = 1; pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Test { diff --git a/frame/scored-pool/src/mock.rs b/frame/scored-pool/src/mock.rs index fa8b11e69e..58acc9c8d7 100644 --- a/frame/scored-pool/src/mock.rs +++ b/frame/scored-pool/src/mock.rs @@ -46,7 +46,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); - pub const ExistentialDeposit: u64 = 0; + pub const ExistentialDeposit: u64 = 1; pub const CreationFee: u64 = 0; } ord_parameter_types! { diff --git a/frame/society/src/lib.rs b/frame/society/src/lib.rs index 28220f1063..0188ef7cb2 100644 --- a/frame/society/src/lib.rs +++ b/frame/society/src/lib.rs @@ -263,7 +263,7 @@ use frame_support::{decl_error, decl_module, decl_storage, decl_event, ensure, d use frame_support::weights::SimpleDispatchInfo; use frame_support::traits::{ Currency, ReservableCurrency, Randomness, Get, ChangeMembers, - ExistenceRequirement::{KeepAlive, AllowDeath}, + ExistenceRequirement::AllowDeath, }; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -788,7 +788,7 @@ decl_module! { let mut payouts = >::get(&who); if let Some((when, amount)) = payouts.first() { if when <= &>::block_number() { - T::Currency::transfer(&Self::payouts(), &who, *amount, KeepAlive)?; + T::Currency::transfer(&Self::payouts(), &who, *amount, AllowDeath)?; payouts.remove(0); if payouts.is_empty() { >::remove(&who); diff --git a/frame/society/src/mock.rs b/frame/society/src/mock.rs index 5c772478c8..9f202d6b17 100644 --- a/frame/society/src/mock.rs +++ b/frame/society/src/mock.rs @@ -50,7 +50,7 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); - pub const ExistentialDeposit: u64 = 0; + pub const ExistentialDeposit: u64 = 1; pub const CreationFee: u64 = 0; } diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 3b2443c2ce..7da30300f0 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -233,7 +233,7 @@ pub struct ExtBuilder { impl Default for ExtBuilder { fn default() -> Self { Self { - existential_deposit: 0, + existential_deposit: 1, validator_pool: false, nominate: true, validator_count: 2, @@ -290,7 +290,7 @@ impl ExtBuilder { pub fn build(self) -> sp_io::TestExternalities { self.set_associated_consts(); let mut storage = frame_system::GenesisConfig::default().build_storage::().unwrap(); - let balance_factor = if self.existential_deposit > 0 { + let balance_factor = if self.existential_deposit > 1 { 256 } else { 1 diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index f62a58e20b..e59f211b87 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -2066,7 +2066,8 @@ fn slash_in_old_span_does_not_deselect() { ), reporters: vec![], }], - &[Perbill::from_percent(100)], + // NOTE: A 100% slash here would clean up the account, causing de-registration. + &[Perbill::from_percent(95)], 1, ); @@ -2272,7 +2273,7 @@ fn only_slash_for_max_in_era() { #[test] fn garbage_collection_after_slashing() { - ExtBuilder::default().existential_deposit(1).build().execute_with(|| { + ExtBuilder::default().existential_deposit(2).build().execute_with(|| { assert_eq!(Balances::free_balance(11), 256_000); on_offence_now( diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 645c3f8af5..2b9637651d 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -306,7 +306,7 @@ mod tests { parameter_types! { pub const CreationFee: u64 = 0; - pub const ExistentialDeposit: u64 = 0; + pub const ExistentialDeposit: u64 = 1; } impl pallet_balances::Trait for Runtime { @@ -394,14 +394,18 @@ mod tests { self.set_constants(); 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), - (3, 30 * self.balance_factor), - (4, 40 * self.balance_factor), - (5, 50 * self.balance_factor), - (6, 60 * self.balance_factor) - ], + balances: if self.balance_factor > 0 { + vec![ + (1, 10 * self.balance_factor), + (2, 20 * self.balance_factor), + (3, 30 * self.balance_factor), + (4, 40 * self.balance_factor), + (5, 50 * self.balance_factor), + (6, 60 * self.balance_factor) + ] + } else { + vec![] + }, }.assimilate_storage(&mut t).unwrap(); t.into() } diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index fcd340eef5..72f35745a4 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -702,7 +702,7 @@ mod tests { type ModuleToIndex = (); } parameter_types! { - pub const ExistentialDeposit: u64 = 0; + pub const ExistentialDeposit: u64 = 1; pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Test { -- GitLab From ea721a19b7e1b97fbae5db5551e7656384d8302f Mon Sep 17 00:00:00 2001 From: Toralf Wittner Date: Wed, 12 Feb 2020 11:50:52 +0100 Subject: [PATCH 137/180] network: Use "one shot" protocol handler. (#3520) * network: Use "one shot" protocol handler. Add two new `NetworkBehaviour`s, one handling remote block requests and another one to handle light client requests (both local and from remote). The change is motivated by the desire to use multiple substreams of a single connection for different protocols. To achieve this, libp2p's `OneShotHandler` is used as a protocol handler in each behaviour. It will open a fresh substream for the duration of the request and close it afterwards. For block requests, we currently only handle incoming requests from remote and tests are missing. For light client handling we support incoming requests from remote and also ported a substantial amount of functionality over from `light_dispatch.rs` (including several tests). However the result lacks in at least two aspects: (1) We require external updates w.r.t. the best block per peer and currently nothing updates this information. (2) We carry a lot of peer-related state around. Both aspects could be simplified by externalising peer selection and just requiring a specific peer ID where the request should be sent to. We still have to maintain some peer related state due to the way libp2p's swarm and network behaviour work (e.g. we must make sure to always issue `NetworkBehaviourAction::SendEvent`s to peers we are connected to, otherwise the actions die a silent death. Another change implemented here is the use of protocol buffers as the encoding for network messages. Certain individual fields of messages are still SCALE encoded. There has been some discussion about this in another PR (https://github.com/paritytech/substrate/pull/3452), so far without resolution. * Uncomment `Behaviour::light_client_request`. * Add license headers. --- Cargo.lock | 7 + client/network/Cargo.toml | 10 + client/network/build.rs | 8 + client/network/src/behaviour.rs | 19 +- client/network/src/protocol.rs | 15 + client/network/src/protocol/block_requests.rs | 354 ++++ .../src/protocol/light_client_handler.rs | 1793 +++++++++++++++++ client/network/src/protocol/light_dispatch.rs | 47 +- .../network/src/protocol/schema/api.v1.proto | 59 + .../src/protocol/schema/light.v1.proto | 128 ++ client/network/src/service.rs | 23 +- 11 files changed, 2436 insertions(+), 27 deletions(-) create mode 100644 client/network/build.rs create mode 100644 client/network/src/protocol/block_requests.rs create mode 100644 client/network/src/protocol/light_client_handler.rs create mode 100644 client/network/src/protocol/schema/api.v1.proto create mode 100644 client/network/src/protocol/schema/light.v1.proto diff --git a/Cargo.lock b/Cargo.lock index 8ac3012df7..f2cfaae187 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6034,6 +6034,8 @@ dependencies = [ name = "sc-network" version = "0.8.0" dependencies = [ + "assert_matches", + "async-std", "bitflags", "bytes 0.5.4", "derive_more", @@ -6050,8 +6052,11 @@ dependencies = [ "linked_hash_set", "log 0.4.8", "lru 0.4.3", + "nohash-hasher", "parity-scale-codec", "parking_lot 0.10.0", + "prost", + "prost-build", "quickcheck", "rand 0.7.3", "rustc-hex", @@ -6073,8 +6078,10 @@ dependencies = [ "sp-runtime", "sp-test-primitives", "substrate-test-client", + "substrate-test-runtime", "substrate-test-runtime-client", "tempfile", + "thiserror", "unsigned-varint", "void", "wasm-timer", diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index db3e32393d..f6ff3bcb73 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -6,6 +6,9 @@ license = "GPL-3.0" authors = ["Parity Technologies "] edition = "2018" +[build-dependencies] +prost-build = "0.6.1" + [dependencies] bitflags = "1.2.0" bytes = "0.5.0" @@ -24,7 +27,9 @@ linked-hash-map = "0.5.2" linked_hash_set = "0.1.3" log = "0.4.8" lru = "0.4.0" +nohash-hasher = "0.1.3" parking_lot = "0.10.0" +prost = "0.6.1" rand = "0.7.2" rustc-hex = "2.0.1" sc-block-builder = { version = "0.8", path = "../block-builder" } @@ -45,17 +50,22 @@ sp-keyring = { version = "2.0.0", optional = true, path = "../../primitives/keyr sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } 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" } +thiserror = "1" unsigned-varint = { version = "0.3.0", features = ["codec"] } void = "1.0.2" zeroize = "1.0.0" yamux = "0.4.2" [dev-dependencies] +async-std = "1.5" +assert_matches = "1.3" env_logger = "0.7.0" quickcheck = "0.9.0" rand = "0.7.2" sp-keyring = { version = "2.0.0", path = "../../primitives/keyring" } sp-test-primitives = { version = "2.0.0", path = "../../primitives/test-primitives" } +substrate-test-runtime = { version = "2.0.0", path = "../../test-utils/runtime" } +substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" } tempfile = "3.1.0" [features] diff --git a/client/network/build.rs b/client/network/build.rs new file mode 100644 index 0000000000..0fd1f12866 --- /dev/null +++ b/client/network/build.rs @@ -0,0 +1,8 @@ +const PROTOS: &[&str] = &[ + "src/protocol/schema/api.v1.proto", + "src/protocol/schema/light.v1.proto" +]; + +fn main() { + prost_build::compile_protos(PROTOS, &["src/protocol"]).unwrap(); +} diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index a1f54654b3..63cbea4da5 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -19,7 +19,7 @@ use crate::{ Event, protocol::event::DhtEvent }; use crate::{ExHashT, specialization::NetworkSpecialization}; -use crate::protocol::{CustomMessageOutcome, Protocol}; +use crate::protocol::{self, light_client_handler, CustomMessageOutcome, Protocol}; use libp2p::NetworkBehaviour; use libp2p::core::{Multiaddr, PeerId, PublicKey}; use libp2p::kad::record; @@ -42,7 +42,10 @@ pub struct Behaviour, H: ExHashT> { debug_info: debug_info::DebugInfoBehaviour>, /// Discovers nodes of the network. discovery: DiscoveryBehaviour>, - + /// Block request handling. + block_requests: protocol::BlockRequests, B>, + /// Light client request handling. + light_client_handler: protocol::LightClientHandler, B>, /// Queue of events to produce for the outside. #[behaviour(ignore)] events: Vec>, @@ -66,6 +69,8 @@ impl, H: ExHashT> Behaviour { enable_mdns: bool, allow_private_ipv4: bool, discovery_only_if_under_num: u64, + block_requests: protocol::BlockRequests, B>, + light_client_handler: protocol::LightClientHandler, B>, ) -> Self { Behaviour { substrate, @@ -77,7 +82,9 @@ impl, H: ExHashT> Behaviour { allow_private_ipv4, discovery_only_if_under_num, ).await, - events: Vec::new(), + block_requests, + light_client_handler, + events: Vec::new() } } @@ -119,6 +126,12 @@ impl, H: ExHashT> Behaviour { pub fn put_value(&mut self, key: record::Key, value: Vec) { self.discovery.put_value(key, value); } + + /// Issue a light client request. + #[allow(unused)] + pub fn light_client_request(&mut self, r: light_client_handler::Request) -> Result<(), light_client_handler::Error> { + self.light_client_handler.request(r) + } } impl, H: ExHashT> NetworkBehaviourEventProcess for diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 99b0117882..8e5f9d6e7b 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -54,15 +54,30 @@ use crate::error; use util::LruHashSet; use wasm_timer::Instant; +// Include sources generated from protobuf definitions. +pub mod api { + pub mod v1 { + include!(concat!(env!("OUT_DIR"), "/api.v1.rs")); + pub mod light { + include!(concat!(env!("OUT_DIR"), "/api.v1.light.rs")); + } + } +} + mod legacy_proto; mod util; +pub mod block_requests; pub mod message; pub mod event; +pub mod light_client_handler; pub mod light_dispatch; pub mod specialization; pub mod sync; +pub use block_requests::BlockRequests; +pub use light_client_handler::LightClientHandler; + const REQUEST_TIMEOUT_SEC: u64 = 40; /// Interval at which we perform time based maintenance const TICK_TIMEOUT: time::Duration = time::Duration::from_millis(1100); diff --git a/client/network/src/protocol/block_requests.rs b/client/network/src/protocol/block_requests.rs new file mode 100644 index 0000000000..f8a905c288 --- /dev/null +++ b/client/network/src/protocol/block_requests.rs @@ -0,0 +1,354 @@ +// Copyright 2020 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 . + +//! `NetworkBehaviour` implementation which handles incoming block requests. +//! +//! Every request is coming in on a separate connection substream which gets +//! closed after we have sent the response back. Incoming requests are encoded +//! as protocol buffers (cf. `api.v1.proto`). + +#![allow(unused)] + +use bytes::Bytes; +use codec::{Encode, Decode}; +use crate::{ + chain::Client, + config::ProtocolId, + protocol::{api, message::BlockAttributes} +}; +use futures::{future::BoxFuture, prelude::*, stream::FuturesUnordered}; +use libp2p::{ + core::{ + ConnectedPoint, + Multiaddr, + PeerId, + upgrade::{InboundUpgrade, ReadOneError, UpgradeInfo, Negotiated}, + upgrade::{DeniedUpgrade, read_one, write_one} + }, + swarm::{NetworkBehaviour, NetworkBehaviourAction, OneShotHandler, PollParameters, SubstreamProtocol} +}; +use prost::Message; +use sp_runtime::{generic::BlockId, traits::{Block, Header, One, Zero}}; +use std::{ + cmp::min, + io, + iter, + sync::Arc, + time::Duration, + task::{Context, Poll} +}; +use void::{Void, unreachable}; + +// Type alias for convenience. +pub type Error = Box; + +/// Configuration options for `BlockRequests`. +#[derive(Debug, Clone)] +pub struct Config { + max_block_data_response: u32, + max_request_len: usize, + inactivity_timeout: Duration, + protocol: Bytes, +} + +impl Config { + /// Create a fresh configuration with the following options: + /// + /// - max. block data in response = 128 + /// - max. request size = 1 MiB + /// - inactivity timeout = 15s + pub fn new(id: &ProtocolId) -> Self { + let mut c = Config { + max_block_data_response: 128, + max_request_len: 1024 * 1024, + inactivity_timeout: Duration::from_secs(15), + protocol: Bytes::new(), + }; + c.set_protocol(id); + c + } + + /// Limit the max. number of block data in a response. + pub fn set_max_block_data_response(&mut self, v: u32) -> &mut Self { + self.max_block_data_response = v; + self + } + + /// Limit the max. length of incoming block request bytes. + pub fn set_max_request_len(&mut self, v: usize) -> &mut Self { + self.max_request_len = v; + self + } + + /// Limit the max. duration the substream may remain inactive before closing it. + pub fn set_inactivity_timeout(&mut self, v: Duration) -> &mut Self { + self.inactivity_timeout = v; + self + } + + /// Set protocol to use for upgrade negotiation. + pub fn set_protocol(&mut self, id: &ProtocolId) -> &mut Self { + let mut v = Vec::new(); + v.extend_from_slice(b"/"); + v.extend_from_slice(id.as_bytes()); + v.extend_from_slice(b"/sync/1"); + self.protocol = v.into(); + self + } +} + +/// The block request handling behaviour. +pub struct BlockRequests { + /// This behaviour's configuration. + config: Config, + /// Blockchain client. + chain: Arc>, + /// Futures sending back the block request response. + outgoing: FuturesUnordered>, + /// Type witness term. + _marker: std::marker::PhantomData +} + +impl BlockRequests +where + T: AsyncRead + AsyncWrite + Unpin + Send + 'static, + B: Block, +{ + pub fn new(cfg: Config, chain: Arc>) -> Self { + BlockRequests { + config: cfg, + chain, + outgoing: FuturesUnordered::new(), + _marker: std::marker::PhantomData + } + } + + /// Callback, invoked when a new block request has been received from remote. + fn on_block_request + ( &mut self + , peer: &PeerId + , request: &api::v1::BlockRequest + ) -> Result + { + log::trace!("block request {} from peer {}: from block {:?} to block {:?}, max blocks {:?}", + request.id, + peer, + request.from_block, + request.to_block, + request.max_blocks); + + let from_block_id = + match request.from_block { + Some(api::v1::block_request::FromBlock::Hash(ref h)) => { + let h = Decode::decode(&mut h.as_ref())?; + BlockId::::Hash(h) + } + Some(api::v1::block_request::FromBlock::Number(ref n)) => { + let n = Decode::decode(&mut n.as_ref())?; + BlockId::::Number(n) + } + None => { + let msg = "missing `BlockRequest::from_block` field"; + return Err(io::Error::new(io::ErrorKind::Other, msg).into()) + } + }; + + let max_blocks = + if request.max_blocks == 0 { + self.config.max_block_data_response + } else { + min(request.max_blocks, self.config.max_block_data_response) + }; + + let direction = + if request.direction == api::v1::Direction::Ascending as i32 { + api::v1::Direction::Ascending + } else if request.direction == api::v1::Direction::Descending as i32 { + api::v1::Direction::Descending + } else { + let msg = format!("invalid `BlockRequest::direction` value: {}", request.direction); + return Err(io::Error::new(io::ErrorKind::Other, msg).into()) + }; + + let attributes = BlockAttributes::decode(&mut request.fields.to_be_bytes().as_ref())?; + let get_header = attributes.contains(BlockAttributes::HEADER); + let get_body = attributes.contains(BlockAttributes::BODY); + let get_justification = attributes.contains(BlockAttributes::JUSTIFICATION); + + let mut blocks = Vec::new(); + let mut block_id = from_block_id; + while let Some(header) = self.chain.header(&block_id).unwrap_or(None) { + if blocks.len() >= max_blocks as usize { + break + } + + let number = header.number().clone(); + let hash = header.hash(); + let parent_hash = header.parent_hash().clone(); + + let block_data = api::v1::BlockData { + hash: hash.encode(), + header: if get_header { + header.encode() + } else { + Vec::new() + }, + body: if get_body { + self.chain.body(&BlockId::Hash(hash))? + .unwrap_or(Vec::new()) + .iter_mut() + .map(|extrinsic| extrinsic.encode()) + .collect() + } else { + Vec::new() + }, + receipt: Vec::new(), + message_queue: Vec::new(), + justification: if get_justification { + self.chain.justification(&BlockId::Hash(hash))?.unwrap_or(Vec::new()) + } else { + Vec::new() + } + }; + + blocks.push(block_data); + + match direction { + api::v1::Direction::Ascending => { + block_id = BlockId::Number(number + One::one()) + } + api::v1::Direction::Descending => { + if number.is_zero() { + break + } + block_id = BlockId::Hash(parent_hash) + } + } + } + + Ok(api::v1::BlockResponse { id: request.id, blocks }) + } +} + +impl NetworkBehaviour for BlockRequests +where + T: AsyncRead + AsyncWrite + Unpin + Send + 'static, + B: Block +{ + type ProtocolsHandler = OneShotHandler>>; + type OutEvent = Void; + + fn new_handler(&mut self) -> Self::ProtocolsHandler { + let p = Protocol { + max_request_len: self.config.max_request_len, + protocol: self.config.protocol.clone(), + }; + OneShotHandler::new(SubstreamProtocol::new(p), self.config.inactivity_timeout) + } + + fn addresses_of_peer(&mut self, _: &PeerId) -> Vec { + Vec::new() + } + + fn inject_connected(&mut self, _peer: PeerId, _info: ConnectedPoint) { + } + + fn inject_disconnected(&mut self, _peer: &PeerId, _info: ConnectedPoint) { + } + + fn inject_node_event(&mut self, peer: PeerId, Request(request, mut stream): Request>) { + match self.on_block_request(&peer, &request) { + Ok(res) => { + log::trace!("enqueueing block response {} for peer {} with {} blocks", res.id, peer, res.blocks.len()); + let mut data = Vec::with_capacity(res.encoded_len()); + if let Err(e) = res.encode(&mut data) { + log::debug!("error encoding block response {} for peer {}: {}", res.id, peer, e) + } else { + let future = async move { + if let Err(e) = write_one(&mut stream, data).await { + log::debug!("error writing block response: {}", e) + } + }; + self.outgoing.push(future.boxed()) + } + } + Err(e) => log::debug!("error handling block request {} from peer {}: {}", request.id, peer, e) + } + } + + fn poll(&mut self, cx: &mut Context, _: &mut impl PollParameters) -> Poll> { + while let Poll::Ready(Some(_)) = self.outgoing.poll_next_unpin(cx) {} + Poll::Pending + } +} + +/// The incoming block request. +/// +/// Holds the protobuf value and the connection substream which made the +/// request and over which to send the response. +#[derive(Debug)] +pub struct Request(api::v1::BlockRequest, T); + +impl From for Request { + fn from(v: Void) -> Self { + unreachable(v) + } +} + +/// Substream upgrade protocol. +/// +/// We attempt to parse an incoming protobuf encoded request (cf. `Request`) +/// which will be handled by the `BlockRequests` behaviour, i.e. the request +/// will become visible via `inject_node_event` which then dispatches to the +/// relevant callback to process the message and prepare a response. +#[derive(Debug, Clone)] +pub struct Protocol { + /// The max. request length in bytes. + max_request_len: usize, + /// The protocol to use during upgrade negotiation. + protocol: Bytes, +} + +impl UpgradeInfo for Protocol { + type Info = Bytes; + type InfoIter = iter::Once; + + fn protocol_info(&self) -> Self::InfoIter { + iter::once(self.protocol.clone()) + } +} + +impl InboundUpgrade for Protocol +where + T: AsyncRead + AsyncWrite + Unpin + Send + 'static +{ + type Output = Request; + type Error = ReadOneError; + type Future = BoxFuture<'static, Result>; + + fn upgrade_inbound(self, mut s: T, _: Self::Info) -> Self::Future { + let future = async move { + let len = self.max_request_len; + let vec = read_one(&mut s, len).await?; + match api::v1::BlockRequest::decode(&vec[..]) { + Ok(r) => Ok(Request(r, s)), + Err(e) => Err(ReadOneError::Io(io::Error::new(io::ErrorKind::Other, e))) + } + }; + future.boxed() + } +} + diff --git a/client/network/src/protocol/light_client_handler.rs b/client/network/src/protocol/light_client_handler.rs new file mode 100644 index 0000000000..f5be23c0d4 --- /dev/null +++ b/client/network/src/protocol/light_client_handler.rs @@ -0,0 +1,1793 @@ +// Copyright 2020 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 . + +//! [`NetworkBehaviour`] implementation which handles light client requests. +//! +//! Every request is coming in on a separate connection substream which gets +//! closed after we have sent the response back. Requests and responses are +//! encoded as protocol buffers (cf. `api.v1.proto`). +//! +//! For every outgoing request we likewise open a separate substream. + +#![allow(unused)] + +use bytes::Bytes; +use codec::{self, Encode, Decode}; +use crate::{ + chain::Client, + config::ProtocolId, + protocol::{api, light_dispatch::TIMEOUT_REPUTATION_CHANGE} +}; +use futures::{channel::oneshot, future::BoxFuture, prelude::*, stream::FuturesUnordered}; +use libp2p::{ + core::{ + ConnectedPoint, + Multiaddr, + PeerId, + upgrade::{InboundUpgrade, ReadOneError, UpgradeInfo, Negotiated}, + upgrade::{OutboundUpgrade, read_one, write_one} + }, + swarm::{NetworkBehaviour, NetworkBehaviourAction, OneShotHandler, PollParameters, SubstreamProtocol} +}; +use nohash_hasher::IntMap; +use prost::Message; +use rustc_hex::ToHex; +use sc_client::light::fetcher; +use sc_client_api::StorageProof; +use sc_peerset::ReputationChange; +use sp_core::storage::{ChildInfo, StorageKey}; +use sp_blockchain::{Error as ClientError}; +use sp_runtime::traits::{Block, Header, NumberFor, Zero}; +use std::{ + collections::{BTreeMap, VecDeque, HashMap}, + iter, + io, + sync::Arc, + time::{Duration, Instant}, + task::{Context, Poll} +}; +use void::Void; + +/// Configuration options for `LightClientHandler` behaviour. +#[derive(Debug, Clone)] +pub struct Config { + max_data_size: usize, + max_pending_requests: usize, + inactivity_timeout: Duration, + request_timeout: Duration, + protocol: Bytes, +} + +impl Config { + /// Create a fresh configuration with the following options: + /// + /// - max. data size = 1 MiB + /// - max. pending requests = 128 + /// - inactivity timeout = 15s + /// - request timeout = 15s + pub fn new(id: &ProtocolId) -> Self { + let mut c = Config { + max_data_size: 1024 * 1024, + max_pending_requests: 128, + inactivity_timeout: Duration::from_secs(15), + request_timeout: Duration::from_secs(15), + protocol: Bytes::new(), + }; + c.set_protocol(id); + c + } + + /// Limit the max. length of incoming request bytes. + pub fn set_max_data_size(&mut self, v: usize) -> &mut Self { + self.max_data_size = v; + self + } + + /// Limit the max. number of pending requests. + pub fn set_max_pending_requests(&mut self, v: usize) -> &mut Self { + self.max_pending_requests = v; + self + } + + /// Limit the max. duration the connection may remain inactive before closing it. + pub fn set_inactivity_timeout(&mut self, v: Duration) -> &mut Self { + self.inactivity_timeout = v; + self + } + + /// Limit the max. request duration. + pub fn set_request_timeout(&mut self, v: Duration) -> &mut Self { + self.request_timeout = v; + self + } + + /// Set protocol to use for upgrade negotiation. + pub fn set_protocol(&mut self, id: &ProtocolId) -> &mut Self { + let mut v = Vec::new(); + v.extend_from_slice(b"/"); + v.extend_from_slice(id.as_bytes()); + v.extend_from_slice(b"/light/1"); + self.protocol = v.into(); + self + } +} + +/// Possible errors while handling light clients. +#[derive(Debug, thiserror::Error)] +pub enum Error { + /// There are currently too many pending request. + #[error("too many pending requests")] + TooManyRequests, + /// The response type does not correspond to the issued request. + #[error("unexpected response")] + UnexpectedResponse, + /// A bad request has been received. + #[error("bad request: {0}")] + BadRequest(&'static str), + /// The chain client errored. + #[error("client error: {0}")] + Client(#[from] ClientError), + /// Encoding or decoding of some data failed. + #[error("codec error: {0}")] + Codec(#[from] codec::Error), +} + +/// The possible light client requests we support. +/// +/// The associated `oneshot::Sender` will be used to convey the result of +/// their request back to them (cf. `Reply`). +// +// This is modeled after light_dispatch.rs's `RequestData` which is not +// used because we currently only support a subset of those. +#[derive(Debug)] +pub enum Request { + Header { + request: fetcher::RemoteHeaderRequest, + sender: oneshot::Sender> + }, + Read { + request: fetcher::RemoteReadRequest, + sender: oneshot::Sender, Option>>, ClientError>> + }, + ReadChild { + request: fetcher::RemoteReadChildRequest, + sender: oneshot::Sender, Option>>, ClientError>> + }, + Call { + request: fetcher::RemoteCallRequest, + sender: oneshot::Sender, ClientError>> + }, + Changes { + request: fetcher::RemoteChangesRequest, + sender: oneshot::Sender, u32)>, ClientError>> + } +} + +/// The data to send back to the light client over the oneshot channel. +// +// It is unified here in order to be able to return it as a function +// result instead of delivering it to the client as a side effect of +// response processing. +#[derive(Debug)] +enum Reply { + VecU8(Vec), + VecNumberU32(Vec<(::Number, u32)>), + MapVecU8OptVecU8(HashMap, Option>>), + Header(B::Header) +} + +/// Augments a light client request with metadata. +#[derive(Debug)] +struct RequestWrapper { + /// Time when this value was created. + timestamp: Instant, + /// Remaining retries. + retries: usize, + /// The actual request. + request: Request, + /// Peer information, e.g. `PeerId`. + peer: P +} + +/// Information we have about some peer. +#[derive(Debug)] +struct PeerInfo { + address: Multiaddr, + best_block: Option>, + status: PeerStatus, +} + +/// A peer is either idle or busy processing a request from us. +#[derive(Debug, Clone, PartialEq, Eq)] +enum PeerStatus { + /// The peer is available. + Idle, + /// We wait for the peer to return us a response for the given request ID. + BusyWith(u64), +} + +/// The light client handler behaviour. +pub struct LightClientHandler { + /// This behaviour's configuration. + config: Config, + /// Blockchain client. + chain: Arc>, + /// Verifies that received responses are correct. + checker: Arc>, + /// Peer information (addresses, their best block, etc.) + peers: HashMap>, + /// Futures sending back response to remote clients. + responses: FuturesUnordered>, + /// Pending (local) requests. + pending_requests: VecDeque>, + /// Requests on their way to remote peers. + outstanding: IntMap>, + /// (Local) Request ID counter + next_request_id: u64, + /// Handle to use for reporting misbehaviour of peers. + peerset: sc_peerset::PeersetHandle, + /// Type witness term. + _marker: std::marker::PhantomData +} + +impl LightClientHandler +where + T: AsyncRead + AsyncWrite + Unpin + Send + 'static, + B: Block, +{ + /// Construct a new light client handler. + pub fn new + ( cfg: Config + , chain: Arc> + , checker: Arc> + , peerset: sc_peerset::PeersetHandle + ) -> Self + { + LightClientHandler { + config: cfg, + chain, + checker, + peers: HashMap::new(), + responses: FuturesUnordered::new(), + pending_requests: VecDeque::new(), + outstanding: IntMap::default(), + next_request_id: 1, + peerset, + _marker: std::marker::PhantomData + } + } + + /// We rely on external information about peers best blocks as we lack the + /// means to determine it ourselves. + pub fn update_best_block(&mut self, peer: &PeerId, num: NumberFor) { + if let Some(info) = self.peers.get_mut(peer) { + info.best_block = Some(num) + } + } + + /// Issue a new light client request. + pub fn request(&mut self, req: Request) -> Result<(), Error> { + if self.pending_requests.len() >= self.config.max_pending_requests { + return Err(Error::TooManyRequests) + } + let rw = RequestWrapper { + timestamp: Instant::now(), + retries: retries(&req), + request: req, + peer: (), // we do not know the peer yet + }; + self.pending_requests.push_back(rw); + Ok(()) + } + + fn next_request_id(&mut self) -> u64 { + let id = self.next_request_id; + self.next_request_id += 1; + id + } + + // Iterate over peers known to possess a certain block. + fn idle_peers_with_block(&mut self, num: NumberFor) -> impl Iterator + '_ { + self.peers.iter() + .filter(move |(_, info)| { + info.status == PeerStatus::Idle && info.best_block >= Some(num) + }) + .map(|(peer, _)| peer.clone()) + } + + // Iterate over peers without a known block. + fn idle_peers_with_unknown_block(&mut self) -> impl Iterator + '_ { + self.peers.iter() + .filter(|(_, info)| { + info.status == PeerStatus::Idle && info.best_block.is_none() + }) + .map(|(peer, _)| peer.clone()) + } + + /// Remove the given peer. + /// + /// If we have a request to this peer in flight, we move it back to + /// the pending requests queue. + fn remove_peer(&mut self, peer: &PeerId) { + if let Some(id) = self.outstanding.iter().find(|(_, rw)| &rw.peer == peer).map(|(k, _)| *k) { + let rw = self.outstanding.remove(&id).expect("key belongs to entry in this map"); + let rw = RequestWrapper { + timestamp: rw.timestamp, + retries: rw.retries, + request: rw.request, + peer: (), // need to find another peer + }; + self.pending_requests.push_back(rw); + } + self.peers.remove(peer); + } + + /// Process a local request's response from remote. + /// + /// If successful, this will give us the actual, checked data we should be + /// sending back to the client, otherwise an error. + fn on_response + ( &mut self + , peer: &PeerId + , request: &Request + , response: api::v1::light::Response + ) -> Result, Error> + { + log::trace!("response {} from {}", response.id, peer); + use api::v1::light::response::Response; + match response.response { + Some(Response::RemoteCallResponse(response)) => + if let Request::Call { request , .. } = request { + let proof = Decode::decode(&mut response.proof.as_ref())?; + let reply = self.checker.check_execution_proof(request, proof)?; + Ok(Reply::VecU8(reply)) + } else { + Err(Error::UnexpectedResponse) + } + Some(Response::RemoteReadResponse(response)) => + match request { + Request::Read { request, .. } => { + let proof = Decode::decode(&mut response.proof.as_ref())?; + let reply = self.checker.check_read_proof(&request, proof)?; + Ok(Reply::MapVecU8OptVecU8(reply)) + } + Request::ReadChild { request, .. } => { + let proof = Decode::decode(&mut response.proof.as_ref())?; + let reply = self.checker.check_read_child_proof(&request, proof)?; + Ok(Reply::MapVecU8OptVecU8(reply)) + } + _ => Err(Error::UnexpectedResponse) + } + Some(Response::RemoteChangesResponse(response)) => + if let Request::Changes { request, .. } = request { + let max_block = Decode::decode(&mut response.max.as_ref())?; + let roots_proof = Decode::decode(&mut response.roots_proof.as_ref())?; + let roots = { + let mut r = BTreeMap::new(); + for pair in response.roots { + let k = Decode::decode(&mut pair.fst.as_ref())?; + let v = Decode::decode(&mut pair.snd.as_ref())?; + r.insert(k, v); + } + r + }; + let reply = self.checker.check_changes_proof(&request, fetcher::ChangesProof { + max_block, + proof: response.proof, + roots, + roots_proof, + })?; + Ok(Reply::VecNumberU32(reply)) + } else { + Err(Error::UnexpectedResponse) + } + Some(Response::RemoteHeaderResponse(response)) => + if let Request::Header { request, .. } = request { + let header = + if response.header.is_empty() { + None + } else { + Some(Decode::decode(&mut response.header.as_ref())?) + }; + let proof = Decode::decode(&mut response.proof.as_ref())?; + let reply = self.checker.check_header_proof(&request, header, proof)?; + Ok(Reply::Header(reply)) + } else { + Err(Error::UnexpectedResponse) + } + None => Err(Error::UnexpectedResponse) + } + } + + fn on_remote_call_request + ( &mut self + , peer: &PeerId + , request_id: u64 + , request: &api::v1::light::RemoteCallRequest + ) -> Result + { + log::trace!("remote call request {} from {} ({} at {:?})", + request_id, + peer, + request.method, + request.block); + + let block = Decode::decode(&mut request.block.as_ref())?; + + let proof = match self.chain.execution_proof(&block, &request.method, &request.data) { + Ok((_, proof)) => proof, + Err(e) => { + log::trace!("remote call request {} from {} ({} at {:?}) failed with: {}", + request_id, + peer, + request.method, + request.block, + e); + StorageProof::empty() + } + }; + + let response = { + let r = api::v1::light::RemoteCallResponse { proof: proof.encode() }; + api::v1::light::response::Response::RemoteCallResponse(r) + }; + + Ok(api::v1::light::Response { id: request_id, response: Some(response) }) + } + + fn on_remote_read_request + ( &mut self + , peer: &PeerId + , request_id: u64 + , request: &api::v1::light::RemoteReadRequest + ) -> Result + { + if request.keys.is_empty() { + log::debug!("invalid remote read request sent by {}", peer); + return Err(Error::BadRequest("remote read request without keys")) + } + + log::trace!("remote read request {} from {} ({} at {:?})", + request_id, + peer, + fmt_keys(request.keys.first(), request.keys.last()), + request.block); + + let block = Decode::decode(&mut request.block.as_ref())?; + + let proof = match self.chain.read_proof(&block, &request.keys) { + Ok(proof) => proof, + Err(error) => { + log::trace!("remote read request {} from {} ({} at {:?}) failed with: {}", + request_id, + peer, + fmt_keys(request.keys.first(), request.keys.last()), + request.block, + error); + StorageProof::empty() + } + }; + + let response = { + let r = api::v1::light::RemoteReadResponse { proof: proof.encode() }; + api::v1::light::response::Response::RemoteReadResponse(r) + }; + + Ok(api::v1::light::Response { id: request_id, response: Some(response) }) + } + + fn on_remote_read_child_request + ( &mut self + , peer: &PeerId + , request_id: u64 + , request: &api::v1::light::RemoteReadChildRequest + ) -> Result + { + if request.keys.is_empty() { + log::debug!("invalid remote child read request sent by {}", peer); + return Err(Error::BadRequest("remove read child request without keys")) + } + + log::trace!("remote read child request {} from {} ({} {} at {:?})", + request_id, + peer, + request.storage_key.to_hex::(), + fmt_keys(request.keys.first(), request.keys.last()), + request.block); + + let block = Decode::decode(&mut request.block.as_ref())?; + + let proof = + if let Some(info) = ChildInfo::resolve_child_info(request.child_type, &request.child_info[..]) { + match self.chain.read_child_proof(&block, &request.storage_key, info, &request.keys) { + Ok(proof) => proof, + Err(error) => { + log::trace!("remote read child request {} from {} ({} {} at {:?}) failed with: {}", + request_id, + peer, + request.storage_key.to_hex::(), + fmt_keys(request.keys.first(), request.keys.last()), + request.block, + error); + StorageProof::empty() + } + } + } else { + log::trace!("remote read child request {} from {} ({} {} at {:?}) failed with: {}", + request_id, + peer, + request.storage_key.to_hex::(), + fmt_keys(request.keys.first(), request.keys.last()), + request.block, + "invalid child info and type" + ); + StorageProof::empty() + }; + + let response = { + let r = api::v1::light::RemoteReadResponse { proof: proof.encode() }; + api::v1::light::response::Response::RemoteReadResponse(r) + }; + + Ok(api::v1::light::Response { id: request_id, response: Some(response) }) + } + + fn on_remote_header_request + ( &mut self + , peer: &PeerId + , request_id: u64 + , request: &api::v1::light::RemoteHeaderRequest + ) -> Result + { + log::trace!("remote header proof request {} from {} ({:?})", request_id, peer, request.block); + + let block = Decode::decode(&mut request.block.as_ref())?; + + let (header, proof) = match self.chain.header_proof(block) { + Ok((header, proof)) => (header.encode(), proof), + Err(error) => { + log::trace!("remote header proof request {} from {} ({:?}) failed with: {}", + request_id, + peer, + request.block, + error); + (Default::default(), StorageProof::empty()) + } + }; + + let response = { + let r = api::v1::light::RemoteHeaderResponse { header, proof: proof.encode() }; + api::v1::light::response::Response::RemoteHeaderResponse(r) + }; + + Ok(api::v1::light::Response { id: request_id, response: Some(response) }) + } + + fn on_remote_changes_request + ( &mut self + , peer: &PeerId + , request_id: u64 + , request: &api::v1::light::RemoteChangesRequest + ) -> Result + { + log::trace!("remote changes proof request {} from {} for key {} ({:?}..{:?})", + request_id, + peer, + if !request.storage_key.is_empty() { + format!("{} : {}", request.storage_key.to_hex::(), request.key.to_hex::()) + } else { + request.key.to_hex::() + }, + request.first, + request.last); + + let first = Decode::decode(&mut request.first.as_ref())?; + let last = Decode::decode(&mut request.last.as_ref())?; + let min = Decode::decode(&mut request.min.as_ref())?; + let max = Decode::decode(&mut request.max.as_ref())?; + let key = StorageKey(request.key.clone()); + let storage_key = + if request.storage_key.is_empty() { + None + } else { + Some(StorageKey(request.storage_key.clone())) + }; + + let proof = match self.chain.key_changes_proof(first, last, min, max, storage_key.as_ref(), &key) { + Ok(proof) => proof, + Err(error) => { + log::trace!("remote changes proof request {} from {} for key {} ({:?}..{:?}) failed with: {}", + request_id, + peer, + if let Some(sk) = storage_key { + format!("{} : {}", sk.0.to_hex::(), key.0.to_hex::()) + } else { + key.0.to_hex::() + }, + request.first, + request.last, + error); + + fetcher::ChangesProof:: { + max_block: Zero::zero(), + proof: Vec::new(), + roots: BTreeMap::new(), + roots_proof: StorageProof::empty(), + } + } + }; + + let response = { + let r = api::v1::light::RemoteChangesResponse { + max: proof.max_block.encode(), + proof: proof.proof, + roots: proof.roots.into_iter() + .map(|(k, v)| api::v1::light::Pair { fst: k.encode(), snd: v.encode() }) + .collect(), + roots_proof: proof.roots_proof.encode(), + }; + api::v1::light::response::Response::RemoteChangesResponse(r) + }; + + Ok(api::v1::light::Response { id: request_id, response: Some(response) }) + } +} + +impl NetworkBehaviour for LightClientHandler +where + T: AsyncRead + AsyncWrite + Unpin + Send + 'static, + B: Block +{ + type ProtocolsHandler = OneShotHandler>>; + type OutEvent = Void; + + fn new_handler(&mut self) -> Self::ProtocolsHandler { + let p = InboundProtocol { + max_data_size: self.config.max_data_size, + protocol: self.config.protocol.clone(), + }; + OneShotHandler::new(SubstreamProtocol::new(p), self.config.inactivity_timeout) + } + + fn addresses_of_peer(&mut self, peer: &PeerId) -> Vec { + self.peers.get(peer) + .map(|info| vec![info.address.clone()]) + .unwrap_or_default() + } + + fn inject_connected(&mut self, peer: PeerId, info: ConnectedPoint) { + let peer_address = match info { + ConnectedPoint::Listener { send_back_addr, .. } => send_back_addr, + ConnectedPoint::Dialer { address } => address + }; + + log::trace!("peer {} connected with address {}", peer, peer_address); + + let info = PeerInfo { + address: peer_address, + best_block: None, + status: PeerStatus::Idle, + }; + + self.peers.insert(peer, info); + } + + fn inject_disconnected(&mut self, peer: &PeerId, _: ConnectedPoint) { + log::trace!("peer {} disconnected", peer); + self.remove_peer(peer) + } + + fn inject_node_event(&mut self, peer: PeerId, event: Event>) { + match event { + // An incoming request from remote has been received. + Event::Request(request, mut stream) => { + log::trace!("incoming request {} from {}", peer, request.id); + let result = match &request.request { + Some(api::v1::light::request::Request::RemoteCallRequest(r)) => + self.on_remote_call_request(&peer, request.id, r), + Some(api::v1::light::request::Request::RemoteReadRequest(r)) => + self.on_remote_read_request(&peer, request.id, r), + Some(api::v1::light::request::Request::RemoteHeaderRequest(r)) => + self.on_remote_header_request(&peer, request.id, r), + Some(api::v1::light::request::Request::RemoteReadChildRequest(r)) => + self.on_remote_read_child_request(&peer, request.id, r), + Some(api::v1::light::request::Request::RemoteChangesRequest(r)) => + self.on_remote_changes_request(&peer, request.id, r), + None => { + log::debug!("ignoring request {} without request data from peer {}", request.id, peer); + return + } + }; + match result { + Ok(response) => { + log::trace!("enqueueing response {} for peer {}", response.id, peer); + let mut data = Vec::new(); + if let Err(e) = response.encode(&mut data) { + log::debug!("error encoding response {} for peer {}: {}", response.id, peer, e) + } else { + let future = async move { + if let Err(e) = write_one(&mut stream, data).await { + log::debug!("error writing response: {}", e) + } + }; + self.responses.push(future.boxed()) + } + } + Err(Error::BadRequest(_)) => { + self.remove_peer(&peer); + self.peerset.report_peer(peer, ReputationChange::new(-(1 << 12), "bad request")) + } + Err(e) => log::debug!("error handling request {} from peer {}: {}", request.id, peer, e) + } + } + // A response to one of our own requests has been received. + Event::Response(response) => { + let id = response.id; + if let Some(request) = self.outstanding.remove(&id) { + // We first just check if the response originates from the expected peer. + if request.peer != peer { + log::debug!("was expecting response {} from {} instead of {}", id, request.peer, peer); + self.outstanding.insert(id, request); + self.remove_peer(&peer); + self.peerset.report_peer(peer, ReputationChange::new_fatal("response from unexpected peer")); + return + } + + if let Some(info) = self.peers.get_mut(&peer) { + if info.status != PeerStatus::BusyWith(id) { + // If we get here, something is wrong with our internal handling of peer + // status information. At any time, a single peer processes at most one + // request from us and its status should contain the request ID we are + // expecting a response for. If a peer would send us a response with a + // random ID, we should not have an entry for it with this peer ID in + // our `outstanding` map, so a malicious peer should not be able to get + // us here. It is our own fault and must be fixed! + panic!("unexpected peer status {:?} for {}", info.status, peer); + } + + info.status = PeerStatus::Idle; // Make peer available again. + + match self.on_response(&peer, &request.request, response) { + Ok(reply) => send_reply(Ok(reply), request.request), + Err(Error::UnexpectedResponse) => { + log::debug!("unexpected response {} from peer {}", id, peer); + self.remove_peer(&peer); + self.peerset.report_peer(peer, ReputationChange::new_fatal("unexpected response from peer")); + let rw = RequestWrapper { + timestamp: request.timestamp, + retries: request.retries, + request: request.request, + peer: (), + }; + self.pending_requests.push_back(rw); + } + Err(other) => { + log::debug!("error handling response {} from peer {}: {}", id, peer, other); + self.remove_peer(&peer); + self.peerset.report_peer(peer, ReputationChange::new_fatal("invalid response from peer")); + if request.retries > 0 { + let rw = RequestWrapper { + timestamp: request.timestamp, + retries: request.retries - 1, + request: request.request, + peer: (), + }; + self.pending_requests.push_back(rw) + } else { + send_reply(Err(ClientError::RemoteFetchFailed), request.request) + } + } + } + } else { + // If we get here, something is wrong with our internal handling of peers. + // We apparently have an entry in our `outstanding` map and the peer is the one we + // expected. So, if we can not find an entry for it in our peer information table, + // then these two collections are out of sync which must not happen and is a clear + // programmer error that must be fixed! + panic!("missing peer information for {}; response {}", peer, id); + } + } else { + log::debug!("unexpected response {} from peer {}", id, peer); + self.remove_peer(&peer); + self.peerset.report_peer(peer, ReputationChange::new_fatal("response from unexpected peer")); + } + } + } + } + + fn poll(&mut self, cx: &mut Context, _: &mut impl PollParameters) -> Poll> { + // Process response sending futures. + while let Poll::Ready(Some(_)) = self.responses.poll_next_unpin(cx) {} + + // If we have a pending request to send, try to find an available peer and send it. + let now = Instant::now(); + while let Some(mut request) = self.pending_requests.pop_front() { + if now > request.timestamp + self.config.request_timeout { + if request.retries == 0 { + send_reply(Err(ClientError::RemoteFetchFailed), request.request); + continue + } + request.timestamp = Instant::now(); + request.retries -= 1 + } + let number = required_block(&request.request); + let available_peer = { + let p = self.idle_peers_with_block(number).next(); + if p.is_none() { + self.idle_peers_with_unknown_block().next() + } else { + p + } + }; + if let Some(peer) = available_peer { + let id = self.next_request_id(); + let rq = serialise_request(id, &request.request); + let mut buf = Vec::with_capacity(rq.encoded_len()); + if let Err(e) = rq.encode(&mut buf) { + log::debug!("failed to serialise request {}: {}", id, e); + send_reply(Err(ClientError::RemoteFetchFailed), request.request) + } else { + log::trace!("sending request {} to peer {}", id, peer); + let protocol = OutboundProtocol { + request: buf, + max_data_size: self.config.max_data_size, + protocol: self.config.protocol.clone(), + }; + self.peers.get_mut(&peer).map(|info| info.status = PeerStatus::BusyWith(id)); + let rw = RequestWrapper { + timestamp: request.timestamp, + retries: request.retries, + request: request.request, + peer: peer.clone(), + }; + self.outstanding.insert(id, rw); + return Poll::Ready(NetworkBehaviourAction::SendEvent { peer_id: peer, event: protocol }) + } + } else { + self.pending_requests.push_front(request); + log::debug!("no peer available to send request to"); + break + } + } + + // Look for ongoing requests that have timed out. + let mut expired = Vec::new(); + for (id, rw) in &self.outstanding { + if now > rw.timestamp + self.config.request_timeout { + log::debug!("request {} timed out", id); + expired.push(*id) + } + } + for id in expired { + if let Some(rw) = self.outstanding.remove(&id) { + self.remove_peer(&rw.peer); + self.peerset.report_peer(rw.peer.clone(), + ReputationChange::new(TIMEOUT_REPUTATION_CHANGE, "light request timeout")); + if rw.retries == 0 { + send_reply(Err(ClientError::RemoteFetchFailed), rw.request); + continue + } + let rw = RequestWrapper { + timestamp: Instant::now(), + retries: rw.retries - 1, + request: rw.request, + peer: (), + }; + self.pending_requests.push_back(rw) + } + } + + Poll::Pending + } +} + +fn required_block(request: &Request) -> NumberFor { + match request { + Request::Header { request, .. } => request.block, + Request::Read { request, .. } => *request.header.number(), + Request::ReadChild { request, .. } => *request.header.number(), + Request::Call { request, .. } => *request.header.number(), + Request::Changes { request, .. } => request.max_block.0, + } +} + +fn retries(request: &Request) -> usize { + let rc = match request { + Request::Header { request, .. } => request.retry_count, + Request::Read { request, .. } => request.retry_count, + Request::ReadChild { request, .. } => request.retry_count, + Request::Call { request, .. } => request.retry_count, + Request::Changes { request, .. } => request.retry_count, + }; + rc.unwrap_or(0) +} + +fn serialise_request(id: u64, request: &Request) -> api::v1::light::Request { + let request = match request { + Request::Header { request, .. } => { + let r = api::v1::light::RemoteHeaderRequest { block: request.block.encode() }; + api::v1::light::request::Request::RemoteHeaderRequest(r) + } + Request::Read { request, .. } => { + let r = api::v1::light::RemoteReadRequest { + block: request.block.encode(), + keys: request.keys.clone(), + }; + api::v1::light::request::Request::RemoteReadRequest(r) + } + Request::ReadChild { request, .. } => { + let r = api::v1::light::RemoteReadChildRequest { + block: request.block.encode(), + storage_key: request.storage_key.clone(), + child_type: request.child_type.clone(), + child_info: request.child_info.clone(), + keys: request.keys.clone(), + }; + api::v1::light::request::Request::RemoteReadChildRequest(r) + } + Request::Call { request, .. } => { + let r = api::v1::light::RemoteCallRequest { + block: request.block.encode(), + method: request.method.clone(), + data: request.call_data.clone(), + }; + api::v1::light::request::Request::RemoteCallRequest(r) + } + Request::Changes { request, .. } => { + let r = api::v1::light::RemoteChangesRequest { + first: request.first_block.1.encode(), + last: request.last_block.1.encode(), + min: request.tries_roots.1.encode(), + max: request.max_block.1.encode(), + storage_key: request.storage_key.clone().unwrap_or_default(), + key: request.key.clone(), + }; + api::v1::light::request::Request::RemoteChangesRequest(r) + } + }; + + api::v1::light::Request { id, request: Some(request) } +} + +fn send_reply(result: Result, ClientError>, request: Request) { + fn send(item: T, sender: oneshot::Sender) { + let _ = sender.send(item); // It is okay if the other end already hung up. + } + match request { + Request::Header { request, sender } => match result { + Err(e) => send(Err(e), sender), + Ok(Reply::Header(x)) => send(Ok(x), sender), + reply => log::error!("invalid reply for header request: {:?}, {:?}", reply, request), + } + Request::Read { request, sender } => match result { + Err(e) => send(Err(e), sender), + Ok(Reply::MapVecU8OptVecU8(x)) => send(Ok(x), sender), + reply => log::error!("invalid reply for read request: {:?}, {:?}", reply, request), + } + Request::ReadChild { request, sender } => match result { + Err(e) => send(Err(e), sender), + Ok(Reply::MapVecU8OptVecU8(x)) => send(Ok(x), sender), + reply => log::error!("invalid reply for read child request: {:?}, {:?}", reply, request), + } + Request::Call { request, sender } => match result { + Err(e) => send(Err(e), sender), + Ok(Reply::VecU8(x)) => send(Ok(x), sender), + reply => log::error!("invalid reply for call request: {:?}, {:?}", reply, request), + } + Request::Changes { request, sender } => match result { + Err(e) => send(Err(e), sender), + Ok(Reply::VecNumberU32(x)) => send(Ok(x), sender), + reply => log::error!("invalid reply for changes request: {:?}, {:?}", reply, request), + } + } +} + +/// Output type of inbound and outbound substream upgrades. +#[derive(Debug)] +pub enum Event { + /// Incoming request from remote and substream to use for the response. + Request(api::v1::light::Request, T), + /// Incoming response from remote. + Response(api::v1::light::Response), +} + +/// Substream upgrade protocol. +/// +/// Reads incoming requests from remote. +#[derive(Debug, Clone)] +pub struct InboundProtocol { + /// The max. request length in bytes. + max_data_size: usize, + /// The protocol to use for upgrade negotiation. + protocol: Bytes, +} + +impl UpgradeInfo for InboundProtocol { + type Info = Bytes; + type InfoIter = iter::Once; + + fn protocol_info(&self) -> Self::InfoIter { + iter::once(self.protocol.clone()) + } +} + +impl InboundUpgrade for InboundProtocol +where + T: AsyncRead + AsyncWrite + Unpin + Send + 'static +{ + type Output = Event; + type Error = ReadOneError; + type Future = BoxFuture<'static, Result>; + + fn upgrade_inbound(self, mut s: T, _: Self::Info) -> Self::Future { + let future = async move { + let vec = read_one(&mut s, self.max_data_size).await?; + match api::v1::light::Request::decode(&vec[..]) { + Ok(r) => Ok(Event::Request(r, s)), + Err(e) => Err(ReadOneError::Io(io::Error::new(io::ErrorKind::Other, e))) + } + }; + future.boxed() + } +} + +/// Substream upgrade protocol. +/// +/// Sends a request to remote and awaits the response. +#[derive(Debug, Clone)] +pub struct OutboundProtocol { + /// The serialised protobuf request. + request: Vec, + /// The max. request length in bytes. + max_data_size: usize, + /// The protocol to use for upgrade negotiation. + protocol: Bytes, +} + +impl UpgradeInfo for OutboundProtocol { + type Info = Bytes; + type InfoIter = iter::Once; + + fn protocol_info(&self) -> Self::InfoIter { + iter::once(self.protocol.clone()) + } +} + +impl OutboundUpgrade for OutboundProtocol +where + T: AsyncRead + AsyncWrite + Unpin + Send + 'static +{ + type Output = Event; + type Error = ReadOneError; + type Future = BoxFuture<'static, Result>; + + fn upgrade_outbound(self, mut s: T, _: Self::Info) -> Self::Future { + let future = async move { + write_one(&mut s, &self.request).await?; + let vec = read_one(&mut s, self.max_data_size).await?; + api::v1::light::Response::decode(&vec[..]) + .map(Event::Response) + .map_err(|e| { + ReadOneError::Io(io::Error::new(io::ErrorKind::Other, e)) + }) + }; + future.boxed() + } +} + +fn fmt_keys(first: Option<&Vec>, last: Option<&Vec>) -> String { + if let (Some(first), Some(last)) = (first, last) { + if first == last { + first.to_hex::() + } else { + format!("{}..{}", first.to_hex::(), last.to_hex::()) + } + } else { + String::from("n/a") + } +} + +#[cfg(test)] +mod tests { + use async_std::task; + use assert_matches::assert_matches; + use codec::Encode; + use crate::{ + chain::Client, + config::ProtocolId, + protocol::{api, light_dispatch::tests::{DummyFetchChecker, dummy_header}} + }; + use futures::{channel::oneshot, prelude::*}; + use libp2p::{ + PeerId, + Multiaddr, + core::{ + ConnectedPoint, + identity, + muxing::{StreamMuxerBox, SubstreamRef}, + transport::{Transport, boxed::Boxed, memory::MemoryTransport}, + upgrade + }, + noise::{self, Keypair, X25519, NoiseConfig}, + swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}, + yamux + }; + use sc_client_api::StorageProof; + use sc_client::light::fetcher; + use sp_blockchain::{Error as ClientError}; + use sp_core::storage::ChildInfo; + use std::{ + collections::HashSet, + io, + iter::{self, FromIterator}, + pin::Pin, + sync::Arc, + task::{Context, Poll} + }; + use sp_runtime::{generic::Header, traits::BlakeTwo256}; + use super::{Event, LightClientHandler, Request, OutboundProtocol, PeerStatus}; + use void::Void; + + const CHILD_INFO: ChildInfo<'static> = ChildInfo::new_default(b"foobarbaz"); + + type Block = sp_runtime::generic::Block, substrate_test_runtime::Extrinsic>; + type Handler = LightClientHandler>, Block>; + type Swarm = libp2p::swarm::Swarm, Handler>; + + fn empty_proof() -> Vec { + StorageProof::empty().encode() + } + + fn make_swarm(ok: bool, ps: sc_peerset::PeersetHandle, cf: super::Config) -> Swarm { + let client = Arc::new(substrate_test_runtime_client::new()); + let checker = Arc::new(DummyFetchChecker::new(ok)); + let id_key = identity::Keypair::generate_ed25519(); + let dh_key = Keypair::::new().into_authentic(&id_key).unwrap(); + let local_peer = id_key.public().into_peer_id(); + let transport = MemoryTransport::default() + .upgrade(upgrade::Version::V1) + .authenticate(NoiseConfig::xx(dh_key).into_authenticated()) + .multiplex(yamux::Config::default()) + .map(|(peer, muxer), _| (peer, StreamMuxerBox::new(muxer))) + .map_err(|e| io::Error::new(io::ErrorKind::Other, e)) + .boxed(); + Swarm::new(transport, LightClientHandler::new(cf, client, checker, ps), local_peer) + } + + fn make_config() -> super::Config { + super::Config::new(&ProtocolId::from(&b"foo"[..])) + } + + struct EmptyPollParams(PeerId); + + impl PollParameters for EmptyPollParams { + type SupportedProtocolsIter = iter::Empty>; + type ListenedAddressesIter = iter::Empty; + type ExternalAddressesIter = iter::Empty; + + fn supported_protocols(&self) -> Self::SupportedProtocolsIter { + iter::empty() + } + + fn listened_addresses(&self) -> Self::ListenedAddressesIter { + iter::empty() + } + + fn external_addresses(&self) -> Self::ExternalAddressesIter { + iter::empty() + } + + fn local_peer_id(&self) -> &PeerId { + &self.0 + } + } + + fn peerset() -> (sc_peerset::Peerset, sc_peerset::PeersetHandle) { + let cfg = sc_peerset::PeersetConfig { + in_peers: 128, + out_peers: 128, + bootnodes: Vec::new(), + reserved_only: false, + reserved_nodes: Vec::new(), + }; + sc_peerset::Peerset::from_config(cfg) + } + + fn make_behaviour + ( ok: bool + , ps: sc_peerset::PeersetHandle + , cf: super::Config + ) -> LightClientHandler>, Block> + { + let client = Arc::new(substrate_test_runtime_client::new()); + let checker = Arc::new(DummyFetchChecker::new(ok)); + LightClientHandler::new(cf, client, checker, ps) + } + + fn empty_dialer() -> ConnectedPoint { + ConnectedPoint::Dialer { address: Multiaddr::empty() } + } + + fn poll(mut b: &mut LightClientHandler) -> Poll> + where + T: AsyncRead + AsyncWrite + Unpin + Send + 'static + { + let mut p = EmptyPollParams(PeerId::random()); + match future::poll_fn(|cx| Pin::new(&mut b).poll(cx, &mut p)).now_or_never() { + Some(a) => Poll::Ready(a), + None => Poll::Pending + } + } + + #[test] + fn disconnects_from_peer_if_told() { + let peer = PeerId::random(); + let pset = peerset(); + let mut behaviour = make_behaviour(true, pset.1, make_config()); + + behaviour.inject_connected(peer.clone(), empty_dialer()); + assert_eq!(1, behaviour.peers.len()); + + behaviour.inject_disconnected(&peer, empty_dialer()); + assert_eq!(0, behaviour.peers.len()) + } + + #[test] + fn disconnects_from_peer_if_request_times_out() { + let peer0 = PeerId::random(); + let peer1 = PeerId::random(); + let pset = peerset(); + let mut behaviour = make_behaviour(true, pset.1, make_config()); + + behaviour.inject_connected(peer0.clone(), empty_dialer()); + behaviour.inject_connected(peer1.clone(), empty_dialer()); + + // We now know about two peers. + assert_eq!(HashSet::from_iter(&[peer0.clone(), peer1.clone()]), behaviour.peers.keys().collect::>()); + + // No requests have been made yet. + assert!(behaviour.pending_requests.is_empty()); + assert!(behaviour.outstanding.is_empty()); + + // Issue our first request! + let chan = oneshot::channel(); + let request = fetcher::RemoteCallRequest { + block: Default::default(), + header: dummy_header(), + method: "test".into(), + call_data: vec![], + retry_count: Some(1), + }; + behaviour.request(Request::Call { request, sender: chan.0 }).unwrap(); + assert_eq!(1, behaviour.pending_requests.len()); + + // The behaviour should now attempt to send the request. + assert_matches!(poll(&mut behaviour), Poll::Ready(NetworkBehaviourAction::SendEvent { peer_id, .. }) => { + assert!(peer_id == peer0 || peer_id == peer1) + }); + + // And we should have one busy peer. + assert!({ + let (idle, busy): (Vec<_>, Vec<_>) = + behaviour.peers.iter().partition(|(_, info)| info.status == PeerStatus::Idle); + + idle.len() == 1 && busy.len() == 1 + && (idle[0].0 == &peer0 || busy[0].0 == &peer0) + && (idle[0].0 == &peer1 || busy[0].0 == &peer1) + }); + + // No more pending requests, but one should be outstanding. + assert_eq!(0, behaviour.pending_requests.len()); + assert_eq!(1, behaviour.outstanding.len()); + + // We now set back the timestamp of the outstanding request to make it expire. + let request = behaviour.outstanding.values_mut().next().unwrap(); + request.timestamp -= make_config().request_timeout; + + // Make progress, but do not expect some action. + assert_matches!(poll(&mut behaviour), Poll::Pending); + + // The request should have timed out by now and the corresponding peer be removed. + assert_eq!(1, behaviour.peers.len()); + // Since we asked for one retry, the request should be back in the pending queue. + assert_eq!(1, behaviour.pending_requests.len()); + // No other request should be ongoing. + assert_eq!(0, behaviour.outstanding.len()); + } + + #[test] + fn disconnects_from_peer_on_response_with_wrong_id() { + let peer = PeerId::random(); + let pset = peerset(); + let mut behaviour = make_behaviour(true, pset.1, make_config()); + + behaviour.inject_connected(peer.clone(), empty_dialer()); + assert_eq!(1, behaviour.peers.len()); + + let chan = oneshot::channel(); + let request = fetcher::RemoteCallRequest { + block: Default::default(), + header: dummy_header(), + method: "test".into(), + call_data: vec![], + retry_count: Some(1), + }; + behaviour.request(Request::Call { request, sender: chan.0 }).unwrap(); + + assert_eq!(1, behaviour.pending_requests.len()); + assert_eq!(0, behaviour.outstanding.len()); + poll(&mut behaviour); // Make progress + assert_eq!(0, behaviour.pending_requests.len()); + assert_eq!(1, behaviour.outstanding.len()); + + // Construct response with bogus ID + let response = { + let r = api::v1::light::RemoteCallResponse { proof: empty_proof() }; + api::v1::light::Response { + id: 2365789, + response: Some(api::v1::light::response::Response::RemoteCallResponse(r)), + } + }; + + // Make sure our bogus ID is really not used. + assert!(!behaviour.outstanding.keys().any(|id| id == &response.id)); + + behaviour.inject_node_event(peer.clone(), Event::Response(response)); + assert!(behaviour.peers.is_empty()); + + poll(&mut behaviour); // More progress + + // The request should be back in the pending queue + assert_eq!(1, behaviour.pending_requests.len()); + assert_eq!(0, behaviour.outstanding.len()); + } + + #[test] + fn disconnects_from_peer_on_incorrect_response() { + let peer = PeerId::random(); + let pset = peerset(); + let mut behaviour = make_behaviour(false, pset.1, make_config()); + // ^--- Making sure the response data check fails. + + behaviour.inject_connected(peer.clone(), empty_dialer()); + assert_eq!(1, behaviour.peers.len()); + + let chan = oneshot::channel(); + let request = fetcher::RemoteCallRequest { + block: Default::default(), + header: dummy_header(), + method: "test".into(), + call_data: vec![], + retry_count: Some(1), + }; + behaviour.request(Request::Call { request, sender: chan.0 }).unwrap(); + + assert_eq!(1, behaviour.pending_requests.len()); + assert_eq!(0, behaviour.outstanding.len()); + poll(&mut behaviour); // Make progress + assert_eq!(0, behaviour.pending_requests.len()); + assert_eq!(1, behaviour.outstanding.len()); + + let request_id = *behaviour.outstanding.keys().next().unwrap(); + + let response = { + let r = api::v1::light::RemoteCallResponse { proof: empty_proof() }; + api::v1::light::Response { + id: request_id, + response: Some(api::v1::light::response::Response::RemoteCallResponse(r)), + } + }; + + behaviour.inject_node_event(peer.clone(), Event::Response(response)); + assert!(behaviour.peers.is_empty()); + + poll(&mut behaviour); // More progress + + // The request should be back in the pending queue + assert_eq!(1, behaviour.pending_requests.len()); + assert_eq!(0, behaviour.outstanding.len()); + } + + #[test] + fn disconnects_from_peer_on_unexpected_response() { + let peer = PeerId::random(); + let pset = peerset(); + let mut behaviour = make_behaviour(true, pset.1, make_config()); + + behaviour.inject_connected(peer.clone(), empty_dialer()); + assert_eq!(1, behaviour.peers.len()); + assert_eq!(0, behaviour.pending_requests.len()); + assert_eq!(0, behaviour.outstanding.len()); + + // Some unsolicited response + let response = { + let r = api::v1::light::RemoteCallResponse { proof: empty_proof() }; + api::v1::light::Response { + id: 2347895932, + response: Some(api::v1::light::response::Response::RemoteCallResponse(r)), + } + }; + + behaviour.inject_node_event(peer.clone(), Event::Response(response)); + + assert!(behaviour.peers.is_empty()); + poll(&mut behaviour); + assert_eq!(0, behaviour.pending_requests.len()); + assert_eq!(0, behaviour.outstanding.len()); + } + + #[test] + fn disconnects_from_peer_on_wrong_response_type() { + let peer = PeerId::random(); + let pset = peerset(); + let mut behaviour = make_behaviour(true, pset.1, make_config()); + + behaviour.inject_connected(peer.clone(), empty_dialer()); + assert_eq!(1, behaviour.peers.len()); + + let chan = oneshot::channel(); + let request = fetcher::RemoteCallRequest { + block: Default::default(), + header: dummy_header(), + method: "test".into(), + call_data: vec![], + retry_count: Some(1), + }; + behaviour.request(Request::Call { request, sender: chan.0 }).unwrap(); + + assert_eq!(1, behaviour.pending_requests.len()); + assert_eq!(0, behaviour.outstanding.len()); + poll(&mut behaviour); // Make progress + assert_eq!(0, behaviour.pending_requests.len()); + assert_eq!(1, behaviour.outstanding.len()); + + let request_id = *behaviour.outstanding.keys().next().unwrap(); + + let response = { + let r = api::v1::light::RemoteReadResponse { proof: empty_proof() }; // Not a RemoteCallResponse! + api::v1::light::Response { + id: request_id, + response: Some(api::v1::light::response::Response::RemoteReadResponse(r)), + } + }; + + behaviour.inject_node_event(peer.clone(), Event::Response(response)); + assert!(behaviour.peers.is_empty()); + + poll(&mut behaviour); // More progress + + // The request should be back in the pending queue + assert_eq!(1, behaviour.pending_requests.len()); + assert_eq!(0, behaviour.outstanding.len()); + } + + #[test] + fn receives_remote_failure_after_retry_count_failures() { + let peer1 = PeerId::random(); + let peer2 = PeerId::random(); + let peer3 = PeerId::random(); + let peer4 = PeerId::random(); + let pset = peerset(); + let mut behaviour = make_behaviour(false, pset.1, make_config()); + // ^--- Making sure the response data check fails. + + behaviour.inject_connected(peer1.clone(), empty_dialer()); + behaviour.inject_connected(peer2.clone(), empty_dialer()); + behaviour.inject_connected(peer3.clone(), empty_dialer()); + behaviour.inject_connected(peer4.clone(), empty_dialer()); + assert_eq!(4, behaviour.peers.len()); + + let mut chan = oneshot::channel(); + let request = fetcher::RemoteCallRequest { + block: Default::default(), + header: dummy_header(), + method: "test".into(), + call_data: vec![], + retry_count: Some(3), // Attempt up to three retries. + }; + behaviour.request(Request::Call { request, sender: chan.0 }).unwrap(); + + assert_eq!(1, behaviour.pending_requests.len()); + assert_eq!(0, behaviour.outstanding.len()); + assert_matches!(poll(&mut behaviour), Poll::Ready(NetworkBehaviourAction::SendEvent { .. })); + assert_eq!(0, behaviour.pending_requests.len()); + assert_eq!(1, behaviour.outstanding.len()); + + for _ in 0 .. 3 { + // Construct an invalid response + let request_id = *behaviour.outstanding.keys().next().unwrap(); + let responding_peer = behaviour.outstanding.values().next().unwrap().peer.clone(); + let response = { + let r = api::v1::light::RemoteCallResponse { proof: empty_proof() }; + api::v1::light::Response { + id: request_id, + response: Some(api::v1::light::response::Response::RemoteCallResponse(r)) + } + }; + behaviour.inject_node_event(responding_peer, Event::Response(response.clone())); + assert_matches!(poll(&mut behaviour), Poll::Ready(NetworkBehaviourAction::SendEvent { .. })); + assert_matches!(chan.1.try_recv(), Ok(None)) + } + // Final invalid response + let request_id = *behaviour.outstanding.keys().next().unwrap(); + let responding_peer = behaviour.outstanding.values().next().unwrap().peer.clone(); + let response = { + let r = api::v1::light::RemoteCallResponse { proof: empty_proof() }; + api::v1::light::Response { + id: request_id, + response: Some(api::v1::light::response::Response::RemoteCallResponse(r)), + } + }; + behaviour.inject_node_event(responding_peer, Event::Response(response)); + assert_matches!(poll(&mut behaviour), Poll::Pending); + assert_matches!(chan.1.try_recv(), Ok(Some(Err(ClientError::RemoteFetchFailed)))) + } + + fn issue_request(request: Request) { + let peer = PeerId::random(); + let pset = peerset(); + let mut behaviour = make_behaviour(true, pset.1, make_config()); + + behaviour.inject_connected(peer.clone(), empty_dialer()); + assert_eq!(1, behaviour.peers.len()); + + let response = match request { + Request::Header{..} => { + let r = api::v1::light::RemoteHeaderResponse { + header: dummy_header().encode(), + proof: empty_proof() + }; + api::v1::light::Response { + id: 1, + response: Some(api::v1::light::response::Response::RemoteHeaderResponse(r)), + } + } + Request::Read{..} => { + let r = api::v1::light::RemoteReadResponse { proof: empty_proof() }; + api::v1::light::Response { + id: 1, + response: Some(api::v1::light::response::Response::RemoteReadResponse(r)), + } + } + Request::ReadChild{..} => { + let r = api::v1::light::RemoteReadResponse { proof: empty_proof() }; + api::v1::light::Response { + id: 1, + response: Some(api::v1::light::response::Response::RemoteReadResponse(r)), + } + } + Request::Call{..} => { + let r = api::v1::light::RemoteCallResponse { proof: empty_proof() }; + api::v1::light::Response { + id: 1, + response: Some(api::v1::light::response::Response::RemoteCallResponse(r)), + } + } + Request::Changes{..} => { + let r = api::v1::light::RemoteChangesResponse { + max: iter::repeat(1).take(32).collect(), + proof: Vec::new(), + roots: Vec::new(), + roots_proof: empty_proof() + }; + api::v1::light::Response { + id: 1, + response: Some(api::v1::light::response::Response::RemoteChangesResponse(r)), + } + } + }; + + behaviour.request(request).unwrap(); + + assert_eq!(1, behaviour.pending_requests.len()); + assert_eq!(0, behaviour.outstanding.len()); + assert_matches!(poll(&mut behaviour), Poll::Ready(NetworkBehaviourAction::SendEvent { .. })); + assert_eq!(0, behaviour.pending_requests.len()); + assert_eq!(1, behaviour.outstanding.len()); + assert_eq!(1, *behaviour.outstanding.keys().next().unwrap()); + + behaviour.inject_node_event(peer.clone(), Event::Response(response)); + + poll(&mut behaviour); + + assert_eq!(0, behaviour.pending_requests.len()); + assert_eq!(0, behaviour.outstanding.len()) + } + + #[test] + fn receives_remote_call_response() { + let mut chan = oneshot::channel(); + let request = fetcher::RemoteCallRequest { + block: Default::default(), + header: dummy_header(), + method: "test".into(), + call_data: vec![], + retry_count: None, + }; + issue_request(Request::Call { request, sender: chan.0 }); + assert_matches!(chan.1.try_recv(), Ok(Some(Ok(_)))) + } + + #[test] + fn receives_remote_read_response() { + let mut chan = oneshot::channel(); + let request = fetcher::RemoteReadRequest { + header: dummy_header(), + block: Default::default(), + keys: vec![b":key".to_vec()], + retry_count: None, + }; + issue_request(Request::Read { request, sender: chan.0 }); + assert_matches!(chan.1.try_recv(), Ok(Some(Ok(_)))) + } + + #[test] + fn receives_remote_read_child_response() { + let info = CHILD_INFO.info(); + let mut chan = oneshot::channel(); + let request = fetcher::RemoteReadChildRequest { + header: dummy_header(), + block: Default::default(), + storage_key: b":child_storage:sub".to_vec(), + keys: vec![b":key".to_vec()], + child_info: info.0.to_vec(), + child_type: info.1, + retry_count: None, + }; + issue_request(Request::ReadChild { request, sender: chan.0 }); + assert_matches!(chan.1.try_recv(), Ok(Some(Ok(_)))) + } + + #[test] + fn receives_remote_header_response() { + let mut chan = oneshot::channel(); + let request = fetcher::RemoteHeaderRequest { + cht_root: Default::default(), + block: 1, + retry_count: None, + }; + issue_request(Request::Header { request, sender: chan.0 }); + assert_matches!(chan.1.try_recv(), Ok(Some(Ok(_)))) + } + + #[test] + fn receives_remote_changes_response() { + let mut chan = oneshot::channel(); + let request = fetcher::RemoteChangesRequest { + changes_trie_configs: vec![sp_core::ChangesTrieConfigurationRange { + zero: (0, Default::default()), + end: None, + config: Some(sp_core::ChangesTrieConfiguration::new(4, 2)), + }], + first_block: (1, Default::default()), + last_block: (100, Default::default()), + max_block: (100, Default::default()), + tries_roots: (1, Default::default(), Vec::new()), + key: Vec::new(), + storage_key: None, + retry_count: None, + }; + issue_request(Request::Changes { request, sender: chan.0 }); + assert_matches!(chan.1.try_recv(), Ok(Some(Ok(_)))) + } + + fn send_receive(request: Request) { + // We start a swarm on the listening side which awaits incoming requests and answers them: + let local_pset = peerset(); + let local_listen_addr: libp2p::Multiaddr = libp2p::multiaddr::Protocol::Memory(rand::random()).into(); + let mut local_swarm = make_swarm(true, local_pset.1, make_config()); + Swarm::listen_on(&mut local_swarm, local_listen_addr.clone()).unwrap(); + + // We also start a swarm that makes requests and awaits responses: + let remote_pset = peerset(); + let mut remote_swarm = make_swarm(true, remote_pset.1, make_config()); + + // We now schedule a request, dial the remote and let the two swarm work it out: + remote_swarm.request(request).unwrap(); + Swarm::dial_addr(&mut remote_swarm, local_listen_addr).unwrap(); + + let future = { + let a = local_swarm.for_each(|_| future::ready(())); + let b = remote_swarm.for_each(|_| future::ready(())); + future::join(a, b).map(|_| ()) + }; + + task::spawn(future); + } + + #[test] + fn send_receive_call() { + let chan = oneshot::channel(); + let request = fetcher::RemoteCallRequest { + block: Default::default(), + header: dummy_header(), + method: "test".into(), + call_data: vec![], + retry_count: None, + }; + send_receive(Request::Call { request, sender: chan.0 }); + assert_eq!(vec![42], task::block_on(chan.1).unwrap().unwrap()); + // ^--- from `DummyFetchChecker::check_execution_proof` + } + + #[test] + fn send_receive_read() { + let chan = oneshot::channel(); + let request = fetcher::RemoteReadRequest { + header: dummy_header(), + block: Default::default(), + keys: vec![b":key".to_vec()], + retry_count: None + }; + send_receive(Request::Read { request, sender: chan.0 }); + assert_eq!(Some(vec![42]), task::block_on(chan.1).unwrap().unwrap().remove(&b":key"[..]).unwrap()); + // ^--- from `DummyFetchChecker::check_read_proof` + } + + #[test] + fn send_receive_read_child() { + let info = CHILD_INFO.info(); + let chan = oneshot::channel(); + let request = fetcher::RemoteReadChildRequest { + header: dummy_header(), + block: Default::default(), + storage_key: b":child_storage:sub".to_vec(), + keys: vec![b":key".to_vec()], + child_info: info.0.to_vec(), + child_type: info.1, + retry_count: None, + }; + send_receive(Request::ReadChild { request, sender: chan.0 }); + assert_eq!(Some(vec![42]), task::block_on(chan.1).unwrap().unwrap().remove(&b":key"[..]).unwrap()); + // ^--- from `DummyFetchChecker::check_read_child_proof` + } + + #[test] + fn send_receive_header() { + let _ = env_logger::try_init(); + let chan = oneshot::channel(); + let request = fetcher::RemoteHeaderRequest { + cht_root: Default::default(), + block: 1, + retry_count: None, + }; + send_receive(Request::Header { request, sender: chan.0 }); + // The remote does not know block 1: + assert_matches!(task::block_on(chan.1).unwrap(), Err(ClientError::RemoteFetchFailed)); + } + + #[test] + fn send_receive_changes() { + let chan = oneshot::channel(); + let request = fetcher::RemoteChangesRequest { + changes_trie_configs: vec![sp_core::ChangesTrieConfigurationRange { + zero: (0, Default::default()), + end: None, + config: Some(sp_core::ChangesTrieConfiguration::new(4, 2)), + }], + first_block: (1, Default::default()), + last_block: (100, Default::default()), + max_block: (100, Default::default()), + tries_roots: (1, Default::default(), Vec::new()), + key: Vec::new(), + storage_key: None, + retry_count: None, + }; + send_receive(Request::Changes { request, sender: chan.0 }); + assert_eq!(vec![(100, 2)], task::block_on(chan.1).unwrap().unwrap()); + // ^--- from `DummyFetchChecker::check_changes_proof` + } +} diff --git a/client/network/src/protocol/light_dispatch.rs b/client/network/src/protocol/light_dispatch.rs index 5b587d2045..2eab0a5a3f 100644 --- a/client/network/src/protocol/light_dispatch.rs +++ b/client/network/src/protocol/light_dispatch.rs @@ -41,7 +41,7 @@ const REQUEST_TIMEOUT: Duration = Duration::from_secs(15); /// Default request retry count. const RETRY_COUNT: usize = 1; /// Reputation change for a peer when a request timed out. -const TIMEOUT_REPUTATION_CHANGE: i32 = -(1 << 8); +pub(crate) const TIMEOUT_REPUTATION_CHANGE: i32 = -(1 << 8); /// Trait used by the `LightDispatch` service to communicate messages back to the network. pub trait LightDispatchNetwork { @@ -692,17 +692,26 @@ pub mod tests { use crate::message::{self, BlockAttributes, Direction, FromBlock, RequestId}; use libp2p::PeerId; use super::{REQUEST_TIMEOUT, LightDispatch, LightDispatchNetwork, RequestData, StorageProof}; - use sp_test_primitives::{Block, Extrinsic, Header}; + use sp_test_primitives::{Block, Header}; - struct DummyFetchChecker { ok: bool } + pub(crate) struct DummyFetchChecker { + pub(crate) ok: bool, + _mark: std::marker::PhantomData + } + + impl DummyFetchChecker { + pub(crate) fn new(ok: bool) -> Self { + DummyFetchChecker { ok, _mark: std::marker::PhantomData } + } + } - impl FetchChecker for DummyFetchChecker { + impl FetchChecker for DummyFetchChecker { fn check_header_proof( &self, - _request: &RemoteHeaderRequest

, - header: Option
, + _request: &RemoteHeaderRequest, + header: Option, _remote_proof: StorageProof, - ) -> ClientResult
{ + ) -> ClientResult { match self.ok { true if header.is_some() => Ok(header.unwrap()), _ => Err(ClientError::Backend("Test error".into())), @@ -711,7 +720,7 @@ pub mod tests { fn check_read_proof( &self, - request: &RemoteReadRequest
, + request: &RemoteReadRequest, _: StorageProof, ) -> ClientResult, Option>>> { match self.ok { @@ -727,7 +736,7 @@ pub mod tests { fn check_read_child_proof( &self, - request: &RemoteReadChildRequest
, + request: &RemoteReadChildRequest, _: StorageProof, ) -> ClientResult, Option>>> { match self.ok { @@ -741,7 +750,7 @@ pub mod tests { } } - fn check_execution_proof(&self, _: &RemoteCallRequest
, _: StorageProof) -> ClientResult> { + fn check_execution_proof(&self, _: &RemoteCallRequest, _: StorageProof) -> ClientResult> { match self.ok { true => Ok(vec![42]), false => Err(ClientError::Backend("Test error".into())), @@ -750,20 +759,20 @@ pub mod tests { fn check_changes_proof( &self, - _: &RemoteChangesRequest
, - _: ChangesProof
- ) -> ClientResult, u32)>> { + _: &RemoteChangesRequest, + _: ChangesProof + ) -> ClientResult, u32)>> { match self.ok { - true => Ok(vec![(100, 2)]), + true => Ok(vec![(100.into(), 2)]), false => Err(ClientError::Backend("Test error".into())), } } fn check_body_proof( &self, - _: &RemoteBodyRequest
, - body: Vec - ) -> ClientResult> { + _: &RemoteBodyRequest, + body: Vec + ) -> ClientResult> { match self.ok { true => Ok(body), false => Err(ClientError::Backend("Test error".into())), @@ -772,7 +781,7 @@ pub mod tests { } fn dummy(ok: bool) -> LightDispatch { - LightDispatch::new(Arc::new(DummyFetchChecker { ok })) + LightDispatch::new(Arc::new(DummyFetchChecker::new(ok))) } fn total_peers(light_dispatch: &LightDispatch) -> usize { @@ -791,7 +800,7 @@ pub mod tests { }); } - fn dummy_header() -> Header { + pub(crate) fn dummy_header() -> Header { Header { parent_hash: Default::default(), number: 0, diff --git a/client/network/src/protocol/schema/api.v1.proto b/client/network/src/protocol/schema/api.v1.proto new file mode 100644 index 0000000000..e4c32ec585 --- /dev/null +++ b/client/network/src/protocol/schema/api.v1.proto @@ -0,0 +1,59 @@ +// Schema definition for block request/response messages. + +syntax = "proto3"; + +package api.v1; + +// Block enumeration direction. +enum Direction { + // Enumerate in ascending order (from child to parent). + Ascending = 0; + // Enumerate in descendfing order (from parent to canonical child). + Descending = 1; +} + +// Request block data from a peer. +message BlockRequest { + // Unique request id. + uint64 id = 1; + // Bits of block data to request. + uint32 fields = 2; + // Start from this block. + oneof from_block { + // Start with given hash. + bytes hash = 3; + // Start with given block number. + bytes number = 4; + } + // End at this block. An implementation defined maximum is used when unspecified. + bytes to_block = 5; // optional + // Sequence direction. + Direction direction = 6; + // Maximum number of blocks to return. An implementation defined maximum is used when unspecified. + uint32 max_blocks = 7; // optional +} + +// Response to `BlockRequest` +message BlockResponse { + // Id of a request this response was made for. + uint64 id = 1; + // Block data for the requested sequence. + repeated BlockData blocks = 2; +} + +// Block data sent in the response. +message BlockData { + // Block header hash. + bytes hash = 1; + // Block header if requested. + bytes header = 2; // optional + // Block body if requested. + repeated bytes body = 3; // optional + // Block receipt if requested. + bytes receipt = 4; // optional + // Block message queue if requested. + bytes message_queue = 5; // optional + // Justification if requested. + bytes justification = 6; // optional +} + diff --git a/client/network/src/protocol/schema/light.v1.proto b/client/network/src/protocol/schema/light.v1.proto new file mode 100644 index 0000000000..b9aee67b5e --- /dev/null +++ b/client/network/src/protocol/schema/light.v1.proto @@ -0,0 +1,128 @@ +// Schema definition for light client messages. + +syntax = "proto3"; + +package api.v1.light; + +// A pair of arbitrary bytes. +message Pair { + // The first element of the pair. + bytes fst = 1; + // The second element of the pair. + bytes snd = 2; +} + +// Enumerate all possible light client request messages. +message Request { + // Unique request id. + uint64 id = 1; + oneof request { + RemoteCallRequest remote_call_request = 2; + RemoteReadRequest remote_read_request = 3; + RemoteHeaderRequest remote_header_request = 4; + RemoteReadChildRequest remote_read_child_request = 5; + RemoteChangesRequest remote_changes_request = 6; + } +} + +// Enumerate all possible light client response messages. +message Response { + /// Id of a request this response was made for. + uint64 id = 1; + oneof response { + RemoteCallResponse remote_call_response = 2; + RemoteReadResponse remote_read_response = 3; + RemoteHeaderResponse remote_header_response = 4; + RemoteChangesResponse remote_changes_response = 6; + } +} + +// Remote call request. +message RemoteCallRequest { + // Block at which to perform call. + bytes block = 2; + // Method name. + string method = 3; + // Call data. + bytes data = 4; +} + +// Remote call response. +message RemoteCallResponse { + // Execution proof. + bytes proof = 2; +} + +// Remote storage read request. +message RemoteReadRequest { + // Block at which to perform call. + bytes block = 2; + // Storage keys. + repeated bytes keys = 3; +} + +// Remote read response. +message RemoteReadResponse { + // Read proof. + bytes proof = 2; +} + +// Remote storage read child request. +message RemoteReadChildRequest { + // Block at which to perform call. + bytes block = 2; + // Child Storage key. + bytes storage_key = 3; + // Child trie source information. + bytes child_info = 4; + /// Child type, its required to resolve `child_info` + /// content and choose child implementation. + uint32 child_type = 5; + // Storage keys. + repeated bytes keys = 6; +} + +// Remote header request. +message RemoteHeaderRequest { + // Block number to request header for. + bytes block = 2; +} + +// Remote header response. +message RemoteHeaderResponse { + // Header. None if proof generation has failed (e.g. header is unknown). + bytes header = 2; // optional + // Header proof. + bytes proof = 3; +} + +/// Remote changes request. +message RemoteChangesRequest { + // Hash of the first block of the range (including first) where changes are requested. + bytes first = 2; + // Hash of the last block of the range (including last) where changes are requested. + bytes last = 3; + // Hash of the first block for which the requester has the changes trie root. All other + // affected roots must be proved. + bytes min = 4; + // Hash of the last block that we can use when querying changes. + bytes max = 5; + // Storage child node key which changes are requested. + bytes storage_key = 6; // optional + // Storage key which changes are requested. + bytes key = 7; +} + +// Remote changes response. +message RemoteChangesResponse { + // Proof has been generated using block with this number as a max block. Should be + // less than or equal to the RemoteChangesRequest::max block number. + bytes max = 2; + // Changes proof. + repeated bytes proof = 3; + // Changes tries roots missing on the requester' node. + repeated Pair roots = 4; + // Missing changes tries roots proof. + bytes roots_proof = 5; +} + diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 3dc8a49764..156e2e3102 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -193,6 +193,10 @@ impl, H: ExHashT> NetworkWorker let local_peer_id = local_public.clone().into_peer_id(); info!(target: "sub-libp2p", "Local node identity is: {}", local_peer_id.to_base58()); + let checker = params.on_demand.as_ref() + .map(|od| od.checker().clone()) + .unwrap_or(Arc::new(AlwaysBadChecker)); + let num_connected = Arc::new(AtomicUsize::new(0)); let is_major_syncing = Arc::new(AtomicBool::new(false)); let (protocol, peerset_handle) = Protocol::new( @@ -200,14 +204,13 @@ impl, H: ExHashT> NetworkWorker roles: params.roles, max_parallel_downloads: params.network_config.max_parallel_downloads, }, - params.chain, - params.on_demand.as_ref().map(|od| od.checker().clone()) - .unwrap_or(Arc::new(AlwaysBadChecker)), + params.chain.clone(), + checker.clone(), params.specialization, params.transaction_pool, - params.finality_proof_provider, + params.finality_proof_provider.clone(), params.finality_proof_request_builder, - params.protocol_id, + params.protocol_id.clone(), peerset_config, params.block_announce_validator )?; @@ -219,6 +222,14 @@ impl, H: ExHashT> NetworkWorker params.network_config.client_version, params.network_config.node_name ); + let block_requests = { + let config = protocol::block_requests::Config::new(¶ms.protocol_id); + protocol::BlockRequests::new(config, params.chain.clone()) + }; + let light_client_handler = { + let config = protocol::light_client_handler::Config::new(¶ms.protocol_id); + protocol::LightClientHandler::new(config, params.chain, checker, peerset_handle.clone()) + }; let behaviour = futures::executor::block_on(Behaviour::new( protocol, user_agent, @@ -233,6 +244,8 @@ impl, H: ExHashT> NetworkWorker TransportConfig::Normal { allow_private_ipv4, .. } => allow_private_ipv4, }, u64::from(params.network_config.out_peers) + 15, + block_requests, + light_client_handler )); let (transport, bandwidth) = { let (config_mem, config_wasm, flowctrl) = match params.network_config.transport { -- GitLab From 2290645fb253cd6629525be775cbbb6bd43658e8 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Wed, 12 Feb 2020 12:11:20 +0100 Subject: [PATCH 138/180] Benchmark the Balances Pallet (#4879) * Initial transfer bench * Add best case * Transfer keep alive * Set balance benchmarks * Bump impl * Fix text Co-authored-by: Gavin Wood --- bin/node/runtime/src/lib.rs | 1 + frame/balances/src/benchmarking.rs | 322 +++++++++++++++++++++++++++++ frame/balances/src/lib.rs | 1 + 3 files changed, 324 insertions(+) create mode 100644 frame/balances/src/benchmarking.rs diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 209208c58f..4800c08260 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -812,6 +812,7 @@ impl_runtime_apis! { -> Option> { match module.as_slice() { + b"pallet-balances" | b"balances" => Balances::run_benchmark(extrinsic, steps, repeat).ok(), b"pallet-identity" | b"identity" => Identity::run_benchmark(extrinsic, steps, repeat).ok(), b"pallet-timestamp" | b"timestamp" => Timestamp::run_benchmark(extrinsic, steps, repeat).ok(), _ => return None, diff --git a/frame/balances/src/benchmarking.rs b/frame/balances/src/benchmarking.rs new file mode 100644 index 0000000000..f48220c1ba --- /dev/null +++ b/frame/balances/src/benchmarking.rs @@ -0,0 +1,322 @@ +// Copyright 2020 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 . + +//! Balances pallet benchmarking. + +use super::*; + +use frame_system::RawOrigin; +use sp_io::hashing::blake2_256; +use sp_runtime::{BenchmarkResults, BenchmarkParameter}; +use sp_runtime::traits::{Bounded, Benchmarking, BenchmarkingSetup, Dispatchable}; + +use crate::Module as Balances; + +// Support Functions +fn account(name: &'static str, index: u32) -> T::AccountId { + let entropy = (name, index).using_encoded(blake2_256); + T::AccountId::decode(&mut &entropy[..]).unwrap_or_default() +} + +// Benchmark `transfer` extrinsic with the worst possible conditions: +// * Transfer will kill the sender account. +// * Transfer will create the recipient account. +struct Transfer; +impl BenchmarkingSetup, RawOrigin> for Transfer { + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + vec![ + // Existential Deposit Multiplier + (BenchmarkParameter::E, 2, 1000), + // User Seed + (BenchmarkParameter::U, 1, 1000), + ] + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(crate::Call, RawOrigin), &'static str> + { + // Constants + let ed = T::ExistentialDeposit::get(); + + // Select an account + let u = components.iter().find(|&c| c.0 == BenchmarkParameter::U).unwrap().1; + let user = account::("user", u); + let user_origin = RawOrigin::Signed(user.clone()); + + // Give some multiple of the existential deposit + creation fee + transfer fee + let e = components.iter().find(|&c| c.0 == BenchmarkParameter::E).unwrap().1; + let mut balance = ed.saturating_mul(e.into()); + balance += T::CreationFee::get(); + let _ = as Currency<_>>::make_free_balance_be(&user, balance); + + // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, and reap this user. + let recipient = account::("recipient", u); + let recipient_lookup: ::Source = T::Lookup::unlookup(recipient); + let transfer_amt = ed.saturating_mul((e - 1).into()) + 1.into(); + + // Return the `transfer` call + Ok((crate::Call::::transfer(recipient_lookup, transfer_amt), user_origin)) + } +} + +// Benchmark `transfer` with the best possible condition: +// * Both accounts exist and will continue to exist. +struct TransferBestCase; +impl BenchmarkingSetup, RawOrigin> for TransferBestCase { + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + vec![ + // Existential Deposit Multiplier + (BenchmarkParameter::E, 2, 1000), + // User Seed + (BenchmarkParameter::U, 1, 1000), + ] + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(crate::Call, RawOrigin), &'static str> + { + // Constants + let ed = T::ExistentialDeposit::get(); + + // Select a sender + let u = components.iter().find(|&c| c.0 == BenchmarkParameter::U).unwrap().1; + let user = account::("user", u); + let user_origin = RawOrigin::Signed(user.clone()); + + // Select a recipient + let recipient = account::("recipient", u); + let recipient_lookup: ::Source = T::Lookup::unlookup(recipient.clone()); + + // Get the existential deposit multiplier + let e = components.iter().find(|&c| c.0 == BenchmarkParameter::E).unwrap().1; + + // Give the sender account max funds for transfer (their account will never reasonably be killed). + let _ = as Currency<_>>::make_free_balance_be(&user, T::Balance::max_value()); + + // Give the recipient account existential deposit (thus their account already exists). + let _ = as Currency<_>>::make_free_balance_be(&recipient, ed); + + // Transfer e * existential deposit. + let transfer_amt = ed.saturating_mul(e.into()); + + // Return the `transfer` call + Ok((crate::Call::::transfer(recipient_lookup, transfer_amt), user_origin)) + } +} + +// Benchmark `transfer_keep_alive` with the worst possible condition: +// * The recipient account is created. +struct TransferKeepAlive; +impl BenchmarkingSetup, RawOrigin> for TransferKeepAlive { + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + vec![ + // Existential Deposit Multiplier + (BenchmarkParameter::E, 2, 1000), + // User Seed + (BenchmarkParameter::U, 1, 1000), + ] + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(crate::Call, RawOrigin), &'static str> + { + // Constants + let ed = T::ExistentialDeposit::get(); + + // Select a sender + let u = components.iter().find(|&c| c.0 == BenchmarkParameter::U).unwrap().1; + let user = account::("user", u); + let user_origin = RawOrigin::Signed(user.clone()); + + // Select a recipient + let recipient = account::("recipient", u); + let recipient_lookup: ::Source = T::Lookup::unlookup(recipient.clone()); + + // Get the existential deposit multiplier + let e = components.iter().find(|&c| c.0 == BenchmarkParameter::E).unwrap().1; + + // Give the sender account max funds, thus a transfer will not kill account. + let _ = as Currency<_>>::make_free_balance_be(&user, T::Balance::max_value()); + + // Transfer e * existential deposit. + let transfer_amt = ed.saturating_mul(e.into()); + + // Return the `transfer_keep_alive` call + Ok((crate::Call::::transfer_keep_alive(recipient_lookup, transfer_amt), user_origin)) + } +} + +// Benchmark `set_balance` coming from ROOT account. This always creates an account. +struct SetBalance; +impl BenchmarkingSetup, RawOrigin> for SetBalance { + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + vec![ + // Existential Deposit Multiplier + (BenchmarkParameter::E, 2, 1000), + // User Seed + (BenchmarkParameter::U, 1, 1000), + ] + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(crate::Call, RawOrigin), &'static str> + { + // Constants + let ed = T::ExistentialDeposit::get(); + + // Select a sender + let u = components.iter().find(|&c| c.0 == BenchmarkParameter::U).unwrap().1; + let user = account::("user", u); + let user_lookup: ::Source = T::Lookup::unlookup(user.clone()); + + // Get the existential deposit multiplier for free and reserved + let e = components.iter().find(|&c| c.0 == BenchmarkParameter::E).unwrap().1; + let balance_amt = ed.saturating_mul(e.into()); + + // Return the `set_balance` call + Ok((crate::Call::::set_balance(user_lookup, balance_amt, balance_amt), RawOrigin::Root)) + } +} + +// Benchmark `set_balance` coming from ROOT account. This always kills an account. +struct SetBalanceKilling; +impl BenchmarkingSetup, RawOrigin> for SetBalanceKilling { + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + vec![ + // Existential Deposit Multiplier + (BenchmarkParameter::E, 2, 1000), + // User Seed + (BenchmarkParameter::U, 1, 1000), + ] + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(crate::Call, RawOrigin), &'static str> + { + // Constants + let ed = T::ExistentialDeposit::get(); + + // Select a sender + let u = components.iter().find(|&c| c.0 == BenchmarkParameter::U).unwrap().1; + let user = account::("user", u); + let user_lookup: ::Source = T::Lookup::unlookup(user.clone()); + + // Get the existential deposit multiplier for free and reserved + let e = components.iter().find(|&c| c.0 == BenchmarkParameter::E).unwrap().1; + // Give the user some initial balance + let balance_amt = ed.saturating_mul(e.into()); + let _ = as Currency<_>>::make_free_balance_be(&user, balance_amt); + + // Return the `set_balance` call that will kill the account + Ok((crate::Call::::set_balance(user_lookup, 0.into(), 0.into()), RawOrigin::Root)) + } +} + +// The list of available benchmarks for this pallet. +enum SelectedBenchmark { + Transfer, + TransferBestCase, + TransferKeepAlive, + SetBalance, + SetBalanceKilling, +} + +// Allow us to select a benchmark from the list of available benchmarks. +impl BenchmarkingSetup, RawOrigin> for SelectedBenchmark { + fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)> { + match self { + Self::Transfer => , RawOrigin>>::components(&Transfer), + Self::TransferBestCase => , RawOrigin>>::components(&TransferBestCase), + Self::TransferKeepAlive => , RawOrigin>>::components(&TransferKeepAlive), + Self::SetBalance => , RawOrigin>>::components(&SetBalance), + Self::SetBalanceKilling => , RawOrigin>>::components(&SetBalanceKilling), + } + } + + fn instance(&self, components: &[(BenchmarkParameter, u32)]) + -> Result<(crate::Call, RawOrigin), &'static str> + { + match self { + Self::Transfer => , RawOrigin>>::instance(&Transfer, components), + Self::TransferBestCase => , RawOrigin>>::instance(&TransferBestCase, components), + Self::TransferKeepAlive => , RawOrigin>>::instance(&TransferKeepAlive, components), + Self::SetBalance => , RawOrigin>>::instance(&SetBalance, components), + Self::SetBalanceKilling => , RawOrigin>>::instance(&SetBalanceKilling, components), + } + } +} + +impl Benchmarking for Module { + fn run_benchmark(extrinsic: Vec, steps: u32, repeat: u32) -> Result, &'static str> { + // Map the input to the selected benchmark. + let selected_benchmark = match extrinsic.as_slice() { + b"transfer" => SelectedBenchmark::Transfer, + b"transfer_best_case" => SelectedBenchmark::TransferBestCase, + b"transfer_keep_alive" => SelectedBenchmark::TransferKeepAlive, + b"set_balance" => SelectedBenchmark::SetBalance, + b"set_balance_killing" => SelectedBenchmark::SetBalanceKilling, + _ => return Err("Could not find extrinsic."), + }; + + // Warm up the DB + sp_io::benchmarking::commit_db(); + sp_io::benchmarking::wipe_db(); + + let components = , RawOrigin>>::components(&selected_benchmark); + // results go here + let mut results: Vec = Vec::new(); + // Select the component we will be benchmarking. Each component will be benchmarked. + for (name, low, high) in components.iter() { + // Create up to `STEPS` steps for that component between high and low. + let step_size = ((high - low) / steps).max(1); + let num_of_steps = (high - low) / step_size; + for s in 0..num_of_steps { + // This is the value we will be testing for component `name` + let component_value = low + step_size * s; + + // Select the mid value for all the other components. + let c: Vec<(BenchmarkParameter, u32)> = components.iter() + .map(|(n, l, h)| + (*n, if n == name { component_value } else { (h - l) / 2 + l }) + ).collect(); + + // Run the benchmark `repeat` times. + for _r in 0..repeat { + // Set up the externalities environment for the setup we want to benchmark. + let (call, caller) = , RawOrigin>>::instance(&selected_benchmark, &c)?; + // Commit the externalities to the database, flushing the DB cache. + // This will enable worst case scenario for reading from the database. + sp_io::benchmarking::commit_db(); + // Run the benchmark. + let start = sp_io::benchmarking::current_time(); + call.dispatch(caller.clone().into())?; + let finish = sp_io::benchmarking::current_time(); + let elapsed = finish - start; + sp_std::if_std!{ + if let RawOrigin::Signed(who) = caller.clone() { + let balance = Account::::get(&who).free; + println!("Free Balance {:?}", balance); + } + } + results.push((c.clone(), elapsed)); + // Wipe the DB back to the genesis state. + sp_io::benchmarking::wipe_db(); + } + } + } + return Ok(results); + } +} diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index ac651a5c24..9ddfd81dae 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -153,6 +153,7 @@ mod mock; #[cfg(test)] mod tests; mod migration; +mod benchmarking; use sp_std::prelude::*; use sp_std::{cmp, result, mem, fmt::Debug, ops::BitOr}; -- GitLab From e1668c2ab676d19c7cbef86f33cd3d09b9f39286 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Wed, 12 Feb 2020 13:15:26 +0100 Subject: [PATCH 139/180] client/network-gossip: Integrate GossipEngine tasks into Future impl (#4767) `GossipEngine` spawns two tasks, one for a periodic tick, one to forward messages from the network to subscribers. These tasks hold an `Arc` to a `GossipEngineInner`. To reduce the amount of shared ownership (locking) this patch integrates the two tasks into a `Future` implementation on the `GossipEngine` struct. This `Future` implementation can now be called from a single owner, e.g. the `finality-grandpa` `NetworkBridge`. As a side effect this removes the requirement on the `network-gossip` crate to spawn tasks and thereby removes the requirement on the `finality-grandpa` crate to spawn any tasks. This is part of a greater effort to reduce the number of owners of components within `finality-grandpa`, `network` and `network-gossip` as well as to reduce the amount of unbounded channels. For details see d4fbb897c, f0c18520a and 5afc7777e. --- bin/node-template/node/src/service.rs | 2 - bin/node/cli/src/service.rs | 2 - .../finality-grandpa/src/communication/mod.rs | 14 +- .../src/communication/tests.rs | 32 ++-- client/finality-grandpa/src/lib.rs | 16 +- client/finality-grandpa/src/observer.rs | 9 +- client/finality-grandpa/src/tests.rs | 62 +++----- client/network-gossip/src/bridge.rs | 137 +++++++++--------- client/network-gossip/src/state_machine.rs | 2 + 9 files changed, 121 insertions(+), 155 deletions(-) diff --git a/bin/node-template/node/src/service.rs b/bin/node-template/node/src/service.rs index d113f90866..cf5cb361fc 100644 --- a/bin/node-template/node/src/service.rs +++ b/bin/node-template/node/src/service.rs @@ -159,7 +159,6 @@ pub fn new_full(config: Configuration) grandpa_link, service.network(), service.on_exit(), - service.spawn_task_handle(), )?); }, (true, false) => { @@ -172,7 +171,6 @@ pub fn new_full(config: Configuration) 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. diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index 2c500c6a1c..a88f2d1add 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -216,7 +216,6 @@ macro_rules! new_full { grandpa_link, service.network(), service.on_exit(), - service.spawn_task_handle(), )?); }, (true, false) => { @@ -229,7 +228,6 @@ 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. diff --git a/client/finality-grandpa/src/communication/mod.rs b/client/finality-grandpa/src/communication/mod.rs index 227ecaa370..540923c1b1 100644 --- a/client/finality-grandpa/src/communication/mod.rs +++ b/client/finality-grandpa/src/communication/mod.rs @@ -178,7 +178,6 @@ impl> NetworkBridge { service: N, config: crate::Config, set_state: crate::environment::SharedVoterSetState, - executor: &impl futures::task::Spawn, ) -> Self { let (validator, report_stream) = GossipValidator::new( config, @@ -186,7 +185,7 @@ impl> NetworkBridge { ); let validator = Arc::new(validator); - let gossip_engine = GossipEngine::new(service.clone(), executor, GRANDPA_ENGINE_ID, validator.clone()); + let gossip_engine = GossipEngine::new(service.clone(), GRANDPA_ENGINE_ID, validator.clone()); { // register all previous votes with the gossip service so that they're @@ -374,10 +373,9 @@ impl> NetworkBridge { |to, neighbor| self.neighbor_sender.send(to, neighbor), ); - let service = self.gossip_engine.clone(); let topic = global_topic::(set_id.0); let incoming = incoming_global( - service, + self.gossip_engine.clone(), topic, voters, self.validator.clone(), @@ -419,7 +417,7 @@ impl> NetworkBridge { impl> Future for NetworkBridge { type Output = Result<(), Error>; - fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { + fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { loop { match self.neighbor_packet_worker.lock().poll_next_unpin(cx) { Poll::Ready(Some((to, packet))) => { @@ -444,6 +442,12 @@ impl> Future for NetworkBridge { } } + match self.gossip_engine.poll_unpin(cx) { + // The gossip engine future finished. We should do the same. + Poll::Ready(()) => return Poll::Ready(Ok(())), + Poll::Pending => {}, + } + Poll::Pending } } diff --git a/client/finality-grandpa/src/communication/tests.rs b/client/finality-grandpa/src/communication/tests.rs index e10d24a16a..040ee4c7bb 100644 --- a/client/finality-grandpa/src/communication/tests.rs +++ b/client/finality-grandpa/src/communication/tests.rs @@ -165,7 +165,7 @@ fn voter_set_state() -> SharedVoterSetState { } // needs to run in a tokio runtime. -pub(crate) fn make_test_network(executor: &impl futures::task::Spawn) -> ( +pub(crate) fn make_test_network() -> ( impl Future, TestNetwork, ) { @@ -187,7 +187,6 @@ pub(crate) fn make_test_network(executor: &impl futures::task::Spawn) -> ( net.clone(), config(), voter_set_state(), - executor, ); ( @@ -261,8 +260,7 @@ fn good_commit_leads_to_relay() { let id = sc_network::PeerId::random(); let global_topic = super::global_topic::(set_id); - let threads_pool = futures::executor::ThreadPool::new().unwrap(); - let test = make_test_network(&threads_pool).0 + let test = make_test_network().0 .then(move |tester| { // register a peer. tester.gossip_validator.new_peer(&mut NoopContext, &id, sc_network::config::Roles::FULL); @@ -281,6 +279,7 @@ fn good_commit_leads_to_relay() { } let commit_to_send = encoded_commit.clone(); + let network_bridge = tester.net_handle.clone(); // asking for global communication will cause the test network // to send us an event asking us for a stream. use it to @@ -325,7 +324,7 @@ fn good_commit_leads_to_relay() { // once the message is sent and commit is "handled" we should have // a repropagation event coming from the network. - future::join(send_message, handle_commit).then(move |(tester, ())| { + let fut = future::join(send_message, handle_commit).then(move |(tester, ())| { tester.filter_network_events(move |event| match event { Event::WriteNotification(_, data) => { data == encoded_commit @@ -333,7 +332,11 @@ fn good_commit_leads_to_relay() { _ => false, }) }) - .map(|_| ()) + .map(|_| ()); + + // Poll both the future sending and handling the commit, as well as the underlying + // NetworkBridge. Complete once the former completes. + future::select(fut, network_bridge) }); futures::executor::block_on(test); @@ -385,8 +388,7 @@ fn bad_commit_leads_to_report() { let id = sc_network::PeerId::random(); let global_topic = super::global_topic::(set_id); - let threads_pool = futures::executor::ThreadPool::new().unwrap(); - let test = make_test_network(&threads_pool).0 + let test = make_test_network().0 .map(move |tester| { // register a peer. tester.gossip_validator.new_peer(&mut NoopContext, &id, sc_network::config::Roles::FULL); @@ -405,6 +407,7 @@ fn bad_commit_leads_to_report() { } let commit_to_send = encoded_commit.clone(); + let network_bridge = tester.net_handle.clone(); // asking for global communication will cause the test network // to send us an event asking us for a stream. use it to @@ -427,7 +430,7 @@ fn bad_commit_leads_to_report() { _ => false, }); - // when the commit comes in, we'll tell the callback it was good. + // when the commit comes in, we'll tell the callback it was bad. let handle_commit = commits_in.into_future() .map(|(item, _)| { match item.unwrap() { @@ -440,7 +443,7 @@ fn bad_commit_leads_to_report() { // once the message is sent and commit is "handled" we should have // a report event coming from the network. - future::join(send_message, handle_commit).then(move |(tester, ())| { + let fut = future::join(send_message, handle_commit).then(move |(tester, ())| { tester.filter_network_events(move |event| match event { Event::Report(who, cost_benefit) => { who == id && cost_benefit == super::cost::INVALID_COMMIT @@ -448,7 +451,11 @@ fn bad_commit_leads_to_report() { _ => false, }) }) - .map(|_| ()) + .map(|_| ()); + + // Poll both the future sending and handling the commit, as well as the underlying + // NetworkBridge. Complete once the former completes. + future::select(fut, network_bridge) }); futures::executor::block_on(test); @@ -458,8 +465,7 @@ fn bad_commit_leads_to_report() { fn peer_with_higher_view_leads_to_catch_up_request() { let id = sc_network::PeerId::random(); - let threads_pool = futures::executor::ThreadPool::new().unwrap(); - let (tester, mut net) = make_test_network(&threads_pool); + let (tester, mut net) = make_test_network(); let test = tester .map(move |tester| { // register a peer with authority role. diff --git a/client/finality-grandpa/src/lib.rs b/client/finality-grandpa/src/lib.rs index afca0ed48b..45a2400226 100644 --- a/client/finality-grandpa/src/lib.rs +++ b/client/finality-grandpa/src/lib.rs @@ -516,7 +516,7 @@ fn register_finality_tracker_inherent_data_provider( } /// Parameters used to run Grandpa. -pub struct GrandpaParams { +pub struct GrandpaParams { /// Configuration for the GRANDPA service. pub config: Config, /// A link to the block import worker. @@ -531,14 +531,12 @@ pub struct GrandpaParams { 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( - grandpa_params: GrandpaParams, +pub fn run_grandpa_voter( + grandpa_params: GrandpaParams, ) -> sp_blockchain::Result + Unpin + Send + 'static> where Block::Hash: Ord, B: Backend + 'static, @@ -551,7 +549,6 @@ pub fn run_grandpa_voter( RA: Send + Sync + 'static, X: futures::Future + Clone + Send + Unpin + 'static, Client: AuxStore, - Sp: futures::task::Spawn + 'static, { let GrandpaParams { config, @@ -561,7 +558,6 @@ pub fn run_grandpa_voter( on_exit, telemetry_on_connect, voting_rule, - executor, } = grandpa_params; let LinkHalf { @@ -575,7 +571,6 @@ pub fn run_grandpa_voter( network, config.clone(), persistent_data.set_state.clone(), - &executor, ); register_finality_tracker_inherent_data_provider(client.clone(), &inherent_data_providers)?; @@ -863,8 +858,8 @@ where } #[deprecated(since = "1.1.0", note = "Please switch to run_grandpa_voter.")] -pub fn run_grandpa( - grandpa_params: GrandpaParams, +pub fn run_grandpa( + grandpa_params: GrandpaParams, ) -> sp_blockchain::Result + Send + 'static> where Block::Hash: Ord, B: Backend + 'static, @@ -877,7 +872,6 @@ pub fn run_grandpa( VR: VotingRule> + Clone + 'static, X: futures::Future + Clone + Send + Unpin + 'static, Client: AuxStore, - Sp: futures::task::Spawn + 'static, { run_grandpa_voter(grandpa_params) } diff --git a/client/finality-grandpa/src/observer.rs b/client/finality-grandpa/src/observer.rs index 7e6d1e7793..ffe71d573a 100644 --- a/client/finality-grandpa/src/observer.rs +++ b/client/finality-grandpa/src/observer.rs @@ -150,12 +150,11 @@ fn grandpa_observer( /// 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( +pub fn run_grandpa_observer( config: Config, link: LinkHalf, network: N, on_exit: impl futures::Future + Clone + Send + Unpin + 'static, - executor: Sp, ) -> sp_blockchain::Result + Unpin + Send + 'static> where B: Backend + 'static, E: CallExecutor + Send + Sync + 'static, @@ -163,7 +162,6 @@ pub fn run_grandpa_observer( SC: SelectChain + 'static, NumberFor: BlockNumberOps, RA: Send + Sync + 'static, - Sp: futures::task::Spawn + 'static, Client: AuxStore, { let LinkHalf { @@ -177,7 +175,6 @@ pub fn run_grandpa_observer( network, config.clone(), persistent_data.set_state.clone(), - &executor, ); let observer_work = ObserverWork::new( @@ -392,10 +389,8 @@ mod tests { /// network. #[test] fn observer_work_polls_underlying_network_bridge() { - let thread_pool = ThreadPool::new().unwrap(); - // Create a test network. - let (tester_fut, _network) = make_test_network(&thread_pool); + let (tester_fut, _network) = make_test_network(); let mut tester = executor::block_on(tester_fut); // Create an observer. diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index 0f4d9dadd0..cf340c6954 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -387,7 +387,6 @@ fn block_until_complete(future: impl Future + Unpin, net: &Arc( runtime: &mut current_thread::Runtime, - threads_pool: &futures::executor::ThreadPool, blocks: u64, net: Arc>, peers: &[Ed25519Keyring], @@ -454,7 +453,6 @@ 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"); @@ -473,12 +471,11 @@ fn run_to_completion_with( fn run_to_completion( runtime: &mut current_thread::Runtime, - threads_pool: &futures::executor::ThreadPool, blocks: u64, net: Arc>, peers: &[Ed25519Keyring] ) -> u64 { - run_to_completion_with(runtime, threads_pool, blocks, net, peers, |_| None) + run_to_completion_with(runtime, blocks, net, peers, |_| None) } fn add_scheduled_change(block: &mut Block, change: ScheduledChange) { @@ -499,17 +496,10 @@ fn add_forced_change( )); } -fn thread_pool() -> futures::executor::ThreadPool { - futures::executor::ThreadPool::builder().pool_size(2) - .create() - .expect("never fails") -} - #[test] fn finalize_3_voters_no_observers() { let _ = env_logger::try_init(); let mut runtime = current_thread::Runtime::new().unwrap(); - let threads_pool = thread_pool(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let voters = make_ids(peers); @@ -523,7 +513,7 @@ fn finalize_3_voters_no_observers() { } let net = Arc::new(Mutex::new(net)); - run_to_completion(&mut runtime, &threads_pool, 20, net.clone(), peers); + run_to_completion(&mut runtime, 20, net.clone(), peers); // normally there's no justification for finalized blocks assert!( @@ -535,7 +525,6 @@ 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 = thread_pool(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let voters = make_ids(peers); @@ -595,7 +584,6 @@ fn finalize_3_voters_1_full_observer() { on_exit: Exit, telemetry_on_connect: None, voting_rule: (), - executor: threads_pool.clone(), }; voters.push(run_grandpa_voter(grandpa_params).expect("all in order with client and network")); @@ -641,7 +629,6 @@ 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 = thread_pool(); net.lock().peer(0).push_blocks(1, false); net.lock().block_until_sync(&mut runtime); @@ -760,7 +747,6 @@ 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"); @@ -776,7 +762,6 @@ 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 = thread_pool(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 3); @@ -785,7 +770,7 @@ fn justification_is_emitted_when_consensus_data_changes() { 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, &threads_pool, 1, net.clone(), peers); + run_to_completion(&mut runtime, 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(), @@ -795,7 +780,6 @@ 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 = thread_pool(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let voters = make_ids(peers); @@ -804,7 +788,7 @@ fn justification_is_generated_periodically() { net.block_until_sync(&mut runtime); let net = Arc::new(Mutex::new(net)); - run_to_completion(&mut runtime, &threads_pool, 32, net.clone(), peers); + run_to_completion(&mut runtime, 32, net.clone(), peers); // when block#32 (justification_period) is finalized, justification // is required => generated @@ -835,7 +819,6 @@ fn consensus_changes_works() { #[test] fn sync_justifications_on_change_blocks() { let mut runtime = current_thread::Runtime::new().unwrap(); - let threads_pool = thread_pool(); let peers_a = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let peers_b = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob]; let voters = make_ids(peers_b); @@ -867,7 +850,7 @@ fn sync_justifications_on_change_blocks() { } let net = Arc::new(Mutex::new(net)); - run_to_completion(&mut runtime, &threads_pool, 25, net.clone(), peers_a); + run_to_completion(&mut runtime, 25, net.clone(), peers_a); // the first 3 peers are grandpa voters and therefore have already finalized // block 21 and stored a justification @@ -890,7 +873,6 @@ 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 = thread_pool(); let peers_a = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let peers_b = &[Ed25519Keyring::Dave, Ed25519Keyring::Eve, Ed25519Keyring::Ferdie]; @@ -944,14 +926,13 @@ fn finalizes_multiple_pending_changes_in_order() { } let net = Arc::new(Mutex::new(net)); - run_to_completion(&mut runtime, &threads_pool, 30, net.clone(), all_peers); + run_to_completion(&mut runtime, 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 = thread_pool(); // two of these guys are offline. let genesis_authorities = &[ Ed25519Keyring::Alice, @@ -1002,7 +983,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, &threads_pool, 25, net, peers_a); + run_to_completion(&mut runtime, 25, net, peers_a); } #[test] @@ -1132,7 +1113,6 @@ fn voter_persists_its_votes() { let _ = env_logger::try_init(); let mut runtime = current_thread::Runtime::new().unwrap(); - let threads_pool = thread_pool(); // 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 @@ -1171,7 +1151,6 @@ fn voter_persists_its_votes() { net: Arc>, client: PeersClient, keystore: KeyStorePtr, - threads_pool: futures::executor::ThreadPool, } impl Future for ResettableVoter { @@ -1210,7 +1189,6 @@ fn voter_persists_its_votes() { on_exit: Exit, telemetry_on_connect: None, voting_rule: VotingRulesBuilder::default().build(), - executor: this.threads_pool.clone(), }; let voter = run_grandpa_voter(grandpa_params) @@ -1242,7 +1220,6 @@ fn voter_persists_its_votes() { net: net.clone(), client: client.clone(), keystore, - threads_pool: threads_pool.clone(), }.unit_error().compat()); } @@ -1278,7 +1255,6 @@ fn voter_persists_its_votes() { net.lock().peers[1].network_service().clone(), config.clone(), set_state, - &threads_pool, ); let (round_rx, round_tx) = network.round_communication( @@ -1289,6 +1265,11 @@ fn voter_persists_its_votes() { HasVoted::No, ); + runtime.spawn( + network.map_err(|e| panic!("network bridge should not error: {:?}", e)) + .compat(), + ); + let round_tx = Arc::new(Mutex::new(round_tx)); let exit_tx = Arc::new(Mutex::new(Some(exit_tx))); @@ -1389,7 +1370,6 @@ 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 = thread_pool(); let authorities = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie]; let voters = make_ids(authorities); @@ -1406,10 +1386,12 @@ fn finalize_3_voters_1_light_observer() { let link = net.lock().peer(3).data.lock().take().expect("link initialized on startup; qed"); let finality_notifications = net.lock().peer(3).client().finality_notification_stream() - .take_while(|n| future::ready(n.header.number() < &20)) + .take_while(|n| { + future::ready(n.header.number() < &20) + }) .collect::>(); - run_to_completion_with(&mut runtime, &threads_pool, 20, net.clone(), authorities, |executor| { + run_to_completion_with(&mut runtime, 20, net.clone(), authorities, |executor| { executor.spawn( run_grandpa_observer( Config { @@ -1423,7 +1405,6 @@ fn finalize_3_voters_1_light_observer() { link, net.lock().peers[3].network_service().clone(), Exit, - threads_pool.clone(), ).unwrap().unit_error().compat() ).unwrap(); @@ -1435,7 +1416,6 @@ 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 = thread_pool(); let peers = &[Ed25519Keyring::Alice]; let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 1); @@ -1445,7 +1425,7 @@ fn finality_proof_is_fetched_by_light_client_when_consensus_data_changes() { // && instead fetches finality proof for block #1 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, &threads_pool, 1, net.clone(), peers); + run_to_completion(&mut runtime, 1, net.clone(), peers); net.lock().block_until_sync(&mut runtime); // check that the block#1 is finalized on light client @@ -1467,7 +1447,6 @@ 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 = thread_pool(); // two of these guys are offline. let genesis_authorities = if FORCE_CHANGE { @@ -1515,7 +1494,7 @@ fn empty_finality_proof_is_returned_to_light_client_when_authority_set_is_differ net.lock().block_until_sync(&mut runtime); // finalize block #11 on full clients - run_to_completion(&mut runtime, &threads_pool, 11, net.clone(), peers_a); + run_to_completion(&mut runtime, 11, net.clone(), peers_a); // request finalization by light client net.lock().add_light_peer(&GrandpaTestNet::default_config()); @@ -1532,7 +1511,6 @@ 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 = thread_pool(); let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob]; let voters = make_ids(peers); @@ -1560,7 +1538,6 @@ fn voter_catches_up_to_latest_round_when_behind() { on_exit: Exit, telemetry_on_connect: None, voting_rule: (), - executor: threads_pool.clone(), }; Box::pin(run_grandpa_voter(grandpa_params).expect("all in order with client and network")) @@ -1652,8 +1629,6 @@ fn grandpa_environment_respects_voting_rules() { use finality_grandpa::Chain; use sc_network_test::TestClient; - let threads_pool = thread_pool(); - let peers = &[Ed25519Keyring::Alice]; let voters = make_ids(peers); @@ -1684,7 +1659,6 @@ fn grandpa_environment_respects_voting_rules() { network_service.clone(), config.clone(), set_state.clone(), - &threads_pool, ); Environment { diff --git a/client/network-gossip/src/bridge.rs b/client/network-gossip/src/bridge.rs index d6d6805b3e..87958cbc14 100644 --- a/client/network-gossip/src/bridge.rs +++ b/client/network-gossip/src/bridge.rs @@ -15,16 +15,17 @@ // along with Substrate. If not, see . use crate::{Network, Validator}; -use crate::state_machine::{ConsensusGossip, TopicNotification}; +use crate::state_machine::{ConsensusGossip, TopicNotification, PERIODIC_MAINTENANCE_INTERVAL}; use sc_network::message::generic::ConsensusMessage; use sc_network::{Event, ReputationChange}; -use futures::{prelude::*, channel::mpsc, compat::Compat01As03, task::SpawnExt as _}; +use futures::{prelude::*, channel::mpsc, compat::Compat01As03}; +use futures01::stream::Stream as Stream01; use libp2p::PeerId; use parking_lot::Mutex; use sp_runtime::{traits::Block as BlockT, ConsensusEngineId}; -use std::{sync::Arc, time::Duration}; +use std::{pin::Pin, sync::Arc, task::{Context, Poll}}; /// Wraps around an implementation of the `Network` crate and provides gossiping capabilities on /// top of it. @@ -36,13 +37,17 @@ pub struct GossipEngine { struct GossipEngineInner { state_machine: ConsensusGossip, network: Box + Send>, + periodic_maintenance_interval: futures_timer::Delay, + network_event_stream: Compat01As03 + Send>>, + engine_id: ConsensusEngineId, } +impl Unpin for GossipEngineInner {} + impl GossipEngine { /// Create a new instance. pub fn new + Send + Clone + 'static>( mut network: N, - executor: &impl futures::task::Spawn, engine_id: ConsensusEngineId, validator: Arc>, ) -> Self where B: 'static { @@ -50,7 +55,7 @@ impl GossipEngine { // We grab the event stream before registering the notifications protocol, otherwise we // might miss events. - let event_stream = network.event_stream(); + let network_event_stream = network.event_stream(); network.register_notifications_protocol(engine_id); state_machine.register_validator(&mut network, engine_id, validator); @@ -58,6 +63,9 @@ impl GossipEngine { let inner = Arc::new(Mutex::new(GossipEngineInner { state_machine, network: Box::new(network), + periodic_maintenance_interval: futures_timer::Delay::new(PERIODIC_MAINTENANCE_INTERVAL), + network_event_stream: Compat01As03::new(network_event_stream), + engine_id, })); let gossip_engine = GossipEngine { @@ -65,72 +73,6 @@ impl GossipEngine { 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.network); - } 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.network, remote, roles); - } - Event::NotificationStreamClosed { 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.network, remote); - }, - Event::NotificationsReceived { remote, messages } => { - let mut inner = inner.lock(); - let inner = &mut *inner; - inner.state_machine.on_incoming( - &mut *inner.network, - 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 } @@ -222,6 +164,59 @@ impl GossipEngine { } } +impl Future for GossipEngine { + type Output = (); + + fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { + self.inner.lock().poll_unpin(cx) + } +} + +impl Future for GossipEngineInner { + type Output = (); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { + let this = &mut *self; + + while let Poll::Ready(Some(Ok(event))) = this.network_event_stream.poll_next_unpin(cx) { + match event { + Event::NotificationStreamOpened { remote, engine_id: msg_engine_id, roles } => { + if msg_engine_id != this.engine_id { + continue; + } + this.state_machine.new_peer(&mut *this.network, remote, roles); + } + Event::NotificationStreamClosed { remote, engine_id: msg_engine_id } => { + if msg_engine_id != this.engine_id { + continue; + } + this.state_machine.peer_disconnected(&mut *this.network, remote); + }, + Event::NotificationsReceived { remote, messages } => { + let engine_id = this.engine_id.clone(); + this.state_machine.on_incoming( + &mut *this.network, + 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(_) => {} + } + } + + while let Poll::Ready(()) = this.periodic_maintenance_interval.poll_unpin(cx) { + this.periodic_maintenance_interval.reset(PERIODIC_MAINTENANCE_INTERVAL); + this.state_machine.tick(&mut *this.network); + } + + Poll::Pending + } +} + impl Clone for GossipEngine { fn clone(&self) -> Self { GossipEngine { diff --git a/client/network-gossip/src/state_machine.rs b/client/network-gossip/src/state_machine.rs index 7be90c10f6..2acfdc3785 100644 --- a/client/network-gossip/src/state_machine.rs +++ b/client/network-gossip/src/state_machine.rs @@ -35,6 +35,8 @@ const KNOWN_MESSAGES_CACHE_SIZE: usize = 4096; const REBROADCAST_INTERVAL: time::Duration = time::Duration::from_secs(30); +pub(crate) const PERIODIC_MAINTENANCE_INTERVAL: time::Duration = time::Duration::from_millis(1100); + mod rep { use sc_network::ReputationChange as Rep; /// Reputation change when a peer sends us a gossip message that we didn't know about. -- GitLab From b955d17f8251a5741c1cb5ad26df4459307a5c33 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Wed, 12 Feb 2020 13:15:49 +0100 Subject: [PATCH 140/180] add some more docs on PreRuntime digests (#4896) --- primitives/runtime/src/generic/digest.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/primitives/runtime/src/generic/digest.rs b/primitives/runtime/src/generic/digest.rs index 4d09b58793..9d4fbe48d5 100644 --- a/primitives/runtime/src/generic/digest.rs +++ b/primitives/runtime/src/generic/digest.rs @@ -87,6 +87,12 @@ pub enum DigestItem { /// the consensus engine can (and should) read them itself to avoid /// code and state duplication. It is erroneous for a runtime to produce /// these, but this is not (yet) checked. + /// + /// NOTE: the runtime is not allowed to panic or fail in an `on_initialize` + /// call if an expected `PreRuntime` digest is not present. It is the + /// responsibility of a external block verifier to check this. Runtime API calls + /// will initialize the block without pre-runtime digests, so initialization + /// cannot fail when they are missing. PreRuntime(ConsensusEngineId, Vec), /// A message from the runtime to the consensus engine. This should *never* -- GitLab From 1b42f2499bd9702fc7413abfe813faf11e94a0ad Mon Sep 17 00:00:00 2001 From: Xiliang Chen Date: Thu, 13 Feb 2020 01:16:00 +1300 Subject: [PATCH 141/180] serialize partial_fee into string (#4898) * serialize partial_fee into string * implement deserialize * bump version --- bin/node/runtime/src/lib.rs | 2 +- .../rpc/runtime-api/src/lib.rs | 79 +++++++++---------- frame/transaction-payment/rpc/src/lib.rs | 16 ++-- primitives/runtime/src/traits.rs | 5 ++ 4 files changed, 52 insertions(+), 50 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 4800c08260..2f7aee7f8f 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -82,7 +82,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 216, - impl_version: 1, + impl_version: 2, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/transaction-payment/rpc/runtime-api/src/lib.rs b/frame/transaction-payment/rpc/runtime-api/src/lib.rs index 6e7425f8b8..77b6e3b454 100644 --- a/frame/transaction-payment/rpc/runtime-api/src/lib.rs +++ b/frame/transaction-payment/rpc/runtime-api/src/lib.rs @@ -22,12 +22,13 @@ 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}; +use serde::{Serialize, Deserialize, Serializer, Deserializer}; +use sp_runtime::traits::{MaybeDisplay, MaybeFromStr}; /// 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))] +#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] +#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] pub struct RuntimeDispatchInfo { /// Weight of this dispatch. pub weight: Weight, @@ -35,47 +36,27 @@ pub struct RuntimeDispatchInfo { 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`). + #[cfg_attr(feature = "std", serde(bound(serialize = "Balance: std::fmt::Display")))] + #[cfg_attr(feature = "std", serde(serialize_with = "serialize_as_string"))] + #[cfg_attr(feature = "std", serde(bound(deserialize = "Balance: std::str::FromStr")))] + #[cfg_attr(feature = "std", serde(deserialize_with = "deserialize_from_string"))] pub partial_fee: Balance, } -/// 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, +#[cfg(feature = "std")] +fn serialize_as_string(t: &T, serializer: S) -> Result { + serializer.serialize_str(&t.to_string()) } -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(), - } - } +#[cfg(feature = "std")] +fn deserialize_from_string<'de, D: Deserializer<'de>, T: std::str::FromStr>(deserializer: D) -> Result { + let s = String::deserialize(deserializer)?; + s.parse::().map_err(|_| serde::de::Error::custom("Parse from string failed")) } sp_api::decl_runtime_apis! { pub trait TransactionPaymentApi where - Balance: Codec, + Balance: Codec + MaybeDisplay + MaybeFromStr, Extrinsic: Codec, { fn query_info(uxt: Extrinsic, len: u32) -> RuntimeDispatchInfo; @@ -87,18 +68,34 @@ mod tests { use super::*; #[test] - fn should_serialize_properly_with_u64() { + fn should_serialize_and_deserialize_properly_with_string() { let info = RuntimeDispatchInfo { weight: 5, class: DispatchClass::Normal, 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}"#, - ); + let json_str = r#"{"weight":5,"class":"normal","partialFee":"1000000"}"#; + + assert_eq!(serde_json::to_string(&info).unwrap(), json_str); + assert_eq!(serde_json::from_str::>(json_str).unwrap(), info); + + // should not panic + serde_json::to_value(&info).unwrap(); + } + + #[test] + fn should_serialize_and_deserialize_properly_large_value() { + let info = RuntimeDispatchInfo { + weight: 5, + class: DispatchClass::Normal, + partial_fee: u128::max_value(), + }; + + let json_str = r#"{"weight":5,"class":"normal","partialFee":"340282366920938463463374607431768211455"}"#; + + assert_eq!(serde_json::to_string(&info).unwrap(), json_str); + assert_eq!(serde_json::from_str::>(json_str).unwrap(), info); // should not panic serde_json::to_value(&info).unwrap(); diff --git a/frame/transaction-payment/rpc/src/lib.rs b/frame/transaction-payment/rpc/src/lib.rs index aadc33759e..945b0119d7 100644 --- a/frame/transaction-payment/rpc/src/lib.rs +++ b/frame/transaction-payment/rpc/src/lib.rs @@ -21,21 +21,21 @@ use codec::{Codec, Decode}; use sp_blockchain::HeaderBackend; use jsonrpc_core::{Error as RpcError, ErrorCode, Result}; use jsonrpc_derive::rpc; -use sp_runtime::{generic::BlockId, traits::{Block as BlockT, UniqueSaturatedInto}}; +use sp_runtime::{generic::BlockId, traits::{Block as BlockT, MaybeDisplay, MaybeFromStr}}; use sp_api::ProvideRuntimeApi; use sp_core::Bytes; -use pallet_transaction_payment_rpc_runtime_api::CappedDispatchInfo; +use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; pub use pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi as TransactionPaymentRuntimeApi; pub use self::gen_client::Client as TransactionPaymentClient; #[rpc] -pub trait TransactionPaymentApi { +pub trait TransactionPaymentApi { #[rpc(name = "payment_queryInfo")] fn query_info( &self, encoded_xt: Bytes, at: Option - ) -> Result; + ) -> Result; } /// A struct that implements the [`TransactionPaymentApi`]. @@ -68,20 +68,20 @@ impl From for i64 { } } -impl TransactionPaymentApi<::Hash, Balance> +impl TransactionPaymentApi<::Hash, RuntimeDispatchInfo> for TransactionPayment where Block: BlockT, C: Send + Sync + 'static + ProvideRuntimeApi + HeaderBackend, C::Api: TransactionPaymentRuntimeApi, - Balance: Codec + UniqueSaturatedInto, + Balance: Codec + MaybeDisplay + MaybeFromStr, 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. @@ -99,6 +99,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/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index c28fe555f7..cc71b38fe3 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -22,6 +22,8 @@ use sp_io; #[cfg(feature = "std")] use std::fmt::Display; #[cfg(feature = "std")] +use std::str::FromStr; +#[cfg(feature = "std")] use serde::{Serialize, Deserialize, de::DeserializeOwned}; use sp_core::{self, Hasher, Blake2Hasher, TypeId, RuntimeDebug}; use crate::BenchmarkParameter; @@ -463,6 +465,9 @@ sp_core::impl_maybe_marker!( /// A type that implements Display when in std environment. trait MaybeDisplay: Display; + /// A type that implements FromStr when in std environment. + trait MaybeFromStr: FromStr; + /// A type that implements Hash when in std environment. trait MaybeHash: sp_std::hash::Hash; -- GitLab From 47076a93246de20cf35c655ddcde430306b33f9d Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Wed, 12 Feb 2020 17:32:38 +0300 Subject: [PATCH 142/180] add sr25519 bench (#4905) --- primitives/core/benches/bench.rs | 22 +++++++++++++++++++++- primitives/core/src/lib.rs | 3 --- primitives/core/src/tests.rs | 17 ----------------- 3 files changed, 21 insertions(+), 21 deletions(-) delete mode 100644 primitives/core/src/tests.rs diff --git a/primitives/core/benches/bench.rs b/primitives/core/benches/bench.rs index 7096cd6c19..7db9d72e6b 100644 --- a/primitives/core/benches/bench.rs +++ b/primitives/core/benches/bench.rs @@ -86,9 +86,29 @@ fn bench_ed25519(c: &mut Criterion) { }, vec![32, 1024, 1024 * 1024]); } +fn bench_sr25519(c: &mut Criterion) { + c.bench_function_over_inputs("signing - sr25519", |b, &msg_size| { + let msg = (0..msg_size) + .map(|_| rand::random::()) + .collect::>(); + let key = sp_core::sr25519::Pair::generate().0; + b.iter(|| key.sign(&msg)) + }, vec![32, 1024, 1024 * 1024]); + + c.bench_function_over_inputs("verifying - sr25519", |b, &msg_size| { + let msg = (0..msg_size) + .map(|_| rand::random::()) + .collect::>(); + let key = sp_core::sr25519::Pair::generate().0; + let sig = key.sign(&msg); + let public = key.public(); + b.iter(|| sp_core::sr25519::Pair::verify(&sig, &msg, &public)) + }, vec![32, 1024, 1024 * 1024]); +} + criterion_group!{ name = benches; config = Criterion::default().warm_up_time(Duration::from_millis(500)).without_plots(); - targets = bench_hash_128_fix_size, bench_hash_128_dyn_size, bench_ed25519 + targets = bench_hash_128_fix_size, bench_hash_128_dyn_size, bench_ed25519, bench_sr25519 } criterion_main!(benches); diff --git a/primitives/core/src/lib.rs b/primitives/core/src/lib.rs index 5bb9a3927f..b1a5916c92 100644 --- a/primitives/core/src/lib.rs +++ b/primitives/core/src/lib.rs @@ -70,9 +70,6 @@ mod changes_trie; pub mod traits; pub mod testing; -#[cfg(test)] -mod tests; - pub use self::hash::{H160, H256, H512, convert_hash}; pub use self::uint::U256; pub use changes_trie::{ChangesTrieConfiguration, ChangesTrieConfigurationRange}; diff --git a/primitives/core/src/tests.rs b/primitives/core/src/tests.rs deleted file mode 100644 index 1eda2157c4..0000000000 --- a/primitives/core/src/tests.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2017-2020 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 . - -//! Tests. -- GitLab From d78534edc04bb1a2eedf7feac0da9ddf85b348e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Thu, 13 Feb 2020 10:06:10 +0100 Subject: [PATCH 143/180] Fix chain-spec and make sure it does not breaks again (#4906) * Fix chain-spec and make sure it does not breaks again * REview feedback --- bin/node/cli/src/chain_spec.rs | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/bin/node/cli/src/chain_spec.rs b/bin/node/cli/src/chain_spec.rs index 868b991480..c68283ad65 100644 --- a/bin/node/cli/src/chain_spec.rs +++ b/bin/node/cli/src/chain_spec.rs @@ -261,13 +261,17 @@ pub fn testnet_genesis( }), pallet_democracy: Some(DemocracyConfig::default()), pallet_collective_Instance1: Some(CouncilConfig { - members: endowed_accounts.iter().cloned() - .collect::>()[..(num_endowed_accounts + 1) / 2].to_vec(), + members: endowed_accounts.iter() + .take((num_endowed_accounts + 1) / 2) + .cloned() + .collect(), phantom: Default::default(), }), pallet_collective_Instance2: Some(TechnicalCommitteeConfig { - members: endowed_accounts.iter().cloned() - .collect::>()[..(num_endowed_accounts + 1) / 2].to_vec(), + members: endowed_accounts.iter() + .take((num_endowed_accounts + 1) / 2) + .cloned() + .collect(), phantom: Default::default(), }), pallet_contracts: Some(ContractsConfig { @@ -295,7 +299,10 @@ pub fn testnet_genesis( pallet_membership_Instance1: Some(Default::default()), pallet_treasury: Some(Default::default()), pallet_society: Some(SocietyConfig { - members: endowed_accounts[0..3].to_vec(), + members: endowed_accounts.iter() + .take((num_endowed_accounts + 1) / 2) + .cloned() + .collect(), pot: 0, max_members: 999, }), @@ -359,6 +366,7 @@ pub(crate) mod tests { use super::*; use crate::service::{new_full, new_light}; use sc_service_test; + use sp_runtime::BuildStorage; fn local_testnet_genesis_instant_single() -> GenesisConfig { testnet_genesis( @@ -408,4 +416,19 @@ pub(crate) mod tests { |config| new_light(config), ); } + + #[test] + fn test_create_development_chain_spec() { + development_config().build_storage().unwrap(); + } + + #[test] + fn test_create_local_testnet_chain_spec() { + local_testnet_config().build_storage().unwrap(); + } + + #[test] + fn test_staging_test_net_chain_spec() { + staging_testnet_config().build_storage().unwrap(); + } } -- GitLab From b01bd0d49ba199abe6625c137a6c4b589eac04f4 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Thu, 13 Feb 2020 14:09:00 +0300 Subject: [PATCH 144/180] Full block import benchmark (#4865) * full block import benchmark * try rocksdb cache * add profiling helper * use random keyring instead of zero caching * update docs * add more io stats * remove last sentence * add ci job to see * Update primitives/keyring/src/sr25519.rs Co-Authored-By: Marcio Diaz * switch to 100tx-block * remove ci script Co-authored-by: Marcio Diaz --- Cargo.lock | 31 ++ bin/node/runtime/src/lib.rs | 3 +- bin/node/testing/Cargo.toml | 23 +- bin/node/testing/benches/import.rs | 503 +++++++++++++++++++++++++++++ bin/node/testing/src/client.rs | 3 + bin/node/testing/src/genesis.rs | 35 +- client/api/src/client.rs | 5 +- client/db/src/lib.rs | 1 + client/db/src/light.rs | 1 + primitives/keyring/src/sr25519.rs | 1 - 10 files changed, 593 insertions(+), 13 deletions(-) create mode 100644 bin/node/testing/benches/import.rs diff --git a/Cargo.lock b/Cargo.lock index f2cfaae187..757958f249 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1578,6 +1578,12 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "fs_extra" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674" + [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -3602,8 +3608,12 @@ dependencies = [ name = "node-testing" version = "2.0.0" dependencies = [ + "criterion 0.3.1", "frame-support", "frame-system", + "fs_extra", + "hex-literal", + "log 0.4.8", "node-executor", "node-primitives", "node-runtime", @@ -3618,13 +3628,24 @@ dependencies = [ "pallet-transaction-payment", "pallet-treasury", "parity-scale-codec", + "sc-cli", "sc-client", + "sc-client-api", + "sc-client-db", "sc-executor", + "sp-api", + "sp-block-builder", + "sp-blockchain", + "sp-consensus", "sp-core", + "sp-finality-tracker", + "sp-inherents", "sp-io", "sp-keyring", "sp-runtime", + "sp-timestamp", "substrate-test-client", + "tempdir", "wabt", ] @@ -7715,6 +7736,16 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" +[[package]] +name = "tempdir" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" +dependencies = [ + "rand 0.4.6", + "remove_dir_all", +] + [[package]] name = "tempfile" version = "3.1.0" diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 2f7aee7f8f..b7065b1854 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -27,7 +27,8 @@ use frame_support::{ traits::{SplitTwoWays, Currency, Randomness}, }; use sp_core::u32_trait::{_1, _2, _3, _4}; -use node_primitives::{AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, Moment, Signature}; +pub use node_primitives::{AccountId, Signature}; +use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment}; use sp_api::impl_runtime_apis; use sp_runtime::{ Permill, Perbill, Percent, ApplyExtrinsicResult, impl_opaque_keys, generic, create_runtime_str, diff --git a/bin/node/testing/Cargo.toml b/bin/node/testing/Cargo.toml index 051460e839..e41af71571 100644 --- a/bin/node/testing/Cargo.toml +++ b/bin/node/testing/Cargo.toml @@ -9,6 +9,8 @@ license = "GPL-3.0" [dependencies] pallet-balances = { version = "2.0.0", path = "../../../frame/balances" } sc-client = { version = "0.8", path = "../../../client/" } +sc-client-db = { version = "0.8", path = "../../../client/db/", features = ["kvdb-rocksdb"] } +sc-client-api = { version = "2.0", path = "../../../client/api/" } codec = { package = "parity-scale-codec", version = "1.0.0" } pallet-contracts = { version = "2.0.0", path = "../../../frame/contracts" } pallet-grandpa = { version = "2.0.0", path = "../../../frame/grandpa" } @@ -24,10 +26,29 @@ pallet-session = { version = "2.0.0", path = "../../../frame/session" } pallet-society = { version = "2.0.0", path = "../../../frame/society" } sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } pallet-staking = { version = "2.0.0", path = "../../../frame/staking" } -sc-executor = { version = "0.8", path = "../../../client/executor" } +sc-executor = { version = "0.8", path = "../../../client/executor", features = ["wasmtime"] } +sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" } 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" +sp-api = { version = "2.0.0", path = "../../../primitives/api" } +sp-finality-tracker = { version = "2.0.0", default-features = false, path = "../../../primitives/finality-tracker" } +sp-timestamp = { version = "2.0.0", default-features = false, path = "../../../primitives/timestamp" } +sp-block-builder = { version = "2.0.0", path = "../../../primitives/block-builder" } +sp-inherents = { version = "2.0.0", path = "../../../primitives/inherents" } +sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" } +log = "0.4.8" + +[dev-dependencies] +criterion = "0.3.0" +tempdir = "0.3" +fs_extra = "1" +hex-literal = "0.2.1" +sc-cli = { version = "0.8.0", path = "../../../client/cli" } + +[[bench]] +name = "import" +harness = false diff --git a/bin/node/testing/benches/import.rs b/bin/node/testing/benches/import.rs new file mode 100644 index 0000000000..86092a7836 --- /dev/null +++ b/bin/node/testing/benches/import.rs @@ -0,0 +1,503 @@ +// Copyright 2020 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 . + +//! Block import benchmark. +//! +//! This benchmark is expected to measure block import operation of +//! some more or less full block. +//! +//! As we also want to protect against cold-cache attacks, this +//! benchmark should not rely on any caching (except those that +//! DO NOT depend on user input). Thus block generation should be +//! based on randomized operation. +//! +//! This is supposed to be very simple benchmark and is not subject +//! to much configuring - just block full of randomized transactions. +//! It is not supposed to measure runtime modules weight correctness + +use std::{sync::Arc, path::Path, collections::BTreeMap}; + +use node_primitives::Block; +use node_testing::client::{Client, Backend}; +use node_testing::keyring::*; +use sc_client_db::PruningMode; +use sc_executor::{NativeExecutor, WasmExecutionMethod}; +use sp_consensus::{ + BlockOrigin, BlockImport, BlockImportParams, + ForkChoiceStrategy, ImportResult, ImportedAux +}; +use sp_runtime::{ + generic::BlockId, + OpaqueExtrinsic, + traits::{Block as BlockT, Verify, Zero, IdentifyAccount}, +}; +use codec::{Decode, Encode}; +use node_runtime::{ + Call, + CheckedExtrinsic, + constants::currency::DOLLARS, + UncheckedExtrinsic, + MinimumPeriod, + BalancesCall, + AccountId, + Signature, +}; +use sp_core::ExecutionContext; +use sp_api::ProvideRuntimeApi; +use sp_block_builder::BlockBuilder; +use sp_inherents::InherentData; +use sc_client_api::{ + Backend as _, ExecutionStrategy, + execution_extensions::{ExecutionExtensions, ExecutionStrategies}, +}; +use sp_core::{Pair, Public, sr25519}; + +use criterion::{Criterion, criterion_group, criterion_main}; + +criterion_group!( + name = benches; + config = Criterion::default().sample_size(10); + targets = bench_block_import +); +criterion_group!( + name = profile; + config = Criterion::default().sample_size(10); + targets = profile_block_import +); +criterion_main!(benches, profile); + +fn genesis(keyring: &BenchKeyring) -> node_runtime::GenesisConfig { + node_testing::genesis::config_endowed( + false, + Some(node_runtime::WASM_BINARY), + keyring.collect_account_ids(), + ) +} + +// this is deterministic keyring of ordered accounts +// //endowed-user//00 +// //endowed-user//01 +// ... +// //endowed-user//N +struct BenchKeyring { + accounts: BTreeMap, +} + +impl BenchKeyring { + fn new(num: usize) -> Self { + let mut accounts = BTreeMap::new(); + + for n in 0..num { + let seed = format!("//endowed-user/{}", n); + let pair = sr25519::Pair::from_string(&seed, None).expect("failed to generate pair"); + let account_id = AccountPublic::from(pair.public()).into_account(); + accounts.insert(account_id, pair); + } + + Self { accounts } + } + + fn collect_account_ids(&self) -> Vec { + self.accounts.keys().cloned().collect() + } + + fn at(&self, index: usize) -> AccountId { + self.accounts.keys().nth(index).expect("Failed to get account").clone() + } + + fn sign(&self, xt: CheckedExtrinsic, version: u32, genesis_hash: [u8; 32]) -> UncheckedExtrinsic { + match xt.signed { + Some((signed, extra)) => { + let payload = (xt.function, extra.clone(), version, genesis_hash, genesis_hash); + let key = self.accounts.get(&signed).expect("Account id not found in keyring"); + let signature = payload.using_encoded(|b| { + if b.len() > 256 { + key.sign(&sp_io::hashing::blake2_256(b)) + } else { + key.sign(b) + } + }).into(); + UncheckedExtrinsic { + signature: Some((pallet_indices::address::Address::Id(signed), signature, extra)), + function: payload.0, + } + } + None => UncheckedExtrinsic { + signature: None, + function: xt.function, + }, + } + } +} + +#[derive(Clone, Copy, Debug)] +enum Profile { + Native, + Wasm, +} + +impl Profile { + fn into_execution_strategies(self) -> ExecutionStrategies { + match self { + Profile::Wasm => ExecutionStrategies { + syncing: ExecutionStrategy::AlwaysWasm, + importing: ExecutionStrategy::AlwaysWasm, + block_construction: ExecutionStrategy::AlwaysWasm, + offchain_worker: ExecutionStrategy::AlwaysWasm, + other: ExecutionStrategy::AlwaysWasm, + }, + Profile::Native => ExecutionStrategies { + syncing: ExecutionStrategy::NativeElseWasm, + importing: ExecutionStrategy::NativeElseWasm, + block_construction: ExecutionStrategy::NativeElseWasm, + offchain_worker: ExecutionStrategy::NativeElseWasm, + other: ExecutionStrategy::NativeElseWasm, + } + } + } +} + +// This should return client that is doing everything that full node +// is doing. +// +// - This client should use best wasm execution method. +// - This client should work with real database only. +fn bench_client(dir: &std::path::Path, profile: Profile, keyring: &BenchKeyring) -> (Client, std::sync::Arc) { + let db_config = sc_client_db::DatabaseSettings { + state_cache_size: 16*1024*1024, + state_cache_child_ratio: Some((0, 100)), + pruning: PruningMode::ArchiveAll, + source: sc_client_db::DatabaseSettingsSrc::Path { + path: dir.into(), + cache_size: None, + }, + }; + + let (client, backend) = sc_client_db::new_client( + db_config, + NativeExecutor::new(WasmExecutionMethod::Compiled, None), + &genesis(keyring), + None, + None, + ExecutionExtensions::new(profile.into_execution_strategies(), None), + ).expect("Should not fail"); + + (client, backend) +} + +struct Guard(tempdir::TempDir); + +struct BenchContext { + client: Client, + backend: Arc, + db_guard: Guard, + keyring: BenchKeyring, +} + +impl BenchContext { + fn new(profile: Profile) -> BenchContext { + let keyring = BenchKeyring::new(128); + + let dir = tempdir::TempDir::new("sub-bench").expect("temp dir creation failed"); + log::trace!( + target: "bench-logistics", + "Created seed db at {}", + dir.path().to_string_lossy(), + ); + let (client, backend) = bench_client(dir.path(), profile, &keyring); + let db_guard = Guard(dir); + + + BenchContext { client, backend, db_guard, keyring } + } + + fn new_from_seed(profile: Profile, seed_dir: &Path) -> BenchContext { + let keyring = BenchKeyring::new(128); + + let dir = tempdir::TempDir::new("sub-bench").expect("temp dir creation failed"); + + log::trace!( + target: "bench-logistics", + "Copying seed db from {} to {}", + seed_dir.to_string_lossy(), + dir.path().to_string_lossy(), + ); + let seed_db_files = std::fs::read_dir(seed_dir) + .expect("failed to list file in seed dir") + .map(|f_result| + f_result.expect("failed to read file in seed db") + .path() + .clone() + ).collect(); + fs_extra::copy_items( + &seed_db_files, + dir.path(), + &fs_extra::dir::CopyOptions::new(), + ).expect("Copy of seed database is ok"); + + let (client, backend) = bench_client(dir.path(), profile, &keyring); + let db_guard = Guard(dir); + + BenchContext { client, backend, db_guard, keyring } + } + + fn keep_db(self) -> Guard { + self.db_guard + } +} + +type AccountPublic = ::Signer; + +pub fn get_from_seed(seed: &str) -> ::Public { + TPublic::Pair::from_string(&format!("//{}", seed), None) + .expect("static values are valid; qed") + .public() +} + +pub fn get_account_id_from_seed(seed: &str) -> AccountId +where + AccountPublic: From<::Public> +{ + AccountPublic::from(get_from_seed::(seed)).into_account() +} + +// Block generation. +fn generate_block_import(client: &Client, keyring: &BenchKeyring) -> Block { + let version = client.runtime_version_at(&BlockId::number(0)) + .expect("There should be runtime version at 0") + .spec_version; + let genesis_hash = client.block_hash(Zero::zero()) + .expect("Database error?") + .expect("Genesis block always exists; qed") + .into(); + + let mut block = client + .new_block(Default::default()) + .expect("Block creation failed"); + + let timestamp = 1 * MinimumPeriod::get(); + + let mut inherent_data = InherentData::new(); + inherent_data.put_data(sp_timestamp::INHERENT_IDENTIFIER, ×tamp) + .expect("Put timestamb failed"); + inherent_data.put_data(sp_finality_tracker::INHERENT_IDENTIFIER, &0) + .expect("Put finality tracker failed"); + + for extrinsic in client.runtime_api() + .inherent_extrinsics_with_context( + &BlockId::number(0), + ExecutionContext::BlockConstruction, + inherent_data, + ).expect("Get inherents failed") + { + block.push(extrinsic).expect("Push inherent failed"); + } + + let mut iteration = 0; + let start = std::time::Instant::now(); + for _ in 0..100 { + + let sender = keyring.at(iteration); + let receiver = get_account_id_from_seed::( + &format!("random-user//{}", iteration) + ); + + let signed = keyring.sign( + CheckedExtrinsic { + signed: Some((sender, signed_extra(0, 1*DOLLARS))), + function: Call::Balances( + BalancesCall::transfer( + pallet_indices::address::Address::Id(receiver), + 1*DOLLARS + ) + ), + }, + version, + genesis_hash, + ); + + let encoded = Encode::encode(&signed); + + let opaque = OpaqueExtrinsic::decode(&mut &encoded[..]) + .expect("Failed to decode opaque"); + + match block.push(opaque) { + Err(sp_blockchain::Error::ApplyExtrinsicFailed( + sp_blockchain::ApplyExtrinsicFailed::Validity(e) + )) if e.exhausted_resources() => { + break; + }, + Err(err) => panic!("Error pushing transaction: {:?}", err), + Ok(_) => {}, + } + iteration += 1; + } + let block = block.build().expect("Block build failed").block; + + log::info!( + target: "bench-logistics", + "Block construction: {:#?} ({} tx)", + start.elapsed(), block.extrinsics.len() + ); + + block +} + +// Import generated block. +fn import_block(client: &mut Client, block: Block) { + let import_params = BlockImportParams { + origin: BlockOrigin::NetworkBroadcast, + header: block.header().clone(), + post_digests: Default::default(), + body: Some(block.extrinsics().to_vec()), + storage_changes: Default::default(), + finalized: false, + justification: Default::default(), + auxiliary: Default::default(), + intermediates: Default::default(), + fork_choice: Some(ForkChoiceStrategy::LongestChain), + allow_missing_state: false, + import_existing: false, + }; + + assert_eq!(client.chain_info().best_number, 0); + + assert_eq!( + client.import_block(import_params, Default::default()) + .expect("Failed to import block"), + ImportResult::Imported( + ImportedAux { + header_only: false, + clear_justification_requests: false, + needs_justification: false, + bad_justification: false, + needs_finality_proof: false, + is_new_best: true, + } + ) + ); + + assert_eq!(client.chain_info().best_number, 1); +} + +fn bench_block_import(c: &mut Criterion) { + sc_cli::init_logger(""); + // for future uses, uncomment if something wrong. + // sc_cli::init_logger("sc_client=debug"); + + let (block, guard) = { + let context = BenchContext::new(Profile::Wasm); + let block = generate_block_import(&context.client, &context.keyring); + (block, context.keep_db()) + }; + + log::trace!( + target: "bench-logistics", + "Seed database directory: {}", + guard.0.path().to_string_lossy(), + ); + + c.bench_function_over_inputs("import block", + move |bencher, profile| { + bencher.iter_batched( + || { + let context = BenchContext::new_from_seed( + *profile, + guard.0.path(), + ); + + // mostly to just launch compiler before benching! + let version = context.client.runtime_version_at(&BlockId::Number(0)) + .expect("Failed to get runtime version") + .spec_version; + + log::trace!( + target: "bench-logistics", + "Next iteration database directory: {}, runtime version: {}", + context.db_guard.0.path().to_string_lossy(), version, + ); + + context + }, + |mut context| { + let start = std::time::Instant::now(); + import_block(&mut context.client, block.clone()); + let elapsed = start.elapsed(); + + log::info!( + target: "bench-logistics", + "imported block with {} tx, took: {:#?}", + block.extrinsics.len(), + elapsed, + ); + + log::info!( + target: "bench-logistics", + "usage info: {}", + context.backend.usage_info() + .expect("RocksDB backend always provides usage info!"), + ); + }, + criterion::BatchSize::PerIteration, + ); + }, + vec![Profile::Wasm, Profile::Native], + ); +} + + +// This is not an actual benchmark, so don't use it to measure anything. +// It just produces special pattern of cpu load that allows easy picking +// the part of block import for the profiling in the tool of choice. +fn profile_block_import(c: &mut Criterion) { + sc_cli::init_logger(""); + + let (block, guard) = { + let context = BenchContext::new(Profile::Wasm); + let block = generate_block_import(&context.client, &context.keyring); + (block, context.keep_db()) + }; + + c.bench_function("profile block", + move |bencher| { + bencher.iter_batched( + || { + let context = BenchContext::new_from_seed( + Profile::Native, + guard.0.path(), + ); + context + }, + |mut context| { + // until better osx signpost/callgrind signal is possible to use + // in rust, we just pause everything completely to help choosing + // actual profiling interval + std::thread::park_timeout(std::time::Duration::from_secs(2)); + import_block(&mut context.client, block.clone()); + // and here as well + std::thread::park_timeout(std::time::Duration::from_secs(2)); + log::info!( + target: "bench-logistics", + "imported block, usage info: {}", + context.backend.usage_info() + .expect("RocksDB backend always provides usage info!"), + ) + }, + criterion::BatchSize::PerIteration, + ); + }, + ); +} \ No newline at end of file diff --git a/bin/node/testing/src/client.rs b/bin/node/testing/src/client.rs index 1dddd8ba5a..29b086c3c1 100644 --- a/bin/node/testing/src/client.rs +++ b/bin/node/testing/src/client.rs @@ -35,6 +35,9 @@ pub type Client = sc_client::Client< node_runtime::RuntimeApi, >; +/// Transaction for node-runtime. +pub type Transaction = sc_client_api::backend::TransactionFor; + /// Genesis configuration parameters for `TestClient`. #[derive(Default)] pub struct GenesisParameters { diff --git a/bin/node/testing/src/genesis.rs b/bin/node/testing/src/genesis.rs index 8c5514defa..58e646e3d7 100644 --- a/bin/node/testing/src/genesis.rs +++ b/bin/node/testing/src/genesis.rs @@ -21,14 +21,38 @@ use sp_keyring::{Ed25519Keyring, Sr25519Keyring}; use node_runtime::{ GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, SystemConfig, GrandpaConfig, IndicesConfig, ContractsConfig, SocietyConfig, WASM_BINARY, + AccountId, }; use node_runtime::constants::currency::*; 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 { + config_endowed(support_changes_trie, code, Default::default()) +} + +/// Create genesis runtime configuration for tests with some extra +/// endowed accounts. +pub fn config_endowed( + support_changes_trie: bool, + code: Option<&[u8]>, + extra_endowed: Vec, +) -> GenesisConfig { + + let mut endowed = vec![ + (alice(), 111 * DOLLARS), + (bob(), 100 * DOLLARS), + (charlie(), 100_000_000 * DOLLARS), + (dave(), 111 * DOLLARS), + (eve(), 101 * DOLLARS), + (ferdie(), 100 * DOLLARS), + ]; + + endowed.extend( + extra_endowed.into_iter().map(|endowed| (endowed, 100*DOLLARS)) + ); + GenesisConfig { frame_system: Some(SystemConfig { changes_trie_config: if support_changes_trie { Some(ChangesTrieConfiguration { @@ -41,14 +65,7 @@ pub fn config(support_changes_trie: bool, code: Option<&[u8]>) -> GenesisConfig ids: vec![alice(), bob(), charlie(), dave(), eve(), ferdie()], }), pallet_balances: Some(BalancesConfig { - balances: vec![ - (alice(), 111 * DOLLARS), - (bob(), 100 * DOLLARS), - (charlie(), 100_000_000 * DOLLARS), - (dave(), 111 * DOLLARS), - (eve(), 101 * DOLLARS), - (ferdie(), 100 * DOLLARS), - ], + balances: endowed, }), pallet_session: Some(SessionConfig { keys: vec![ diff --git a/client/api/src/client.rs b/client/api/src/client.rs index 65952ce787..7503ce4a79 100644 --- a/client/api/src/client.rs +++ b/client/api/src/client.rs @@ -125,6 +125,8 @@ pub struct IoInfo { pub state_reads: u64, /// State reads (keys) from cache. pub state_reads_cache: u64, + /// State reads (keys) from cache. + pub state_writes: u64, } /// Usage statistics for running client instance. @@ -143,7 +145,7 @@ pub struct UsageInfo { impl fmt::Display for UsageInfo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, - "caches: ({} state, {} db overlay), i/o: ({} tx, {} write, {} read, {} avg tx, {}/{} key cache reads/total)", + "caches: ({} state, {} db overlay), i/o: ({} tx, {} write, {} read, {} avg tx, {}/{} key cache reads/total, {} key writes)", self.memory.state_cache, self.memory.database_cache, self.io.transactions, @@ -152,6 +154,7 @@ impl fmt::Display for UsageInfo { self.io.average_transaction_size, self.io.state_reads_cache, self.io.state_reads, + self.io.state_writes, ) } } diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index 20998a57f9..b641234281 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -1472,6 +1472,7 @@ impl sc_client_api::backend::Backend for Backend { average_transaction_size: io_stats.avg_transaction_size() as u64, state_reads: state_stats.reads.ops, state_reads_cache: state_stats.cache_reads.ops, + state_writes: state_stats.writes.ops, }, }) } diff --git a/client/db/src/light.rs b/client/db/src/light.rs index 8fb220973f..bea08d6467 100644 --- a/client/db/src/light.rs +++ b/client/db/src/light.rs @@ -592,6 +592,7 @@ impl LightBlockchainStorage for LightStorage // Light client does not track those state_reads: 0, state_reads_cache: 0, + state_writes: 0, } }) } diff --git a/primitives/keyring/src/sr25519.rs b/primitives/keyring/src/sr25519.rs index d3776f4073..476997f2db 100644 --- a/primitives/keyring/src/sr25519.rs +++ b/primitives/keyring/src/sr25519.rs @@ -86,7 +86,6 @@ impl Keyring { pub fn public(self) -> Public { self.pair().public() } - pub fn to_seed(self) -> String { format!("//{}", self) } -- GitLab From d940c02440f80c5e0ded092c4dbc9f048312d8a6 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Thu, 13 Feb 2020 13:09:33 +0100 Subject: [PATCH 145/180] Per-things trait. (#4904) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Give perthigns the trait it always deserved. * Make staking and phragmen work with the new generic per_thing * Make everything work together 🔨 * a bit of cleanup * Clean usage * Bump. * Fix name * fix grumbles * hopefully fix the ui test * Some grumbles * revamp traits again * Better naming again. --- bin/node-template/runtime/src/lib.rs | 2 +- bin/node/runtime/src/lib.rs | 6 +- bin/node/transaction-factory/src/lib.rs | 6 +- client/src/cht.rs | 12 +- client/src/leaves.rs | 6 +- client/src/light/fetcher.rs | 6 +- client/transaction-pool/src/lib.rs | 6 +- frame/assets/src/lib.rs | 6 +- frame/babe/src/lib.rs | 2 +- frame/babe/src/mock.rs | 2 +- frame/balances/src/lib.rs | 6 +- frame/contracts/src/gas.rs | 4 +- frame/elections-phragmen/src/lib.rs | 9 +- frame/example/src/lib.rs | 3 +- frame/generic-asset/src/lib.rs | 10 +- frame/grandpa/src/lib.rs | 2 +- frame/im-online/src/lib.rs | 4 +- frame/indices/src/lib.rs | 4 +- frame/randomness-collective-flip/src/lib.rs | 4 +- frame/scored-pool/src/lib.rs | 4 +- frame/session/src/mock.rs | 5 +- frame/society/src/mock.rs | 4 +- frame/staking/src/inflation.rs | 4 +- frame/staking/src/lib.rs | 13 +- frame/staking/src/slashing.rs | 2 +- frame/support/src/traits.rs | 8 +- frame/system/benches/bench.rs | 2 +- frame/system/src/lib.rs | 12 +- frame/timestamp/src/lib.rs | 4 +- frame/treasury/src/lib.rs | 6 +- frame/vesting/src/lib.rs | 10 +- primitives/arithmetic/src/lib.rs | 2 +- primitives/arithmetic/src/per_things.rs | 128 +++++++++++++++----- primitives/arithmetic/src/traits.rs | 57 +++++---- primitives/phragmen/src/lib.rs | 81 +++++++------ primitives/phragmen/src/mock.rs | 8 +- primitives/phragmen/src/tests.rs | 25 ++-- primitives/runtime/src/curve.rs | 6 +- primitives/runtime/src/generic/header.rs | 6 +- primitives/runtime/src/lib.rs | 2 +- primitives/runtime/src/traits.rs | 4 +- utils/frame/rpc/system/src/lib.rs | 6 +- 42 files changed, 302 insertions(+), 197 deletions(-) diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index a863ec40a7..b8a12e3112 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -12,7 +12,7 @@ use sp_std::prelude::*; use sp_core::OpaqueMetadata; use sp_runtime::{ ApplyExtrinsicResult, transaction_validity::TransactionValidity, generic, create_runtime_str, - impl_opaque_keys, MultiSignature + impl_opaque_keys, MultiSignature, }; use sp_runtime::traits::{ BlakeTwo256, Block as BlockT, StaticLookup, Verify, ConvertInto, IdentifyAccount diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index b7065b1854..1270c04d04 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -31,8 +31,8 @@ pub use node_primitives::{AccountId, Signature}; use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment}; use sp_api::impl_runtime_apis; use sp_runtime::{ - Permill, Perbill, Percent, ApplyExtrinsicResult, impl_opaque_keys, generic, create_runtime_str, - BenchmarkResults, + Permill, Perbill, Percent, ApplyExtrinsicResult, BenchmarkResults, + impl_opaque_keys, generic, create_runtime_str, }; use sp_runtime::curve::PiecewiseLinear; use sp_runtime::transaction_validity::TransactionValidity; @@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 216, - impl_version: 2, + impl_version: 3, apis: RUNTIME_API_VERSIONS, }; diff --git a/bin/node/transaction-factory/src/lib.rs b/bin/node/transaction-factory/src/lib.rs index 12c24e4f2f..acee44625f 100644 --- a/bin/node/transaction-factory/src/lib.rs +++ b/bin/node/transaction-factory/src/lib.rs @@ -37,15 +37,15 @@ use sp_consensus::block_import::BlockImport; use codec::{Decode, Encode}; use sp_runtime::generic::BlockId; use sp_runtime::traits::{ - Block as BlockT, Header as HeaderT, SimpleArithmetic, One, Zero, + Block as BlockT, Header as HeaderT, AtLeast32Bit, One, Zero, }; pub trait RuntimeAdapter { type AccountId: Display; - type Balance: Display + SimpleArithmetic + From; + type Balance: Display + AtLeast32Bit + From; type Block: BlockT; type Index: Copy; - type Number: Display + PartialOrd + SimpleArithmetic + Zero + One; + type Number: Display + PartialOrd + AtLeast32Bit + Zero + One; type Phase: Copy; type Secret; diff --git a/client/src/cht.rs b/client/src/cht.rs index 29f19a7750..1435b77ec5 100644 --- a/client/src/cht.rs +++ b/client/src/cht.rs @@ -28,7 +28,7 @@ use codec::Encode; use sp_trie; use sp_core::{H256, convert_hash}; -use sp_runtime::traits::{Header as HeaderT, SimpleArithmetic, Zero, One}; +use sp_runtime::traits::{Header as HeaderT, AtLeast32Bit, Zero, One}; use sp_state_machine::{ MemoryDB, TrieBackend, Backend as StateBackend, StorageProof, InMemoryBackend, prove_read_on_trie_backend, read_proof_check, read_proof_check_on_proving_backend @@ -48,7 +48,7 @@ pub fn size>() -> N { /// Returns Some(cht_number) if CHT is need to be built when the block with given number is canonized. pub fn is_build_required(cht_size: N, block_num: N) -> Option where - N: Clone + SimpleArithmetic, + N: Clone + AtLeast32Bit, { let block_cht_num = block_to_cht_number(cht_size.clone(), block_num.clone())?; let two = N::one() + N::one(); @@ -66,7 +66,7 @@ pub fn is_build_required(cht_size: N, block_num: N) -> Option /// Returns Some(max_cht_number) if CHT has ever been built given maximal canonical block number. pub fn max_cht_number(cht_size: N, max_canonical_block: N) -> Option where - N: Clone + SimpleArithmetic, + N: Clone + AtLeast32Bit, { let max_cht_number = block_to_cht_number(cht_size, max_canonical_block)?; let two = N::one() + N::one(); @@ -291,18 +291,18 @@ fn build_pairs( /// More generally: CHT N includes block (1 + N*SIZE)...((N+1)*SIZE). /// This is because the genesis hash is assumed to be known /// and including it would be redundant. -pub fn start_number(cht_size: N, cht_num: N) -> N { +pub fn start_number(cht_size: N, cht_num: N) -> N { (cht_num * cht_size) + N::one() } /// Get the ending block of a given CHT. -pub fn end_number(cht_size: N, cht_num: N) -> N { +pub fn end_number(cht_size: N, cht_num: N) -> N { (cht_num + N::one()) * cht_size } /// Convert a block number to a CHT number. /// Returns `None` for `block_num` == 0, `Some` otherwise. -pub fn block_to_cht_number(cht_size: N, block_num: N) -> Option { +pub fn block_to_cht_number(cht_size: N, block_num: N) -> Option { if block_num == N::zero() { None } else { diff --git a/client/src/leaves.rs b/client/src/leaves.rs index bb556da83a..1082e6ca07 100644 --- a/client/src/leaves.rs +++ b/client/src/leaves.rs @@ -19,7 +19,7 @@ use std::collections::BTreeMap; use std::cmp::Reverse; use kvdb::{KeyValueDB, DBTransaction}; -use sp_runtime::traits::SimpleArithmetic; +use sp_runtime::traits::AtLeast32Bit; use codec::{Encode, Decode}; use sp_blockchain::{Error, Result}; @@ -65,7 +65,7 @@ pub struct LeafSet { impl LeafSet where H: Clone + PartialEq + Decode + Encode, - N: std::fmt::Debug + Clone + SimpleArithmetic + Decode + Encode, + N: std::fmt::Debug + Clone + AtLeast32Bit + Decode + Encode, { /// Construct a new, blank leaf set. pub fn new() -> Self { @@ -251,7 +251,7 @@ pub struct Undo<'a, H: 'a, N: 'a> { impl<'a, H: 'a, N: 'a> Undo<'a, H, N> where H: Clone + PartialEq + Decode + Encode, - N: std::fmt::Debug + Clone + SimpleArithmetic + Decode + Encode, + N: std::fmt::Debug + Clone + AtLeast32Bit + Decode + Encode, { /// Undo an imported block by providing the displaced leaf. pub fn undo_import(&mut self, displaced: ImportDisplaced) { diff --git a/client/src/light/fetcher.rs b/client/src/light/fetcher.rs index d66108b7f0..9df6a38630 100644 --- a/client/src/light/fetcher.rs +++ b/client/src/light/fetcher.rs @@ -25,7 +25,7 @@ use codec::{Decode, Encode}; use sp_core::{convert_hash, traits::CodeExecutor}; use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, Hash, HashFor, NumberFor, - SimpleArithmetic, CheckedConversion, + AtLeast32Bit, CheckedConversion, }; use sp_state_machine::{ ChangesTrieRootsStorage, ChangesTrieAnchorBlockId, ChangesTrieConfigurationRange, @@ -286,7 +286,7 @@ impl FetchChecker for LightDataChecker } /// A view of BTreeMap as a changes trie roots storage. -struct RootsStorage<'a, Number: SimpleArithmetic, Hash: 'a> { +struct RootsStorage<'a, Number: AtLeast32Bit, Hash: 'a> { roots: (Number, &'a [Hash]), prev_roots: &'a BTreeMap, } @@ -294,7 +294,7 @@ struct RootsStorage<'a, Number: SimpleArithmetic, Hash: 'a> { impl<'a, H, Number, Hash> ChangesTrieRootsStorage for RootsStorage<'a, Number, Hash> where H: Hasher, - Number: ::std::fmt::Display + ::std::hash::Hash + Clone + SimpleArithmetic + Encode + Decode + Send + Sync + 'static, + Number: ::std::fmt::Display + ::std::hash::Hash + Clone + AtLeast32Bit + Encode + Decode + Send + Sync + 'static, Hash: 'a + Send + Sync + Clone + AsRef<[u8]>, { fn build_anchor( diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index 139efcd59e..f4895d9a11 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -34,7 +34,7 @@ use parking_lot::Mutex; use sp_runtime::{ generic::BlockId, - traits::{Block as BlockT, NumberFor, SimpleArithmetic, Extrinsic}, + traits::{Block as BlockT, NumberFor, AtLeast32Bit, Extrinsic}, }; use sp_transaction_pool::{ TransactionPool, PoolStatus, ImportNotificationStream, @@ -223,7 +223,7 @@ struct RevalidationAction { revalidate_amount: Option, } -impl RevalidationStrategy { +impl RevalidationStrategy { pub fn clear(&mut self) { if let Self::Light(status) = self { status.clear() @@ -255,7 +255,7 @@ impl RevalidationStrategy { } } -impl RevalidationStatus { +impl RevalidationStatus { /// Called when revalidation is completed. pub fn clear(&mut self) { *self = Self::NotScheduled; diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index 8a62fa9d82..e5c370cd21 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -133,7 +133,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use frame_support::{Parameter, decl_module, decl_event, decl_storage, decl_error, ensure}; -use sp_runtime::traits::{Member, SimpleArithmetic, Zero, StaticLookup}; +use sp_runtime::traits::{Member, AtLeast32Bit, Zero, StaticLookup}; use frame_system::{self as system, ensure_signed}; use sp_runtime::traits::One; @@ -143,10 +143,10 @@ pub trait Trait: frame_system::Trait { type Event: From> + Into<::Event>; /// The units in which we record balances. - type Balance: Member + Parameter + SimpleArithmetic + Default + Copy; + type Balance: Member + Parameter + AtLeast32Bit + Default + Copy; /// The arithmetic type of asset identifier. - type AssetId: Parameter + SimpleArithmetic + Default + Copy; + type AssetId: Parameter + AtLeast32Bit + Default + Copy; } decl_module! { diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index e707b9a10b..5921b1ba20 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -25,7 +25,7 @@ pub use pallet_timestamp; use sp_std::{result, prelude::*}; use frame_support::{decl_storage, decl_module, traits::{FindAuthor, Get, Randomness as RandomnessT}}; use sp_timestamp::OnTimestampSet; -use sp_runtime::{generic::DigestItem, ConsensusEngineId, Perbill}; +use sp_runtime::{generic::DigestItem, ConsensusEngineId, Perbill, PerThing}; use sp_runtime::traits::{IsMember, SaturatedConversion, Saturating, Hash}; use sp_staking::{ SessionIndex, diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index e65f305dc4..f5ade4ab33 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -20,7 +20,7 @@ use super::{Trait, Module, GenesisConfig}; use sp_consensus_babe::AuthorityId; use sp_runtime::{ - traits::IdentityLookup, Perbill, testing::{Header, UintAuthorityId}, impl_opaque_keys, + traits::IdentityLookup, Perbill, PerThing, testing::{Header, UintAuthorityId}, impl_opaque_keys, }; use sp_version::RuntimeVersion; use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index 9ddfd81dae..10151ab461 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -169,7 +169,7 @@ use frame_support::{ use sp_runtime::{ RuntimeDebug, DispatchResult, DispatchError, traits::{ - Zero, SimpleArithmetic, StaticLookup, Member, CheckedAdd, CheckedSub, + Zero, AtLeast32Bit, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Saturating, Bounded, }, }; @@ -180,7 +180,7 @@ pub use self::imbalances::{PositiveImbalance, NegativeImbalance}; pub trait Subtrait: frame_system::Trait { /// The balance of an account. - type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + + type Balance: Parameter + Member + AtLeast32Bit + Codec + Default + Copy + MaybeSerializeDeserialize + Debug; /// A function that is invoked when the free-balance and the reserved-balance has fallen below @@ -202,7 +202,7 @@ pub trait Subtrait: frame_system::Trait { pub trait Trait: frame_system::Trait { /// The balance of an account. - type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + + type Balance: Parameter + Member + AtLeast32Bit + Codec + Default + Copy + MaybeSerializeDeserialize + Debug; /// A function that is invoked when the free-balance and the reserved-balance has fallen below diff --git a/frame/contracts/src/gas.rs b/frame/contracts/src/gas.rs index e0cc7d4bfb..c8572daaa4 100644 --- a/frame/contracts/src/gas.rs +++ b/frame/contracts/src/gas.rs @@ -17,7 +17,7 @@ use crate::{GasSpent, Module, Trait, BalanceOf, NegativeImbalanceOf}; use sp_std::convert::TryFrom; use sp_runtime::traits::{ - CheckedMul, Zero, SaturatedConversion, SimpleArithmetic, UniqueSaturatedInto, + CheckedMul, Zero, SaturatedConversion, AtLeast32Bit, UniqueSaturatedInto, }; use frame_support::{ traits::{Currency, ExistenceRequirement, Imbalance, OnUnbalanced, WithdrawReason}, StorageValue, @@ -248,7 +248,7 @@ pub fn refund_unused_gas( /// A little handy utility for converting a value in balance units into approximate value in gas units /// at the given gas price. pub fn approx_gas_for_balance(gas_price: Balance, balance: Balance) -> Gas - where Balance: SimpleArithmetic + where Balance: AtLeast32Bit { (balance / gas_price).saturated_into::() } diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index b3dc05fe7b..f5ffd87537 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -83,7 +83,10 @@ #![cfg_attr(not(feature = "std"), no_std)] use sp_std::prelude::*; -use sp_runtime::{print, DispatchResult, DispatchError, traits::{Zero, StaticLookup, Convert}}; +use sp_runtime::{ + print, DispatchResult, DispatchError, Perbill, + traits::{Zero, StaticLookup, Convert}, +}; use frame_support::{ decl_storage, decl_event, ensure, decl_module, decl_error, weights::SimpleDispatchInfo, traits::{ @@ -637,7 +640,7 @@ impl Module { let voters_and_votes = >::enumerate() .map(|(v, i)| (v, i)) .collect::)>>(); - let maybe_phragmen_result = sp_phragmen::elect::<_, _, _, T::CurrencyToVote>( + let maybe_phragmen_result = sp_phragmen::elect::<_, _, _, T::CurrencyToVote, Perbill>( num_to_elect, 0, candidates, @@ -664,7 +667,7 @@ impl Module { .filter_map(|(m, a)| if a.is_zero() { None } else { Some(m) } ) .collect::>(); - let support_map = sp_phragmen::build_support_map::<_, _, _, T::CurrencyToVote>( + let support_map = sp_phragmen::build_support_map::<_, _, _, T::CurrencyToVote, Perbill>( &new_set, &phragmen_result.assignments, Self::locked_stake_of, diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index b4e0f3d657..14f88fc5f9 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -651,7 +651,8 @@ mod tests { // 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, + Perbill, + testing::Header, traits::{BlakeTwo256, OnInitialize, OnFinalize, IdentityLookup}, }; diff --git a/frame/generic-asset/src/lib.rs b/frame/generic-asset/src/lib.rs index 5d246a8afd..28986463e5 100644 --- a/frame/generic-asset/src/lib.rs +++ b/frame/generic-asset/src/lib.rs @@ -156,7 +156,7 @@ use codec::{Decode, Encode, HasCompact, Input, Output, Error as CodecError}; use sp_runtime::{RuntimeDebug, DispatchResult, DispatchError}; use sp_runtime::traits::{ - CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Member, One, Saturating, SimpleArithmetic, + CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Member, One, Saturating, AtLeast32Bit, Zero, Bounded, }; @@ -180,24 +180,24 @@ pub use self::imbalances::{NegativeImbalance, PositiveImbalance}; pub trait Trait: frame_system::Trait { type Balance: Parameter + Member - + SimpleArithmetic + + AtLeast32Bit + Default + Copy + MaybeSerializeDeserialize + Debug; - type AssetId: Parameter + Member + SimpleArithmetic + Default + Copy; + type AssetId: Parameter + Member + AtLeast32Bit + Default + Copy; type Event: From> + Into<::Event>; } pub trait Subtrait: frame_system::Trait { type Balance: Parameter + Member - + SimpleArithmetic + + AtLeast32Bit + Default + Copy + MaybeSerializeDeserialize + Debug; - type AssetId: Parameter + Member + SimpleArithmetic + Default + Copy; + type AssetId: Parameter + Member + AtLeast32Bit + Default + Copy; } impl Subtrait for T { diff --git a/frame/grandpa/src/lib.rs b/frame/grandpa/src/lib.rs index 71440f7aac..6164e5ab4b 100644 --- a/frame/grandpa/src/lib.rs +++ b/frame/grandpa/src/lib.rs @@ -34,7 +34,7 @@ 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, + DispatchResult, generic::{DigestItem, OpaqueDigestItemId}, traits::Zero, Perbill, PerThing, }; use sp_staking::{ SessionIndex, diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index f7067a5843..839996da32 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -79,7 +79,7 @@ use pallet_session::historical::IdentificationTuple; use sp_runtime::{ offchain::storage::StorageValueRef, RuntimeDebug, - traits::{Convert, Member, Saturating, SimpleArithmetic}, Perbill, + traits::{Convert, Member, Saturating, AtLeast32Bit}, Perbill, PerThing, transaction_validity::{ TransactionValidity, ValidTransaction, InvalidTransaction, TransactionPriority, @@ -151,7 +151,7 @@ struct HeartbeatStatus { pub sent_at: BlockNumber, } -impl HeartbeatStatus { +impl HeartbeatStatus { /// Returns true if heartbeat has been recently sent. /// /// Parameters: diff --git a/frame/indices/src/lib.rs b/frame/indices/src/lib.rs index e6a2a7c144..945095288a 100644 --- a/frame/indices/src/lib.rs +++ b/frame/indices/src/lib.rs @@ -22,7 +22,7 @@ use sp_std::{prelude::*, marker::PhantomData, convert::TryInto}; use codec::{Encode, Codec}; use frame_support::{Parameter, decl_module, decl_event, decl_storage}; -use sp_runtime::traits::{One, SimpleArithmetic, StaticLookup, Member, LookupError}; +use sp_runtime::traits::{One, AtLeast32Bit, StaticLookup, Member, LookupError}; use frame_system::{IsDeadAccount, OnNewAccount}; use self::address::Address as RawAddress; @@ -59,7 +59,7 @@ impl> 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; + type AccountIndex: Parameter + Member + Codec + Default + AtLeast32Bit + Copy; /// Whether an account is dead or not. type IsDeadAccount: IsDeadAccount; diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index c7f7bb0db7..336b038c18 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -154,7 +154,9 @@ mod tests { use super::*; use sp_core::H256; use sp_runtime::{ - Perbill, traits::{BlakeTwo256, OnInitialize, Header as _, IdentityLookup}, testing::Header, + Perbill, + testing::Header, + traits::{BlakeTwo256, OnInitialize, Header as _, IdentityLookup}, }; use frame_support::{impl_outer_origin, parameter_types, weights::Weight, traits::Randomness}; diff --git a/frame/scored-pool/src/lib.rs b/frame/scored-pool/src/lib.rs index 98a7ed217e..e3854c7524 100644 --- a/frame/scored-pool/src/lib.rs +++ b/frame/scored-pool/src/lib.rs @@ -99,7 +99,7 @@ use frame_support::{ }; use frame_system::{self as system, ensure_root, ensure_signed}; use sp_runtime::{ - traits::{EnsureOrigin, SimpleArithmetic, MaybeSerializeDeserialize, Zero, StaticLookup}, + traits::{EnsureOrigin, AtLeast32Bit, MaybeSerializeDeserialize, Zero, StaticLookup}, }; type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; @@ -121,7 +121,7 @@ pub trait Trait: frame_system::Trait { /// The score attributed to a member or candidate. type Score: - SimpleArithmetic + Clone + Copy + Default + FullCodec + MaybeSerializeDeserialize + Debug; + AtLeast32Bit + Clone + Copy + Default + FullCodec + MaybeSerializeDeserialize + Debug; /// The overarching event type. type Event: From> + Into<::Event>; diff --git a/frame/session/src/mock.rs b/frame/session/src/mock.rs index ff84743a61..9aae181771 100644 --- a/frame/session/src/mock.rs +++ b/frame/session/src/mock.rs @@ -21,8 +21,9 @@ use std::cell::RefCell; 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} + Perbill, impl_opaque_keys, + traits::{BlakeTwo256, IdentityLookup, ConvertInto}, + testing::{Header, UintAuthorityId}, }; use sp_staking::SessionIndex; diff --git a/frame/society/src/mock.rs b/frame/society/src/mock.rs index 9f202d6b17..e3393080ca 100644 --- a/frame/society/src/mock.rs +++ b/frame/society/src/mock.rs @@ -23,7 +23,9 @@ 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 sp_runtime::{ - Perbill, traits::{BlakeTwo256, IdentityLookup, OnInitialize, OnFinalize}, testing::Header, + Perbill, + testing::Header, + traits::{BlakeTwo256, IdentityLookup, OnInitialize, OnFinalize}, }; use frame_system::EnsureSignedBy; diff --git a/frame/staking/src/inflation.rs b/frame/staking/src/inflation.rs index 9f11fa9845..d5135fcc1f 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 sp_runtime::{Perbill, traits::SimpleArithmetic, curve::PiecewiseLinear}; +use sp_runtime::{Perbill, PerThing, traits::AtLeast32Bit, curve::PiecewiseLinear}; /// The total payout to all validators (and their nominators) per era. /// @@ -32,7 +32,7 @@ pub fn compute_total_payout( npos_token_staked: N, total_tokens: N, era_duration: u64 -) -> (N, N) where N: SimpleArithmetic + Clone { +) -> (N, N) where N: AtLeast32Bit + Clone { // Milliseconds per year for the Julian year (365.25 days). const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100; diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 0c1c9a4942..b4745c1fd3 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -267,12 +267,11 @@ use frame_support::{ }; use pallet_session::historical::SessionManager; use sp_runtime::{ - Perbill, - RuntimeDebug, + Perbill, PerThing, RuntimeDebug, curve::PiecewiseLinear, traits::{ Convert, Zero, One, StaticLookup, CheckedSub, Saturating, Bounded, SaturatedConversion, - SimpleArithmetic, EnsureOrigin, + AtLeast32Bit, EnsureOrigin, } }; use sp_staking::{ @@ -396,7 +395,7 @@ pub struct StakingLedger { impl< AccountId, - Balance: HasCompact + Copy + Saturating + SimpleArithmetic, + Balance: HasCompact + Copy + Saturating + AtLeast32Bit, > StakingLedger { /// Remove entries from `unlocking` that are sufficiently old and reduce the /// total by the sum of their balances. @@ -440,7 +439,7 @@ impl< } impl StakingLedger where - Balance: SimpleArithmetic + Saturating + Copy, + Balance: AtLeast32Bit + 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` @@ -1503,7 +1502,7 @@ impl Module { }); all_nominators.extend(nominator_votes); - let maybe_phragmen_result = sp_phragmen::elect::<_, _, _, T::CurrencyToVote>( + let maybe_phragmen_result = sp_phragmen::elect::<_, _, _, T::CurrencyToVote, Perbill>( Self::validator_count() as usize, Self::minimum_validator_count().max(1) as usize, all_validators, @@ -1520,7 +1519,7 @@ impl Module { let to_balance = |e: ExtendedBalance| >>::convert(e); - let supports = sp_phragmen::build_support_map::<_, _, _, T::CurrencyToVote>( + let supports = sp_phragmen::build_support_map::<_, _, _, T::CurrencyToVote, Perbill>( &elected_stashes, &assignments, Self::slashable_balance_of, diff --git a/frame/staking/src/slashing.rs b/frame/staking/src/slashing.rs index df36b1c763..3c8f39501a 100644 --- a/frame/staking/src/slashing.rs +++ b/frame/staking/src/slashing.rs @@ -52,7 +52,7 @@ use super::{ EraIndex, Trait, Module, Store, BalanceOf, Exposure, Perbill, SessionInterface, NegativeImbalanceOf, UnappliedSlash, }; -use sp_runtime::traits::{Zero, Saturating}; +use sp_runtime::{traits::{Zero, Saturating}, PerThing}; use frame_support::{ StorageMap, StorageDoubleMap, traits::{Currency, OnUnbalanced, Imbalance}, diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index f456ef5bec..0722012910 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -24,7 +24,7 @@ use sp_core::u32_trait::Value as U32; use sp_runtime::{ RuntimeDebug, ConsensusEngineId, DispatchResult, DispatchError, - traits::{MaybeSerializeDeserialize, SimpleArithmetic, Saturating, TrailingZeroInput}, + traits::{MaybeSerializeDeserialize, AtLeast32Bit, Saturating, TrailingZeroInput}, }; use crate::dispatch::Parameter; @@ -267,7 +267,7 @@ pub enum SignedImbalance>{ impl< P: Imbalance, N: Imbalance, - B: SimpleArithmetic + FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default, + B: AtLeast32Bit + FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default, > SignedImbalance { pub fn zero() -> Self { SignedImbalance::Positive(P::zero()) @@ -330,7 +330,7 @@ impl< /// Abstraction over a fungible assets system. pub trait Currency { /// The balance of an account. - type Balance: SimpleArithmetic + FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default; + type Balance: AtLeast32Bit + FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default; /// The opaque token type for an imbalance. This is returned by unbalanced operations /// and must be dealt with. It may be dropped but cannot be cloned. @@ -659,7 +659,7 @@ bitmask! { } pub trait Time { - type Moment: SimpleArithmetic + Parameter + Default + Copy; + type Moment: AtLeast32Bit + Parameter + Default + Copy; fn now() -> Self::Moment; } diff --git a/frame/system/benches/bench.rs b/frame/system/benches/bench.rs index 42a35c49a1..49872ef7db 100644 --- a/frame/system/benches/bench.rs +++ b/frame/system/benches/bench.rs @@ -18,7 +18,7 @@ use criterion::{Criterion, criterion_group, criterion_main, black_box}; use frame_system as system; 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}; +use sp_runtime::{Perbill, PerThing, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; mod module { use super::*; diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 03b5d48aad..58a6dbc56d 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -97,14 +97,14 @@ use sp_std::marker::PhantomData; use sp_std::fmt::Debug; use sp_version::RuntimeVersion; use sp_runtime::{ - RuntimeDebug, - generic::{self, Era}, Perbill, DispatchOutcome, DispatchError, + RuntimeDebug, Perbill, DispatchOutcome, DispatchError, + generic::{self, Era}, transaction_validity::{ ValidTransaction, TransactionPriority, TransactionLongevity, TransactionValidityError, InvalidTransaction, TransactionValidity, }, traits::{ - self, CheckEqual, SimpleArithmetic, Zero, SignedExtension, Lookup, LookupError, + self, CheckEqual, AtLeast32Bit, Zero, SignedExtension, Lookup, LookupError, SimpleBitOps, Hash, Member, MaybeDisplay, EnsureOrigin, BadOrigin, SaturatedConversion, MaybeSerialize, MaybeSerializeDeserialize, MaybeMallocSizeOf, StaticLookup, One, Bounded, }, @@ -165,12 +165,12 @@ pub trait Trait: 'static + Eq + Clone { /// Account index (aka nonce) type. This stores the number of previous transactions associated /// with a sender account. type Index: - Parameter + Member + MaybeSerialize + Debug + Default + MaybeDisplay + SimpleArithmetic + Parameter + Member + MaybeSerialize + Debug + Default + MaybeDisplay + AtLeast32Bit + Copy; /// The block number type used by the runtime. type BlockNumber: - Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + SimpleArithmetic + Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + AtLeast32Bit + Default + Bounded + Copy + sp_std::hash::Hash + sp_std::str::FromStr + MaybeMallocSizeOf; /// The output of the `Hashing` function. @@ -898,7 +898,7 @@ impl CheckWeight { /// a portion. fn get_dispatch_limit_ratio(class: DispatchClass) -> Perbill { match class { - DispatchClass::Operational => Perbill::one(), + DispatchClass::Operational => ::one(), DispatchClass::Normal => T::AvailableBlockRatio::get(), } } diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index c437c325cd..6a4cdf92fa 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -99,7 +99,7 @@ use frame_support::traits::{Time, Get}; use sp_runtime::{ RuntimeString, traits::{ - SimpleArithmetic, Zero, SaturatedConversion, Scale + AtLeast32Bit, Zero, SaturatedConversion, Scale } }; use frame_support::weights::SimpleDispatchInfo; @@ -112,7 +112,7 @@ use sp_timestamp::{ /// The module configuration trait pub trait Trait: frame_system::Trait { /// Type used for expressing timestamp. - type Moment: Parameter + Default + SimpleArithmetic + type Moment: Parameter + Default + AtLeast32Bit + Scale + Copy; /// Something which can be notified when the timestamp is set. Set this to `()` if not needed. diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index ef37cc12ee..44ce575f17 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -590,7 +590,7 @@ impl Module { } } - /// Remove any non-members of `Tippers` from a `tips` vectr. `O(T)`. + /// Remove any non-members of `Tippers` from a `tips` vector. `O(T)`. fn retain_active_tips(tips: &mut Vec<(T::AccountId, BalanceOf)>) { let members = T::Tippers::sorted_members(); let mut members_iter = members.iter(); @@ -724,7 +724,9 @@ mod tests { use frame_support::traits::Contains; use sp_core::H256; use sp_runtime::{ - traits::{BlakeTwo256, OnFinalize, IdentityLookup, BadOrigin}, testing::Header, Perbill + Perbill, + testing::Header, + traits::{BlakeTwo256, OnFinalize, IdentityLookup, BadOrigin}, }; impl_outer_origin! { diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index dd12f28ec4..e39e2ae3a5 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -50,7 +50,7 @@ use sp_std::prelude::*; use sp_std::fmt::Debug; use codec::{Encode, Decode}; use sp_runtime::{DispatchResult, RuntimeDebug, traits::{ - StaticLookup, Zero, SimpleArithmetic, MaybeSerializeDeserialize, Saturating, Convert + StaticLookup, Zero, AtLeast32Bit, MaybeSerializeDeserialize, Saturating, Convert }}; use frame_support::{decl_module, decl_event, decl_storage, decl_error}; use frame_support::traits::{ @@ -85,8 +85,8 @@ pub struct VestingInfo { } impl< - Balance: SimpleArithmetic + Copy, - BlockNumber: SimpleArithmetic + Copy, + Balance: AtLeast32Bit + Copy, + BlockNumber: AtLeast32Bit + Copy, > VestingInfo { /// Amount locked at block `n`. pub fn locked_at< @@ -298,7 +298,9 @@ mod tests { // 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, Identity, OnInitialize}, + Perbill, + testing::Header, + traits::{BlakeTwo256, IdentityLookup, Identity, OnInitialize}, }; use sp_storage::Storage; diff --git a/primitives/arithmetic/src/lib.rs b/primitives/arithmetic/src/lib.rs index 0beef84758..c2feae00b7 100644 --- a/primitives/arithmetic/src/lib.rs +++ b/primitives/arithmetic/src/lib.rs @@ -40,5 +40,5 @@ mod fixed64; mod rational128; pub use fixed64::Fixed64; -pub use per_things::{Percent, Permill, Perbill, Perquintill}; +pub use per_things::{PerThing, Percent, Permill, Perbill, Perquintill}; pub use rational128::Rational128; diff --git a/primitives/arithmetic/src/per_things.rs b/primitives/arithmetic/src/per_things.rs index 554f3c3c21..cbb804baf5 100644 --- a/primitives/arithmetic/src/per_things.rs +++ b/primitives/arithmetic/src/per_things.rs @@ -19,50 +19,93 @@ use serde::{Serialize, Deserialize}; use sp_std::{ops, prelude::*, convert::TryInto}; use codec::{Encode, Decode, CompactAs}; -use crate::traits::{SaturatedConversion, UniqueSaturatedInto, Saturating}; +use crate::traits::{ + SaturatedConversion, UniqueSaturatedInto, Saturating, BaseArithmetic, +}; use sp_debug_derive::RuntimeDebug; +/// Something that implements a fixed point ration with an arbitrary granularity `X`, as _parts per +/// `X`_. +pub trait PerThing: Sized + Saturating + Copy { + /// The data type used to build this per-thingy. + type Inner: BaseArithmetic + Copy; + + /// accuracy of this type + const ACCURACY: Self::Inner; + + /// NoThing + fn zero() -> Self; + + /// `true` if this is nothing. + fn is_zero(&self) -> bool; + + /// Everything. + fn one() -> Self; + + /// Consume self and deconstruct into a raw numeric type. + fn deconstruct(self) -> Self::Inner; + + /// From an explicitly defined number of parts per maximum of the type. + fn from_parts(parts: Self::Inner) -> Self; + + /// Converts a percent into `Self`. Equal to `x / 100`. + fn from_percent(x: Self::Inner) -> Self; + + /// Return the product of multiplication of this value by itself. + fn square(self) -> Self; + + /// Converts a fraction into `Self`. + #[cfg(feature = "std")] + fn from_fraction(x: f64) -> Self; + + /// Approximate the fraction `p/q` into a per-thing fraction. This will never overflow. + /// + /// The computation of this approximation is performed in the generic type `N`. Given + /// `M` as the data type that can hold the maximum value of this per-thing (e.g. u32 for + /// perbill), this can only work if `N == M` or `N: From + TryInto`. + fn from_rational_approximation(p: N, q: N) -> Self + where N: Clone + Ord + From + TryInto + ops::Div; +} + 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))] - #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, CompactAs)] + #[derive(Encode, Decode, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, CompactAs)] pub struct $name($type); - impl $name { + impl PerThing for $name { + type Inner = $type; + + /// The accuracy of this type. + const ACCURACY: Self::Inner = $max; + /// Nothing. - pub fn zero() -> Self { Self(0) } + fn zero() -> Self { Self(0) } /// `true` if this is nothing. - pub fn is_zero(&self) -> bool { self.0 == 0 } + fn is_zero(&self) -> bool { self.0 == 0 } /// Everything. - pub fn one() -> Self { Self($max) } + fn one() -> Self { Self($max) } /// Consume self and deconstruct into a raw numeric type. - pub fn deconstruct(self) -> $type { self.0 } - - /// Return the scale at which this per-thing is working. - pub const fn accuracy() -> $type { $max } + fn deconstruct(self) -> Self::Inner { self.0 } /// From an explicitly defined number of parts per maximum of the type. - /// - /// This can be called at compile time. - pub const fn from_parts(parts: $type) -> Self { + fn from_parts(parts: Self::Inner) -> Self { Self([parts, $max][(parts > $max) as usize]) } /// Converts a percent into `Self`. Equal to `x / 100`. - /// - /// This can be created at compile time. - pub const fn from_percent(x: $type) -> Self { + fn from_percent(x: Self::Inner) -> Self { Self([x, 100][(x > 100) as usize] * ($max / 100)) } /// Return the product of multiplication of this value by itself. - pub fn square(self) -> Self { + fn square(self) -> Self { // both can be safely casted and multiplied. let p: $upper_type = self.0 as $upper_type * self.0 as $upper_type; let q: $upper_type = <$upper_type>::from($max) * <$upper_type>::from($max); @@ -71,33 +114,33 @@ macro_rules! implement_per_thing { /// Converts a fraction into `Self`. #[cfg(feature = "std")] - pub fn from_fraction(x: f64) -> Self { Self((x * ($max as f64)) as $type) } + fn from_fraction(x: f64) -> Self { Self((x * ($max as f64)) as Self::Inner) } /// Approximate the fraction `p/q` into a per-thing fraction. This will never overflow. /// /// The computation of this approximation is performed in the generic type `N`. Given /// `M` as the data type that can hold the maximum value of this per-thing (e.g. u32 for /// perbill), this can only work if `N == M` or `N: From + TryInto`. - pub fn from_rational_approximation(p: N, q: N) -> Self - where N: Clone + Ord + From<$type> + TryInto<$type> + ops::Div + fn from_rational_approximation(p: N, q: N) -> Self + where N: Clone + Ord + From + TryInto + ops::Div { // q cannot be zero. - let q = q.max((1 as $type).into()); + let q = q.max((1 as Self::Inner).into()); // p should not be bigger than q. let p = p.min(q.clone()); - let factor = (q.clone() / $max.into()).max((1 as $type).into()); + let factor = (q.clone() / $max.into()).max((1 as Self::Inner).into()); // q cannot overflow: (q / (q/$max)) < 2 * $max. p < q hence p also cannot overflow. - // this implies that $type must be able to fit 2 * $max. - let q_reduce: $type = (q / factor.clone()) + // this implies that Self::Inner must be able to fit 2 * $max. + let q_reduce: Self::Inner = (q / factor.clone()) .try_into() .map_err(|_| "Failed to convert") .expect( "q / (q/$max) < (2 * $max). Macro prevents any type being created that \ does not satisfy this; qed" ); - let p_reduce: $type = (p / factor.clone()) + let p_reduce: Self::Inner = (p / factor.clone()) .try_into() .map_err(|_| "Failed to convert") .expect( @@ -105,14 +148,39 @@ macro_rules! implement_per_thing { does not satisfy this; qed" ); - // `p_reduced` and `q_reduced` are withing $type. Mul by another $max will always - // fit in $upper_type. This is guaranteed by the macro tests. + // `p_reduced` and `q_reduced` are withing Self::Inner. Mul by another $max will + // always fit in $upper_type. This is guaranteed by the macro tests. let part = p_reduce as $upper_type * <$upper_type>::from($max) / q_reduce as $upper_type; - $name(part as $type) + $name(part as Self::Inner) + } + } + + /// Implement const functions + impl $name { + /// From an explicitly defined number of parts per maximum of the type. + /// + /// This can be called at compile time. + pub const fn from_parts(parts: $type) -> Self { + Self([parts, $max][(parts > $max) as usize]) + } + + /// Converts a percent into `Self`. Equal to `x / 100`. + /// + /// This can be created at compile time. + pub const fn from_percent(x: $type) -> Self { + Self([x, 100][(x > 100) as usize] * ($max / 100)) + } + + /// Everything. + /// + /// To avoid having to import `PerThing` when one needs to be used in test mocks. + #[cfg(feature = "std")] + pub fn one() -> Self { + ::one() } } @@ -190,7 +258,7 @@ macro_rules! implement_per_thing { #[cfg(test)] mod $test_mod { use codec::{Encode, Decode}; - use super::{$name, Saturating, RuntimeDebug}; + use super::{$name, Saturating, RuntimeDebug, PerThing}; use crate::traits::Zero; @@ -248,7 +316,7 @@ macro_rules! implement_per_thing { // some really basic stuff assert_eq!($name::zero(), $name::from_parts(Zero::zero())); assert_eq!($name::one(), $name::from_parts($max)); - assert_eq!($name::accuracy(), $max); + assert_eq!($name::ACCURACY, $max); assert_eq!($name::from_percent(0), $name::from_parts(Zero::zero())); assert_eq!($name::from_percent(10), $name::from_parts($max / 10)); assert_eq!($name::from_percent(100), $name::from_parts($max)); diff --git a/primitives/arithmetic/src/traits.rs b/primitives/arithmetic/src/traits.rs index ab525527e9..75adf0e136 100644 --- a/primitives/arithmetic/src/traits.rs +++ b/primitives/arithmetic/src/traits.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Primitives for the runtime modules. +//! Primitive traits for the runtime arithmetic. use sp_std::{self, convert::{TryFrom, TryInto}}; use codec::HasCompact; @@ -28,44 +28,55 @@ use sp_std::ops::{ RemAssign, Shl, Shr }; -/// A meta trait for arithmetic. -/// -/// Arithmetic types do all the usual stuff you'd expect numbers to do. They are guaranteed to -/// be able to represent at least `u32` values without loss, hence the trait implies `From` -/// and smaller ints. All other conversions are fallible. -pub trait SimpleArithmetic: +/// A meta trait for arithmetic type operations, regardless of any limitation on size. +pub trait BaseArithmetic: + From + Zero + One + IntegerSquareRoot + - From + From + From + TryInto + TryInto + TryInto + - TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + - UniqueSaturatedInto + UniqueSaturatedInto + UniqueSaturatedInto + - UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto + Add + AddAssign + Sub + SubAssign + Mul + MulAssign + Div + DivAssign + Rem + RemAssign + Shl + Shr + - CheckedShl + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + - Saturating + PartialOrd + Ord + Bounded + - HasCompact + Sized + CheckedShl + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + Saturating + + PartialOrd + Ord + Bounded + HasCompact + Sized + + TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + + TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + + UniqueSaturatedFrom + UniqueSaturatedInto + + UniqueSaturatedFrom + UniqueSaturatedInto + + UniqueSaturatedFrom + UniqueSaturatedInto + + UniqueSaturatedFrom + UniqueSaturatedInto + + UniqueSaturatedFrom + UniqueSaturatedInto {} + impl + Zero + One + IntegerSquareRoot + - From + From + From + TryInto + TryInto + TryInto + - TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + - UniqueSaturatedInto + UniqueSaturatedInto + UniqueSaturatedInto + - UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + - UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto + Add + AddAssign + Sub + SubAssign + Mul + MulAssign + Div + DivAssign + Rem + RemAssign + Shl + Shr + - CheckedShl + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + - Saturating + PartialOrd + Ord + Bounded + - HasCompact + Sized -> SimpleArithmetic for T {} + CheckedShl + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + Saturating + + PartialOrd + Ord + Bounded + HasCompact + Sized + + TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + + TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + + UniqueSaturatedFrom + UniqueSaturatedInto + + UniqueSaturatedFrom + UniqueSaturatedInto + + UniqueSaturatedFrom + UniqueSaturatedInto + + UniqueSaturatedFrom + UniqueSaturatedInto + + UniqueSaturatedFrom + UniqueSaturatedInto +> BaseArithmetic for T {} + +/// A meta trait for arithmetic. +/// +/// Arithmetic types do all the usual stuff you'd expect numbers to do. They are guaranteed to +/// be able to represent at least `u32` values without loss, hence the trait implies `From` +/// and smaller integers. All other conversions are fallible. +pub trait AtLeast32Bit: BaseArithmetic + From + From {} + +impl + From> AtLeast32Bit for T {} /// Just like `From` except that if the source value is too big to fit into the destination type /// then it'll saturate the destination. diff --git a/primitives/phragmen/src/lib.rs b/primitives/phragmen/src/lib.rs index c13654543d..e2f77e5458 100644 --- a/primitives/phragmen/src/lib.rs +++ b/primitives/phragmen/src/lib.rs @@ -33,10 +33,14 @@ #![cfg_attr(not(feature = "std"), no_std)] -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}; +use sp_std::{prelude::*, collections::btree_map::BTreeMap, convert::TryFrom}; +use sp_runtime::{ + PerThing, Rational128, RuntimeDebug, + helpers_128bit::multiply_by_rational, +}; +use sp_runtime::traits::{ + Zero, Convert, Member, AtLeast32Bit, SaturatedConversion, Bounded, Saturating, +}; #[cfg(test)] mod mock; @@ -93,21 +97,21 @@ pub struct Edge { candidate_index: usize, } -/// Means a particular `AccountId` was backed by `Perbill`th of a nominator's stake. -pub type PhragmenAssignment = (AccountId, Perbill); +/// Particular `AccountId` was backed by `T`-ratio of a nominator's stake. +pub type PhragmenAssignment = (AccountId, T); -/// Means a particular `AccountId` was backed by `ExtendedBalance` of a nominator's stake. +/// Particular `AccountId` was backed by `ExtendedBalance` of a nominator's stake. pub type PhragmenStakedAssignment = (AccountId, ExtendedBalance); /// Final result of the phragmen election. #[derive(RuntimeDebug)] -pub struct PhragmenResult { +pub struct PhragmenResult { /// Just winners zipped with their approval stake. Note that the approval stake is merely the /// sub of their received stake and could be used for very basic sorting and approval voting. pub winners: Vec<(AccountId, ExtendedBalance)>, /// Individual assignments. for each tuple, the first elements is a voter and the second /// is the list of candidates that it supports. - pub assignments: Vec<(AccountId, Vec>)> + pub assignments: Vec<(AccountId, Vec>)> } /// A structure to demonstrate the phragmen result from the perspective of the candidate, i.e. how @@ -145,23 +149,24 @@ pub type SupportMap = BTreeMap>; /// responsibility of the caller to make sure only those candidates who have a sensible economic /// value are passed in. From the perspective of this function, a candidate can easily be among the /// winner with no backing stake. -pub fn elect( +pub fn elect( candidate_count: usize, minimum_candidate_count: usize, initial_candidates: Vec, initial_voters: Vec<(AccountId, Vec)>, stake_of: FS, -) -> Option> where +) -> Option> where AccountId: Default + Ord + Member, - Balance: Default + Copy + SimpleArithmetic, + Balance: Default + Copy + AtLeast32Bit, for<'r> FS: Fn(&'r AccountId) -> Balance, C: Convert + Convert, + R: PerThing, { let to_votes = |b: Balance| >::convert(b) as ExtendedBalance; // return structures let mut elected_candidates: Vec<(AccountId, ExtendedBalance)>; - let mut assigned: Vec<(AccountId, Vec>)>; + let mut assigned: Vec<(AccountId, Vec>)>; // used to cache and access candidates index. let mut c_idx_cache = BTreeMap::::new(); @@ -272,20 +277,29 @@ pub fn elect( let mut assignment = (n.who.clone(), vec![]); for e in &mut n.edges { if elected_candidates.iter().position(|(ref c, _)| *c == e.who).is_some() { - let per_bill_parts = + let per_bill_parts: R::Inner = { if n.load == e.load { // Full support. No need to calculate. - Perbill::accuracy().into() + R::ACCURACY } else { if e.load.d() == n.load.d() { // return e.load / n.load. - let desired_scale: u128 = Perbill::accuracy().into(); - multiply_by_rational( + let desired_scale: u128 = R::ACCURACY.saturated_into(); + let parts = multiply_by_rational( desired_scale, e.load.n(), n.load.n(), - ).unwrap_or(Bounded::max_value()) + ) + // If result cannot fit in u128. Not much we can do about it. + .unwrap_or(Bounded::max_value()); + + TryFrom::try_from(parts) + // If the result cannot fit into R::Inner. Defensive only. This can + // never happen. `desired_scale * e / n`, where `e / n < 1` always + // yields a value smaller than `desired_scale`, which will fit into + // R::Inner. + .unwrap_or(Bounded::max_value()) } else { // defensive only. Both edge and nominator loads are built from // scores, hence MUST have the same denominator. @@ -293,10 +307,7 @@ pub fn elect( } } }; - // safer to .min() inside as well to argue as u32 is safe. - let per_thing = Perbill::from_parts( - per_bill_parts.min(Perbill::accuracy().into()) as u32 - ); + let per_thing = R::from_parts(per_bill_parts); assignment.1.push((e.who.clone(), per_thing)); } } @@ -304,20 +315,19 @@ pub fn elect( if assignment.1.len() > 0 { // To ensure an assertion indicating: no stake from the nominator going to waste, // we add a minimal post-processing to equally assign all of the leftover stake ratios. - let vote_count = assignment.1.len() as u32; + let vote_count: R::Inner = assignment.1.len().saturated_into(); let len = assignment.1.len(); - let sum = assignment.1.iter() - .map(|a| a.1.deconstruct()) - .sum::(); - let accuracy = Perbill::accuracy(); - let diff = accuracy.checked_sub(sum).unwrap_or(0); + let mut sum: R::Inner = Zero::zero(); + assignment.1.iter().for_each(|a| sum = sum.saturating_add(a.1.deconstruct())); + let accuracy = R::ACCURACY; + let diff = accuracy.saturating_sub(sum); let diff_per_vote = (diff / vote_count).min(accuracy); - if diff_per_vote > 0 { + if !diff_per_vote.is_zero() { for i in 0..len { let current_ratio = assignment.1[i % len].1; let next_ratio = current_ratio - .saturating_add(Perbill::from_parts(diff_per_vote)); + .saturating_add(R::from_parts(diff_per_vote)); assignment.1[i % len].1 = next_ratio; } } @@ -325,9 +335,9 @@ pub fn elect( // `remainder` is set to be less than maximum votes of a nominator (currently 16). // safe to cast it to usize. let remainder = diff - diff_per_vote * vote_count; - for i in 0..remainder as usize { + for i in 0..remainder.saturated_into::() { let current_ratio = assignment.1[i % len].1; - let next_ratio = current_ratio.saturating_add(Perbill::from_parts(1)); + let next_ratio = current_ratio.saturating_add(R::from_parts(1u8.into())); assignment.1[i % len].1 = next_ratio; } assigned.push(assignment); @@ -341,15 +351,16 @@ pub fn elect( } /// Build the support map from the given phragmen result. -pub fn build_support_map( +pub fn build_support_map( elected_stashes: &Vec, - assignments: &Vec<(AccountId, Vec>)>, + assignments: &Vec<(AccountId, Vec>)>, stake_of: FS, ) -> SupportMap where AccountId: Default + Ord + Member, - Balance: Default + Copy + SimpleArithmetic, + Balance: Default + Copy + AtLeast32Bit, C: Convert + Convert, for<'r> FS: Fn(&'r AccountId) -> Balance, + R: PerThing + sp_std::ops::Mul, { let to_votes = |b: Balance| >::convert(b) as ExtendedBalance; // Initialize the support of each candidate. diff --git a/primitives/phragmen/src/mock.rs b/primitives/phragmen/src/mock.rs index 59b8d4eb5c..b3110a5dba 100644 --- a/primitives/phragmen/src/mock.rs +++ b/primitives/phragmen/src/mock.rs @@ -20,7 +20,7 @@ use crate::{elect, PhragmenResult, PhragmenAssignment}; use sp_runtime::{ - assert_eq_error_rate, Perbill, + assert_eq_error_rate, Perbill, PerThing, traits::{Convert, Member, SaturatedConversion} }; use sp_std::collections::btree_map::BTreeMap; @@ -320,10 +320,10 @@ pub(crate) fn create_stake_of(stakes: &[(AccountId, Balance)]) } -pub fn check_assignments(assignments: Vec<(AccountId, Vec>)>) { +pub fn check_assignments(assignments: Vec<(AccountId, Vec>)>) { for (_, a) in assignments { let sum: u32 = a.iter().map(|(_, p)| p.deconstruct()).sum(); - assert_eq_error_rate!(sum, Perbill::accuracy(), 5); + assert_eq_error_rate!(sum, Perbill::ACCURACY, 5); } } @@ -335,7 +335,7 @@ pub(crate) fn run_and_compare( min_to_elect: usize, ) { // run fixed point code. - let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>( + let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote, Perbill>( to_elect, min_to_elect, candidates.clone(), diff --git a/primitives/phragmen/src/tests.rs b/primitives/phragmen/src/tests.rs index b182cfca05..9027cc335f 100644 --- a/primitives/phragmen/src/tests.rs +++ b/primitives/phragmen/src/tests.rs @@ -23,6 +23,8 @@ use crate::{elect, PhragmenResult, PhragmenStakedAssignment, build_support_map, use substrate_test_utils::assert_eq_uvec; use sp_runtime::Perbill; +type Output = Perbill; + #[test] fn float_phragmen_poc_works() { let candidates = vec![1, 2, 3]; @@ -78,7 +80,7 @@ fn phragmen_poc_works() { (30, vec![2, 3]), ]; - let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>( + let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote, Output>( 2, 2, candidates, @@ -147,7 +149,7 @@ fn phragmen_accuracy_on_large_scale_only_validators() { (5, (u64::max_value() - 2).into()), ]); - let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>( + let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote, Output>( 2, 2, candidates.clone(), @@ -178,7 +180,7 @@ fn phragmen_accuracy_on_large_scale_validators_and_nominators() { (14, u64::max_value().into()), ]); - let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>( + let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote, Output>( 2, 2, candidates, @@ -210,7 +212,7 @@ fn phragmen_accuracy_on_small_scale_self_vote() { (30, 1), ]); - let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote>( + let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote, Output>( 3, 3, candidates, @@ -241,7 +243,7 @@ fn phragmen_accuracy_on_small_scale_no_self_vote() { (3, 1), ]); - let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote>( + let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote, Output>( 3, 3, candidates, @@ -275,7 +277,7 @@ fn phragmen_large_scale_test() { (50, 990000000000000000), ]); - let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>( + let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote, Output>( 2, 2, candidates, @@ -302,7 +304,7 @@ fn phragmen_large_scale_test_2() { (50, nom_budget.into()), ]); - let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote>( + let PhragmenResult { winners, assignments } = elect::<_, _, _, TestCurrencyToVote, Output>( 2, 2, candidates, @@ -367,7 +369,7 @@ fn elect_has_no_entry_barrier() { (2, 10), ]); - let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote>( + let PhragmenResult { winners, assignments: _ } = elect::<_, _, _, TestCurrencyToVote, Output>( 3, 3, candidates, @@ -395,7 +397,7 @@ fn minimum_to_elect_is_respected() { (2, 10), ]); - let maybe_result = elect::<_, _, _, TestCurrencyToVote>( + let maybe_result = elect::<_, _, _, TestCurrencyToVote, Output>( 10, 10, candidates, @@ -422,7 +424,7 @@ fn self_votes_should_be_kept() { (1, 8), ]); - let result = elect::<_, _, _, TestCurrencyToVote>( + let result = elect::<_, _, _, TestCurrencyToVote, Output>( 2, 2, candidates, @@ -448,7 +450,8 @@ fn self_votes_should_be_kept() { Balance, AccountId, _, - TestCurrencyToVote + TestCurrencyToVote, + Output, >( &result.winners.into_iter().map(|(who, _)| who).collect(), &result.assignments, diff --git a/primitives/runtime/src/curve.rs b/primitives/runtime/src/curve.rs index b45501fdb7..a230e2f32d 100644 --- a/primitives/runtime/src/curve.rs +++ b/primitives/runtime/src/curve.rs @@ -16,7 +16,7 @@ //! Provides some utilities to define a piecewise linear function. -use crate::{Perbill, traits::{SimpleArithmetic, SaturatedConversion}}; +use crate::{Perbill, PerThing, traits::{AtLeast32Bit, SaturatedConversion}}; use core::ops::Sub; /// Piecewise Linear function in [0, 1] -> [0, 1]. @@ -35,7 +35,7 @@ fn abs_sub + Clone>(a: N, b: N) -> N where { impl<'a> PiecewiseLinear<'a> { /// Compute `f(n/d)*d` with `n <= d`. This is useful to avoid loss of precision. pub fn calculate_for_fraction_times_denominator(&self, n: N, d: N) -> N where - N: SimpleArithmetic + Clone + N: AtLeast32Bit + Clone { let n = n.min(d.clone()); @@ -79,7 +79,7 @@ impl<'a> PiecewiseLinear<'a> { // This is guaranteed not to overflow on whatever values nor lose precision. // `q` must be superior to zero. fn multiply_by_rational_saturating(value: N, p: u32, q: u32) -> N - where N: SimpleArithmetic + Clone + where N: AtLeast32Bit + Clone { let q = q.max(1); diff --git a/primitives/runtime/src/generic/header.rs b/primitives/runtime/src/generic/header.rs index 5bc7932feb..5efb36603d 100644 --- a/primitives/runtime/src/generic/header.rs +++ b/primitives/runtime/src/generic/header.rs @@ -20,7 +20,7 @@ use serde::{Deserialize, Serialize}; use crate::codec::{Decode, Encode, Codec, Input, Output, HasCompact, EncodeAsRef, Error}; use crate::traits::{ - self, Member, SimpleArithmetic, SimpleBitOps, Hash as HashT, + self, Member, AtLeast32Bit, SimpleBitOps, Hash as HashT, MaybeSerializeDeserialize, MaybeSerialize, MaybeDisplay, MaybeMallocSizeOf, }; @@ -122,7 +122,7 @@ impl codec::EncodeLike for Header where impl traits::Header for Header where Number: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + MaybeDisplay + - SimpleArithmetic + Codec + Copy + Into + TryFrom + sp_std::str::FromStr + + AtLeast32Bit + Codec + Copy + Into + TryFrom + sp_std::str::FromStr + MaybeMallocSizeOf, Hash: HashT, Hash::Output: Default + sp_std::hash::Hash + Copy + Member + Ord + @@ -170,7 +170,7 @@ impl traits::Header for Header where } impl Header where - Number: Member + sp_std::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec + Into + TryFrom, + Number: Member + sp_std::hash::Hash + Copy + MaybeDisplay + AtLeast32Bit + Codec + Into + TryFrom, Hash: HashT, Hash::Output: Default + sp_std::hash::Hash + Copy + Member + MaybeDisplay + SimpleBitOps + Codec, { diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index f525f91ff6..517141a210 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -68,7 +68,7 @@ pub use sp_application_crypto::{RuntimeAppPublic, BoundToRuntimeAppPublic}; pub use sp_core::RuntimeDebug; /// Re-export top-level arithmetic stuff. -pub use sp_arithmetic::{Perquintill, Perbill, Permill, Percent, Rational128, Fixed64}; +pub use sp_arithmetic::{Perquintill, Perbill, Permill, Percent, Rational128, Fixed64, PerThing}; /// Re-export 128 bit helpers. pub use sp_arithmetic::helpers_128bit; /// Re-export big_uint stuff. diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index cc71b38fe3..4cb9cb3212 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -33,7 +33,7 @@ use crate::transaction_validity::{ }; use crate::generic::{Digest, DigestItem}; pub use sp_arithmetic::traits::{ - SimpleArithmetic, UniqueSaturatedInto, UniqueSaturatedFrom, Saturating, SaturatedConversion, + AtLeast32Bit, UniqueSaturatedInto, UniqueSaturatedFrom, Saturating, SaturatedConversion, Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, CheckedShl, CheckedShr, IntegerSquareRoot }; @@ -502,7 +502,7 @@ pub trait Header: { /// Header number. type Number: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash - + Copy + MaybeDisplay + SimpleArithmetic + Codec + sp_std::str::FromStr + + Copy + MaybeDisplay + AtLeast32Bit + Codec + sp_std::str::FromStr + MaybeMallocSizeOf; /// Header hash type type Hash: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + Ord diff --git a/utils/frame/rpc/system/src/lib.rs b/utils/frame/rpc/system/src/lib.rs index d26821caf2..9cc01fb6ec 100644 --- a/utils/frame/rpc/system/src/lib.rs +++ b/utils/frame/rpc/system/src/lib.rs @@ -87,7 +87,7 @@ where P: TransactionPool + 'static, Block: traits::Block, AccountId: Clone + std::fmt::Display + Codec, - Index: Clone + std::fmt::Display + Codec + Send + traits::SimpleArithmetic + 'static, + Index: Clone + std::fmt::Display + Codec + Send + traits::AtLeast32Bit + 'static, { fn nonce(&self, account: AccountId) -> FutureResult { let get_nonce = || { @@ -141,7 +141,7 @@ where F: Fetcher + 'static, Block: traits::Block, AccountId: Clone + std::fmt::Display + Codec + Send + 'static, - Index: Clone + std::fmt::Display + Codec + Send + traits::SimpleArithmetic + 'static, + Index: Clone + std::fmt::Display + Codec + Send + traits::AtLeast32Bit + 'static, { fn nonce(&self, account: AccountId) -> FutureResult { let best_hash = self.client.info().best_hash; @@ -189,7 +189,7 @@ fn adjust_nonce( ) -> Index where P: TransactionPool, AccountId: Clone + std::fmt::Display + Encode, - Index: Clone + std::fmt::Display + Encode + traits::SimpleArithmetic + 'static, + Index: Clone + std::fmt::Display + Encode + traits::AtLeast32Bit + 'static, { log::debug!(target: "rpc", "State nonce for {}: {}", account, nonce); // Now we need to query the transaction pool -- GitLab From 0b2ae97fd54d23a323c70b32145af1d7b5cfd4d2 Mon Sep 17 00:00:00 2001 From: Sergei Pepyakin Date: Thu, 13 Feb 2020 14:54:19 +0100 Subject: [PATCH 146/180] executor: Migrate wasmtime backend to a high-level API (#4686) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Migrate wasmtime backend to wasmtime-api * Port to a newer version of wasmtime * Update to the latest changes. * Rejig the sandbox module a bit * Materialze * Fixes. * executor wasm_runtime fix * Refactor everything * More refactoring * Even more refactorings * More cleaning. * Update to the latest wasmtime * Reformat * Renames * Refactoring and comments. * Docs * Rename FunctionExecutor to host. * Imrpove docs. * fmt * Remove panic * Assert the number of arguments are equal between wasmtime and hostfunc. * Comment a possible panic if there is no corresponding value variant. * Check signature of the entrypoint. * Use git version of wasmtime * Refine and doc the sandbox code. * Comment RefCells. * Update wasmtime to the latest-ish master. This may solve a problem with segfaults. * Apply suggestions from code review Co-Authored-By: Tomasz Drwięga * Use full SHA1 hash of wasmtime commit. * Add a panic message. * Add some documentation * Update wasmtime version to include SIGSEGV fix * Update to crates.io version of wasmtime * Make it work. * Move the creation of memory into `InstanceWrapper::new` * Make `InstanceWrapper` !Send & !Sync * Avoid using `take_mut` * Update client/executor/wasmtime/Cargo.toml Co-Authored-By: Bastian Köcher * Limit maximum size of memory. * Rename `init_state` to `with_initialized_state` Co-authored-by: Tomasz Drwięga Co-authored-by: Bastian Köcher --- Cargo.lock | 158 ++++-- client/executor/common/src/wasm_runtime.rs | 6 - client/executor/src/integration_tests/mod.rs | 4 +- client/executor/src/wasm_runtime.rs | 5 +- client/executor/wasmi/src/lib.rs | 12 +- client/executor/wasmtime/Cargo.toml | 9 +- .../wasmtime/src/function_executor.rs | 379 ------------- client/executor/wasmtime/src/host.rs | 349 ++++++++++++ client/executor/wasmtime/src/imports.rs | 333 +++++++++++ .../executor/wasmtime/src/instance_wrapper.rs | 258 +++++++++ client/executor/wasmtime/src/lib.rs | 7 +- client/executor/wasmtime/src/runtime.rs | 535 +++--------------- client/executor/wasmtime/src/state_holder.rs | 77 +++ client/executor/wasmtime/src/trampoline.rs | 361 ------------ client/executor/wasmtime/src/util.rs | 105 +--- 15 files changed, 1221 insertions(+), 1377 deletions(-) delete mode 100644 client/executor/wasmtime/src/function_executor.rs create mode 100644 client/executor/wasmtime/src/host.rs create mode 100644 client/executor/wasmtime/src/imports.rs create mode 100644 client/executor/wasmtime/src/instance_wrapper.rs create mode 100644 client/executor/wasmtime/src/state_holder.rs delete mode 100644 client/executor/wasmtime/src/trampoline.rs diff --git a/Cargo.lock b/Cargo.lock index 757958f249..d3fe6848e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -723,24 +723,25 @@ checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" [[package]] name = "cranelift-bforest" -version = "0.50.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd05aac8cefcde54ce26178df8f36cb1f518ac691db650e7d2440c2b6b41c4dc" +checksum = "fd0f53d59dc9ab1c8ab68c991d8406b52b7a0aab0b15b05a3a6895579c4e5dd9" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.50.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c63d9b6ff8a94f98deabab21880d7fd54996e0e16be687b6f80a3b6bdd9c188d" +checksum = "0381a794836fb994c47006465d46d46be072483b667f36013d993b9895117fee" dependencies = [ "byteorder 1.3.4", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", "cranelift-entity", + "gimli 0.20.0", "log 0.4.8", "serde", "smallvec 1.2.0", @@ -750,9 +751,9 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.50.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cb3df51c2c07d719d02869bfac6cabd8d82ee308d5b29ca62e6528723cc33a4" +checksum = "208c3c8d82bfef32a534c5020c6cfc3bc92f41388f1246b7bb98cf543331abaa" dependencies = [ "cranelift-codegen-shared", "cranelift-entity", @@ -760,24 +761,24 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.50.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758f9426b2e22bf83fc1a6b231a9d53cd4830751883c7f0e196ebb3c210467b3" +checksum = "ea048c456a517e56fd6df8f0e3947922897e6e6f61fbc5eb557a36c7b8ff6394" [[package]] name = "cranelift-entity" -version = "0.50.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff064733df8b98f453060264a8790393d1e807aca6942706b42f79a4f7aae9ed" +checksum = "0c8c7ed50812194c9e9de1fa39c77b39fc9ab48173d5e7ee88b25b6a8953e9b8" dependencies = [ "serde", ] [[package]] name = "cranelift-frontend" -version = "0.50.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1eaafb5fa623dcbe19a28084a8226d7a1b17184a949c1a1f29a46b479867998d" +checksum = "21ceb931d9f919731df1b1ecdc716b5c66384b413a7f95909d1f45441ab9bef5" dependencies = [ "cranelift-codegen", "log 0.4.8", @@ -787,9 +788,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.50.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90033dbd7293f6fad4cf9dcd769cd621d60df22b1c5a11799e86359b7447a51d" +checksum = "564ee82268bc25b914fcf331edfc2452f2d9ca34f976b187b4ca668beba250c8" dependencies = [ "cranelift-codegen", "raw-cpuid", @@ -798,9 +799,9 @@ dependencies = [ [[package]] name = "cranelift-wasm" -version = "0.50.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54cb82a1071f88822763a583ec1a8688ffe5e2cda02c111d4483dd4376ed14d8" +checksum = "de63e2271b374be5b07f359184e2126a08fb24d24a740cbc178b7e0107ddafa5" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -808,7 +809,7 @@ dependencies = [ "log 0.4.8", "serde", "thiserror", - "wasmparser", + "wasmparser 0.48.2", ] [[package]] @@ -1289,9 +1290,9 @@ dependencies = [ [[package]] name = "faerie" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f902f2af041f6c7177a2a04f805687cdc71e69c7cbef059a2755d8923f4cd7a8" +checksum = "74b9ed6159e4a6212c61d9c6a86bee01876b192a64accecf58d5b5ae3b667b52" dependencies = [ "anyhow", "goblin", @@ -1858,6 +1859,16 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "gimli" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81dd6190aad0f05ddbbf3245c54ed14ca4aa6dd32f22312b70d8f168c3e3e633" +dependencies = [ + "byteorder 1.3.4", + "indexmap", +] + [[package]] name = "glob" version = "0.2.11" @@ -2599,6 +2610,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" +[[package]] +name = "leb128" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a" + [[package]] name = "libc" version = "0.2.66" @@ -5960,11 +5977,6 @@ name = "sc-executor-wasmtime" version = "0.8.0" dependencies = [ "assert_matches", - "cranelift-codegen", - "cranelift-entity", - "cranelift-frontend", - "cranelift-native", - "cranelift-wasm", "log 0.4.8", "parity-scale-codec", "parity-wasm 0.41.0", @@ -5974,9 +5986,7 @@ dependencies = [ "sp-runtime-interface", "sp-wasm-interface", "wasmi", - "wasmtime-environ", - "wasmtime-jit", - "wasmtime-runtime", + "wasmtime", ] [[package]] @@ -7726,9 +7736,9 @@ checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" [[package]] name = "target-lexicon" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f4c118a7a38378f305a9e111fcb2f7f838c0be324bfb31a77ea04f7f6e684b4" +checksum = "ab0e7238dcc7b40a7be719a25365910f6807bd864f4cce6b2e6b873658e2b19d" [[package]] name = "target_info" @@ -8310,7 +8320,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" dependencies = [ - "rand 0.3.23", + "rand 0.7.3", ] [[package]] @@ -8673,35 +8683,61 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.39.3" +version = "0.48.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "073da89bf1c84db000dd68ce660c1b4a08e3a2d28fd1e3394ab9e7abdde4a0f8" + +[[package]] +name = "wasmparser" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c702914acda5feeeffbc29e4d953e5b9ce79d8b98da4dbf18a77086e116c5470" +checksum = "9e41b27a1677fe28c115de49efca55dabb14f7fece2c32947ffb9b1064fe5bd4" + +[[package]] +name = "wasmtime" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5614d964c3e7d07a13b59aca66103c52656bd80430f0d86dc7eeb3af4f03d4a2" +dependencies = [ + "anyhow", + "backtrace", + "cfg-if", + "lazy_static", + "libc", + "region", + "rustc-demangle", + "target-lexicon", + "wasmparser 0.51.1", + "wasmtime-environ", + "wasmtime-jit", + "wasmtime-runtime", + "wat", + "winapi 0.3.8", +] [[package]] name = "wasmtime-debug" -version = "0.8.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5008729ad53f75020f28fa0d682269335d6f0eac0b3ffafe31f185b2f33aca74" +checksum = "feb5900275b4ef0b621ce725b9d5660b12825d7f7d79b392b97baf089ffab8c0" dependencies = [ "anyhow", - "cranelift-codegen", - "cranelift-entity", - "cranelift-wasm", "faerie", - "gimli", + "gimli 0.19.0", "more-asserts", "target-lexicon", "thiserror", - "wasmparser", + "wasmparser 0.51.1", "wasmtime-environ", ] [[package]] name = "wasmtime-environ" -version = "0.8.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3947662a0b8e05b1418465e64f16de9114f9fec18cc3f56e0ed5aa7737b89d0" +checksum = "f04661851e133fb11691c4a0f92a705766b4bbf7afc06811f949e295cc8414fc" dependencies = [ + "anyhow", "base64 0.11.0", "bincode", "cranelift-codegen", @@ -8711,37 +8747,37 @@ dependencies = [ "errno", "file-per-thread-logger", "indexmap", - "lazy_static", "libc", "log 0.4.8", "more-asserts", "rayon", "serde", "sha2", - "spin", "thiserror", "toml", - "wasmparser", + "wasmparser 0.51.1", "winapi 0.3.8", "zstd", ] [[package]] name = "wasmtime-jit" -version = "0.8.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed7922689461a7b5bd0d9c7350cac526c8a520a23b3ffd7f5b446ac51dfc51f" +checksum = "d451353764ce55c9bb6a8b260063cfc209b7adadd277a9a872ab4563a69e357c" dependencies = [ "anyhow", + "cfg-if", "cranelift-codegen", "cranelift-entity", "cranelift-frontend", + "cranelift-native", "cranelift-wasm", "more-asserts", "region", "target-lexicon", "thiserror", - "wasmparser", + "wasmparser 0.51.1", "wasmtime-debug", "wasmtime-environ", "wasmtime-runtime", @@ -8750,16 +8786,14 @@ dependencies = [ [[package]] name = "wasmtime-runtime" -version = "0.8.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "781d6bb8b346efaa3dc39746386957cd79b8d841e8652ed9b02d77bcf64fb514" +checksum = "7dbd4fc114b828cae3e405fed413df4b3814d87a92ea029640cec9ba41f0c162" dependencies = [ + "backtrace", "cc", - "cranelift-codegen", - "cranelift-entity", - "cranelift-wasm", + "cfg-if", "indexmap", - "lazy_static", "libc", "memoffset", "more-asserts", @@ -8769,6 +8803,24 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "wast" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12a729d076deb29c8509fa71f2d427729f9394f9496844ed8fcab152f35d163d" +dependencies = [ + "leb128", +] + +[[package]] +name = "wat" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5795e34a4b39893653dec97e644fac85c31398e0ce1abecc48967aac83d9e8ce" +dependencies = [ + "wast", +] + [[package]] name = "web-sys" version = "0.3.35" diff --git a/client/executor/common/src/wasm_runtime.rs b/client/executor/common/src/wasm_runtime.rs index 0733350f4c..9b0ad6b780 100644 --- a/client/executor/common/src/wasm_runtime.rs +++ b/client/executor/common/src/wasm_runtime.rs @@ -23,12 +23,6 @@ use sp_wasm_interface::Function; /// /// This can be implemented by an execution engine. pub trait WasmRuntime { - /// Attempt to update the number of heap pages available during execution. - /// - /// Returns false if the update cannot be applied. The function is guaranteed to return true if - /// the heap pages would not change from its current value. - fn update_heap_pages(&mut self, heap_pages: u64) -> bool; - /// Return the host functions that are registered for this Wasm runtime. fn host_functions(&self) -> &[&'static dyn Function]; diff --git a/client/executor/src/integration_tests/mod.rs b/client/executor/src/integration_tests/mod.rs index 3f3d9f69e1..8c48ec7fcb 100644 --- a/client/executor/src/integration_tests/mod.rs +++ b/client/executor/src/integration_tests/mod.rs @@ -88,7 +88,7 @@ fn call_not_existing_function(wasm_method: WasmExecutionMethod) { #[cfg(feature = "wasmtime")] WasmExecutionMethod::Compiled => assert_eq!( &format!("{:?}", e), - "Other(\"call to undefined external function with index 68\")" + "Other(\"Wasm execution trapped: call to a missing function env:missing_external\")" ), } } @@ -117,7 +117,7 @@ fn call_yet_another_not_existing_function(wasm_method: WasmExecutionMethod) { #[cfg(feature = "wasmtime")] WasmExecutionMethod::Compiled => assert_eq!( &format!("{:?}", e), - "Other(\"call to undefined external function with index 69\")" + "Other(\"Wasm execution trapped: call to a missing function env:yet_another_missing_external\")" ), } } diff --git a/client/executor/src/wasm_runtime.rs b/client/executor/src/wasm_runtime.rs index b8966c3af2..9d54246ee0 100644 --- a/client/executor/src/wasm_runtime.rs +++ b/client/executor/src/wasm_runtime.rs @@ -42,6 +42,8 @@ pub enum WasmExecutionMethod { /// A Wasm runtime object along with its cached runtime version. struct VersionedRuntime { runtime: Box, + /// The number of WebAssembly heap pages this instance was created with. + heap_pages: u64, /// Runtime version according to `Core_version`. version: RuntimeVersion, } @@ -122,7 +124,7 @@ impl RuntimesCache { Entry::Occupied(o) => { let result = o.into_mut(); if let Ok(ref mut cached_runtime) = result { - let heap_pages_changed = !cached_runtime.runtime.update_heap_pages(heap_pages); + let heap_pages_changed = cached_runtime.heap_pages != heap_pages; let host_functions_changed = cached_runtime.runtime.host_functions() != host_functions; if heap_pages_changed || host_functions_changed { @@ -236,6 +238,7 @@ fn create_versioned_wasm_runtime( Ok(VersionedRuntime { runtime, version, + heap_pages, }) } diff --git a/client/executor/wasmi/src/lib.rs b/client/executor/wasmi/src/lib.rs index 6fbfdbc1cc..7965c7f95e 100644 --- a/client/executor/wasmi/src/lib.rs +++ b/client/executor/wasmi/src/lib.rs @@ -73,8 +73,7 @@ impl<'a> sandbox::SandboxCapabilities for FunctionExecutor<'a> { invoke_args_len: WordSize, state: u32, func_idx: sandbox::SupervisorFuncIndex, - ) -> Result - { + ) -> Result { let result = wasmi::FuncInstance::invoke( dispatch_thunk, &[ @@ -536,7 +535,6 @@ struct StateSnapshot { data_segments: Vec<(u32, Vec)>, /// The list of all global mutable variables of the module in their sequential order. global_mut_values: Vec, - heap_pages: u64, } impl StateSnapshot { @@ -544,7 +542,6 @@ impl StateSnapshot { fn take( module_instance: &ModuleRef, data_segments: Vec, - heap_pages: u64, ) -> Option { let prepared_segments = data_segments .into_iter() @@ -590,7 +587,6 @@ impl StateSnapshot { Some(Self { data_segments: prepared_segments, global_mut_values, - heap_pages, }) } @@ -646,10 +642,6 @@ pub struct WasmiRuntime { } impl WasmRuntime for WasmiRuntime { - fn update_heap_pages(&mut self, heap_pages: u64) -> bool { - self.state_snapshot.heap_pages == heap_pages - } - fn host_functions(&self) -> &[&'static dyn Function] { &self.host_functions } @@ -702,7 +694,7 @@ pub fn create_instance( ).map_err(|e| WasmError::Instantiation(e.to_string()))?; // Take state snapshot before executing anything. - let state_snapshot = StateSnapshot::take(&instance, data_segments, heap_pages) + let state_snapshot = StateSnapshot::take(&instance, data_segments) .expect( "`take` returns `Err` if the module is not valid; we already loaded module above, thus the `Module` is proven to be valid at this point; diff --git a/client/executor/wasmtime/Cargo.toml b/client/executor/wasmtime/Cargo.toml index 30d3a5dc87..eb41adb271 100644 --- a/client/executor/wasmtime/Cargo.toml +++ b/client/executor/wasmtime/Cargo.toml @@ -16,14 +16,7 @@ sp-runtime-interface = { version = "2.0.0", path = "../../../primitives/runtime- sp-core = { version = "2.0.0", path = "../../../primitives/core" } sp-allocator = { version = "2.0.0", path = "../../../primitives/allocator" } -cranelift-codegen = "0.50" -cranelift-entity = "0.50" -cranelift-frontend = "0.50" -cranelift-native = "0.50" -cranelift-wasm = "0.50" -wasmtime-environ = "0.8" -wasmtime-jit = "0.8" -wasmtime-runtime = "0.8" +wasmtime = "0.11" [dev-dependencies] assert_matches = "1.3.0" diff --git a/client/executor/wasmtime/src/function_executor.rs b/client/executor/wasmtime/src/function_executor.rs deleted file mode 100644 index b4971f8b8a..0000000000 --- a/client/executor/wasmtime/src/function_executor.rs +++ /dev/null @@ -1,379 +0,0 @@ -// Copyright 2019-2020 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 sp_allocator::FreeingBumpHeapAllocator; -use sc_executor_common::error::{Error, Result}; -use sc_executor_common::sandbox::{self, SandboxCapabilities, SupervisorFuncIndex}; -use crate::util::{ - checked_range, cranelift_ir_signature, read_memory_into, write_memory_from, -}; - -use codec::{Decode, Encode}; -use cranelift_codegen::ir; -use cranelift_codegen::isa::TargetFrontendConfig; -use log::trace; -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 sp_wasm_interface::{ - FunctionContext, MemoryId, Pointer, Result as WResult, Sandbox, Signature, Value, ValueType, - WordSize, -}; - -/// Wrapper type for pointer to a Wasm table entry. -/// -/// The wrapper type is used to ensure that the function reference is valid as it must be unsafely -/// dereferenced from within the safe method `::invoke`. -#[derive(Clone, Copy)] -pub struct SupervisorFuncRef(*const VMCallerCheckedAnyfunc); - -/// The state required to construct a FunctionExecutor context. The context only lasts for one host -/// call, whereas the state is maintained for the duration of a Wasm runtime call, which may make -/// many different host calls that must share state. -/// -/// This is stored as part of the host state of the "env" Wasmtime instance. -pub struct FunctionExecutorState { - sandbox_store: sandbox::Store, - heap: FreeingBumpHeapAllocator, -} - -impl FunctionExecutorState { - /// Constructs a new `FunctionExecutorState`. - pub fn new(heap_base: u32) -> Self { - FunctionExecutorState { - sandbox_store: sandbox::Store::new(), - heap: FreeingBumpHeapAllocator::new(heap_base), - } - } - - /// Returns a mutable reference to the heap allocator. - pub fn heap(&mut self) -> &mut FreeingBumpHeapAllocator { - &mut self.heap - } -} - -/// A `FunctionExecutor` implements `FunctionContext` for making host calls from a Wasmtime -/// runtime. The `FunctionExecutor` exists only for the lifetime of the call and borrows state from -/// a longer-living `FunctionExecutorState`. -pub struct FunctionExecutor<'a> { - compiler: &'a mut Compiler, - sandbox_store: &'a mut sandbox::Store, - heap: &'a mut FreeingBumpHeapAllocator, - memory: &'a mut [u8], - table: Option<&'a [VMCallerCheckedAnyfunc]>, -} - -impl<'a> FunctionExecutor<'a> { - /// Construct a new `FunctionExecutor`. - /// - /// The vmctx MUST come from a call to a function in the "env" module. - /// The state MUST be looked up from the host state of the "env" module. - pub unsafe fn new( - vmctx: *mut VMContext, - compiler: &'a mut Compiler, - state: &'a mut FunctionExecutorState, - ) -> Result - { - let memory = match (*vmctx).lookup_global_export("memory") { - Some(Export::Memory { definition, vmctx: _, memory: _ }) => - std::slice::from_raw_parts_mut( - (*definition).base, - (*definition).current_length, - ), - _ => return Err(Error::InvalidMemoryReference), - }; - let table = match (*vmctx).lookup_global_export("__indirect_function_table") { - Some(Export::Table { definition, vmctx: _, table: _ }) => - Some(std::slice::from_raw_parts( - (*definition).base as *const VMCallerCheckedAnyfunc, - (*definition).current_elements as usize, - )), - _ => None, - }; - Ok(FunctionExecutor { - compiler, - sandbox_store: &mut state.sandbox_store, - heap: &mut state.heap, - memory, - table, - }) - } -} - -impl<'a> SandboxCapabilities for FunctionExecutor<'a> { - type SupervisorFuncRef = SupervisorFuncRef; - - fn invoke( - &mut self, - dispatch_thunk: &Self::SupervisorFuncRef, - invoke_args_ptr: Pointer, - invoke_args_len: WordSize, - state: u32, - func_idx: SupervisorFuncIndex, - ) -> Result - { - let func_ptr = unsafe { (*dispatch_thunk.0).func_ptr }; - let vmctx = unsafe { (*dispatch_thunk.0).vmctx }; - - // The following code is based on the wasmtime_jit::Context::invoke. - let value_size = mem::size_of::(); - let (signature, mut values_vec) = generate_signature_and_args( - &[ - Value::I32(u32::from(invoke_args_ptr) as i32), - Value::I32(invoke_args_len as i32), - Value::I32(state as i32), - Value::I32(usize::from(func_idx) as i32), - ], - Some(ValueType::I64), - self.compiler.frontend_config(), - ); - - // Get the trampoline to call for this function. - let exec_code_buf = self.compiler - .get_published_trampoline(func_ptr, &signature, value_size) - .map_err(ActionError::Setup) - .map_err(|e| Error::Other(e.to_string()))?; - - // Call the trampoline. - if let Err(message) = unsafe { - wasmtime_call_trampoline( - vmctx, - exec_code_buf, - values_vec.as_mut_ptr() as *mut u8, - ) - } { - return Err(Error::Other(message)); - } - - // Load the return value out of `values_vec`. - Ok(unsafe { ptr::read(values_vec.as_ptr() as *const i64) }) - } -} - -impl<'a> FunctionContext for FunctionExecutor<'a> { - fn read_memory_into(&self, address: Pointer, dest: &mut [u8]) -> WResult<()> { - read_memory_into(self.memory, address, dest).map_err(|e| e.to_string()) - } - - fn write_memory(&mut self, address: Pointer, data: &[u8]) -> WResult<()> { - write_memory_from(self.memory, address, data).map_err(|e| e.to_string()) - } - - fn allocate_memory(&mut self, size: WordSize) -> WResult> { - self.heap.allocate(self.memory, size).map_err(|e| e.to_string()) - } - - fn deallocate_memory(&mut self, ptr: Pointer) -> WResult<()> { - self.heap.deallocate(self.memory, ptr).map_err(|e| e.to_string()) - } - - fn sandbox(&mut self) -> &mut dyn Sandbox { - self - } -} - -impl<'a> Sandbox for FunctionExecutor<'a> { - fn memory_get( - &mut self, - memory_id: MemoryId, - offset: WordSize, - buf_ptr: Pointer, - buf_len: WordSize, - ) -> WResult - { - let sandboxed_memory = self.sandbox_store.memory(memory_id) - .map_err(|e| e.to_string())?; - sandboxed_memory.with_direct_access(|memory| { - let len = buf_len as usize; - let src_range = match checked_range(offset as usize, len, memory.len()) { - Some(range) => range, - None => return Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), - }; - let dst_range = match checked_range(buf_ptr.into(), len, self.memory.len()) { - Some(range) => range, - None => return Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), - }; - &mut self.memory[dst_range].copy_from_slice(&memory[src_range]); - Ok(sandbox_primitives::ERR_OK) - }) - } - - fn memory_set( - &mut self, - memory_id: MemoryId, - offset: WordSize, - val_ptr: Pointer, - val_len: WordSize, - ) -> WResult - { - let sandboxed_memory = self.sandbox_store.memory(memory_id) - .map_err(|e| e.to_string())?; - sandboxed_memory.with_direct_access_mut(|memory| { - let len = val_len as usize; - let src_range = match checked_range(val_ptr.into(), len, self.memory.len()) { - Some(range) => range, - None => return Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), - }; - let dst_range = match checked_range(offset as usize, len, memory.len()) { - Some(range) => range, - None => return Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), - }; - &mut memory[dst_range].copy_from_slice(&self.memory[src_range]); - Ok(sandbox_primitives::ERR_OK) - }) - } - - fn memory_teardown(&mut self, memory_id: MemoryId) - -> WResult<()> - { - self.sandbox_store.memory_teardown(memory_id).map_err(|e| e.to_string()) - } - - fn memory_new(&mut self, initial: u32, maximum: MemoryId) -> WResult { - self.sandbox_store.new_memory(initial, maximum).map_err(|e| e.to_string()) - } - - fn invoke( - &mut self, - instance_id: u32, - export_name: &str, - args: &[u8], - return_val: Pointer, - return_val_len: u32, - state: u32, - ) -> WResult { - trace!(target: "sp-sandbox", "invoke, instance_idx={}", instance_id); - - // Deserialize arguments and convert them into wasmi types. - let args = Vec::::decode(&mut &args[..]) - .map_err(|_| "Can't decode serialized arguments for the invocation")? - .into_iter() - .map(Into::into) - .collect::>(); - - let instance = self.sandbox_store.instance(instance_id).map_err(|e| e.to_string())?; - let result = instance.invoke(export_name, &args, self, state); - - match result { - Ok(None) => Ok(sandbox_primitives::ERR_OK), - Ok(Some(val)) => { - // Serialize return value and write it back into the memory. - sp_wasm_interface::ReturnValue::Value(val.into()).using_encoded(|val| { - if val.len() > return_val_len as usize { - Err("Return value buffer is too small")?; - } - FunctionContext::write_memory(self, return_val, val)?; - Ok(sandbox_primitives::ERR_OK) - }) - } - Err(_) => Ok(sandbox_primitives::ERR_EXECUTION), - } - } - - fn instance_teardown(&mut self, instance_id: u32) -> WResult<()> { - self.sandbox_store.instance_teardown(instance_id).map_err(|e| e.to_string()) - } - - fn instance_new(&mut self, dispatch_thunk_id: u32, wasm: &[u8], raw_env_def: &[u8], state: u32) - -> WResult - { - // Extract a dispatch thunk from instance's table by the specified index. - let dispatch_thunk = { - let table = self.table.as_ref() - .ok_or_else(|| "Runtime doesn't have a table; sandbox is unavailable")?; - let func_ref = table.get(dispatch_thunk_id as usize) - .ok_or_else(|| "dispatch_thunk_idx is out of the table bounds")?; - SupervisorFuncRef(func_ref) - }; - - let guest_env = match sandbox::GuestEnvironment::decode(&self.sandbox_store, raw_env_def) { - Ok(guest_env) => guest_env, - Err(_) => return Ok(sandbox_primitives::ERR_MODULE as u32), - }; - - let instance_idx_or_err_code = - match sandbox::instantiate(self, dispatch_thunk, wasm, guest_env, state) - .map(|i| i.register(&mut self.sandbox_store)) - { - Ok(instance_idx) => instance_idx, - Err(sandbox::InstantiationError::StartTrapped) => - sandbox_primitives::ERR_EXECUTION, - Err(_) => sandbox_primitives::ERR_MODULE, - }; - - Ok(instance_idx_or_err_code as u32) - } - - fn get_global_val( - &self, - instance_idx: u32, - name: &str, - ) -> WResult> { - self.sandbox_store - .instance(instance_idx) - .map(|i| i.get_global_val(name)) - .map_err(|e| e.to_string()) - } -} - -// The storage for a Wasmtime invocation argument. -#[derive(Debug, Default, Copy, Clone)] -#[repr(C, align(8))] -struct VMInvokeArgument([u8; 8]); - -fn generate_signature_and_args( - args: &[Value], - result_type: Option, - frontend_config: TargetFrontendConfig, -) -> (ir::Signature, Vec) -{ - // This code is based on the wasmtime_jit::Context::invoke. - - let param_types = args.iter() - .map(|arg| arg.value_type()) - .collect::>(); - let signature = translate_signature( - cranelift_ir_signature( - Signature::new(param_types, result_type), - &frontend_config.default_call_conv - ), - frontend_config.pointer_type() - ); - - let mut values_vec = vec![ - VMInvokeArgument::default(); - cmp::max(args.len(), result_type.iter().len()) - ]; - - // Store the argument values into `values_vec`. - for (index, arg) in args.iter().enumerate() { - unsafe { - let ptr = values_vec.as_mut_ptr().add(index); - - match arg { - Value::I32(x) => ptr::write(ptr as *mut i32, *x), - Value::I64(x) => ptr::write(ptr as *mut i64, *x), - Value::F32(x) => ptr::write(ptr as *mut u32, *x), - Value::F64(x) => ptr::write(ptr as *mut u64, *x), - } - } - } - - (signature, values_vec) -} - diff --git a/client/executor/wasmtime/src/host.rs b/client/executor/wasmtime/src/host.rs new file mode 100644 index 0000000000..e0cc6ecc9a --- /dev/null +++ b/client/executor/wasmtime/src/host.rs @@ -0,0 +1,349 @@ +// Copyright 2019-2020 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 . + +//! This module defines `HostState` and `HostContext` structs which provide logic and state +//! required for execution of host. + +use crate::instance_wrapper::InstanceWrapper; +use crate::util; +use std::cell::RefCell; +use log::trace; +use codec::{Encode, Decode}; +use sp_allocator::FreeingBumpHeapAllocator; +use sc_executor_common::error::Result; +use sc_executor_common::sandbox::{self, SandboxCapabilities, SupervisorFuncIndex}; +use sp_core::sandbox as sandbox_primitives; +use sp_wasm_interface::{FunctionContext, MemoryId, Pointer, Sandbox, WordSize}; +use wasmtime::{Func, Val}; + +/// Wrapper type for pointer to a Wasm table entry. +/// +/// The wrapper type is used to ensure that the function reference is valid as it must be unsafely +/// dereferenced from within the safe method `::invoke`. +#[derive(Clone)] +pub struct SupervisorFuncRef(Func); + +/// The state required to construct a HostContext context. The context only lasts for one host +/// call, whereas the state is maintained for the duration of a Wasm runtime call, which may make +/// many different host calls that must share state. +pub struct HostState { + // We need some interior mutability here since the host state is shared between all host + // function handlers and the wasmtime backend's `impl WasmRuntime`. + // + // Furthermore, because of recursive calls (e.g. runtime can create and call an sandboxed + // instance which in turn can call the runtime back) we have to be very careful with borrowing + // those. + // + // Basically, most of the interactions should do temporary borrow immediately releasing the + // borrow after performing necessary queries/changes. + sandbox_store: RefCell>, + allocator: RefCell, + instance: InstanceWrapper, +} + +impl HostState { + /// Constructs a new `HostState`. + pub fn new(allocator: FreeingBumpHeapAllocator, instance: InstanceWrapper) -> Self { + HostState { + sandbox_store: RefCell::new(sandbox::Store::new()), + allocator: RefCell::new(allocator), + instance, + } + } + + /// Destruct the host state and extract the `InstanceWrapper` passed at the creation. + pub fn into_instance(self) -> InstanceWrapper { + self.instance + } + + /// Materialize `HostContext` that can be used to invoke a substrate host `dyn Function`. + pub fn materialize<'a>(&'a self) -> HostContext<'a> { + HostContext(self) + } +} + +/// A `HostContext` implements `FunctionContext` for making host calls from a Wasmtime +/// runtime. The `HostContext` exists only for the lifetime of the call and borrows state from +/// a longer-living `HostState`. +pub struct HostContext<'a>(&'a HostState); + +impl<'a> std::ops::Deref for HostContext<'a> { + type Target = HostState; + fn deref(&self) -> &HostState { + self.0 + } +} + +impl<'a> SandboxCapabilities for HostContext<'a> { + type SupervisorFuncRef = SupervisorFuncRef; + + fn invoke( + &mut self, + dispatch_thunk: &Self::SupervisorFuncRef, + invoke_args_ptr: Pointer, + invoke_args_len: WordSize, + state: u32, + func_idx: SupervisorFuncIndex, + ) -> Result { + let result = dispatch_thunk.0.call(&[ + Val::I32(u32::from(invoke_args_ptr) as i32), + Val::I32(invoke_args_len as i32), + Val::I32(state as i32), + Val::I32(usize::from(func_idx) as i32), + ]); + match result { + Ok(ret_vals) => { + let ret_val = if ret_vals.len() != 1 { + return Err(format!( + "Supervisor function returned {} results, expected 1", + ret_vals.len() + ) + .into()); + } else { + &ret_vals[0] + }; + + if let Some(ret_val) = ret_val.i64() { + Ok(ret_val) + } else { + return Err("Supervisor function returned unexpected result!".into()); + } + } + Err(err) => Err(err.message().to_string().into()), + } + } +} + +impl<'a> sp_wasm_interface::FunctionContext for HostContext<'a> { + fn read_memory_into( + &self, + address: Pointer, + dest: &mut [u8], + ) -> sp_wasm_interface::Result<()> { + self.instance + .read_memory_into(address, dest) + .map_err(|e| e.to_string()) + } + + fn write_memory(&mut self, address: Pointer, data: &[u8]) -> sp_wasm_interface::Result<()> { + self.instance + .write_memory_from(address, data) + .map_err(|e| e.to_string()) + } + + fn allocate_memory(&mut self, size: WordSize) -> sp_wasm_interface::Result> { + self.instance + .allocate(&mut *self.allocator.borrow_mut(), size) + .map_err(|e| e.to_string()) + } + + fn deallocate_memory(&mut self, ptr: Pointer) -> sp_wasm_interface::Result<()> { + self.instance + .deallocate(&mut *self.allocator.borrow_mut(), ptr) + .map_err(|e| e.to_string()) + } + + fn sandbox(&mut self) -> &mut dyn Sandbox { + self + } +} + +impl<'a> Sandbox for HostContext<'a> { + fn memory_get( + &mut self, + memory_id: MemoryId, + offset: WordSize, + buf_ptr: Pointer, + buf_len: WordSize, + ) -> sp_wasm_interface::Result { + let sandboxed_memory = self + .sandbox_store + .borrow() + .memory(memory_id) + .map_err(|e| e.to_string())?; + sandboxed_memory.with_direct_access(|sandboxed_memory| { + let len = buf_len as usize; + let src_range = match util::checked_range(offset as usize, len, sandboxed_memory.len()) + { + Some(range) => range, + None => return Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), + }; + let supervisor_mem_size = self.instance.memory_size() as usize; + let dst_range = match util::checked_range(buf_ptr.into(), len, supervisor_mem_size) { + Some(range) => range, + None => return Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), + }; + self.instance + .write_memory_from( + Pointer::new(dst_range.start as u32), + &sandboxed_memory[src_range], + ) + .expect("ranges are checked above; write can't fail; qed"); + Ok(sandbox_primitives::ERR_OK) + }) + } + + fn memory_set( + &mut self, + memory_id: MemoryId, + offset: WordSize, + val_ptr: Pointer, + val_len: WordSize, + ) -> sp_wasm_interface::Result { + let sandboxed_memory = self + .sandbox_store + .borrow() + .memory(memory_id) + .map_err(|e| e.to_string())?; + sandboxed_memory.with_direct_access_mut(|sandboxed_memory| { + let len = val_len as usize; + let supervisor_mem_size = self.instance.memory_size() as usize; + let src_range = match util::checked_range(val_ptr.into(), len, supervisor_mem_size) { + Some(range) => range, + None => return Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), + }; + let dst_range = match util::checked_range(offset as usize, len, sandboxed_memory.len()) + { + Some(range) => range, + None => return Ok(sandbox_primitives::ERR_OUT_OF_BOUNDS), + }; + self.instance + .read_memory_into( + Pointer::new(src_range.start as u32), + &mut sandboxed_memory[dst_range], + ) + .expect("ranges are checked above; read can't fail; qed"); + Ok(sandbox_primitives::ERR_OK) + }) + } + + fn memory_teardown(&mut self, memory_id: MemoryId) -> sp_wasm_interface::Result<()> { + self.sandbox_store + .borrow_mut() + .memory_teardown(memory_id) + .map_err(|e| e.to_string()) + } + + fn memory_new(&mut self, initial: u32, maximum: MemoryId) -> sp_wasm_interface::Result { + self.sandbox_store + .borrow_mut() + .new_memory(initial, maximum) + .map_err(|e| e.to_string()) + } + + fn invoke( + &mut self, + instance_id: u32, + export_name: &str, + args: &[u8], + return_val: Pointer, + return_val_len: u32, + state: u32, + ) -> sp_wasm_interface::Result { + trace!(target: "sp-sandbox", "invoke, instance_idx={}", instance_id); + + // Deserialize arguments and convert them into wasmi types. + let args = Vec::::decode(&mut &args[..]) + .map_err(|_| "Can't decode serialized arguments for the invocation")? + .into_iter() + .map(Into::into) + .collect::>(); + + let instance = self + .sandbox_store + .borrow() + .instance(instance_id) + .map_err(|e| e.to_string())?; + let result = instance.invoke(export_name, &args, self, state); + + match result { + Ok(None) => Ok(sandbox_primitives::ERR_OK), + Ok(Some(val)) => { + // Serialize return value and write it back into the memory. + sp_wasm_interface::ReturnValue::Value(val.into()).using_encoded(|val| { + if val.len() > return_val_len as usize { + Err("Return value buffer is too small")?; + } + ::write_memory(self, return_val, val) + .map_err(|_| "can't write return value")?; + Ok(sandbox_primitives::ERR_OK) + }) + } + Err(_) => Ok(sandbox_primitives::ERR_EXECUTION), + } + } + + fn instance_teardown(&mut self, instance_id: u32) -> sp_wasm_interface::Result<()> { + self.sandbox_store + .borrow_mut() + .instance_teardown(instance_id) + .map_err(|e| e.to_string()) + } + + fn instance_new( + &mut self, + dispatch_thunk_id: u32, + wasm: &[u8], + raw_env_def: &[u8], + state: u32, + ) -> sp_wasm_interface::Result { + // Extract a dispatch thunk from the instance's table by the specified index. + let dispatch_thunk = { + let table_item = self + .instance + .table() + .as_ref() + .ok_or_else(|| "Runtime doesn't have a table; sandbox is unavailable")? + .get(dispatch_thunk_id); + + let func_ref = table_item + .ok_or_else(|| "dispatch_thunk_id is out of bounds")? + .funcref() + .ok_or_else(|| "dispatch_thunk_idx should be a funcref")? + .clone(); + SupervisorFuncRef(func_ref) + }; + + let guest_env = + match sandbox::GuestEnvironment::decode(&*self.sandbox_store.borrow(), raw_env_def) { + Ok(guest_env) => guest_env, + Err(_) => return Ok(sandbox_primitives::ERR_MODULE as u32), + }; + + let instance_idx_or_err_code = + match sandbox::instantiate(self, dispatch_thunk, wasm, guest_env, state) + .map(|i| i.register(&mut *self.sandbox_store.borrow_mut())) + { + Ok(instance_idx) => instance_idx, + Err(sandbox::InstantiationError::StartTrapped) => sandbox_primitives::ERR_EXECUTION, + Err(_) => sandbox_primitives::ERR_MODULE, + }; + + Ok(instance_idx_or_err_code as u32) + } + + fn get_global_val( + &self, + instance_idx: u32, + name: &str, + ) -> sp_wasm_interface::Result> { + self.sandbox_store + .borrow() + .instance(instance_idx) + .map(|i| i.get_global_val(name)) + .map_err(|e| e.to_string()) + } +} diff --git a/client/executor/wasmtime/src/imports.rs b/client/executor/wasmtime/src/imports.rs new file mode 100644 index 0000000000..349f84a0d7 --- /dev/null +++ b/client/executor/wasmtime/src/imports.rs @@ -0,0 +1,333 @@ +// Copyright 2020 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::state_holder::StateHolder; +use sc_executor_common::error::WasmError; +use sp_wasm_interface::{Function, Value, ValueType}; +use std::any::Any; +use std::rc::Rc; +use wasmtime::{ + Callable, Extern, ExternType, Func, FuncType, ImportType, Limits, Memory, MemoryType, Module, + Trap, Val, +}; + +pub struct Imports { + /// Contains the index into `externs` where the memory import is stored if any. `None` if there + /// is none. + pub memory_import_index: Option, + pub externs: Vec, +} + +/// Goes over all imports of a module and prepares a vector of `Extern`s that can be used for +/// instantiation of the module. Returns an error if there are imports that cannot be satisfied. +pub fn resolve_imports( + state_holder: &StateHolder, + module: &Module, + host_functions: &[&'static dyn Function], + heap_pages: u32, + allow_missing_func_imports: bool, +) -> Result { + let mut externs = vec![]; + let mut memory_import_index = None; + for import_ty in module.imports() { + if import_ty.module() != "env" { + return Err(WasmError::Other(format!( + "host doesn't provide any imports from non-env module: {}:{}", + import_ty.module(), + import_ty.name() + ))); + } + + let resolved = match import_ty.name() { + "memory" => { + memory_import_index = Some(externs.len()); + resolve_memory_import(module, import_ty, heap_pages)? + } + _ => resolve_func_import( + module, + state_holder, + import_ty, + host_functions, + allow_missing_func_imports, + )?, + }; + externs.push(resolved); + } + Ok(Imports { + memory_import_index, + externs, + }) +} + +fn resolve_memory_import( + module: &Module, + import_ty: &ImportType, + heap_pages: u32, +) -> Result { + let requested_memory_ty = match import_ty.ty() { + ExternType::Memory(memory_ty) => memory_ty, + _ => { + return Err(WasmError::Other(format!( + "this import must be of memory type: {}:{}", + import_ty.module(), + import_ty.name() + ))) + } + }; + + // Increment the min (a.k.a initial) number of pages by `heap_pages` and check if it exceeds the + // maximum specified by the import. + let initial = requested_memory_ty + .limits() + .min() + .saturating_add(heap_pages); + if let Some(max) = requested_memory_ty.limits().max() { + if initial > max { + return Err(WasmError::Other(format!( + "incremented number of pages by heap_pages (total={}) is more than maximum requested\ + by the runtime wasm module {}", + initial, + max, + ))); + } + } + + let memory_ty = MemoryType::new(Limits::new(initial, requested_memory_ty.limits().max())); + let memory = Memory::new(module.store(), memory_ty); + Ok(Extern::Memory(memory)) +} + +fn resolve_func_import( + module: &Module, + state_holder: &StateHolder, + import_ty: &ImportType, + host_functions: &[&'static dyn Function], + allow_missing_func_imports: bool, +) -> Result { + let func_ty = match import_ty.ty() { + ExternType::Func(func_ty) => func_ty, + _ => { + return Err(WasmError::Other(format!( + "host doesn't provide any non function imports besides 'memory': {}:{}", + import_ty.module(), + import_ty.name() + ))); + } + }; + + let host_func = match host_functions + .iter() + .find(|host_func| host_func.name() == import_ty.name()) + { + Some(host_func) => host_func, + None if allow_missing_func_imports => { + return Ok(MissingHostFuncHandler::new(import_ty).into_extern(module, func_ty)); + } + None => { + return Err(WasmError::Other(format!( + "host doesn't provide such function: {}:{}", + import_ty.module(), + import_ty.name() + ))); + } + }; + if !signature_matches(&func_ty, &wasmtime_func_sig(*host_func)) { + return Err(WasmError::Other(format!( + "signature mismatch for: {}:{}", + import_ty.module(), + import_ty.name() + ))); + } + + Ok(HostFuncHandler::new(&state_holder, *host_func).into_extern(module)) +} + +/// Returns `true` if `lhs` and `rhs` represent the same signature. +fn signature_matches(lhs: &wasmtime::FuncType, rhs: &wasmtime::FuncType) -> bool { + lhs.params() == rhs.params() && lhs.results() == rhs.results() +} + +/// This structure implements `Callable` and acts as a bridge between wasmtime and +/// substrate host functions. +struct HostFuncHandler { + state_holder: StateHolder, + host_func: &'static dyn Function, +} + +impl HostFuncHandler { + fn new(state_holder: &StateHolder, host_func: &'static dyn Function) -> Self { + Self { + state_holder: state_holder.clone(), + host_func, + } + } + + fn into_extern(self, module: &Module) -> Extern { + let func_ty = wasmtime_func_sig(self.host_func); + let func = Func::new(module.store(), func_ty, Rc::new(self)); + Extern::Func(func) + } +} + +impl Callable for HostFuncHandler { + fn call( + &self, + wasmtime_params: &[Val], + wasmtime_results: &mut [Val], + ) -> Result<(), wasmtime::Trap> { + let unwind_result = self.state_holder.with_context(|host_ctx| { + let mut host_ctx = host_ctx.expect( + "host functions can be called only from wasm instance; + wasm instance is always called initializing context; + therefore host_ctx cannot be None; + qed + ", + ); + // `into_value` panics if it encounters a value that doesn't fit into the values + // available in substrate. + // + // This, however, cannot happen since the signature of this function is created from + // a `dyn Function` signature of which cannot have a non substrate value by definition. + let mut params = wasmtime_params.iter().cloned().map(into_value); + + std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + self.host_func.execute(&mut host_ctx, &mut params) + })) + }); + + let execution_result = match unwind_result { + Ok(execution_result) => execution_result, + Err(err) => return Err(Trap::new(stringify_panic_payload(err))), + }; + + match execution_result { + Ok(Some(ret_val)) => { + debug_assert!( + wasmtime_results.len() == 1, + "wasmtime function signature, therefore the number of results, should always \ + correspond to the number of results returned by the host function", + ); + wasmtime_results[0] = into_wasmtime_val(ret_val); + Ok(()) + } + Ok(None) => { + debug_assert!( + wasmtime_results.len() == 0, + "wasmtime function signature, therefore the number of results, should always \ + correspond to the number of results returned by the host function", + ); + Ok(()) + } + Err(msg) => Err(Trap::new(msg)), + } + } +} + +/// A `Callable` handler for missing functions. +struct MissingHostFuncHandler { + module: String, + name: String, +} + +impl MissingHostFuncHandler { + fn new(import_ty: &ImportType) -> Self { + Self { + module: import_ty.module().to_string(), + name: import_ty.name().to_string(), + } + } + + fn into_extern(self, module: &Module, func_ty: &FuncType) -> Extern { + let func = Func::new(module.store(), func_ty.clone(), Rc::new(self)); + Extern::Func(func) + } +} + +impl Callable for MissingHostFuncHandler { + fn call( + &self, + _wasmtime_params: &[Val], + _wasmtime_results: &mut [Val], + ) -> Result<(), wasmtime::Trap> { + Err(Trap::new(format!( + "call to a missing function {}:{}", + self.module, self.name + ))) + } +} + +fn wasmtime_func_sig(func: &dyn Function) -> wasmtime::FuncType { + let params = func + .signature() + .args + .iter() + .cloned() + .map(into_wasmtime_val_type) + .collect::>() + .into_boxed_slice(); + let results = func + .signature() + .return_value + .iter() + .cloned() + .map(into_wasmtime_val_type) + .collect::>() + .into_boxed_slice(); + wasmtime::FuncType::new(params, results) +} + +fn into_wasmtime_val_type(val_ty: ValueType) -> wasmtime::ValType { + match val_ty { + ValueType::I32 => wasmtime::ValType::I32, + ValueType::I64 => wasmtime::ValType::I64, + ValueType::F32 => wasmtime::ValType::F32, + ValueType::F64 => wasmtime::ValType::F64, + } +} + +/// Converts a `Val` into a substrate runtime interface `Value`. +/// +/// Panics if the given value doesn't have a corresponding variant in `Value`. +fn into_value(val: Val) -> Value { + match val { + Val::I32(v) => Value::I32(v), + Val::I64(v) => Value::I64(v), + Val::F32(f_bits) => Value::F32(f_bits), + Val::F64(f_bits) => Value::F64(f_bits), + _ => panic!("Given value type is unsupported by substrate"), + } +} + +fn into_wasmtime_val(value: Value) -> wasmtime::Val { + match value { + Value::I32(v) => Val::I32(v), + Value::I64(v) => Val::I64(v), + Value::F32(f_bits) => Val::F32(f_bits), + Value::F64(f_bits) => Val::F64(f_bits), + } +} + +/// Attempt to convert a opaque panic payload to a string. +fn stringify_panic_payload(payload: Box) -> String { + match payload.downcast::<&'static str>() { + Ok(msg) => msg.to_string(), + Err(payload) => match payload.downcast::() { + Ok(msg) => *msg, + // At least we tried... + Err(_) => "Box".to_string(), + }, + } +} diff --git a/client/executor/wasmtime/src/instance_wrapper.rs b/client/executor/wasmtime/src/instance_wrapper.rs new file mode 100644 index 0000000000..8f722f6490 --- /dev/null +++ b/client/executor/wasmtime/src/instance_wrapper.rs @@ -0,0 +1,258 @@ +// Copyright 2020 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 . + +//! Defines data and logic needed for interaction with an WebAssembly instance of a substrate +//! runtime module. + +use crate::util; +use crate::imports::Imports; + +use sc_executor_common::error::{Error, Result}; +use sp_wasm_interface::{Pointer, WordSize}; +use std::slice; +use std::marker; +use wasmtime::{Instance, Module, Memory, Table}; + +/// Wrap the given WebAssembly Instance of a wasm module with Substrate-runtime. +/// +/// This struct is a handy wrapper around a wasmtime `Instance` that provides substrate specific +/// routines. +pub struct InstanceWrapper { + instance: Instance, + // The memory instance of the `intance`. + // + // It is important to make sure that we don't make any copies of this to make it easier to proof + // See `memory_as_slice` and `memory_as_slice_mut`. + memory: Memory, + table: Option, + // Make this struct explicitly !Send & !Sync. + _not_send_nor_sync: marker::PhantomData<*const ()>, +} + +impl InstanceWrapper { + /// Create a new instance wrapper from the given wasm module. + pub fn new(module: &Module, imports: &Imports, heap_pages: u32) -> Result { + let instance = Instance::new(module, &imports.externs) + .map_err(|e| Error::from(format!("cannot instantiate: {}", e)))?; + + let memory = match imports.memory_import_index { + Some(memory_idx) => { + imports.externs[memory_idx] + .memory() + .expect("only memory can be at the `memory_idx`; qed") + .clone() + } + None => { + let memory = get_linear_memory(&instance)?; + if !memory.grow(heap_pages).is_ok() { + return Err("failed top increase the linear memory size".into()); + } + memory + }, + }; + + Ok(Self { + table: get_table(&instance), + memory, + instance, + _not_send_nor_sync: marker::PhantomData, + }) + } + + /// Resolves a substrate entrypoint by the given name. + /// + /// An entrypoint must have a signature `(i32, i32) -> i64`, otherwise this function will return + /// an error. + pub fn resolve_entrypoint(&self, name: &str) -> Result { + // Resolve the requested method and verify that it has a proper signature. + let export = self + .instance + .get_export(name) + .ok_or_else(|| Error::from(format!("Exported method {} is not found", name)))?; + let entrypoint = export + .func() + .ok_or_else(|| Error::from(format!("Export {} is not a function", name)))?; + match (entrypoint.ty().params(), entrypoint.ty().results()) { + (&[wasmtime::ValType::I32, wasmtime::ValType::I32], &[wasmtime::ValType::I64]) => {} + _ => { + return Err(Error::from(format!( + "method {} have an unsupported signature", + name + ))) + } + } + Ok(entrypoint.clone()) + } + + /// Returns an indirect function table of this instance. + pub fn table(&self) -> Option<&Table> { + self.table.as_ref() + } + + /// Returns the byte size of the linear memory instance attached to this instance. + pub fn memory_size(&self) -> u32 { + self.memory.data_size() as u32 + } + + /// Reads `__heap_base: i32` global variable and returns it. + /// + /// If it doesn't exist, not a global or of not i32 type returns an error. + pub fn extract_heap_base(&self) -> Result { + let heap_base_export = self + .instance + .get_export("__heap_base") + .ok_or_else(|| Error::from("__heap_base is not found"))?; + + let heap_base_global = heap_base_export + .global() + .ok_or_else(|| Error::from("__heap_base is not a global"))?; + + let heap_base = heap_base_global + .get() + .i32() + .ok_or_else(|| Error::from("__heap_base is not a i32"))?; + + Ok(heap_base as u32) + } +} + +/// Extract linear memory instance from the given instance. +fn get_linear_memory(instance: &Instance) -> Result { + let memory_export = instance + .get_export("memory") + .ok_or_else(|| Error::from("memory is not exported under `memory` name"))?; + + let memory = memory_export + .memory() + .ok_or_else(|| Error::from("the `memory` export should have memory type"))? + .clone(); + + Ok(memory) +} + +/// Extract the table from the given instance if any. +fn get_table(instance: &Instance) -> Option
{ + instance + .get_export("__indirect_function_table") + .and_then(|export| export.table()) + .cloned() +} + +/// Functions realted to memory. +impl InstanceWrapper { + /// Read data from a slice of memory into a destination buffer. + /// + /// Returns an error if the read would go out of the memory bounds. + pub fn read_memory_into(&self, address: Pointer, dest: &mut [u8]) -> Result<()> { + unsafe { + // This should be safe since we don't grow up memory while caching this reference and + // we give up the reference before returning from this function. + let memory = self.memory_as_slice(); + + let range = util::checked_range(address.into(), dest.len(), memory.len()) + .ok_or_else(|| Error::Other("memory read is out of bounds".into()))?; + dest.copy_from_slice(&memory[range]); + Ok(()) + } + } + + /// Write data to a slice of memory. + /// + /// Returns an error if the write would go out of the memory bounds. + pub fn write_memory_from(&self, address: Pointer, data: &[u8]) -> Result<()> { + unsafe { + // This should be safe since we don't grow up memory while caching this reference and + // we give up the reference before returning from this function. + let memory = self.memory_as_slice_mut(); + + let range = util::checked_range(address.into(), data.len(), memory.len()) + .ok_or_else(|| Error::Other("memory write is out of bounds".into()))?; + &mut memory[range].copy_from_slice(data); + Ok(()) + } + } + + /// Allocate some memory of the given size. Returns pointer to the allocated memory region. + /// + /// Returns `Err` in case memory cannot be allocated. Refer to the allocator documentation + /// to get more details. + pub fn allocate( + &self, + allocator: &mut sp_allocator::FreeingBumpHeapAllocator, + size: WordSize, + ) -> Result> { + unsafe { + // This should be safe since we don't grow up memory while caching this reference and + // we give up the reference before returning from this function. + let memory = self.memory_as_slice_mut(); + + allocator.allocate(memory, size).map_err(Into::into) + } + } + + /// Deallocate the memory pointed by the given pointer. + /// + /// Returns `Err` in case the given memory region cannot be deallocated. + pub fn deallocate( + &self, + allocator: &mut sp_allocator::FreeingBumpHeapAllocator, + ptr: Pointer, + ) -> Result<()> { + unsafe { + // This should be safe since we don't grow up memory while caching this reference and + // we give up the reference before returning from this function. + let memory = self.memory_as_slice_mut(); + + allocator.deallocate(memory, ptr).map_err(Into::into) + } + } + + /// Returns linear memory of the wasm instance as a slice. + /// + /// # Safety + /// + /// Wasmtime doesn't provide comprehensive documentation about the exact behavior of the data + /// pointer. If a dynamic style heap is used the base pointer of the heap can change. Since + /// growing, we cannot guarantee the lifetime of the returned slice reference. + unsafe fn memory_as_slice(&self) -> &[u8] { + let ptr = self.memory.data_ptr() as *const _; + let len = self.memory.data_size(); + + if len == 0 { + &[] + } else { + slice::from_raw_parts(ptr, len) + } + } + + /// Returns linear memory of the wasm instance as a slice. + /// + /// # Safety + /// + /// See `[memory_as_slice]`. In addition to those requirements, since a mutable reference is + /// returned it must be ensured that only one mutable and no shared references to memory exists + /// at the same time. + unsafe fn memory_as_slice_mut(&self) -> &mut [u8] { + let ptr = self.memory.data_ptr(); + let len = self.memory.data_size(); + + if len == 0 { + &mut [] + } else { + slice::from_raw_parts_mut(ptr, len) + } + } +} diff --git a/client/executor/wasmtime/src/lib.rs b/client/executor/wasmtime/src/lib.rs index 244fca8f84..8f4801e6da 100644 --- a/client/executor/wasmtime/src/lib.rs +++ b/client/executor/wasmtime/src/lib.rs @@ -16,10 +16,11 @@ ///! Defines a `WasmRuntime` that uses the Wasmtime JIT to execute. -mod function_executor; +mod host; mod runtime; -mod trampoline; +mod state_holder; +mod imports; +mod instance_wrapper; mod util; pub use runtime::create_instance; - diff --git a/client/executor/wasmtime/src/runtime.rs b/client/executor/wasmtime/src/runtime.rs index abf860667f..106a398dfc 100644 --- a/client/executor/wasmtime/src/runtime.rs +++ b/client/executor/wasmtime/src/runtime.rs @@ -16,67 +16,42 @@ //! Defines the compiled Wasm runtime that uses Wasmtime internally. -use crate::function_executor::FunctionExecutorState; -use crate::trampoline::{EnvState, make_trampoline}; -use crate::util::{ - cranelift_ir_signature, - convert_parity_wasm_signature, - read_memory_into, - write_memory_from -}; +use crate::host::HostState; +use crate::imports::{resolve_imports, Imports}; +use crate::instance_wrapper::InstanceWrapper; +use crate::state_holder::StateHolder; use sc_executor_common::{ error::{Error, Result, WasmError}, wasm_runtime::WasmRuntime, }; -use sp_wasm_interface::{Pointer, WordSize, Function}; +use sp_allocator::FreeingBumpHeapAllocator; use sp_runtime_interface::unpack_ptr_and_len; +use sp_wasm_interface::{Function, Pointer, WordSize}; +use wasmtime::{Config, Engine, Module, Store}; -use std::{cell::RefCell, collections::HashMap, convert::TryFrom, rc::Rc}; - -use cranelift_codegen::ir; -use cranelift_codegen::isa::TargetIsa; -use cranelift_entity::{EntityRef, PrimaryMap}; -use cranelift_frontend::FunctionBuilderContext; -use cranelift_wasm::{DefinedFuncIndex, MemoryIndex}; -use wasmtime_environ::{Module, translate_signature}; -use wasmtime_jit::{ - ActionOutcome, CodeMemory, CompilationStrategy, CompiledModule, Compiler, Context, RuntimeValue, -}; -use wasmtime_runtime::{Export, Imports, InstanceHandle, VMFunctionBody}; - -/// TODO: We should remove this in https://github.com/paritytech/substrate/pull/4686 -/// Currently there is no way to extract this with wasmtime. -const INITIAL_HEAP_PAGES: u32 = 17; - -/// A `WasmRuntime` implementation using the Wasmtime JIT to compile the runtime module to native +/// A `WasmRuntime` implementation using wasmtime to compile the runtime module to machine code /// and execute the compiled code. pub struct WasmtimeRuntime { - module: CompiledModule, - context: Context, + module: Module, + imports: Imports, + state_holder: StateHolder, heap_pages: u32, - /// The host functions registered for this instance. host_functions: Vec<&'static dyn Function>, - /// The index of the memory in the module. - memory_index: MemoryIndex, } impl WasmRuntime for WasmtimeRuntime { - fn update_heap_pages(&mut self, heap_pages: u64) -> bool { - self.heap_pages as u64 == heap_pages - } - fn host_functions(&self) -> &[&'static dyn Function] { &self.host_functions } fn call(&mut self, method: &str, data: &[u8]) -> Result> { call_method( - &mut self.context, - &mut self.module, + &self.module, + &mut self.imports, + &self.state_holder, method, data, - self.memory_index, self.heap_pages, ) } @@ -90,445 +65,105 @@ pub fn create_instance( host_functions: Vec<&'static dyn Function>, allow_missing_func_imports: bool, ) -> std::result::Result { - let heap_pages = u32::try_from(heap_pages) - .map_err(|e| - WasmError::Other(format!("Heap pages can not be converted into `u32`: {:?}", e)) - )?; - - let (compiled_module, context, memory_index) = create_compiled_unit( - code, + // Create the engine, store and finally the module from the given code. + let mut config = Config::new(); + config.cranelift_opt_level(wasmtime::OptLevel::SpeedAndSize); + + let engine = Engine::new(&config); + let store = Store::new(&engine); + let module = Module::new(&store, code) + .map_err(|e| WasmError::Other(format!("cannot create module: {}", e)))?; + + let state_holder = StateHolder::empty(); + + // Scan all imports, find the matching host functions, and create stubs that adapt arguments + // and results. + let imports = resolve_imports( + &state_holder, + &module, &host_functions, - heap_pages, + heap_pages as u32, allow_missing_func_imports, )?; - let module = compiled_module.module_ref(); - if !module.is_imported_memory(memory_index) { - // Inspect the module for the min and max memory sizes. - let (min_memory_size, max_memory_size) = { - let memory_plan = module.memory_plans - .get(memory_index) - .ok_or_else(|| WasmError::InvalidMemory)?; - (memory_plan.memory.minimum, memory_plan.memory.maximum) - }; - - // Check that heap_pages is within the allowed range. - let max_heap_pages = max_memory_size.map(|max| max.saturating_sub(min_memory_size)); - - if max_heap_pages.map(|m| heap_pages > m).unwrap_or(false) { - return Err(WasmError::InvalidHeapPages) - } - } - Ok(WasmtimeRuntime { - module: compiled_module, - context, - heap_pages, + module, + imports, + state_holder, + heap_pages: heap_pages as u32, host_functions, - memory_index, }) } -#[derive(Debug)] -struct MissingFunction { - name: String, - sig: cranelift_codegen::ir::Signature, -} - -#[derive(Debug)] -struct MissingFunctionStubs { - stubs: HashMap>, -} - -impl MissingFunctionStubs { - fn new() -> Self { - Self { - stubs: HashMap::new(), - } - } - - fn insert(&mut self, module: String, name: String, sig: cranelift_codegen::ir::Signature) { - self.stubs.entry(module).or_insert_with(Vec::new).push(MissingFunction { - name, - sig, - }); - } -} - -fn scan_missing_functions( - code: &[u8], - host_functions: &[&'static dyn Function], -) -> std::result::Result { - let isa = target_isa()?; - let call_conv = isa.default_call_conv(); - - let module = parity_wasm::elements::Module::from_bytes(code) - .map_err(|e| WasmError::Other(format!("cannot deserialize error: {}", e)))?; - - let types = module.type_section().map(|ts| ts.types()).unwrap_or(&[]); - let import_entries = module - .import_section() - .map(|is| is.entries()) - .unwrap_or(&[]); - - let mut missing_functions = MissingFunctionStubs::new(); - for import_entry in import_entries { - let func_ty = match import_entry.external() { - parity_wasm::elements::External::Function(func_ty_idx) => { - let parity_wasm::elements::Type::Function(ref func_ty) = - types.get(*func_ty_idx as usize).ok_or_else(|| { - WasmError::Other(format!("corrupted module, type out of bounds")) - })?; - func_ty - } - _ => { - // We are looking only for missing **functions** here. Any other items, be they - // missing or not, will be handled at the resolution stage later. - continue; - } - }; - let signature = convert_parity_wasm_signature(func_ty); - - if import_entry.module() == "env" { - if let Some(hf) = host_functions - .iter() - .find(|hf| hf.name() == import_entry.field()) - { - if signature == hf.signature() { - continue; - } - } - } - - // This function is either not from the env module, or doesn't have a corresponding host - // function, or the signature is not matching. Add it to the list. - let sig = cranelift_ir_signature(signature, &call_conv); - - missing_functions.insert( - import_entry.module().to_string(), - import_entry.field().to_string(), - sig, - ); - } - - Ok(missing_functions) -} - -fn create_compiled_unit( - code: &[u8], - host_functions: &[&'static dyn Function], - heap_pages: u32, - allow_missing_func_imports: bool, -) -> std::result::Result<(CompiledModule, Context, MemoryIndex), WasmError> { - let compilation_strategy = CompilationStrategy::Cranelift; - - let compiler = new_compiler(compilation_strategy)?; - let mut context = Context::new(Box::new(compiler)); - - // Enable/disable producing of debug info. - context.set_debug_info(false); - - // Instantiate and link the env module. - let global_exports = context.get_global_exports(); - let compiler = new_compiler(compilation_strategy)?; - - let mut missing_functions_stubs = if allow_missing_func_imports { - scan_missing_functions(code, host_functions)? - } else { - // If there are in fact missing functions they will be detected at the instantiation time - // and the module will be rejected. - MissingFunctionStubs::new() - }; - - let env_missing_functions = missing_functions_stubs.stubs - .remove("env") - .unwrap_or_else(|| Vec::new()); - - let (module, memory_index) = instantiate_env_module( - global_exports, - compiler, - host_functions, - heap_pages, - env_missing_functions, - true, - )?; - - context.name_instance("env".to_owned(), module); - - for (module, missing_functions_stubs) in missing_functions_stubs.stubs { - let compiler = new_compiler(compilation_strategy)?; - let global_exports = context.get_global_exports(); - let instance = instantiate_env_module( - global_exports, - compiler, - &[], - heap_pages, - missing_functions_stubs, - false, - )?.0; - context.name_instance(module, instance); - } - - // Compile the wasm module. - let module = context.compile_module(&code) - .map_err(|e| WasmError::Other(format!("module compile error: {}", e)))?; - - Ok((module, context, memory_index.expect("Memory is added on request; qed"))) -} - /// Call a function inside a precompiled Wasm module. fn call_method( - context: &mut Context, - module: &mut CompiledModule, + module: &Module, + imports: &mut Imports, + state_holder: &StateHolder, method: &str, data: &[u8], - memory_index: MemoryIndex, heap_pages: u32, ) -> Result> { - let is_imported_memory = module.module().is_imported_memory(memory_index); - // Old exports get clobbered in `InstanceHandle::new` if we don't explicitly remove them first. - // - // The global exports mechanism is temporary in Wasmtime and expected to be removed. - // https://github.com/CraneStation/wasmtime/issues/332 - clear_globals(&mut *context.get_global_exports().borrow_mut(), is_imported_memory); - - let mut instance = module.instantiate().map_err(|e| Error::Other(e.to_string()))?; - - if !is_imported_memory { - grow_memory(&mut instance, heap_pages)?; - } - - // Initialize the function executor state. - let heap_base = get_heap_base(&instance)?; - let executor_state = FunctionExecutorState::new(heap_base); - reset_env_state_and_take_trap(context, Some(executor_state))?; + let instance_wrapper = InstanceWrapper::new(module, imports, heap_pages)?; + let entrypoint = instance_wrapper.resolve_entrypoint(method)?; + let heap_base = instance_wrapper.extract_heap_base()?; + let allocator = FreeingBumpHeapAllocator::new(heap_base); - // Write the input data into guest memory. - let (data_ptr, data_len) = inject_input_data(context, &mut instance, data, memory_index)?; - let args = [RuntimeValue::I32(u32::from(data_ptr) as i32), RuntimeValue::I32(data_len as i32)]; - - // Invoke the function in the runtime. - let outcome = context - .invoke(&mut instance, method, &args[..]) - .map_err(|e| Error::Other(format!("error calling runtime: {}", e)))?; - let trap_error = reset_env_state_and_take_trap(context, None)?; - let (output_ptr, output_len) = match outcome { - ActionOutcome::Returned { values } => match values.as_slice() { - [RuntimeValue::I64(retval)] => unpack_ptr_and_len(*retval as u64), - _ => return Err(Error::InvalidReturn), - } - ActionOutcome::Trapped { message } => return Err(trap_error.unwrap_or_else( - || format!("Wasm execution trapped: {}", message).into() - )), - }; - - // Read the output data from guest memory. - let mut output = vec![0; output_len as usize]; - let memory = get_memory_mut(&mut instance, memory_index)?; - read_memory_into(memory, Pointer::new(output_ptr), &mut output)?; - Ok(output) + perform_call(data, state_holder, instance_wrapper, entrypoint, allocator) } -/// The implementation is based on wasmtime_wasi::instantiate_wasi. -fn instantiate_env_module( - global_exports: Rc>>>, - compiler: Compiler, - host_functions: &[&'static dyn Function], - heap_pages: u32, - missing_functions_stubs: Vec, - add_memory: bool, -) -> std::result::Result<(InstanceHandle, Option), WasmError> { - let isa = target_isa()?; - let pointer_type = isa.pointer_type(); - let call_conv = isa.default_call_conv(); - - let mut fn_builder_ctx = FunctionBuilderContext::new(); - let mut module = Module::new(); - let mut finished_functions = >::new(); - let mut code_memory = CodeMemory::new(); - - for function in host_functions { - let sig = translate_signature( - cranelift_ir_signature(function.signature(), &call_conv), - pointer_type, - ); - let sig_id = module.signatures.push(sig.clone()); - let func_id = module.functions.push(sig_id); - module - .exports - .insert(function.name().to_string(), wasmtime_environ::Export::Function(func_id)); - - let trampoline = make_trampoline( - isa.as_ref(), - &mut code_memory, - &mut fn_builder_ctx, - func_id.index() as u32, - &sig, - )?; - finished_functions.push(trampoline); - } - - for MissingFunction { name, sig } in missing_functions_stubs { - let sig = translate_signature( - sig, - pointer_type, - ); - let sig_id = module.signatures.push(sig.clone()); - let func_id = module.functions.push(sig_id); - module - .exports - .insert(name, wasmtime_environ::Export::Function(func_id)); - let trampoline = make_trampoline( - isa.as_ref(), - &mut code_memory, - &mut fn_builder_ctx, - func_id.index() as u32, - &sig, - )?; - finished_functions.push(trampoline); - } - - code_memory.publish(); - - let memory_id = if add_memory { - let memory = cranelift_wasm::Memory { - minimum: heap_pages + INITIAL_HEAP_PAGES, - maximum: Some(heap_pages + INITIAL_HEAP_PAGES), - shared: false, - }; - let memory_plan = wasmtime_environ::MemoryPlan::for_memory(memory, &Default::default()); - - let memory_id = module.memory_plans.push(memory_plan); - module.exports.insert("memory".into(), wasmtime_environ::Export::Memory(memory_id)); - - Some(memory_id) - } else { - None - }; - - let imports = Imports::none(); - let data_initializers = Vec::new(); - let signatures = PrimaryMap::new(); - let env_state = EnvState::new(code_memory, compiler, host_functions); - - let result = InstanceHandle::new( - Rc::new(module), - global_exports, - finished_functions.into_boxed_slice(), - imports, - &data_initializers, - signatures.into_boxed_slice(), - None, - Box::new(env_state), - ); - - result - .map_err(|e| WasmError::Other(format!("cannot instantiate env: {}", e))) - .map(|r| (r, memory_id)) -} - -/// Build a new TargetIsa for the host machine. -fn target_isa() -> std::result::Result, WasmError> { - let isa_builder = cranelift_native::builder() - .map_err(|e| WasmError::Other(format!("missing compiler support: {}", e)))?; - let flag_builder = cranelift_codegen::settings::builder(); - Ok(isa_builder.finish(cranelift_codegen::settings::Flags::new(flag_builder))) -} - -fn new_compiler(strategy: CompilationStrategy) -> std::result::Result { - let isa = target_isa()?; - Ok(Compiler::new(isa, strategy)) -} - -fn clear_globals(global_exports: &mut HashMap>, is_imported_memory: bool) { - // When memory is imported, we can not delete the global export. - if !is_imported_memory { - global_exports.remove("memory"); - } - global_exports.remove("__heap_base"); - global_exports.remove("__indirect_function_table"); -} - -fn grow_memory(instance: &mut InstanceHandle, pages: u32) -> Result<()> { - // This is safe to wrap in an unsafe block as: - // - The result of the `lookup_immutable` call is not mutated - // - The definition pointer is returned by a lookup on a valid instance - let memory_index = unsafe { - match instance.lookup_immutable("memory") { - Some(Export::Memory { definition, vmctx: _, memory: _ }) => - instance.memory_index(&*definition), - _ => return Err(Error::InvalidMemoryReference), +fn perform_call( + data: &[u8], + state_holder: &StateHolder, + instance_wrapper: InstanceWrapper, + entrypoint: wasmtime::Func, + mut allocator: FreeingBumpHeapAllocator, +) -> Result> { + let (data_ptr, data_len) = inject_input_data(&instance_wrapper, &mut allocator, data)?; + + let host_state = HostState::new(allocator, instance_wrapper); + let (ret, host_state) = state_holder.with_initialized_state(host_state, || { + match entrypoint.call(&[ + wasmtime::Val::I32(u32::from(data_ptr) as i32), + wasmtime::Val::I32(u32::from(data_len) as i32), + ]) { + Ok(results) => { + let retval = results[0].unwrap_i64() as u64; + Ok(unpack_ptr_and_len(retval)) + } + Err(trap) => { + return Err(Error::from(format!( + "Wasm execution trapped: {}", + trap.message() + ))); + } } - }; - instance.memory_grow(memory_index, pages) - .map(|_| ()) - .ok_or_else(|| "requested heap_pages would exceed maximum memory size".into()) -} + }); + let (output_ptr, output_len) = ret?; -fn get_env_state(context: &mut Context) -> Result<&mut EnvState> { - let env_instance = context.get_instance("env") - .map_err(|err| format!("cannot find \"env\" module: {}", err))?; - env_instance - .host_state() - .downcast_mut::() - .ok_or_else(|| "cannot get \"env\" module host state".into()) -} + let instance = host_state.into_instance(); + let output = extract_output_data(&instance, output_ptr, output_len)?; -fn reset_env_state_and_take_trap( - context: &mut Context, - executor_state: Option, -) -> Result> -{ - let env_state = get_env_state(context)?; - env_state.executor_state = executor_state; - Ok(env_state.take_trap()) + Ok(output) } fn inject_input_data( - context: &mut Context, - instance: &mut InstanceHandle, + instance: &InstanceWrapper, + allocator: &mut FreeingBumpHeapAllocator, data: &[u8], - memory_index: MemoryIndex, ) -> Result<(Pointer, WordSize)> { - let env_state = get_env_state(context)?; - let executor_state = env_state.executor_state - .as_mut() - .ok_or_else(|| "cannot get \"env\" module executor state")?; - - let memory = get_memory_mut(instance, memory_index)?; - let data_len = data.len() as WordSize; - let data_ptr = executor_state.heap().allocate(memory, data_len)?; - write_memory_from(memory, data_ptr, data)?; + let data_ptr = instance.allocate(allocator, data_len)?; + instance.write_memory_from(data_ptr, data)?; Ok((data_ptr, data_len)) } -fn get_memory_mut(instance: &mut InstanceHandle, memory_index: MemoryIndex) -> Result<&mut [u8]> { - match instance.lookup_by_declaration(&wasmtime_environ::Export::Memory(memory_index)) { - // This is safe to wrap in an unsafe block as: - // - The definition pointer is returned by a lookup on a valid instance and thus points to - // a valid memory definition - Export::Memory { definition, vmctx: _, memory: _ } => unsafe { - Ok(std::slice::from_raw_parts_mut( - (*definition).base, - (*definition).current_length, - )) - }, - _ => Err(Error::InvalidMemoryReference), - } -} - -fn get_heap_base(instance: &InstanceHandle) -> Result { - // This is safe to wrap in an unsafe block as: - // - The result of the `lookup_immutable` call is not mutated - // - The definition pointer is returned by a lookup on a valid instance - // - The defined value is checked to be an I32, which can be read safely as a u32 - unsafe { - match instance.lookup_immutable("__heap_base") { - Some(Export::Global { definition, vmctx: _, global }) - if global.ty == ir::types::I32 => - Ok(*(*definition).as_u32()), - _ => return Err(Error::HeapBaseNotFoundOrInvalid), - } - } +fn extract_output_data( + instance: &InstanceWrapper, + output_ptr: u32, + output_len: u32, +) -> Result> { + let mut output = vec![0; output_len as usize]; + instance.read_memory_into(Pointer::new(output_ptr), &mut output)?; + Ok(output) } diff --git a/client/executor/wasmtime/src/state_holder.rs b/client/executor/wasmtime/src/state_holder.rs new file mode 100644 index 0000000000..57564ed3ec --- /dev/null +++ b/client/executor/wasmtime/src/state_holder.rs @@ -0,0 +1,77 @@ +// Copyright 2020 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::host::{HostContext, HostState}; +use std::cell::RefCell; +use std::rc::Rc; + +/// A common place to store a reference to the `HostState`. +/// +/// This structure is passed into each host function handler and retained in the implementation of +/// `WasmRuntime`. Whenever a call into a runtime method is initiated, the host state is populated +/// with the state for that runtime method call. +/// +/// During the execution of the runtime method call, wasm can call imported host functions. When +/// that happens the host function handler gets a `HostContext` (obtainable through having a +/// `HostState` reference). +#[derive(Clone)] +pub struct StateHolder { + // This is `Some` only during a call. + state: Rc>>, +} + +impl StateHolder { + /// Create a placeholder `StateHolder`. + pub fn empty() -> StateHolder { + StateHolder { + state: Rc::new(RefCell::new(None)), + } + } + + /// Provide `HostState` for the runtime method call and execute the given function `f`. + /// + /// During the execution of the provided function `with_context` will be callable. + pub fn with_initialized_state(&self, state: HostState, f: F) -> (R, HostState) + where + F: FnOnce() -> R, + { + *self.state.borrow_mut() = Some(state); + + let ret = f(); + let state = self + .state + .borrow_mut() + .take() + .expect("cannot be None since was just assigned; qed"); + + (ret, state) + } + + /// Create a `HostContext` from the contained `HostState` and execute the given function `f`. + /// + /// This function is only callable within closure passed to `init_state`. Otherwise, the passed + /// context will be `None`. + pub fn with_context(&self, f: F) -> R + where + F: FnOnce(Option) -> R, + { + let state = self.state.borrow(); + match *state { + Some(ref state) => f(Some(state.materialize())), + None => f(None), + } + } +} diff --git a/client/executor/wasmtime/src/trampoline.rs b/client/executor/wasmtime/src/trampoline.rs deleted file mode 100644 index 8a21477609..0000000000 --- a/client/executor/wasmtime/src/trampoline.rs +++ /dev/null @@ -1,361 +0,0 @@ -// Copyright 2019-2020 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 . - -//! The trampoline is the dynamically generated entry point to a runtime host call. -//! -//! This code is based on and large parts are copied from wasmtime's -//! wasmtime-api/src/trampoline/func.rs. - -use crate::function_executor::{FunctionExecutorState, FunctionExecutor}; -use sc_executor_common::error::{Error, WasmError}; - -use cranelift_codegen::{Context, binemit, ir, isa}; -use cranelift_codegen::ir::{InstBuilder, StackSlotData, StackSlotKind, TrapCode}; -use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; -use cranelift_codegen::print_errors::pretty_error; -use wasmtime_jit::{CodeMemory, Compiler}; -use wasmtime_environ::CompiledFunction; -use wasmtime_runtime::{VMContext, VMFunctionBody}; -use sp_wasm_interface::{Function, Value, ValueType}; -use std::{cmp, panic::{self, AssertUnwindSafe}, ptr}; - -const CALL_SUCCESS: u32 = 0; -const CALL_FAILED_WITH_ERROR: u32 = 1; -const CALL_WITH_BAD_HOST_STATE: u32 = 2; - -/// A code to trap with that indicates a host call error. -const TRAP_USER_CODE: u16 = 0; - -/// The only Wasm types allowed in host function signatures (I32, I64, F32, F64) are all -/// represented in at most 8 bytes. -const MAX_WASM_TYPE_SIZE: usize = 8; - -/// The top-level host state of the "env" module. This state is used by the trampoline function to -/// construct a `FunctionExecutor` which can execute the host call. -pub struct EnvState { - host_functions: Vec<&'static dyn Function>, - compiler: Compiler, - // The code memory must be kept around on the state to prevent it from being dropped. - #[allow(dead_code)] - code_memory: CodeMemory, - trap: Option, - /// The executor state stored across host calls during a single Wasm runtime call. - /// During a runtime call, this MUST be `Some`. - pub executor_state: Option, -} - -impl EnvState { - /// Construct a new `EnvState` which owns the given code memory. - pub fn new( - code_memory: CodeMemory, - compiler: Compiler, - host_functions: &[&'static dyn Function], - ) -> Self { - EnvState { - trap: None, - compiler, - code_memory, - executor_state: None, - host_functions: host_functions.to_vec(), - } - } - - /// Resets the trap error to None and returns the current value. - pub fn take_trap(&mut self) -> Option { - self.trap.take() - } -} - -/// This is called by the dynamically generated trampoline taking the function index and reference -/// to the call arguments on the stack as arguments. Returns zero on success and a non-zero value -/// on failure. -unsafe extern "C" fn stub_fn(vmctx: *mut VMContext, func_index: u32, values_vec: *mut i64) -> u32 { - if let Some(state) = (*vmctx).host_state().downcast_mut::() { - match stub_fn_inner( - vmctx, - &state.host_functions, - &mut state.compiler, - state.executor_state.as_mut(), - func_index, - values_vec, - ) { - Ok(()) => CALL_SUCCESS, - Err(err) => { - state.trap = Some(err); - CALL_FAILED_WITH_ERROR - } - } - } else { - // Well, we can't even set a trap message, so we'll just exit without one. - CALL_WITH_BAD_HOST_STATE - } -} - -/// Implements most of the logic in `stub_fn` but returning a `Result` instead of an integer error -/// for the sake of readability. -unsafe fn stub_fn_inner( - vmctx: *mut VMContext, - externals: &[&dyn Function], - compiler: &mut Compiler, - executor_state: Option<&mut FunctionExecutorState>, - func_index: u32, - values_vec: *mut i64, -) -> Result<(), Error> { - let func = externals.get(func_index as usize) - .ok_or_else(|| format!("call to undefined external function with index {}", func_index))?; - let executor_state = executor_state - .ok_or_else(|| "executor state is None during call to external function")?; - - // Build the external function context. - let mut context = FunctionExecutor::new(vmctx, compiler, executor_state)?; - let mut context = AssertUnwindSafe(&mut context); - - // Execute and write output back to the stack. - let return_val = panic::catch_unwind(move || { - let signature = func.signature(); - - // Read the arguments from the stack. - let mut args = signature.args.iter() - .enumerate() - .map(|(i, ¶m_type)| read_value_from(values_vec.offset(i as isize), param_type)); - - func.execute(&mut **context, &mut args) - }); - - match return_val { - Ok(ret_val) => { - if let Some(val) = ret_val - .map_err(|e| Error::FunctionExecution(func.name().to_string(), e))? { - write_value_to(values_vec, val); - } - - Ok(()) - }, - Err(e) => { - let message = if let Some(err) = e.downcast_ref::() { - err.to_string() - } else if let Some(err) = e.downcast_ref::<&str>() { - err.to_string() - } else { - "Panicked without any further information!".into() - }; - - Err(Error::FunctionExecution(func.name().to_string(), message)) - } - } -} - -/// Create a trampoline for invoking a host function. -/// -/// The trampoline is a dynamically generated entry point to a runtime host call. The function is -/// generated by manually constructing Cranelift IR and using the Cranelift compiler. The -/// trampoline embeds the function index as a constant and delegates to a stub function in Rust, -/// which takes the function index and a memory reference to the stack arguments and return value -/// slots. -/// -/// This code is of modified copy of wasmtime's wasmtime-api/src/trampoline/func.rs. -pub fn make_trampoline( - isa: &dyn isa::TargetIsa, - code_memory: &mut CodeMemory, - fn_builder_ctx: &mut FunctionBuilderContext, - func_index: u32, - signature: &ir::Signature, -) -> Result<*const VMFunctionBody, WasmError> { - // Mostly reverse copy of the similar method from wasmtime's - // wasmtime-jit/src/compiler.rs. - let pointer_type = isa.pointer_type(); - let mut stub_sig = ir::Signature::new(isa.frontend_config().default_call_conv); - - // Ensure that the first parameter of the generated function is the `VMContext` pointer. - assert_eq!( - signature.params[0], - ir::AbiParam::special(pointer_type, ir::ArgumentPurpose::VMContext) - ); - - // Add the `vmctx` parameter. - stub_sig.params.push(ir::AbiParam::special( - pointer_type, - ir::ArgumentPurpose::VMContext, - )); - - // Add the `func_index` parameter. - stub_sig.params.push(ir::AbiParam::new(ir::types::I32)); - - // Add the `values_vec` parameter. - stub_sig.params.push(ir::AbiParam::new(pointer_type)); - - // Add error/trap return. - stub_sig.returns.push(ir::AbiParam::new(ir::types::I32)); - - // Each parameter and return value gets a 64-bit (8-byte) wide slot on the stack, as that is - // large enough to fit all Wasm primitive types that can be used in host function signatures. - // The `VMContext` pointer, which is a parameter of the function signature, is excluded as it - // is passed directly to the stub function rather than being looked up on the caller stack from - // the `values_vec` pointer. - let values_vec_len = cmp::max(signature.params.len() - 1, signature.returns.len()); - let values_vec_size = (MAX_WASM_TYPE_SIZE * values_vec_len) as u32; - - let mut context = Context::new(); - context.func = - ir::Function::with_name_signature(ir::ExternalName::user(0, 0), signature.clone()); - - let ss = context.func.create_stack_slot(StackSlotData::new( - StackSlotKind::ExplicitSlot, - values_vec_size, - )); - - { - let mut builder = FunctionBuilder::new(&mut context.func, fn_builder_ctx); - let block0 = builder.create_ebb(); - - builder.append_ebb_params_for_function_params(block0); - builder.switch_to_block(block0); - builder.seal_block(block0); - - let values_vec_ptr_val = builder.ins().stack_addr(pointer_type, ss, 0); - let mflags = ir::MemFlags::trusted(); - for i in 1..signature.params.len() { - let val = builder.func.dfg.ebb_params(block0)[i]; - builder.ins().store( - mflags, - val, - values_vec_ptr_val, - ((i - 1) * MAX_WASM_TYPE_SIZE) as i32, - ); - } - - let vmctx_ptr_val = builder.func.dfg.ebb_params(block0)[0]; - let func_index_val = builder.ins().iconst(ir::types::I32, func_index as i64); - - let callee_args = vec![vmctx_ptr_val, func_index_val, values_vec_ptr_val]; - - let new_sig = builder.import_signature(stub_sig.clone()); - - let callee_value = builder - .ins() - .iconst(pointer_type, stub_fn as *const VMFunctionBody as i64); - let call = builder - .ins() - .call_indirect(new_sig, callee_value, &callee_args); - - let call_result = builder.func.dfg.inst_results(call)[0]; - builder.ins().trapnz(call_result, TrapCode::User(TRAP_USER_CODE)); - - let mflags = ir::MemFlags::trusted(); - let mut results = Vec::new(); - for (i, r) in signature.returns.iter().enumerate() { - let load = builder.ins().load( - r.value_type, - mflags, - values_vec_ptr_val, - (i * MAX_WASM_TYPE_SIZE) as i32, - ); - results.push(load); - } - builder.ins().return_(&results); - builder.finalize() - } - - let mut code_buf: Vec = Vec::new(); - let mut reloc_sink = RelocSink; - let mut trap_sink = binemit::NullTrapSink {}; - let mut stackmap_sink = binemit::NullStackmapSink {}; - context - .compile_and_emit( - isa, - &mut code_buf, - &mut reloc_sink, - &mut trap_sink, - &mut stackmap_sink, - ) - .map_err(|e| { - WasmError::Instantiation(format!( - "failed to compile trampoline: {}", - pretty_error(&context.func, Some(isa), e) - )) - })?; - - let mut unwind_info = Vec::new(); - context.emit_unwind_info(isa, &mut unwind_info); - - let func_ref = code_memory - .allocate_for_function(&CompiledFunction { - body: code_buf, - jt_offsets: context.func.jt_offsets, - unwind_info, - }) - .map_err(|e| WasmError::Instantiation(format!("failed to allocate code memory: {}", e)))?; - - Ok(func_ref.as_ptr()) -} - -/// We don't expect trampoline compilation to produce any relocations, so -/// this `RelocSink` just asserts that it doesn't recieve any. -struct RelocSink; - -impl binemit::RelocSink for RelocSink { - fn reloc_ebb( - &mut self, - _offset: binemit::CodeOffset, - _reloc: binemit::Reloc, - _ebb_offset: binemit::CodeOffset, - ) { - panic!("trampoline compilation should not produce ebb relocs"); - } - fn reloc_external( - &mut self, - _offset: binemit::CodeOffset, - _reloc: binemit::Reloc, - _name: &ir::ExternalName, - _addend: binemit::Addend, - ) { - panic!("trampoline compilation should not produce external symbol relocs"); - } - fn reloc_constant( - &mut self, - _code_offset: binemit::CodeOffset, - _reloc: binemit::Reloc, - _constant_offset: ir::ConstantOffset, - ) { - panic!("trampoline compilation should not produce constant relocs"); - } - fn reloc_jt( - &mut self, - _offset: binemit::CodeOffset, - _reloc: binemit::Reloc, - _jt: ir::JumpTable, - ) { - panic!("trampoline compilation should not produce jump table relocs"); - } -} - -unsafe fn write_value_to(p: *mut i64, val: Value) { - match val { - Value::I32(i) => ptr::write(p as *mut i32, i), - Value::I64(i) => ptr::write(p as *mut i64, i), - Value::F32(u) => ptr::write(p as *mut u32, u), - Value::F64(u) => ptr::write(p as *mut u64, u), - } -} - -unsafe fn read_value_from(p: *const i64, ty: ValueType) -> Value { - match ty { - ValueType::I32 => Value::I32(ptr::read(p as *const i32)), - ValueType::I64 => Value::I64(ptr::read(p as *const i64)), - ValueType::F32 => Value::F32(ptr::read(p as *const u32)), - ValueType::F64 => Value::F64(ptr::read(p as *const u64)), - } -} diff --git a/client/executor/wasmtime/src/util.rs b/client/executor/wasmtime/src/util.rs index 77fb8af386..d2de95d4cc 100644 --- a/client/executor/wasmtime/src/util.rs +++ b/client/executor/wasmtime/src/util.rs @@ -1,4 +1,4 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. // Substrate is free software: you can redistribute it and/or modify @@ -14,31 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use sc_executor_common::error::{Error, Result}; - -use cranelift_codegen::{ir, isa}; use std::ops::Range; -use sp_wasm_interface::{Pointer, Signature, ValueType}; - -/// Read data from a slice of memory into a destination buffer. -/// -/// Returns an error if the read would go out of the memory bounds. -pub fn read_memory_into(memory: &[u8], address: Pointer, dest: &mut [u8]) -> Result<()> { - let range = checked_range(address.into(), dest.len(), memory.len()) - .ok_or_else(|| Error::Other("memory read is out of bounds".into()))?; - dest.copy_from_slice(&memory[range]); - Ok(()) -} - -/// Write data to a slice of memory. -/// -/// Returns an error if the write would go out of the memory bounds. -pub fn write_memory_from(memory: &mut [u8], address: Pointer, data: &[u8]) -> Result<()> { - let range = checked_range(address.into(), data.len(), memory.len()) - .ok_or_else(|| Error::Other("memory write is out of bounds".into()))?; - &mut memory[range].copy_from_slice(data); - Ok(()) -} /// Construct a range from an offset to a data length after the offset. /// Returns None if the end of the range would exceed some maximum offset. @@ -50,82 +26,3 @@ pub fn checked_range(offset: usize, len: usize, max: usize) -> Option Signature { - fn convert_value_type(val_ty: parity_wasm::elements::ValueType) -> ValueType { - use parity_wasm::elements::ValueType::*; - match val_ty { - I32 => ValueType::I32, - I64 => ValueType::I64, - F32 => ValueType::F32, - F64 => ValueType::F64, - } - } - - Signature::new( - func_ty.params().iter().cloned().map(convert_value_type).collect::>(), - func_ty.return_type().map(convert_value_type), - ) -} - -/// Convert a wasm_interface Signature into a cranelift_codegen Signature. -pub fn cranelift_ir_signature(signature: Signature, call_conv: &isa::CallConv) -> ir::Signature { - ir::Signature { - params: signature.args.iter() - .map(cranelift_ir_type) - .map(ir::AbiParam::new) - .collect(), - returns: signature.return_value.iter() - .map(cranelift_ir_type) - .map(ir::AbiParam::new) - .collect(), - call_conv: call_conv.clone(), - } -} - -/// Convert a wasm_interface ValueType into a cranelift_codegen Type. -pub fn cranelift_ir_type(value_type: &ValueType) -> ir::types::Type { - match value_type { - ValueType::I32 => ir::types::I32, - ValueType::I64 => ir::types::I64, - ValueType::F32 => ir::types::F32, - ValueType::F64 => ir::types::F64, - } -} - -#[cfg(test)] -mod tests { - use super::*; - use assert_matches::assert_matches; - - #[test] - fn test_read_memory_into() { - let mut memory = [0; 20]; - let mut dest = [0; 5]; - - &mut memory[15..20].copy_from_slice(b"hello"); - - read_memory_into(&memory[..], Pointer::new(15), &mut dest[..]).unwrap(); - - // Test that out of bounds read fails. - assert_matches!( - read_memory_into(&memory[..], Pointer::new(16), &mut dest[..]), - Err(Error::Other(_)) - ) - } - - #[test] - fn test_write_memory_from() { - let mut memory = [0; 20]; - let data = b"hello"; - - write_memory_from(&mut memory[..], Pointer::new(15), data).unwrap(); - - // Test that out of bounds write fails. - assert_matches!( - write_memory_from(&mut memory[..], Pointer::new(16), data), - Err(Error::Other(_)) - ) - } -} -- GitLab From b36497ad7e7c1922605de9217df737457eb8efa7 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Thu, 13 Feb 2020 17:26:56 +0300 Subject: [PATCH 147/180] reference sc-service with rocksdb feature (#4918) --- Cargo.lock | 1 + bin/node/testing/Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index d3fe6848e4..1adf990df0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3650,6 +3650,7 @@ dependencies = [ "sc-client-api", "sc-client-db", "sc-executor", + "sc-service", "sp-api", "sp-block-builder", "sp-blockchain", diff --git a/bin/node/testing/Cargo.toml b/bin/node/testing/Cargo.toml index e41af71571..558c8f2f0b 100644 --- a/bin/node/testing/Cargo.toml +++ b/bin/node/testing/Cargo.toml @@ -48,6 +48,7 @@ tempdir = "0.3" fs_extra = "1" hex-literal = "0.2.1" sc-cli = { version = "0.8.0", path = "../../../client/cli" } +sc-service = { version = "0.8.0", path = "../../../client/service", features = ["rocksdb"] } [[bench]] name = "import" -- GitLab From 067c8844240dbb1069391c0b4dd530f37b723df7 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Thu, 13 Feb 2020 19:12:26 +0100 Subject: [PATCH 148/180] pallet-evm: add support for transaction-level create2 (#4907) * pallet-evm: add support for transaction-level create2 * Bump runtime version * Switch to FunctionOf for weights --- Cargo.lock | 16 ++--- bin/node/runtime/src/lib.rs | 4 +- frame/evm/Cargo.toml | 2 +- frame/evm/src/lib.rs | 113 ++++++++++++++++++++++++------------ 4 files changed, 88 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1adf990df0..52a9c261ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1235,9 +1235,9 @@ dependencies = [ [[package]] name = "evm" -version = "0.14.2" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f887b371f9999682ccc5b1cb771e7d4408ae61e93fc0343ceaeb761fca42d1" +checksum = "272f65e18a2b6449b682bfcdf6c3ccc63db0b93898d89c0fb237548bbfc764a5" dependencies = [ "evm-core", "evm-gasometer", @@ -1250,18 +1250,18 @@ dependencies = [ [[package]] name = "evm-core" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bcde5af3d542874ddeb53de0919302d57586ea04b3f76f54d865f8a6cdc70ae" +checksum = "66534d42e13d50f9101bed87cb568fd5aa929c600c3c13f8dadbbf39f5635945" dependencies = [ "primitive-types", ] [[package]] name = "evm-gasometer" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b82bc9f275cb59d2bcc05d85c98736ddfaba003a7ef7b73893fa7c1c1fab29dc" +checksum = "39bc5b592803ca644781fe2290b7305ea5182f7c9516d615ddfb2308c2cab639" dependencies = [ "evm-core", "evm-runtime", @@ -1270,9 +1270,9 @@ dependencies = [ [[package]] name = "evm-runtime" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dbbc89d29618c3722c17ba78ddf432d40ace8ee27e3f8b28b52a85921112e4b" +checksum = "389e4b447fb26971a9c76c8aa49c0ab435f8e46e8fc46e1bc4ebf01f3c2b428f" dependencies = [ "evm-core", "primitive-types", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 1270c04d04..a922e2f61c 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -82,8 +82,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 216, - impl_version: 3, + spec_version: 217, + impl_version: 0, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/evm/Cargo.toml b/frame/evm/Cargo.toml index 50d7b03672..66c809fa44 100644 --- a/frame/evm/Cargo.toml +++ b/frame/evm/Cargo.toml @@ -18,7 +18,7 @@ sp-std = { version = "2.0.0", default-features = false, path = "../../primitives sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" } primitive-types = { version = "0.6.2", default-features = false, features = ["rlp"] } rlp = { version = "0.4", default-features = false } -evm = { version = "0.14", default-features = false } +evm = { version = "0.15", default-features = false } sha3 = { version = "0.8", default-features = false } [features] diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index 7413292cd5..9476321596 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -25,7 +25,7 @@ pub use crate::backend::{Account, Log, Vicinity, Backend}; 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::weights::{Weight, DispatchClass, FunctionOf}; use frame_support::traits::{Currency, WithdrawReason, ExistenceRequirement}; use frame_system::{self as system, ensure_signed}; use sp_runtime::ModuleId; @@ -34,6 +34,7 @@ use sp_core::{U256, H256, H160, Hasher}; use sp_runtime::{ DispatchResult, traits::{UniqueSaturatedInto, AccountIdConversion, SaturatedConversion}, }; +use sha3::{Digest, Keccak256}; use evm::{ExitReason, ExitSucceed, ExitError}; use evm::executor::StackExecutor; use evm::backend::ApplyBackend; @@ -115,38 +116,6 @@ impl Precompiles for () { } } -struct WeightForCallCreate; - -impl WeighData<(&H160, &Vec, &U256, &u32, &U256, &Option)> for WeightForCallCreate { - fn weigh_data( - &self, - (_, _, _, gas_provided, gas_price, _): (&H160, &Vec, &U256, &u32, &U256, &Option) - ) -> Weight { - (*gas_price).saturated_into::().saturating_mul(*gas_provided) - } -} - -impl WeighData<(&Vec, &U256, &u32, &U256, &Option)> for WeightForCallCreate { - fn weigh_data( - &self, - (_, _, gas_provided, gas_price, _): (&Vec, &U256, &u32, &U256, &Option) - ) -> 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, _: T) -> bool { - true - } -} - /// EVM module trait pub trait Trait: frame_system::Trait + pallet_timestamp::Trait { /// Calculator for current gas price. @@ -252,7 +221,7 @@ decl_module! { } /// Issue an EVM call operation. This is similar to a message call transaction in Ethereum. - #[weight = WeightForCallCreate] + #[weight = FunctionOf(|(_, _, _, gas_limit, gas_price, _): (&H160, &Vec, &U256, &u32, &U256, &Option)| (*gas_price).saturated_into::().saturating_mul(*gas_limit), DispatchClass::Normal, true)] fn call( origin, target: H160, @@ -315,7 +284,7 @@ decl_module! { /// Issue an EVM create operation. This is similar to a contract creation transaction in /// Ethereum. - #[weight = WeightForCallCreate] + #[weight = FunctionOf(|(_, _, gas_limit, gas_price, _): (&Vec, &U256, &u32, &U256, &Option)| (*gas_price).saturated_into::().saturating_mul(*gas_limit), DispatchClass::Normal, true)] fn create( origin, init: Vec, @@ -353,7 +322,9 @@ decl_module! { ensure!(source_account.nonce == nonce, Error::::InvalidNonce); } - let create_address = executor.create_address(source, evm::CreateScheme::Dynamic); + let create_address = executor.create_address( + evm::CreateScheme::Legacy { caller: source } + ); let reason = executor.transact_create( source, value, @@ -378,6 +349,76 @@ decl_module! { ret.map_err(Into::into) } + + /// Issue an EVM create2 operation. + #[weight = FunctionOf(|(_, _, _, gas_limit, gas_price, _): (&Vec, &H256, &U256, &u32, &U256, &Option)| (*gas_price).saturated_into::().saturating_mul(*gas_limit), DispatchClass::Normal, true)] + fn create2( + origin, + init: Vec, + salt: H256, + value: U256, + gas_limit: u32, + gas_price: U256, + nonce: Option, + ) -> 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 vicinity = Vicinity { + gas_price, + origin: source, + }; + + let mut backend = Backend::::new(&vicinity); + let mut executor = StackExecutor::new_with_precompile( + &backend, + gas_limit as usize, + &backend::GASOMETER_CONFIG, + T::Precompiles::execute, + ); + + let total_fee = gas_price.checked_mul(U256::from(gas_limit)) + .ok_or(Error::::FeeOverflow)?; + let total_payment = value.checked_add(total_fee).ok_or(Error::::PaymentOverflow)?; + let source_account = Accounts::get(&source); + ensure!(source_account.balance >= total_payment, Error::::BalanceLow); + executor.withdraw(source, total_fee).map_err(|_| Error::::WithdrawFailed)?; + + if let Some(nonce) = nonce { + ensure!(source_account.nonce == nonce, Error::::InvalidNonce); + } + + let code_hash = H256::from_slice(Keccak256::digest(&init).as_slice()); + let create_address = executor.create_address( + evm::CreateScheme::Create2 { caller: source, code_hash, salt } + ); + let reason = executor.transact_create2( + source, + value, + init, + salt, + gas_limit as usize, + ); + + let ret = match reason { + ExitReason::Succeed(_) => { + Module::::deposit_event(Event::Created(create_address)); + Ok(()) + }, + 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)); + + let (values, logs) = executor.deconstruct(); + backend.apply(values, logs, true); + + ret.map_err(Into::into) + } } } -- GitLab From 7d544ef396130426be1799729fbc9b9b22488c8e Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Thu, 13 Feb 2020 21:21:19 +0100 Subject: [PATCH 149/180] pallet-evm: refactor duplicate code in call/create/create2 (#4922) * pallet-evm: refactor duplicate code in call/create/create2 * Bump runtime version --- bin/node/runtime/src/lib.rs | 2 +- frame/evm/src/lib.rs | 241 +++++++++++++++--------------------- 2 files changed, 101 insertions(+), 142 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index a922e2f61c..8d8e784f98 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 217, - impl_version: 0, + impl_version: 1, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index 9476321596..a12d06c69b 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -232,54 +232,22 @@ decl_module! { nonce: Option, ) -> 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 vicinity = Vicinity { - gas_price, - origin: source, - }; - - let mut backend = Backend::::new(&vicinity); - let mut executor = StackExecutor::new_with_precompile( - &backend, - gas_limit as usize, - &backend::GASOMETER_CONFIG, - T::Precompiles::execute, - ); - - let total_fee = gas_price.checked_mul(U256::from(gas_limit)) - .ok_or(Error::::FeeOverflow)?; - let total_payment = value.checked_add(total_fee).ok_or(Error::::PaymentOverflow)?; - let source_account = Accounts::get(&source); - ensure!(source_account.balance >= total_payment, Error::::BalanceLow); - executor.withdraw(source, total_fee).map_err(|_| Error::::WithdrawFailed)?; - - if let Some(nonce) = nonce { - ensure!(source_account.nonce == nonce, Error::::InvalidNonce); - } - - let reason = executor.transact_call( + Self::execute_evm( source, - target, value, - input, - gas_limit as usize, - ); - - let ret = match reason { - ExitReason::Succeed(_) => Ok(()), - 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)); - - let (values, logs) = executor.deconstruct(); - backend.apply(values, logs, true); - - ret.map_err(Into::into) + gas_limit, + gas_price, + nonce, + |executor| ((), executor.transact_call( + source, + target, + value, + input, + gas_limit as usize, + )), + ).map_err(Into::into) } /// Issue an EVM create operation. This is similar to a contract creation transaction in @@ -294,60 +262,28 @@ decl_module! { nonce: Option, ) -> 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 vicinity = Vicinity { - gas_price, - origin: source, - }; - - let mut backend = Backend::::new(&vicinity); - let mut executor = StackExecutor::new_with_precompile( - &backend, - gas_limit as usize, - &backend::GASOMETER_CONFIG, - T::Precompiles::execute, - ); - - let total_fee = gas_price.checked_mul(U256::from(gas_limit)) - .ok_or(Error::::FeeOverflow)?; - let total_payment = value.checked_add(total_fee).ok_or(Error::::PaymentOverflow)?; - let source_account = Accounts::get(&source); - ensure!(source_account.balance >= total_payment, Error::::BalanceLow); - executor.withdraw(source, total_fee).map_err(|_| Error::::WithdrawFailed)?; - - if let Some(nonce) = nonce { - ensure!(source_account.nonce == nonce, Error::::InvalidNonce); - } - - let create_address = executor.create_address( - evm::CreateScheme::Legacy { caller: source } - ); - let reason = executor.transact_create( + let create_address = Self::execute_evm( source, value, - init, - gas_limit as usize, - ); - - let ret = match reason { - ExitReason::Succeed(_) => { - Module::::deposit_event(Event::Created(create_address)); - Ok(()) + gas_limit, + gas_price, + nonce, + |executor| { + (executor.create_address( + evm::CreateScheme::Legacy { caller: source }, + ), executor.transact_create( + source, + value, + init, + gas_limit as usize, + )) }, - 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)); - - let (values, logs) = executor.deconstruct(); - backend.apply(values, logs, true); + )?; - ret.map_err(Into::into) + Module::::deposit_event(Event::Created(create_address)); + Ok(()) } /// Issue an EVM create2 operation. @@ -362,62 +298,30 @@ decl_module! { nonce: Option, ) -> 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 vicinity = Vicinity { - gas_price, - origin: source, - }; - - let mut backend = Backend::::new(&vicinity); - let mut executor = StackExecutor::new_with_precompile( - &backend, - gas_limit as usize, - &backend::GASOMETER_CONFIG, - T::Precompiles::execute, - ); - - let total_fee = gas_price.checked_mul(U256::from(gas_limit)) - .ok_or(Error::::FeeOverflow)?; - let total_payment = value.checked_add(total_fee).ok_or(Error::::PaymentOverflow)?; - let source_account = Accounts::get(&source); - ensure!(source_account.balance >= total_payment, Error::::BalanceLow); - executor.withdraw(source, total_fee).map_err(|_| Error::::WithdrawFailed)?; - - if let Some(nonce) = nonce { - ensure!(source_account.nonce == nonce, Error::::InvalidNonce); - } - let code_hash = H256::from_slice(Keccak256::digest(&init).as_slice()); - let create_address = executor.create_address( - evm::CreateScheme::Create2 { caller: source, code_hash, salt } - ); - let reason = executor.transact_create2( + let create_address = Self::execute_evm( source, value, - init, - salt, - gas_limit as usize, - ); - - let ret = match reason { - ExitReason::Succeed(_) => { - Module::::deposit_event(Event::Created(create_address)); - Ok(()) + gas_limit, + gas_price, + nonce, + |executor| { + (executor.create_address( + evm::CreateScheme::Create2 { caller: source, code_hash, salt }, + ), executor.transact_create2( + source, + value, + init, + salt, + gas_limit as usize, + )) }, - 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)); - - let (values, logs) = executor.deconstruct(); - backend.apply(values, logs, true); + )?; - ret.map_err(Into::into) + Module::::deposit_event(Event::Created(create_address)); + Ok(()) } } } @@ -454,4 +358,59 @@ impl Module { AccountCodes::remove(address); AccountStorages::remove_prefix(address); } + + /// Execute an EVM operation. + fn execute_evm( + source: H160, + value: U256, + gas_limit: u32, + gas_price: U256, + nonce: Option, + f: F, + ) -> Result> where + F: FnOnce(&mut StackExecutor>) -> (R, ExitReason), + { + ensure!(gas_price >= T::FeeCalculator::min_gas_price(), Error::::GasPriceTooLow); + + let vicinity = Vicinity { + gas_price, + origin: source, + }; + + let mut backend = Backend::::new(&vicinity); + let mut executor = StackExecutor::new_with_precompile( + &backend, + gas_limit as usize, + &backend::GASOMETER_CONFIG, + T::Precompiles::execute, + ); + + let total_fee = gas_price.checked_mul(U256::from(gas_limit)) + .ok_or(Error::::FeeOverflow)?; + let total_payment = value.checked_add(total_fee).ok_or(Error::::PaymentOverflow)?; + let source_account = Accounts::get(&source); + ensure!(source_account.balance >= total_payment, Error::::BalanceLow); + executor.withdraw(source, total_fee).map_err(|_| Error::::WithdrawFailed)?; + + if let Some(nonce) = nonce { + ensure!(source_account.nonce == nonce, Error::::InvalidNonce); + } + + let (retv, reason) = f(&mut executor); + + let ret = match reason { + ExitReason::Succeed(_) => Ok(retv), + 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)); + + let (values, logs) = executor.deconstruct(); + backend.apply(values, logs, true); + + ret + } } -- GitLab From d02c720e5e3cf54c27919f0629961594385ed8f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 14 Feb 2020 01:42:27 +0100 Subject: [PATCH 150/180] Adds a test to ensure that we clear the heap between calls into runtime (#4903) * Adds a test to ensure that we clear the heap between calls into runtime The tests shows that we currently not clearing the heap in wasmtime. For now we don't run the test for wasmtime. * Fix compilation --- client/executor/common/src/wasm_runtime.rs | 5 +++- client/executor/runtime-test/src/lib.rs | 14 +++++++++++ client/executor/src/integration_tests/mod.rs | 23 +++++++++++++++++++ client/executor/wasmi/src/lib.rs | 13 +++++++++++ .../executor/wasmtime/src/instance_wrapper.rs | 22 ++++++++++++++++-- client/executor/wasmtime/src/runtime.rs | 8 ++++++- 6 files changed, 81 insertions(+), 4 deletions(-) diff --git a/client/executor/common/src/wasm_runtime.rs b/client/executor/common/src/wasm_runtime.rs index 9b0ad6b780..7af6c2bd53 100644 --- a/client/executor/common/src/wasm_runtime.rs +++ b/client/executor/common/src/wasm_runtime.rs @@ -17,7 +17,7 @@ //! Definitions for a wasm runtime. use crate::error::Error; -use sp_wasm_interface::Function; +use sp_wasm_interface::{Function, Value}; /// A trait that defines an abstract wasm runtime. /// @@ -28,4 +28,7 @@ pub trait WasmRuntime { /// Call a method in the Substrate runtime by name. Returns the encoded result on success. fn call(&mut self, method: &str, data: &[u8]) -> Result, Error>; + + /// Get the value from a global with the given `name`. + fn get_global_val(&self, name: &str) -> Result, Error>; } diff --git a/client/executor/runtime-test/src/lib.rs b/client/executor/runtime-test/src/lib.rs index b183398c02..38a16ae39e 100644 --- a/client/executor/runtime-test/src/lib.rs +++ b/client/executor/runtime-test/src/lib.rs @@ -275,6 +275,20 @@ sp_core::wasm_export_functions! { data.to_vec() } + + // Check that the heap at `heap_base + offset` don't contains the test message. + // After the check succeeds the test message is written into the heap. + // + // It is expected that the given pointer is not allocated. + fn check_and_set_in_heap(heap_base: u32, offset: u32) { + let test_message = b"Hello invalid heap memory"; + let ptr = unsafe { (heap_base + offset) as *mut u8 }; + + let message_slice = unsafe { sp_std::slice::from_raw_parts_mut(ptr, test_message.len()) }; + + assert_ne!(test_message, message_slice); + message_slice.copy_from_slice(test_message); + } } #[cfg(not(feature = "std"))] diff --git a/client/executor/src/integration_tests/mod.rs b/client/executor/src/integration_tests/mod.rs index 8c48ec7fcb..c0516d3ac7 100644 --- a/client/executor/src/integration_tests/mod.rs +++ b/client/executor/src/integration_tests/mod.rs @@ -565,3 +565,26 @@ fn restoration_of_globals(wasm_method: WasmExecutionMethod) { let res = instance.call("allocates_huge_stack_array", &false.encode()); assert!(res.is_ok()); } + +#[test_case(WasmExecutionMethod::Interpreted)] +fn heap_is_reset_between_calls(wasm_method: WasmExecutionMethod) { + let mut instance = crate::wasm_runtime::create_wasm_runtime_with_code( + wasm_method, + 1024, + &WASM_BINARY[..], + HostFunctions::host_functions(), + true, + ).expect("Creates instance"); + + let heap_base = instance.get_global_val("__heap_base") + .expect("`__heap_base` is valid") + .expect("`__heap_base` exists") + .as_i32() + .expect("`__heap_base` is an `i32`"); + + let params = (heap_base as u32, 512u32 * 64 * 1024).encode(); + instance.call("check_and_set_in_heap", ¶ms).unwrap(); + + // Cal it a second time to check that the heap was freed. + instance.call("check_and_set_in_heap", ¶ms).unwrap(); +} diff --git a/client/executor/wasmi/src/lib.rs b/client/executor/wasmi/src/lib.rs index 7965c7f95e..b90c0f05f5 100644 --- a/client/executor/wasmi/src/lib.rs +++ b/client/executor/wasmi/src/lib.rs @@ -669,6 +669,19 @@ impl WasmRuntime for WasmiRuntime { &self.missing_functions, ) } + + fn get_global_val(&self, name: &str) -> Result, Error> { + match self.instance.export_by_name(name) { + Some(global) => Ok(Some( + global + .as_global() + .ok_or_else(|| format!("`{}` is not a global", name))? + .get() + .into() + )), + None => Ok(None), + } + } } pub fn create_instance( diff --git a/client/executor/wasmtime/src/instance_wrapper.rs b/client/executor/wasmtime/src/instance_wrapper.rs index 8f722f6490..013651cd7a 100644 --- a/client/executor/wasmtime/src/instance_wrapper.rs +++ b/client/executor/wasmtime/src/instance_wrapper.rs @@ -21,10 +21,10 @@ use crate::util; use crate::imports::Imports; use sc_executor_common::error::{Error, Result}; -use sp_wasm_interface::{Pointer, WordSize}; +use sp_wasm_interface::{Pointer, WordSize, Value}; use std::slice; use std::marker; -use wasmtime::{Instance, Module, Memory, Table}; +use wasmtime::{Instance, Module, Memory, Table, Val}; /// Wrap the given WebAssembly Instance of a wasm module with Substrate-runtime. /// @@ -127,6 +127,24 @@ impl InstanceWrapper { Ok(heap_base as u32) } + + /// Get the value from a global with the given `name`. + pub fn get_global_val(&self, name: &str) -> Result> { + let global = match self.instance.get_export(name) { + Some(global) => global, + None => return Ok(None), + }; + + let global = global.global().ok_or_else(|| format!("`{}` is not a global", name))?; + + match global.get() { + Val::I32(val) => Ok(Some(Value::I32(val))), + Val::I64(val) => Ok(Some(Value::I64(val))), + Val::F32(val) => Ok(Some(Value::F32(val))), + Val::F64(val) => Ok(Some(Value::F64(val))), + _ => Err("Unknow value type".into()), + } + } } /// Extract linear memory instance from the given instance. diff --git a/client/executor/wasmtime/src/runtime.rs b/client/executor/wasmtime/src/runtime.rs index 106a398dfc..b99d334787 100644 --- a/client/executor/wasmtime/src/runtime.rs +++ b/client/executor/wasmtime/src/runtime.rs @@ -27,7 +27,7 @@ use sc_executor_common::{ }; use sp_allocator::FreeingBumpHeapAllocator; use sp_runtime_interface::unpack_ptr_and_len; -use sp_wasm_interface::{Function, Pointer, WordSize}; +use sp_wasm_interface::{Function, Pointer, WordSize, Value}; use wasmtime::{Config, Engine, Module, Store}; /// A `WasmRuntime` implementation using wasmtime to compile the runtime module to machine code @@ -55,6 +55,12 @@ impl WasmRuntime for WasmtimeRuntime { self.heap_pages, ) } + + fn get_global_val(&self, name: &str) -> Result> { + // Yeah, there is no better way currently :( + InstanceWrapper::new(&self.module, &self.imports, self.heap_pages)? + .get_global_val(name) + } } /// Create a new `WasmtimeRuntime` given the code. This function performs translation from Wasm to -- GitLab From 29454c30501ccf3a09fe82b965dd50e1a9e5aa24 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Fri, 14 Feb 2020 00:47:51 +0000 Subject: [PATCH 151/180] Composite accounts (#4820) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Basic account composition. * Add try_mutate_exists * De-duplicate * Refactor away the UpdateBalanceOutcome * Expunge final UpdateBalanceOutcome refs * Refactor transfer * Refactor reservable currency stuff. * Test with the alternative setup. * Fixes * Test with both setups. * Fixes * Fix * Fix macros * Make indices opt-in * Remove CreationFee, and make indices opt-in. * Fix construct_runtime * Fix last few bits * Fix tests * Update trait impls * Don't hardcode the system event * Make tests build and fix some stuff. * Pointlessly bump runtime version * Fix benchmark * Another fix * Whitespace * Make indices module economically safe * Migrations for indices. * Fix * Whilespace * Trim defunct migrations * Remove unused storage item * More contains_key fixes * Docs. * Bump runtime * Remove unneeded code * Fix test * Fix test * Update frame/balances/src/lib.rs Co-Authored-By: Shawn Tabrizi * Fix ED logic * Repatriate reserved logic * Typo * Fix typo * Update frame/system/src/lib.rs Co-Authored-By: Shawn Tabrizi * Update frame/system/src/lib.rs Co-Authored-By: Shawn Tabrizi * Last few fixes * Another fix * Build fix Co-authored-by: Bastian Köcher Co-authored-by: Jaco Greeff Co-authored-by: Shawn Tabrizi --- Cargo.lock | 1 + bin/node-template/node/src/chain_spec.rs | 4 +- .../pallets/template/src/mock.rs | 3 + bin/node-template/runtime/src/lib.rs | 33 +- bin/node/cli/src/chain_spec.rs | 8 +- bin/node/executor/tests/basic.rs | 56 +- bin/node/executor/tests/fees.rs | 11 +- bin/node/executor/tests/submit_transaction.rs | 2 +- bin/node/runtime/src/lib.rs | 68 +- bin/node/testing/src/genesis.rs | 2 +- frame/assets/src/lib.rs | 3 + frame/aura/src/mock.rs | 3 + frame/authority-discovery/src/lib.rs | 3 + frame/authorship/src/lib.rs | 3 + frame/babe/src/mock.rs | 3 + frame/balances/src/benchmarking.rs | 15 +- frame/balances/src/lib.rs | 576 ++++---- frame/balances/src/tests.rs | 1274 ++++++++--------- .../src/{mock.rs => tests_composite.rs} | 37 +- frame/balances/src/tests_local.rs | 144 ++ frame/collective/src/lib.rs | 5 +- frame/contracts/src/account_db.rs | 8 +- frame/contracts/src/exec.rs | 25 +- frame/contracts/src/lib.rs | 8 - frame/contracts/src/tests.rs | 321 +++-- frame/democracy/src/lib.rs | 13 +- frame/elections-phragmen/src/lib.rs | 25 +- frame/elections/src/lib.rs | 4 +- frame/elections/src/mock.rs | 18 +- frame/example/src/lib.rs | 11 +- frame/executive/src/lib.rs | 12 +- frame/finality-tracker/src/lib.rs | 3 + frame/generic-asset/src/lib.rs | 43 +- frame/generic-asset/src/mock.rs | 6 +- frame/generic-asset/src/tests.rs | 4 +- frame/grandpa/src/mock.rs | 4 + frame/identity/src/benchmarking.rs | 26 +- frame/identity/src/lib.rs | 13 +- frame/im-online/src/mock.rs | 3 + frame/indices/Cargo.toml | 3 + frame/indices/src/lib.rs | 325 +++-- frame/indices/src/mock.rs | 97 +- frame/indices/src/tests.rs | 80 +- frame/membership/src/lib.rs | 3 + frame/nicks/src/lib.rs | 9 +- frame/offences/src/mock.rs | 4 + frame/randomness-collective-flip/src/lib.rs | 3 + frame/recovery/src/lib.rs | 4 +- frame/recovery/src/mock.rs | 14 +- frame/scored-pool/src/mock.rs | 9 +- frame/session/src/mock.rs | 3 + frame/society/src/lib.rs | 4 +- frame/society/src/mock.rs | 9 +- frame/staking/src/lib.rs | 13 +- frame/staking/src/migration.rs | 140 -- frame/staking/src/mock.rs | 11 +- frame/staking/src/tests.rs | 58 - .../procedural/src/construct_runtime/mod.rs | 76 +- frame/support/src/event.rs | 47 +- frame/support/src/metadata.rs | 1 + frame/support/src/storage/generator/map.rs | 50 +- frame/support/src/storage/generator/value.rs | 4 + .../src => support/src/storage}/migration.rs | 16 +- frame/support/src/storage/mod.rs | 26 +- frame/support/src/traits.rs | 164 ++- .../missing_system_module.stderr | 2 +- frame/support/test/tests/decl_error.rs | 2 +- frame/support/test/tests/instance.rs | 2 +- frame/support/test/tests/issue2219.rs | 2 +- frame/support/test/tests/system.rs | 5 +- frame/system/benches/bench.rs | 4 + frame/system/src/lib.rs | 503 ++++--- frame/system/src/offchain.rs | 12 +- frame/timestamp/src/lib.rs | 3 + frame/transaction-payment/src/lib.rs | 12 +- frame/treasury/src/lib.rs | 11 +- frame/utility/src/lib.rs | 10 +- frame/vesting/src/lib.rs | 16 +- test-utils/runtime/src/lib.rs | 7 +- 79 files changed, 2462 insertions(+), 2103 deletions(-) rename frame/balances/src/{mock.rs => tests_composite.rs} (79%) create mode 100644 frame/balances/src/tests_local.rs delete mode 100644 frame/staking/src/migration.rs rename frame/{balances/src => support/src/storage}/migration.rs (75%) diff --git a/Cargo.lock b/Cargo.lock index 52a9c261ce..7a44b0ed77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4218,6 +4218,7 @@ version = "2.0.0" dependencies = [ "frame-support", "frame-system", + "pallet-balances", "parity-scale-codec", "serde", "sp-core", diff --git a/bin/node-template/node/src/chain_spec.rs b/bin/node-template/node/src/chain_spec.rs index aa50d06b23..9bdfea3b78 100644 --- a/bin/node-template/node/src/chain_spec.rs +++ b/bin/node-template/node/src/chain_spec.rs @@ -1,7 +1,7 @@ use sp_core::{Pair, Public, sr25519}; use node_template_runtime::{ AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, - SudoConfig, IndicesConfig, SystemConfig, WASM_BINARY, Signature + IndicesConfig, SudoConfig, SystemConfig, WASM_BINARY, Signature }; use sp_consensus_aura::sr25519::{AuthorityId as AuraId}; use grandpa_primitives::{AuthorityId as GrandpaId}; @@ -128,7 +128,7 @@ fn testnet_genesis(initial_authorities: Vec<(AuraId, GrandpaId)>, changes_trie_config: Default::default(), }), indices: Some(IndicesConfig { - ids: endowed_accounts.clone(), + indices: vec![], }), balances: Some(BalancesConfig { balances: endowed_accounts.iter().cloned().map(|k|(k, 1 << 60)).collect(), diff --git a/bin/node-template/pallets/template/src/mock.rs b/bin/node-template/pallets/template/src/mock.rs index 2cbfc89d5b..b3c1098db6 100644 --- a/bin/node-template/pallets/template/src/mock.rs +++ b/bin/node-template/pallets/template/src/mock.rs @@ -39,6 +39,9 @@ impl system::Trait for Test { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } impl Trait for Test { type Event = (); diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index b8a12e3112..04394917f1 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -161,6 +161,12 @@ impl system::Trait for Runtime { /// /// This type is being generated by `construct_runtime!`. type ModuleToIndex = ModuleToIndex; + /// What to do if a new account is created. + type OnNewAccount = (); + /// What to do if an account is fully reaped from the system. + type OnReapAccount = Balances; + /// The data to be stored in an account. + type AccountData = balances::AccountData; } impl aura::Trait for Runtime { @@ -171,16 +177,21 @@ impl grandpa::Trait for Runtime { type Event = Event; } +parameter_types! { + /// How much an index costs. + pub const IndexDeposit: u128 = 100; +} + impl indices::Trait for Runtime { /// The type for recording indexing into the account enumeration. If this ever overflows, there /// will be problems! type AccountIndex = AccountIndex; - /// Use the standard means of resolving an index hint from an id. - type ResolveHint = indices::SimpleResolveHint; - /// Determine whether an account is dead. - type IsDeadAccount = Balances; /// The ubiquitous event type. type Event = Event; + /// The currency type. + type Currency = Balances; + /// How much an index costs. + type Deposit = IndexDeposit; } parameter_types! { @@ -196,22 +207,16 @@ impl timestamp::Trait for Runtime { parameter_types! { pub const ExistentialDeposit: u128 = 500; - pub const CreationFee: u128 = 0; } impl balances::Trait for Runtime { /// The type for recording an account's balance. type Balance = Balance; - /// What to do if an account is fully reaped from the system. - type OnReapAccount = System; - /// What to do if a new account is created. - type OnNewAccount = Indices; /// The ubiquitous event type. type Event = Event; type DustRemoval = (); - type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; + type AccountStore = System; } parameter_types! { @@ -244,12 +249,12 @@ construct_runtime!( NodeBlock = opaque::Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system::{Module, Call, Storage, Config, Event}, + System: system::{Module, Call, Config, Storage, Event}, Timestamp: timestamp::{Module, Call, Storage, Inherent}, Aura: aura::{Module, Config, Inherent(Timestamp)}, Grandpa: grandpa::{Module, Call, Storage, Config, Event}, - Indices: indices, - Balances: balances, + Indices: indices::{Module, Call, Storage, Event, Config}, + Balances: balances::{Module, Call, Storage, Config, Event}, TransactionPayment: transaction_payment::{Module, Storage}, Sudo: sudo, // Used for the module template in `./template.rs` diff --git a/bin/node/cli/src/chain_spec.rs b/bin/node/cli/src/chain_spec.rs index c68283ad65..5cdfb5cab8 100644 --- a/bin/node/cli/src/chain_spec.rs +++ b/bin/node/cli/src/chain_spec.rs @@ -21,8 +21,8 @@ use sp_core::{Pair, Public, crypto::UncheckedInto, sr25519}; use serde::{Serialize, Deserialize}; use node_runtime::{ AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, DemocracyConfig, - GrandpaConfig, ImOnlineConfig, IndicesConfig, SessionConfig, SessionKeys, StakerStatus, StakingConfig, - SocietyConfig, SudoConfig, SystemConfig, TechnicalCommitteeConfig, WASM_BINARY, + GrandpaConfig, ImOnlineConfig, SessionConfig, SessionKeys, StakerStatus, StakingConfig, + IndicesConfig, SocietyConfig, SudoConfig, SystemConfig, TechnicalCommitteeConfig, WASM_BINARY, }; use node_runtime::Block; use node_runtime::constants::currency::*; @@ -239,9 +239,7 @@ pub fn testnet_genesis( .collect(), }), pallet_indices: Some(IndicesConfig { - ids: endowed_accounts.iter().cloned() - .chain(initial_authorities.iter().map(|x| x.0.clone())) - .collect::>(), + indices: vec![], }), pallet_session: Some(SessionConfig { keys: initial_authorities.iter().map(|x| { diff --git a/bin/node/executor/tests/basic.rs b/bin/node/executor/tests/basic.rs index b306852f45..100bdf3fe6 100644 --- a/bin/node/executor/tests/basic.rs +++ b/bin/node/executor/tests/basic.rs @@ -35,7 +35,7 @@ use frame_system::{self, EventRecord, Phase}; use node_runtime::{ Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances, - System, TransactionPayment, Event, TransactionBaseFee, TransactionByteFee, CreationFee, + System, TransactionPayment, Event, TransactionBaseFee, TransactionByteFee, constants::currency::*, }; use node_primitives::{Balance, Hash}; @@ -163,15 +163,12 @@ fn block_with_size(time: u64, nonce: u32, size: usize) -> (Vec, Hash) { fn panic_execution_with_foreign_code_gives_error() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, Storage { top: map![ - >::hashed_key_for(alice()) => { + >::hashed_key_for(alice()) => { (69u128, 0u128, 0u128, 0u128).encode() }, >::hashed_key().to_vec() => { 69_u128.encode() }, - >::hashed_key().to_vec() => { - 0_u128.encode() - }, >::hashed_key_for(0) => { vec![0u8; 32] } @@ -202,15 +199,12 @@ fn panic_execution_with_foreign_code_gives_error() { fn bad_extrinsic_with_native_equivalent_code_gives_error() { let mut t = TestExternalities::::new_with_code(COMPACT_CODE, Storage { top: map![ - >::hashed_key_for(alice()) => { - (69u128, 0u128, 0u128, 0u128).encode() + >::hashed_key_for(alice()) => { + (0u32, 69u128, 0u128, 0u128, 0u128).encode() }, >::hashed_key().to_vec() => { 69_u128.encode() }, - >::hashed_key().to_vec() => { - 0_u128.encode() - }, >::hashed_key_for(0) => { vec![0u8; 32] } @@ -241,13 +235,12 @@ fn bad_extrinsic_with_native_equivalent_code_gives_error() { fn successful_execution_with_native_equivalent_code_gives_ok() { let mut t = TestExternalities::::new_with_code(COMPACT_CODE, Storage { top: map![ - >::hashed_key_for(alice()) => { - (111 * DOLLARS, 0u128, 0u128, 0u128).encode() + >::hashed_key_for(alice()) => { + (0u32, 111 * DOLLARS, 0u128, 0u128, 0u128).encode() }, >::hashed_key().to_vec() => { (111 * DOLLARS).encode() }, - >::hashed_key().to_vec() => vec![0u8; 16], >::hashed_key_for(0) => vec![0u8; 32] ], children: map![], @@ -274,7 +267,7 @@ fn successful_execution_with_native_equivalent_code_gives_ok() { assert!(r.is_ok()); t.execute_with(|| { - let fees = transfer_fee(&xt(), fm) + CreationFee::get(); + let fees = transfer_fee(&xt(), fm); assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); @@ -284,13 +277,12 @@ fn successful_execution_with_native_equivalent_code_gives_ok() { fn successful_execution_with_foreign_code_gives_ok() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, Storage { top: map![ - >::hashed_key_for(alice()) => { - (111 * DOLLARS, 0u128, 0u128, 0u128).encode() + >::hashed_key_for(alice()) => { + (0u32, 111 * DOLLARS, 0u128, 0u128, 0u128).encode() }, >::hashed_key().to_vec() => { (111 * DOLLARS).encode() }, - >::hashed_key().to_vec() => vec![0u8; 16], >::hashed_key_for(0) => vec![0u8; 32] ], children: map![], @@ -317,7 +309,7 @@ fn successful_execution_with_foreign_code_gives_ok() { assert!(r.is_ok()); t.execute_with(|| { - let fees = transfer_fee(&xt(), fm) + CreationFee::get(); + let fees = transfer_fee(&xt(), fm); assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); @@ -348,7 +340,7 @@ fn full_native_block_import_works() { let events = vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: Event::system(frame_system::Event::ExtrinsicSuccess( + event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( DispatchInfo { weight: 10000, class: DispatchClass::Operational, pays_fee: true } )), topics: vec![], @@ -364,13 +356,12 @@ fn full_native_block_import_works() { alice().into(), bob().into(), 69 * DOLLARS, - 0, )), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(1), - event: Event::system(frame_system::Event::ExtrinsicSuccess( + event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( DispatchInfo { weight: 1000000, class: DispatchClass::Normal, pays_fee: true } )), topics: vec![], @@ -401,7 +392,7 @@ fn full_native_block_import_works() { let events = vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: Event::system(frame_system::Event::ExtrinsicSuccess( + event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( DispatchInfo { weight: 10000, class: DispatchClass::Operational, pays_fee: true } )), topics: vec![], @@ -418,14 +409,13 @@ fn full_native_block_import_works() { bob().into(), alice().into(), 5 * DOLLARS, - 0, ) ), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(1), - event: Event::system(frame_system::Event::ExtrinsicSuccess( + event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( DispatchInfo { weight: 1000000, class: DispatchClass::Normal, pays_fee: true } )), topics: vec![], @@ -442,14 +432,13 @@ fn full_native_block_import_works() { alice().into(), bob().into(), 15 * DOLLARS, - 0, ) ), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(2), - event: Event::system(frame_system::Event::ExtrinsicSuccess( + event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( DispatchInfo { weight: 1000000, class: DispatchClass::Normal, pays_fee: true } )), topics: vec![], @@ -712,13 +701,9 @@ fn native_big_block_import_fails_on_fallback() { fn panic_execution_gives_error() { let mut t = TestExternalities::::new_with_code(BLOATY_CODE, Storage { top: map![ - >::hashed_key_for(alice()) => { - (0_u128, 0_u128, 0_u128, 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![], @@ -747,13 +732,12 @@ fn panic_execution_gives_error() { fn successful_execution_gives_ok() { let mut t = TestExternalities::::new_with_code(COMPACT_CODE, Storage { top: map![ - >::hashed_key_for(alice()) => { - (111 * DOLLARS, 0u128, 0u128, 0u128).encode() + >::hashed_key_for(alice()) => { + (0u32, 111 * DOLLARS, 0u128, 0u128, 0u128).encode() }, >::hashed_key().to_vec() => { (111 * DOLLARS).encode() }, - >::hashed_key().to_vec() => vec![0u8; 16], >::hashed_key_for(0) => vec![0u8; 32] ], children: map![], @@ -777,11 +761,11 @@ fn successful_execution_gives_ok() { ).0.unwrap().into_encoded(); ApplyExtrinsicResult::decode(&mut &r[..]) .unwrap() - .expect("Extrinsic could be applied") - .expect("Extrinsic did not fail"); + .expect("Extrinsic could not be applied") + .expect("Extrinsic failed"); t.execute_with(|| { - let fees = transfer_fee(&xt(), fm) + CreationFee::get(); + let fees = transfer_fee(&xt(), fm); assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); diff --git a/bin/node/executor/tests/fees.rs b/bin/node/executor/tests/fees.rs index 155cefa4cc..ba303a6feb 100644 --- a/bin/node/executor/tests/fees.rs +++ b/bin/node/executor/tests/fees.rs @@ -134,16 +134,15 @@ fn transaction_fee_is_correct_ultimate() { // (this baed on assigning 0.1 CENT to the cheapest tx with `weight = 100`) let mut t = TestExternalities::::new_with_code(COMPACT_CODE, Storage { top: map![ - >::hashed_key_for(alice()) => { - (100 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS).encode() + >::hashed_key_for(alice()) => { + (0u32, 100 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS).encode() }, - >::hashed_key_for(bob()) => { - (10 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS).encode() + >::hashed_key_for(bob()) => { + (0u32, 10 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS).encode() }, >::hashed_key().to_vec() => { - (110 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS).encode() + (110 * DOLLARS).encode() }, - >::hashed_key().to_vec() => vec![0u8; 16], >::hashed_key_for(0) => vec![0u8; 32] ], children: map![], diff --git a/bin/node/executor/tests/submit_transaction.rs b/bin/node/executor/tests/submit_transaction.rs index 40c0c6b80f..b870cf4037 100644 --- a/bin/node/executor/tests/submit_transaction.rs +++ b/bin/node/executor/tests/submit_transaction.rs @@ -168,7 +168,7 @@ fn submitted_transaction_should_be_valid() { let author = extrinsic.signature.clone().unwrap().0; let address = Indices::lookup(author).unwrap(); let account = pallet_balances::AccountData { free: 5_000_000_000_000, ..Default::default() }; - >::insert(&address, account); + >::insert(&address, (0u32, account)); // check validity let res = Executive::validate_transaction(extrinsic); diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 8d8e784f98..cdcf670c64 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -82,8 +82,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 217, - impl_version: 1, + spec_version: 218, + impl_version: 0, apis: RUNTIME_API_VERSIONS, }; @@ -130,6 +130,9 @@ impl frame_system::Trait for Runtime { type AvailableBlockRatio = AvailableBlockRatio; type Version = Version; type ModuleToIndex = ModuleToIndex; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnReapAccount = (Balances, Staking, Contracts, Session, Recovery); } parameter_types! { @@ -160,27 +163,27 @@ impl pallet_babe::Trait for Runtime { type EpochChangeTrigger = pallet_babe::ExternalTrigger; } +parameter_types! { + pub const IndexDeposit: Balance = 1 * DOLLARS; +} + impl pallet_indices::Trait for Runtime { type AccountIndex = AccountIndex; - type IsDeadAccount = Balances; - type ResolveHint = pallet_indices::SimpleResolveHint; type Event = Event; + type Currency = Balances; + type Deposit = IndexDeposit; } parameter_types! { pub const ExistentialDeposit: Balance = 1 * DOLLARS; - pub const CreationFee: Balance = 1 * CENTS; } impl pallet_balances::Trait for Runtime { type Balance = Balance; - type OnReapAccount = ((((System, Staking), Contracts), Session), Recovery); - type OnNewAccount = Indices; - type Event = Event; type DustRemoval = (); - type TransferPayment = (); + type Event = Event; type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; + type AccountStore = frame_system::Module; } parameter_types! { @@ -235,13 +238,13 @@ parameter_types! { } impl pallet_session::Trait for Runtime { - type SessionManager = Staking; - type SessionHandler = ::KeyTypeIdProviders; - type ShouldEndSession = Babe; type Event = Event; - type Keys = SessionKeys; type ValidatorId = ::AccountId; type ValidatorIdOf = pallet_staking::StashOf; + type ShouldEndSession = Babe; + type SessionManager = Staking; + type SessionHandler = ::KeyTypeIdProviders; + type Keys = SessionKeys; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; } @@ -303,7 +306,6 @@ impl pallet_democracy::Trait for Runtime { type EnactmentPeriod = EnactmentPeriod; type LaunchPeriod = LaunchPeriod; type VotingPeriod = VotingPeriod; - type EmergencyVotingPeriod = EmergencyVotingPeriod; type MinimumDeposit = MinimumDeposit; /// A straight majority of the council can decide what their next motion is. type ExternalOrigin = pallet_collective::EnsureProportionAtLeast<_1, _2, AccountId, CouncilCollective>; @@ -315,6 +317,7 @@ impl pallet_democracy::Trait for Runtime { /// Two thirds of the technical committee can have an ExternalMajority/ExternalDefault vote /// be tabled immediately and with a shorter voting/enactment period. type FastTrackOrigin = pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, TechnicalCollective>; + type EmergencyVotingPeriod = EmergencyVotingPeriod; // To cancel a proposal which has been passed, 2/3 of the council must agree to it. type CancellationOrigin = pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId, CouncilCollective>; // Any single technical committee member may veto a coming council proposal, however they can @@ -343,16 +346,16 @@ parameter_types! { impl pallet_elections_phragmen::Trait for Runtime { type Event = Event; type Currency = Balances; + type ChangeMembers = Council; type CurrencyToVote = CurrencyToVoteHandler; type CandidacyBond = CandidacyBond; type VotingBond = VotingBond; - type TermDuration = TermDuration; - type DesiredMembers = DesiredMembers; - type DesiredRunnersUp = DesiredRunnersUp; type LoserCandidate = (); type BadReport = (); type KickedMember = (); - type ChangeMembers = Council; + type DesiredMembers = DesiredMembers; + type DesiredRunnersUp = DesiredRunnersUp; + type TermDuration = TermDuration; } type TechnicalCollective = pallet_collective::Instance2; @@ -387,22 +390,20 @@ impl pallet_treasury::Trait for Runtime { type Currency = Balances; type ApproveOrigin = pallet_collective::EnsureMembers<_4, AccountId, CouncilCollective>; type RejectOrigin = pallet_collective::EnsureMembers<_2, AccountId, CouncilCollective>; + type Tippers = Elections; + type TipCountdown = TipCountdown; + type TipFindersFee = TipFindersFee; + type TipReportDepositBase = TipReportDepositBase; + type TipReportDepositPerByte = TipReportDepositPerByte; type Event = Event; type ProposalRejection = (); type ProposalBond = ProposalBond; type ProposalBondMinimum = ProposalBondMinimum; type SpendPeriod = SpendPeriod; type Burn = Burn; - type Tippers = Elections; - type TipCountdown = TipCountdown; - type TipFindersFee = TipFindersFee; - type TipReportDepositBase = TipReportDepositBase; - type TipReportDepositPerByte = TipReportDepositPerByte; } parameter_types! { - pub const ContractTransferFee: Balance = 1 * CENTS; - pub const ContractCreationFee: Balance = 1 * CENTS; pub const ContractTransactionBaseFee: Balance = 1 * CENTS; pub const ContractTransactionByteFee: Balance = 10 * MILLICENTS; pub const ContractFee: Balance = 1 * CENTS; @@ -429,7 +430,6 @@ impl pallet_contracts::Trait for Runtime { type RentByteFee = RentByteFee; type RentDepositOffset = RentDepositOffset; type SurchargeReward = SurchargeReward; - type CreationFee = ContractCreationFee; type TransactionBaseFee = ContractTransactionBaseFee; type TransactionByteFee = ContractTransactionByteFee; type ContractFee = ContractFee; @@ -454,11 +454,11 @@ parameter_types! { impl pallet_im_online::Trait for Runtime { type AuthorityId = ImOnlineId; - type Call = Call; type Event = Event; + type Call = Call; type SubmitTransaction = SubmitTransaction; - type ReportUnresponsiveness = Offences; type SessionDuration = SessionDuration; + type ReportUnresponsiveness = Offences; } impl pallet_offences::Trait for Runtime { @@ -495,14 +495,14 @@ parameter_types! { impl pallet_identity::Trait for Runtime { type Event = Event; type Currency = Balances; - type Slashed = Treasury; type BasicDeposit = BasicDeposit; type FieldDeposit = FieldDeposit; type SubAccountDeposit = SubAccountDeposit; type MaxSubAccounts = MaxSubAccounts; type MaxAdditionalFields = MaxAdditionalFields; - type RegistrarOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; + type Slashed = Treasury; type ForceOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; + type RegistrarOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; } impl frame_system::offchain::CreateTransaction for Runtime { @@ -600,13 +600,13 @@ construct_runtime!( NodeBlock = node_primitives::Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: frame_system::{Module, Call, Storage, Config, Event}, + System: frame_system::{Module, Call, Config, Storage, Event}, Utility: pallet_utility::{Module, Call, Storage, 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, + Indices: pallet_indices::{Module, Call, Storage, Config, Event}, + Balances: pallet_balances::{Module, Call, Storage, Config, Event}, TransactionPayment: pallet_transaction_payment::{Module, Storage}, Staking: pallet_staking, Session: pallet_session::{Module, Call, Storage, Event, Config}, diff --git a/bin/node/testing/src/genesis.rs b/bin/node/testing/src/genesis.rs index 58e646e3d7..9c163ea615 100644 --- a/bin/node/testing/src/genesis.rs +++ b/bin/node/testing/src/genesis.rs @@ -62,7 +62,7 @@ pub fn config_endowed( code: code.map(|x| x.to_vec()).unwrap_or_else(|| WASM_BINARY.to_vec()), }), pallet_indices: Some(IndicesConfig { - ids: vec![alice(), bob(), charlie(), dave(), eve(), ferdie()], + indices: vec![], }), pallet_balances: Some(BalancesConfig { balances: endowed, diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index e5c370cd21..8cdc9b9cc0 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -293,6 +293,9 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type Version = (); type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } impl Trait for Test { type Event = (); diff --git a/frame/aura/src/mock.rs b/frame/aura/src/mock.rs index 81366cf084..5b3ccd7745 100644 --- a/frame/aura/src/mock.rs +++ b/frame/aura/src/mock.rs @@ -61,6 +61,9 @@ impl frame_system::Trait for Test { type MaximumBlockLength = MaximumBlockLength; type Version = (); type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } impl pallet_timestamp::Trait for Test { diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index 22ea3d3bba..77906e1bfe 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -157,6 +157,9 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type Version = (); type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } impl_outer_origin! { diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index 216f5c729a..f2dbd4674f 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -431,6 +431,9 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type Version = (); type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } parameter_types! { diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index f5ade4ab33..efb5570c1d 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -66,6 +66,9 @@ impl frame_system::Trait for Test { type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } impl_opaque_keys! { diff --git a/frame/balances/src/benchmarking.rs b/frame/balances/src/benchmarking.rs index f48220c1ba..605561d597 100644 --- a/frame/balances/src/benchmarking.rs +++ b/frame/balances/src/benchmarking.rs @@ -50,7 +50,7 @@ impl BenchmarkingSetup, RawOrigin> for { // Constants let ed = T::ExistentialDeposit::get(); - + // Select an account let u = components.iter().find(|&c| c.0 == BenchmarkParameter::U).unwrap().1; let user = account::("user", u); @@ -58,8 +58,7 @@ impl BenchmarkingSetup, RawOrigin> for // Give some multiple of the existential deposit + creation fee + transfer fee let e = components.iter().find(|&c| c.0 == BenchmarkParameter::E).unwrap().1; - let mut balance = ed.saturating_mul(e.into()); - balance += T::CreationFee::get(); + let balance = ed.saturating_mul(e.into()); let _ = as Currency<_>>::make_free_balance_be(&user, balance); // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, and reap this user. @@ -90,7 +89,7 @@ impl BenchmarkingSetup, RawOrigin> for { // Constants let ed = T::ExistentialDeposit::get(); - + // Select a sender let u = components.iter().find(|&c| c.0 == BenchmarkParameter::U).unwrap().1; let user = account::("user", u); @@ -135,7 +134,7 @@ impl BenchmarkingSetup, RawOrigin> for { // Constants let ed = T::ExistentialDeposit::get(); - + // Select a sender let u = components.iter().find(|&c| c.0 == BenchmarkParameter::U).unwrap().1; let user = account::("user", u); @@ -176,7 +175,7 @@ impl BenchmarkingSetup, RawOrigin> for { // Constants let ed = T::ExistentialDeposit::get(); - + // Select a sender let u = components.iter().find(|&c| c.0 == BenchmarkParameter::U).unwrap().1; let user = account::("user", u); @@ -208,7 +207,7 @@ impl BenchmarkingSetup, RawOrigin> for { // Constants let ed = T::ExistentialDeposit::get(); - + // Select a sender let u = components.iter().find(|&c| c.0 == BenchmarkParameter::U).unwrap().1; let user = account::("user", u); @@ -275,7 +274,7 @@ impl Benchmarking for Module { sp_io::benchmarking::commit_db(); sp_io::benchmarking::wipe_db(); - let components = , RawOrigin>>::components(&selected_benchmark); + let components = , RawOrigin>>::components(&selected_benchmark); // results go here let mut results: Vec = Vec::new(); // Select the component we will be benchmarking. Each component will be benchmarked. diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index 10151ab461..fc2294dd51 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -149,21 +149,24 @@ #![cfg_attr(not(feature = "std"), no_std)] #[cfg(test)] -mod mock; +mod tests_local; #[cfg(test)] +mod tests_composite; +#[cfg(test)] +#[macro_use] mod tests; -mod migration; mod benchmarking; use sp_std::prelude::*; -use sp_std::{cmp, result, mem, fmt::Debug, ops::BitOr}; +use sp_std::{cmp, result, mem, fmt::Debug, ops::BitOr, convert::Infallible}; use codec::{Codec, Encode, Decode}; use frame_support::{ StorageValue, Parameter, decl_event, decl_storage, decl_module, decl_error, ensure, - weights::SimpleDispatchInfo, traits::{ - UpdateBalanceOutcome, Currency, OnReapAccount, OnUnbalanced, TryDrop, + weights::SimpleDispatchInfo, traits::{ + Currency, OnReapAccount, OnUnbalanced, TryDrop, StoredMap, WithdrawReason, WithdrawReasons, LockIdentifier, LockableCurrency, ExistenceRequirement, - Imbalance, SignedImbalance, ReservableCurrency, Get, ExistenceRequirement::KeepAlive + Imbalance, SignedImbalance, ReservableCurrency, Get, ExistenceRequirement::KeepAlive, + ExistenceRequirement::AllowDeath, IsDeadAccount, BalanceStatus as Status } }; use sp_runtime::{ @@ -173,8 +176,10 @@ use sp_runtime::{ MaybeSerializeDeserialize, Saturating, Bounded, }, }; -use frame_system::{self as system, IsDeadAccount, OnNewAccount, ensure_signed, ensure_root}; -use migration::{get_storage_value, put_storage_value, StorageIterator}; +use frame_system::{self as system, ensure_signed, ensure_root}; +use frame_support::storage::migration::{ + get_storage_value, take_storage_value, put_storage_value, StorageIterator +}; pub use self::imbalances::{PositiveImbalance, NegativeImbalance}; @@ -183,21 +188,11 @@ pub trait Subtrait: frame_system::Trait { type Balance: Parameter + Member + AtLeast32Bit + Codec + Default + Copy + MaybeSerializeDeserialize + Debug; - /// A function that is invoked when the free-balance and the reserved-balance has fallen below - /// the existential deposit and both have been reduced to zero. - /// - /// All resources should be cleaned up all resources associated with the given account. - type OnReapAccount: OnReapAccount; - - /// Handler for when a new account is created. - type OnNewAccount: OnNewAccount; - /// The minimum amount required to keep an account open. type ExistentialDeposit: Get; - /// The fee required to create an account. If you're doing significant stuff with `OnNewAccount` - /// then you'll probably want to make this non-zero. - type CreationFee: Get; + /// The means of storing the balances of an account. + type AccountStore: StoredMap>; } pub trait Trait: frame_system::Trait { @@ -205,19 +200,6 @@ pub trait Trait: frame_system::Trait { type Balance: Parameter + Member + AtLeast32Bit + Codec + Default + Copy + MaybeSerializeDeserialize + Debug; - /// A function that is invoked when the free-balance and the reserved-balance has fallen below - /// the existential deposit and both have been reduced to zero. - /// - /// All resources should be cleaned up all resources associated with the given account. - type OnReapAccount: OnReapAccount; - - /// Handler for when a new account is created. - type OnNewAccount: OnNewAccount; - - /// Handler for the unbalanced reduction when taking fees associated with balance - /// transfer (which may also include account creation). - type TransferPayment: OnUnbalanced>; - /// Handler for the unbalanced reduction when removing a dust account. type DustRemoval: OnUnbalanced>; @@ -227,16 +209,14 @@ pub trait Trait: frame_system::Trait { /// The minimum amount required to keep an account open. type ExistentialDeposit: Get; - /// The fee required to create an account. - type CreationFee: Get; + /// The means of storing the balances of an account. + type AccountStore: StoredMap>; } impl, I: Instance> Subtrait for T { type Balance = T::Balance; - type OnReapAccount = T::OnReapAccount; - type OnNewAccount = T::OnNewAccount; type ExistentialDeposit = T::ExistentialDeposit; - type CreationFee = T::CreationFee; + type AccountStore = T::AccountStore; } decl_event!( @@ -244,12 +224,13 @@ decl_event!( ::AccountId, >::Balance { - /// A new account was created. - NewAccount(AccountId, Balance), - /// An account was reaped. - ReapedAccount(AccountId, Balance), - /// Transfer succeeded (from, to, value, fees). - Transfer(AccountId, AccountId, Balance, Balance), + /// An account was created with some free balance. + Endowed(AccountId, Balance), + /// An account was removed whose balance was non-zero but below ExistentialDeposit, + /// resulting in an outright loss. + DustLost(AccountId, Balance), + /// Transfer succeeded (from, to, value). + Transfer(AccountId, AccountId, Balance), /// A balance was set by root (who, free, reserved). BalanceSet(AccountId, Balance, Balance), /// Some amount was deposited (e.g. for transaction fees). @@ -376,11 +357,9 @@ decl_storage! { /// /// NOTE: THIS MAY NEVER BE IN EXISTENCE AND YET HAVE A `total().is_zero()`. If the total /// is ever zero, then the entry *MUST* be removed. - pub Account get(fn account) - build(|config: &GenesisConfig| config.balances.iter() - .map(|&(ref who, free)| (who.clone(), AccountData { free, .. Default::default() })) - .collect::>() - ): map hasher(blake2_256) T::AccountId => AccountData; + /// + /// NOTE: This is only used in the case that this module is used to store balances. + pub Account: map hasher(blake2_256) T::AccountId => AccountData; /// Any liquidity locks on some account balances. /// NOTE: Should only be accessed when setting, changing and freeing a lock. @@ -405,6 +384,9 @@ decl_storage! { "the balance of any account should always be more than existential deposit.", ) } + for &(ref who, free) in config.balances.iter() { + T::AccountStore::insert(who, AccountData { free, .. Default::default() }); + } }); } } @@ -416,9 +398,6 @@ decl_module! { /// The minimum amount required to keep an account open. const ExistentialDeposit: T::Balance = T::ExistentialDeposit::get(); - /// The fee required to create an account. - const CreationFee: T::Balance = T::CreationFee::get(); - fn deposit_event() = default; /// Transfer some liquid free balance to another account. @@ -484,24 +463,25 @@ decl_module! { let new_free = if wipeout { Zero::zero() } else { new_free }; let new_reserved = if wipeout { Zero::zero() } else { new_reserved }; - let old_account = Account::::get(&who); - - if new_free > old_account.free { - mem::drop(PositiveImbalance::::new(new_free - old_account.free)); - } else if new_free < old_account.free { - mem::drop(NegativeImbalance::::new(old_account.free - new_free)); - } + let (free, reserved) = Self::mutate_account(&who, |account| { + if new_free > account.free { + mem::drop(PositiveImbalance::::new(new_free - account.free)); + } else if new_free < account.free { + mem::drop(NegativeImbalance::::new(account.free - new_free)); + } - if new_reserved > old_account.reserved { - mem::drop(PositiveImbalance::::new(new_reserved - old_account.reserved)); - } else if new_reserved < old_account.reserved { - mem::drop(NegativeImbalance::::new(old_account.reserved - new_reserved)); - } + if new_reserved > account.reserved { + mem::drop(PositiveImbalance::::new(new_reserved - account.reserved)); + } else if new_reserved < account.reserved { + mem::drop(NegativeImbalance::::new(account.reserved - new_reserved)); + } - let account = AccountData { free: new_free, reserved: new_reserved, ..old_account }; - Self::set_account(&who, &account, &old_account); + account.free = new_free; + account.reserved = new_reserved; - Self::deposit_event(RawEvent::BalanceSet(who, account.free, account.reserved)); + (account.free, account.reserved) + }); + Self::deposit_event(RawEvent::BalanceSet(who, free, reserved)); } /// Exactly as `transfer`, except the origin must be root and the source account may be @@ -626,87 +606,110 @@ impl, I: Instance> Module { put_storage_value(b"Balances", b"Locks", &hash, locks); put_storage_value(b"Balances", b"Account", &hash, account); } + + for (hash, balances) in StorageIterator::>::new(b"Balances", b"Account").drain() { + let nonce = take_storage_value::(b"System", b"AccountNonce", &hash).unwrap_or_default(); + put_storage_value(b"System", b"Account", &hash, (nonce, balances)); + } } /// Get the free balance of an account. pub fn free_balance(who: impl sp_std::borrow::Borrow) -> T::Balance { - Account::::get(who.borrow()).free + Self::account(who.borrow()).free } /// Get the balance of an account that can be used for transfers, reservations, or any other /// non-locking, non-transaction-fee activity. Will be at most `free_balance`. pub fn usable_balance(who: impl sp_std::borrow::Borrow) -> T::Balance { - Account::::get(who.borrow()).usable(Reasons::Misc) + Self::account(who.borrow()).usable(Reasons::Misc) } /// Get the balance of an account that can be used for paying transaction fees (not tipping, /// or any other kind of fees, though). Will be at most `free_balance`. pub fn usable_balance_for_fees(who: impl sp_std::borrow::Borrow) -> T::Balance { - Account::::get(who.borrow()).usable(Reasons::Fee) + Self::account(who.borrow()).usable(Reasons::Fee) } /// Get the reserved balance of an account. pub fn reserved_balance(who: impl sp_std::borrow::Borrow) -> T::Balance { - Account::::get(who.borrow()).reserved + Self::account(who.borrow()).reserved } - /// Set both the free and reserved balance of an account to some new value. Will enforce - /// `ExistentialDeposit` law, annulling the account as needed. - /// - /// Will return `AccountKilled` if either reserved or free are too low. - /// - /// NOTE: This assumes that `account` is the same as `Self::account(who)` except for altered - /// values of `free` and `balance`. - /// - /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used - /// when it is known that the account already exists. + /// Get both the free and reserved balances of an account. + fn account(who: &T::AccountId) -> AccountData { + T::AccountStore::get(&who) + } + + /// Places the `free` and `reserved` parts of `new` into `account`. Also does any steps needed + /// after mutating an account. This includes DustRemoval unbalancing, in the case than the `new` + /// account's total balance is non-zero but below ED. /// - /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that - /// the caller will do this. - fn set_account( + /// Returns the final free balance, iff the account was previously of total balance zero, known + /// as its "endowment". + fn post_mutation( who: &T::AccountId, - account: &AccountData, - old: &AccountData, - ) -> UpdateBalanceOutcome { - let total = account.free + account.reserved; + new: AccountData, + ) -> Option> { + let total = new.total(); if total < T::ExistentialDeposit::get() { - T::DustRemoval::on_unbalanced(NegativeImbalance::new(total)); - if !old.total().is_zero() { - Self::reap_account(who, total); - UpdateBalanceOutcome::AccountKilled - } else { - UpdateBalanceOutcome::StillDead + if !total.is_zero() { + T::DustRemoval::on_unbalanced(NegativeImbalance::new(total)); + Self::deposit_event(RawEvent::DustLost(who.clone(), total)); } + None } else { - if old.total().is_zero() { - Self::about_to_create_account(who, account.free); - } - Account::::insert(who, account); - UpdateBalanceOutcome::Updated + Some(new) } } - /// Register a new account (with existential balance). + /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce + /// `ExistentialDeposit` law, annulling the account as needed. /// - /// This just calls appropriate hooks. It doesn't (necessarily) make any state changes. - fn about_to_create_account(who: &T::AccountId, balance: T::Balance) { - T::OnNewAccount::on_new_account(&who); - Self::deposit_event(RawEvent::NewAccount(who.clone(), balance.clone())); + /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used + /// when it is known that the account already exists. + /// + /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that + /// the caller will do this. + fn mutate_account( + who: &T::AccountId, + f: impl FnOnce(&mut AccountData) -> R + ) -> R { + Self::try_mutate_account(who, |a| -> Result { Ok(f(a)) }) + .expect("Error is infallible; qed") } - /// Unregister an account. + /// Mutate an account to some new value, or delete it entirely with `None`. Will enforce + /// `ExistentialDeposit` law, annulling the account as needed. This will do nothing if the + /// result of `f` is an `Err`. /// - /// This just removes the nonce and leaves an event. - fn reap_account(who: &T::AccountId, dust: T::Balance) { - Locks::::remove(who); - Account::::remove(who); - T::OnReapAccount::on_reap_account(who); - Self::deposit_event(RawEvent::ReapedAccount(who.clone(), dust)); + /// NOTE: Doesn't do any preparatory work for creating a new account, so should only be used + /// when it is known that the account already exists. + /// + /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that + /// the caller will do this. + fn try_mutate_account( + who: &T::AccountId, + f: impl FnOnce(&mut AccountData) -> Result + ) -> Result { + T::AccountStore::try_mutate_exists(who, |maybe_account| { + let mut account = maybe_account.take().unwrap_or_default(); + let was_zero = account.total().is_zero(); + f(&mut account).map(move |result| { + let maybe_endowed = if was_zero { Some(account.free) } else { None }; + *maybe_account = Self::post_mutation(who, account); + (maybe_endowed, result) + }) + }).map(|(maybe_endowed, result)| { + if let Some(endowed) = maybe_endowed { + Self::deposit_event(RawEvent::Endowed(who.clone(), endowed)); + } + result + }) } /// Update the account entry for `who`, given the locks. fn update_locks(who: &T::AccountId, locks: &[BalanceLock]) { - Account::::mutate(who, |b| { + Self::mutate_account(who, |b| { b.misc_frozen = Zero::zero(); b.fee_frozen = Zero::zero(); for l in locks.iter() { @@ -722,6 +725,13 @@ impl, I: Instance> Module { } } +impl, I: Instance> OnReapAccount for Module { + fn on_reap_account(who: &T::AccountId) { + Locks::::remove(who); + Account::::remove(who); + } +} + // wrapping these imbalances in a private module is necessary to ensure absolute privacy // of the inner member. mod imbalances { @@ -885,9 +895,8 @@ mod imbalances { // its type declaration). // This works as long as `increase_total_issuance_by` doesn't use the Imbalance // types (basically for charging fees). -// This should eventually be refactored so that the three type items that do -// depend on the Imbalance type (TransferPayment, DustRemoval) -// are placed in their own SRML module. +// This should eventually be refactored so that the type item that +// depends on the Imbalance type (DustRemoval) is placed in its own SRML module. struct ElevatedTrait, I: Instance>(T, I); impl, I: Instance> Clone for ElevatedTrait { fn clone(&self) -> Self { unimplemented!() } @@ -913,16 +922,16 @@ impl, I: Instance> frame_system::Trait for ElevatedTrait { type AvailableBlockRatio = T::AvailableBlockRatio; type Version = T::Version; type ModuleToIndex = T::ModuleToIndex; + type OnNewAccount = T::OnNewAccount; + type OnReapAccount = T::OnReapAccount; + type AccountData = T::AccountData; } impl, I: Instance> Trait for ElevatedTrait { type Balance = T::Balance; - type OnReapAccount = T::OnReapAccount; - type OnNewAccount = T::OnNewAccount; type Event = (); - type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = T::ExistentialDeposit; - type CreationFee = T::CreationFee; + type AccountStore = T::AccountStore; } impl, I: Instance> Currency for Module where @@ -950,10 +959,6 @@ impl, I: Instance> Currency for Module where T::ExistentialDeposit::get() } - fn free_balance(who: &T::AccountId) -> Self::Balance { - Account::::get(who).free - } - // Burn funds from the total issuance, returning a positive imbalance for the amount burned. // Is a no-op if amount to be burned is zero. fn burn(mut amount: Self::Balance) -> Self::PositiveImbalance { @@ -981,6 +986,10 @@ impl, I: Instance> Currency for Module where NegativeImbalance::new(amount) } + fn free_balance(who: &T::AccountId) -> Self::Balance { + Self::account(who).free + } + // Ensure that an account can withdraw from their free balance given any existing withdrawal // restrictions like locks and vesting balance. // Is a no-op if amount to be withdrawn is zero. @@ -996,7 +1005,7 @@ impl, I: Instance> Currency for Module where new_balance: T::Balance, ) -> DispatchResult { if amount.is_zero() { return Ok(()) } - let min_balance = Account::::get(who).frozen(reasons.into()); + let min_balance = Self::account(who).frozen(reasons.into()); ensure!(new_balance >= min_balance, Error::::LiquidityRestrictions); Ok(()) } @@ -1011,80 +1020,38 @@ impl, I: Instance> Currency for Module where ) -> DispatchResult { if value.is_zero() || transactor == dest { return Ok(()) } - let old_from_account = Self::account(transactor); - let mut from_account = old_from_account.clone(); - let old_to_account = Self::account(dest); - let mut to_account = old_to_account.clone(); + Self::try_mutate_account(dest, |to_account| -> DispatchResult { + Self::try_mutate_account(transactor, |from_account| -> DispatchResult { + from_account.free = from_account.free.checked_sub(&value) + .ok_or(Error::::InsufficientBalance)?; - let would_create = to_account.total().is_zero(); - let fee = if would_create { T::CreationFee::get() } else { Zero::zero() }; - let liability = value.checked_add(&fee).ok_or(Error::::Overflow)?; + // NOTE: total stake being stored in the same type means that this could never overflow + // but better to be safe than sorry. + to_account.free = to_account.free.checked_add(&value).ok_or(Error::::Overflow)?; - from_account.free = from_account.free.checked_sub(&liability) - .ok_or(Error::::InsufficientBalance)?; + let ed = T::ExistentialDeposit::get(); + ensure!(to_account.total() >= ed, Error::::ExistentialDeposit); - // NOTE: total stake being stored in the same type means that this could never overflow - // but better to be safe than sorry. - to_account.free = to_account.free.checked_add(&value).ok_or(Error::::Overflow)?; + Self::ensure_can_withdraw( + transactor, + value, + WithdrawReason::Transfer.into(), + from_account.free, + )?; - let ed = T::ExistentialDeposit::get(); - ensure!(to_account.free >= ed, Error::::ExistentialDeposit); + let allow_death = existence_requirement == ExistenceRequirement::AllowDeath; + ensure!(allow_death || from_account.free >= ed, Error::::KeepAlive); - Self::ensure_can_withdraw( - transactor, - value, - WithdrawReason::Transfer.into(), - from_account.free, - )?; - - let allow_death = existence_requirement == ExistenceRequirement::AllowDeath; - ensure!(allow_death || from_account.free >= ed, Error::::KeepAlive); - - Self::set_account(transactor, &from_account, &old_from_account); - - // Take action on the set_account call. - // This will emit events that _resulted_ from the transfer. - Self::set_account(dest, &to_account, &old_to_account); + Ok(()) + }) + })?; // Emit transfer event. - Self::deposit_event(RawEvent::Transfer(transactor.clone(), dest.clone(), value, fee)); - - T::TransferPayment::on_unbalanced(NegativeImbalance::new(fee)); + Self::deposit_event(RawEvent::Transfer(transactor.clone(), dest.clone(), value)); Ok(()) } - // Withdraw some free balance from an account, respecting existence requirements. - // Is a no-op if value to be withdrawn is zero. - fn withdraw( - who: &T::AccountId, - value: Self::Balance, - reasons: WithdrawReasons, - liveness: ExistenceRequirement, - ) -> result::Result { - if value.is_zero() { return Ok(NegativeImbalance::zero()); } - - let old_account = Self::account(who); - let mut account = old_account.clone(); - if let Some(new_free_account) = account.free.checked_sub(&value) { - // if we need to keep the account alive... - if liveness == ExistenceRequirement::KeepAlive - // ...and it would be dead afterwards... - && new_free_account < T::ExistentialDeposit::get() - // ...yet is was alive before - && account.free >= T::ExistentialDeposit::get() - { - Err(Error::::KeepAlive)? - } - Self::ensure_can_withdraw(who, value, reasons, new_free_account)?; - account.free = new_free_account; - Self::set_account(who, &account, &old_account); - Ok(NegativeImbalance::new(value)) - } else { - Err(Error::::InsufficientBalance)? - } - } - /// Slash a target account `who`, returning the negative imbalance created and any left over /// amount that could not be slashed. /// @@ -1100,22 +1067,19 @@ impl, I: Instance> Currency for Module where ) -> (Self::NegativeImbalance, Self::Balance) { if value.is_zero() { return (NegativeImbalance::zero(), Zero::zero()) } - let old_account = Self::account(who); - let mut account = old_account.clone(); + Self::mutate_account(who, |account| { + let free_slash = cmp::min(account.free, value); + account.free -= free_slash; - let free_slash = cmp::min(account.free, value); - account.free -= free_slash; - - let remaining_slash = value - free_slash; - let result = if !remaining_slash.is_zero() { - let reserved_slash = cmp::min(account.reserved, remaining_slash); - account.reserved -= reserved_slash; - (NegativeImbalance::new(free_slash + reserved_slash), remaining_slash - reserved_slash) - } else { - (NegativeImbalance::new(value), Zero::zero()) - }; - Self::set_account(who, &account, &old_account); - result + let remaining_slash = value - free_slash; + if !remaining_slash.is_zero() { + let reserved_slash = cmp::min(account.reserved, remaining_slash); + account.reserved -= reserved_slash; + (NegativeImbalance::new(free_slash + reserved_slash), remaining_slash - reserved_slash) + } else { + (NegativeImbalance::new(value), Zero::zero()) + } + }) } /// Deposit some `value` into the free balance of an existing target account `who`. @@ -1124,16 +1088,14 @@ impl, I: Instance> Currency for Module where fn deposit_into_existing( who: &T::AccountId, value: Self::Balance - ) -> result::Result { + ) -> Result { if value.is_zero() { return Ok(PositiveImbalance::zero()) } - let old_account = Self::account(who); - let mut account = old_account.clone(); - ensure!(!account.total().is_zero(), Error::::DeadAccount); - account.free = account.free.checked_add(&value).ok_or(Error::::Overflow)?; - - Self::set_account(who, &account, &old_account); - Ok(PositiveImbalance::new(value)) + Self::try_mutate_account(who, |account| -> Result { + ensure!(!account.total().is_zero(), Error::::DeadAccount); + account.free = account.free.checked_add(&value).ok_or(Error::::Overflow)?; + Ok(PositiveImbalance::new(value)) + }) } /// Deposit some `value` into the free balance of `who`, possibly creating a new account. @@ -1148,34 +1110,58 @@ impl, I: Instance> Currency for Module where ) -> Self::PositiveImbalance { if value.is_zero() { return Self::PositiveImbalance::zero() } - let old_account = Self::account(who); - let mut account = old_account.clone(); - let ed = T::ExistentialDeposit::get(); + Self::try_mutate_account(who, |account| -> Result { + // bail if not yet created and this operation wouldn't be enough to create it. + let ed = T::ExistentialDeposit::get(); + ensure!(value >= ed || !account.total().is_zero(), Self::PositiveImbalance::zero()); - // bail if not yet created and this operation wouldn't be enough to create it. - if value < ed && account.total().is_zero() { return Self::PositiveImbalance::zero() } + // defensive only: overflow should never happen, however in case it does, then this + // operation is a no-op. + account.free = account.free.checked_add(&value).ok_or(Self::PositiveImbalance::zero())?; - // defensive only: overflow should never happen, however in case it does, then this - // operation is a no-op. - account.free = match account.free.checked_add(&value) { - Some(f) => f, - None => return Self::PositiveImbalance::zero(), - }; + Ok(PositiveImbalance::new(value)) + }).unwrap_or_else(|x| x) + } - Self::set_account(who, &account, &old_account); + /// Withdraw some free balance from an account, respecting existence requirements. + /// + /// Is a no-op if value to be withdrawn is zero. + fn withdraw( + who: &T::AccountId, + value: Self::Balance, + reasons: WithdrawReasons, + liveness: ExistenceRequirement, + ) -> result::Result { + if value.is_zero() { return Ok(NegativeImbalance::zero()); } + + Self::try_mutate_account(who, |account| + -> Result + { + let new_free_account = account.free.checked_sub(&value) + .ok_or(Error::::InsufficientBalance)?; - PositiveImbalance::new(value) + // bail if we need to keep the account alive and this would kill it. + let ed = T::ExistentialDeposit::get(); + let would_be_dead = new_free_account + account.reserved < ed; + let would_kill = would_be_dead && account.free + account.reserved >= ed; + ensure!(liveness == AllowDeath || !would_kill, Error::::KeepAlive); + + Self::ensure_can_withdraw(who, value, reasons, new_free_account)?; + + account.free = new_free_account; + + Ok(NegativeImbalance::new(value)) + }) } /// Force the new free balance of a target account `who` to some new value `balance`. - fn make_free_balance_be(who: &T::AccountId, value: Self::Balance) -> ( - SignedImbalance, - UpdateBalanceOutcome - ) { - let old_account = Self::account(who); - let mut account = old_account.clone(); - - if value < T::ExistentialDeposit::get() && account.free.is_zero() { + fn make_free_balance_be(who: &T::AccountId, value: Self::Balance) + -> SignedImbalance + { + Self::try_mutate_account(who, |account| + -> Result, ()> + { + let ed = T::ExistentialDeposit::get(); // If we're attempting to set an existing account to less than ED, then // bypass the entire operation. It's a no-op if you follow it through, but // since this is an instance where we might account for a negative imbalance @@ -1183,24 +1169,16 @@ impl, I: Instance> Currency for Module where // equal and opposite cause (returned as an Imbalance), then in the // instance that there's no other accounts on the system at all, we might // underflow the issuance and our arithmetic will be off. - return ( - SignedImbalance::Positive(Self::PositiveImbalance::zero()), - UpdateBalanceOutcome::AccountKilled, - ) - } - let imbalance = if account.free <= value { - SignedImbalance::Positive(PositiveImbalance::new(value - account.free)) - } else { - SignedImbalance::Negative(NegativeImbalance::new(account.free - value)) - }; - account.free = value; - - // If the balance is too low, then the account is reaped. - // Free balance can never be less than ED. If that happens, it gets reduced to zero - // and the account information relevant to this subsystem is deleted (i.e. the - // account is reaped). - let outcome = Self::set_account(who, &account, &old_account); - (imbalance, outcome) + ensure!(value + account.reserved >= ed || !account.total().is_zero(), ()); + + let imbalance = if account.free <= value { + SignedImbalance::Positive(PositiveImbalance::new(value - account.free)) + } else { + SignedImbalance::Negative(NegativeImbalance::new(account.free - value)) + }; + account.free = value; + Ok(imbalance) + }).unwrap_or(SignedImbalance::Positive(Self::PositiveImbalance::zero())) } } @@ -1226,18 +1204,14 @@ impl, I: Instance> ReservableCurrency for Module /// Move `value` from the free balance from `who` to their reserved balance. /// /// Is a no-op if value to be reserved is zero. - fn reserve(who: &T::AccountId, value: Self::Balance) -> result::Result<(), DispatchError> { + fn reserve(who: &T::AccountId, value: Self::Balance) -> DispatchResult { if value.is_zero() { return Ok(()) } - let old_account = Self::account(who); - let mut account = old_account.clone(); - - account.free = account.free.checked_sub(&value).ok_or(Error::::InsufficientBalance)?; - account.reserved = account.reserved.checked_add(&value).ok_or(Error::::Overflow)?; - Self::ensure_can_withdraw(who, value, WithdrawReason::Reserve.into(), account.free)?; - - Self::set_account(who, &account, &old_account); - Ok(()) + Self::try_mutate_account(who, |account| -> DispatchResult { + account.free = account.free.checked_sub(&value).ok_or(Error::::InsufficientBalance)?; + account.reserved = account.reserved.checked_add(&value).ok_or(Error::::Overflow)?; + Self::ensure_can_withdraw(who, value, WithdrawReason::Reserve.into(), account.free) + }) } /// Unreserve some funds, returning any amount that was unable to be unreserved. @@ -1246,18 +1220,14 @@ impl, I: Instance> ReservableCurrency for Module fn unreserve(who: &T::AccountId, value: Self::Balance) -> Self::Balance { if value.is_zero() { return Zero::zero() } - let old_account = Self::account(who); - let mut account = old_account.clone(); - - let actual = cmp::min(account.reserved, value); - account.reserved -= actual; - // defensive only: this can never fail since total issuance which is at least free+reserved - // fits into the same datatype. - account.free = account.free.saturating_add(actual); - - Self::set_account(who, &account, &old_account); - - value - actual + Self::mutate_account(who, |account| { + let actual = cmp::min(account.reserved, value); + account.reserved -= actual; + // defensive only: this can never fail since total issuance which is at least free+reserved + // fits into the same datatype. + account.free = account.free.saturating_add(actual); + value - actual + }) } /// Slash from reserved balance, returning the negative imbalance created, @@ -1270,47 +1240,46 @@ impl, I: Instance> ReservableCurrency for Module ) -> (Self::NegativeImbalance, Self::Balance) { if value.is_zero() { return (NegativeImbalance::zero(), Zero::zero()) } - let old_account = Self::account(who); - let mut account = old_account.clone(); - - // underflow should never happen, but it if does, there's nothing to be done here. - let actual = cmp::min(account.reserved, value); - account.reserved -= actual; - - Self::set_account(who, &account, &old_account); - - (NegativeImbalance::new(actual), value - actual) + Self::mutate_account(who, |account| { + // underflow should never happen, but it if does, there's nothing to be done here. + let actual = cmp::min(account.reserved, value); + account.reserved -= actual; + (NegativeImbalance::new(actual), value - actual) + }) } - /// Move the reserved balance of one account into the free balance of another. + /// Move the reserved balance of one account into the balance of another, according to `status`. /// - /// Is a no-op if the value to be moved is zero. + /// Is a no-op if: + /// - the value to be moved is zero; or + /// - the `slashed` id equal to `beneficiary` and the `status` is `Reserved`. fn repatriate_reserved( slashed: &T::AccountId, beneficiary: &T::AccountId, value: Self::Balance, - ) -> result::Result { - if value.is_zero() { return Ok (Zero::zero()) } + status: Status, + ) -> Result { + if value.is_zero() { return Ok(Zero::zero()) } if slashed == beneficiary { - return Ok(Self::unreserve(slashed, value)); + return match status { + Status::Free => Ok(Self::unreserve(slashed, value)), + Status::Reserved => Ok(value.saturating_sub(Self::reserved_balance(slashed))), + }; } - let old_to_account = Self::account(beneficiary); - let mut to_account = old_to_account.clone(); - ensure!(!to_account.total().is_zero(), Error::::DeadAccount); - - let old_from_account = Self::account(slashed); - let mut from_account = old_from_account.clone(); - let actual = cmp::min(from_account.reserved, value); - - to_account.free = to_account.free.checked_add(&actual).ok_or(Error::::Overflow)?; - from_account.reserved -= actual; - - Self::set_account(slashed, &from_account, &old_from_account); - Self::set_account(beneficiary, &to_account, &old_to_account); - - Ok(value - actual) + Self::try_mutate_account(beneficiary, |to_account| -> Result { + ensure!(!to_account.total().is_zero(), Error::::DeadAccount); + Self::try_mutate_account(slashed, |from_account| -> Result { + let actual = cmp::min(from_account.reserved, value); + match status { + Status::Free => to_account.free = to_account.free.checked_add(&actual).ok_or(Error::::Overflow)?, + Status::Reserved => to_account.reserved = to_account.reserved.checked_add(&actual).ok_or(Error::::Overflow)?, + } + from_account.reserved -= actual; + Ok(value - actual) + }) + }) } } @@ -1380,12 +1349,11 @@ where } } -impl, I: Instance> IsDeadAccount for Module -where +impl, I: Instance> IsDeadAccount for Module where T::Balance: MaybeSerializeDeserialize + Debug { fn is_dead_account(who: &T::AccountId) -> bool { // this should always be exactly equivalent to `Self::account(who).total().is_zero()` - !Account::::contains_key(who) + !T::AccountStore::is_explicit(who) } } diff --git a/frame/balances/src/tests.rs b/frame/balances/src/tests.rs index 816768901b..3d0c9e9207 100644 --- a/frame/balances/src/tests.rs +++ b/frame/balances/src/tests.rs @@ -14,644 +14,638 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Tests for the module. - -use super::*; -use mock::{Balances, ExtBuilder, Test, System, info_from_weight, CALL}; -use sp_runtime::{Fixed64, traits::{SignedExtension, BadOrigin}}; -use frame_support::{ - assert_noop, assert_ok, assert_err, - traits::{LockableCurrency, LockIdentifier, WithdrawReason, WithdrawReasons, - Currency, ReservableCurrency, ExistenceRequirement::AllowDeath} -}; -use pallet_transaction_payment::ChargeTransactionPayment; -use frame_system::RawOrigin; - -const ID_1: LockIdentifier = *b"1 "; -const ID_2: LockIdentifier = *b"2 "; - -#[test] -fn basic_locking_should_work() { - ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - assert_eq!(Balances::free_balance(1), 10); - Balances::set_lock(ID_1, &1, 9, WithdrawReasons::all()); - assert_noop!( - >::transfer(&1, &2, 5, AllowDeath), - Error::::LiquidityRestrictions - ); - }); -} - -#[test] -fn partial_locking_should_work() { - ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); - assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); - }); -} - -#[test] -fn lock_removal_should_work() { - ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - Balances::set_lock(ID_1, &1, u64::max_value(), WithdrawReasons::all()); - Balances::remove_lock(ID_1, &1); - assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); - }); -} - -#[test] -fn lock_replacement_should_work() { - ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - Balances::set_lock(ID_1, &1, u64::max_value(), WithdrawReasons::all()); - Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); - assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); - }); -} - -#[test] -fn double_locking_should_work() { - ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); - Balances::set_lock(ID_2, &1, 5, WithdrawReasons::all()); - assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); - }); -} - -#[test] -fn combination_locking_should_work() { - ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - Balances::set_lock(ID_1, &1, u64::max_value(), WithdrawReasons::none()); - Balances::set_lock(ID_2, &1, 0, WithdrawReasons::all()); - assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); - }); -} - -#[test] -fn lock_value_extension_should_work() { - ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); - assert_noop!( - >::transfer(&1, &2, 6, AllowDeath), - Error::::LiquidityRestrictions - ); - Balances::extend_lock(ID_1, &1, 2, WithdrawReasons::all()); - assert_noop!( - >::transfer(&1, &2, 6, AllowDeath), - Error::::LiquidityRestrictions - ); - Balances::extend_lock(ID_1, &1, 8, WithdrawReasons::all()); - assert_noop!( - >::transfer(&1, &2, 3, AllowDeath), - Error::::LiquidityRestrictions - ); - }); -} - -#[test] -fn lock_reasons_should_work() { - ExtBuilder::default() - .existential_deposit(1) - .monied(true) - .build() - .execute_with(|| { - pallet_transaction_payment::NextFeeMultiplier::put(Fixed64::from_natural(1)); - Balances::set_lock(ID_1, &1, 10, WithdrawReason::Reserve.into()); - assert_noop!( - >::transfer(&1, &2, 1, AllowDeath), - Error::::LiquidityRestrictions - ); - assert_noop!( - >::reserve(&1, 1), - Error::::LiquidityRestrictions - ); - assert!( as SignedExtension>::pre_dispatch( - ChargeTransactionPayment::from(1), - &1, - CALL, - info_from_weight(1), - 1, - ).is_err()); - assert!( as SignedExtension>::pre_dispatch( - ChargeTransactionPayment::from(0), - &1, - CALL, - info_from_weight(1), - 1, - ).is_ok()); - - Balances::set_lock(ID_1, &1, 10, WithdrawReason::TransactionPayment.into()); - assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); - assert_ok!(>::reserve(&1, 1)); - assert!( as SignedExtension>::pre_dispatch( - ChargeTransactionPayment::from(1), - &1, - CALL, - info_from_weight(1), - 1, - ).is_err()); - assert!( as SignedExtension>::pre_dispatch( - ChargeTransactionPayment::from(0), - &1, - CALL, - info_from_weight(1), - 1, - ).is_err()); - }); -} - -#[test] -fn lock_block_number_extension_should_work() { - ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - Balances::set_lock(ID_1, &1, 10, WithdrawReasons::all()); - assert_noop!( - >::transfer(&1, &2, 6, AllowDeath), - Error::::LiquidityRestrictions - ); - Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); - assert_noop!( - >::transfer(&1, &2, 6, AllowDeath), - Error::::LiquidityRestrictions - ); - System::set_block_number(2); - Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); - assert_noop!( - >::transfer(&1, &2, 3, AllowDeath), - Error::::LiquidityRestrictions - ); - }); -} - -#[test] -fn lock_reasons_extension_should_work() { - ExtBuilder::default().existential_deposit(1).monied(true).build().execute_with(|| { - Balances::set_lock(ID_1, &1, 10, WithdrawReason::Transfer.into()); - assert_noop!( - >::transfer(&1, &2, 6, AllowDeath), - Error::::LiquidityRestrictions - ); - Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::none()); - assert_noop!( - >::transfer(&1, &2, 6, AllowDeath), - Error::::LiquidityRestrictions - ); - Balances::extend_lock(ID_1, &1, 10, WithdrawReason::Reserve.into()); - assert_noop!( - >::transfer(&1, &2, 6, AllowDeath), - Error::::LiquidityRestrictions - ); - }); -} - -#[test] -fn default_indexing_on_new_accounts_should_not_work2() { - ExtBuilder::default() - .existential_deposit(10) - .creation_fee(50) - .monied(true) - .build() - .execute_with(|| { - assert_eq!(Balances::is_dead_account(&5), true); // account 5 should not exist - // ext_deposit is 10, value is 9, not satisfies for ext_deposit - assert_noop!( - Balances::transfer(Some(1).into(), 5, 9), - Error::::ExistentialDeposit, - ); - assert_eq!(Balances::is_dead_account(&5), true); // account 5 should not exist - assert_eq!(Balances::free_balance(1), 100); - }); -} - -#[test] -fn reserved_balance_should_prevent_reclaim_count() { - ExtBuilder::default() - .existential_deposit(256 * 1) - .monied(true) - .build() - .execute_with(|| { - System::inc_account_nonce(&2); - assert_eq!(Balances::is_dead_account(&2), false); - assert_eq!(Balances::is_dead_account(&5), true); - assert_eq!(Balances::total_balance(&2), 256 * 20); - - assert_ok!(Balances::reserve(&2, 256 * 19 + 1)); // account 2 becomes mostly reserved - assert_eq!(Balances::free_balance(2), 255); // "free" account deleted." - 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); - - // account 4 tries to take index 1 for account 5. - assert_ok!(Balances::transfer(Some(4).into(), 5, 256 * 1 + 0x69)); - assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69); - assert_eq!(Balances::is_dead_account(&5), false); - - 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 - assert_eq!(Balances::is_dead_account(&2), true); - - // account 4 tries to take index 1 again for account 6. - assert_ok!(Balances::transfer(Some(4).into(), 6, 256 * 1 + 0x69)); - assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69); - assert_eq!(Balances::is_dead_account(&6), false); - }); -} - - -#[test] -fn reward_should_work() { - ExtBuilder::default().monied(true).build().execute_with(|| { - assert_eq!(Balances::total_balance(&1), 10); - assert_ok!(Balances::deposit_into_existing(&1, 10).map(drop)); - assert_eq!(Balances::total_balance(&1), 20); - assert_eq!(>::get(), 120); - }); -} - -#[test] -fn dust_account_removal_should_work() { - ExtBuilder::default() - .existential_deposit(100) - .monied(true) - .build() - .execute_with(|| { - System::inc_account_nonce(&2); - assert_eq!(System::account_nonce(&2), 1); - assert_eq!(Balances::total_balance(&2), 2000); - - assert_ok!(Balances::transfer(Some(2).into(), 5, 1901)); // index 1 (account 2) becomes zombie - assert_eq!(Balances::total_balance(&2), 0); - assert_eq!(Balances::total_balance(&5), 1901); - assert_eq!(System::account_nonce(&2), 0); - }); -} - -#[test] -fn dust_account_removal_should_work2() { - ExtBuilder::default() - .existential_deposit(100) - .creation_fee(50) - .monied(true) - .build() - .execute_with(|| { - System::inc_account_nonce(&2); - assert_eq!(System::account_nonce(&2), 1); - assert_eq!(Balances::total_balance(&2), 2000); - // index 1 (account 2) becomes zombie for 256*10 + 50(fee) < 256 * 10 (ext_deposit) - assert_ok!(Balances::transfer(Some(2).into(), 5, 1851)); - assert_eq!(Balances::total_balance(&2), 0); - assert_eq!(Balances::total_balance(&5), 1851); - assert_eq!(System::account_nonce(&2), 0); - }); -} - -#[test] -fn balance_works() { - ExtBuilder::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 42); - assert_eq!(Balances::free_balance(1), 42); - assert_eq!(Balances::reserved_balance(1), 0); - assert_eq!(Balances::total_balance(&1), 42); - assert_eq!(Balances::free_balance(2), 0); - assert_eq!(Balances::reserved_balance(2), 0); - assert_eq!(Balances::total_balance(&2), 0); - }); -} - -#[test] -fn balance_transfer_works() { - ExtBuilder::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - assert_ok!(Balances::transfer(Some(1).into(), 2, 69)); - assert_eq!(Balances::total_balance(&1), 42); - assert_eq!(Balances::total_balance(&2), 69); - }); -} - -#[test] -fn force_transfer_works() { - ExtBuilder::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - assert_noop!( - Balances::force_transfer(Some(2).into(), 1, 2, 69), - BadOrigin, - ); - assert_ok!(Balances::force_transfer(RawOrigin::Root.into(), 1, 2, 69)); - assert_eq!(Balances::total_balance(&1), 42); - assert_eq!(Balances::total_balance(&2), 69); - }); -} - -#[test] -fn reserving_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - - assert_eq!(Balances::total_balance(&1), 111); - assert_eq!(Balances::free_balance(1), 111); - assert_eq!(Balances::reserved_balance(1), 0); - - assert_ok!(Balances::reserve(&1, 69)); - - assert_eq!(Balances::total_balance(&1), 111); - assert_eq!(Balances::free_balance(1), 42); - assert_eq!(Balances::reserved_balance(1), 69); - }); -} - -#[test] -fn balance_transfer_when_reserved_should_not_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - assert_ok!(Balances::reserve(&1, 69)); - assert_noop!( - Balances::transfer(Some(1).into(), 2, 69), - Error::::InsufficientBalance, - ); - }); -} - -#[test] -fn deducting_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - assert_ok!(Balances::reserve(&1, 69)); - assert_eq!(Balances::free_balance(1), 42); - }); -} - -#[test] -fn refunding_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 42); - let account = Balances::account(&1); - Balances::set_account(&1, &AccountData { reserved: 69, ..account }, &account); - Balances::unreserve(&1, 69); - assert_eq!(Balances::free_balance(1), 111); - assert_eq!(Balances::reserved_balance(1), 0); - }); -} - -#[test] -fn slashing_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - assert_ok!(Balances::reserve(&1, 69)); - assert!(Balances::slash(&1, 69).1.is_zero()); - assert_eq!(Balances::free_balance(1), 0); - assert_eq!(Balances::reserved_balance(1), 42); - assert_eq!(>::get(), 42); - }); -} - -#[test] -fn slashing_incomplete_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 42); - assert_ok!(Balances::reserve(&1, 21)); - assert_eq!(Balances::slash(&1, 69).1, 27); - assert_eq!(Balances::free_balance(1), 0); - assert_eq!(Balances::reserved_balance(1), 0); - assert_eq!(>::get(), 0); - }); -} - -#[test] -fn unreserving_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - assert_ok!(Balances::reserve(&1, 111)); - Balances::unreserve(&1, 42); - assert_eq!(Balances::reserved_balance(1), 69); - assert_eq!(Balances::free_balance(1), 42); - }); -} - -#[test] -fn slashing_reserved_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - assert_ok!(Balances::reserve(&1, 111)); - assert_eq!(Balances::slash_reserved(&1, 42).1, 0); - assert_eq!(Balances::reserved_balance(1), 69); - assert_eq!(Balances::free_balance(1), 0); - assert_eq!(>::get(), 69); - }); -} - -#[test] -fn slashing_incomplete_reserved_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - assert_ok!(Balances::reserve(&1, 42)); - assert_eq!(Balances::slash_reserved(&1, 69).1, 27); - assert_eq!(Balances::free_balance(1), 69); - assert_eq!(Balances::reserved_balance(1), 0); - assert_eq!(>::get(), 69); - }); -} - -#[test] -fn transferring_reserved_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 110); - let _ = Balances::deposit_creating(&2, 1); - assert_ok!(Balances::reserve(&1, 110)); - assert_ok!(Balances::repatriate_reserved(&1, &2, 41), 0); - assert_eq!(Balances::reserved_balance(1), 69); - assert_eq!(Balances::free_balance(1), 0); - assert_eq!(Balances::reserved_balance(2), 0); - assert_eq!(Balances::free_balance(2), 42); - }); -} - -#[test] -fn transferring_reserved_balance_to_nonexistent_should_fail() { - ExtBuilder::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); - assert_ok!(Balances::reserve(&1, 111)); - assert_noop!(Balances::repatriate_reserved(&1, &2, 42), Error::::DeadAccount); - }); -} - -#[test] -fn transferring_incomplete_reserved_balance_should_work() { - ExtBuilder::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 110); - let _ = Balances::deposit_creating(&2, 1); - assert_ok!(Balances::reserve(&1, 41)); - assert_ok!(Balances::repatriate_reserved(&1, &2, 69), 28); - assert_eq!(Balances::reserved_balance(1), 0); - assert_eq!(Balances::free_balance(1), 69); - assert_eq!(Balances::reserved_balance(2), 0); - assert_eq!(Balances::free_balance(2), 42); - }); -} - -#[test] -fn transferring_too_high_value_should_not_panic() { - ExtBuilder::default().build().execute_with(|| { - Account::::insert(1, AccountData { free: u64::max_value(), .. Default::default() }); - Account::::insert(2, AccountData { free: 1, .. Default::default() }); - - assert_err!( - Balances::transfer(Some(1).into(), 2, u64::max_value()), - Error::::Overflow, - ); - - assert_eq!(Balances::free_balance(1), u64::max_value()); - assert_eq!(Balances::free_balance(2), 1); - }); -} - -#[test] -fn account_create_on_free_too_low_with_other() { - ExtBuilder::default().existential_deposit(100).build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 100); - assert_eq!(>::get(), 100); - - // No-op. - let _ = Balances::deposit_creating(&2, 50); - assert_eq!(Balances::free_balance(2), 0); - assert_eq!(>::get(), 100); - }) -} - - -#[test] -fn account_create_on_free_too_low() { - ExtBuilder::default().existential_deposit(100).build().execute_with(|| { - // No-op. - let _ = Balances::deposit_creating(&2, 50); - assert_eq!(Balances::free_balance(2), 0); - assert_eq!(>::get(), 0); - }) -} - -#[test] -fn account_removal_on_free_too_low() { - ExtBuilder::default().existential_deposit(100).build().execute_with(|| { - assert_eq!(>::get(), 0); - - // Setup two accounts with free balance above the existential threshold. - let _ = Balances::deposit_creating(&1, 110); - let _ = Balances::deposit_creating(&2, 110); - - assert_eq!(Balances::free_balance(1), 110); - assert_eq!(Balances::free_balance(2), 110); - assert_eq!(>::get(), 220); - - // Transfer funds from account 1 of such amount that after this transfer - // the balance of account 1 will be below the existential threshold. - // This should lead to the removal of all balance of this account. - assert_ok!(Balances::transfer(Some(1).into(), 2, 20)); - - // Verify free balance removal of account 1. - assert_eq!(Balances::free_balance(1), 0); - assert_eq!(Balances::free_balance(2), 130); - - // Verify that TotalIssuance tracks balance removal when free balance is too low. - assert_eq!(>::get(), 130); - }); -} - -#[test] -fn transfer_overflow_isnt_exploitable() { - ExtBuilder::default().creation_fee(50).build().execute_with(|| { - // Craft a value that will overflow if summed with `creation_fee`. - let evil_value = u64::max_value() - 49; - - assert_err!( - Balances::transfer(Some(1).into(), 5, evil_value), - Error::::Overflow, - ); - }); -} - -#[test] -fn burn_must_work() { - ExtBuilder::default().monied(true).build().execute_with(|| { - let init_total_issuance = Balances::total_issuance(); - let imbalance = Balances::burn(10); - assert_eq!(Balances::total_issuance(), init_total_issuance - 10); - drop(imbalance); - assert_eq!(Balances::total_issuance(), init_total_issuance); - }); -} - -#[test] -fn transfer_keep_alive_works() { - ExtBuilder::default().existential_deposit(1).build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 100); - assert_err!( - Balances::transfer_keep_alive(Some(1).into(), 2, 100), - Error::::KeepAlive - ); - assert_eq!(Balances::is_dead_account(&1), false); - assert_eq!(Balances::total_balance(&1), 100); - assert_eq!(Balances::total_balance(&2), 0); - }); -} - -#[test] -#[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 = frame_system::GenesisConfig::default().build_storage::().unwrap(); - let _ = GenesisConfig:: { - balances: vec![(1, 10)], - }.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, 0)); - // Check balance - assert_eq!(Balances::free_balance(1), 100); - assert_eq!(Balances::reserved_balance(1), 0); - - // Reserve some free balance - assert_ok!(Balances::reserve(&1, 50)); - // Check balance, the account should be ok. - assert_eq!(Balances::free_balance(1), 50); - assert_eq!(Balances::reserved_balance(1), 50); - - // Reserve the rest of the free balance - assert_ok!(Balances::reserve(&1, 50)); - // Check balance, the account should be ok. - assert_eq!(Balances::free_balance(1), 0); - assert_eq!(Balances::reserved_balance(1), 100); - - // Unreserve everything - Balances::unreserve(&1, 100); - // Check balance, all 100 should move to free_balance - assert_eq!(Balances::free_balance(1), 100); - assert_eq!(Balances::reserved_balance(1), 0); - }); -} - -#[test] -fn account_deleted_when_just_dust() { - 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, 50, 50)); - // Check balance - assert_eq!(Balances::free_balance(1), 50); - assert_eq!(Balances::reserved_balance(1), 50); - - // Reserve some free balance - let _ = Balances::slash(&1, 1); - // The account should be dead. - assert!(Balances::is_dead_account(&1)); - assert_eq!(Balances::free_balance(1), 0); - assert_eq!(Balances::reserved_balance(1), 0); - }); +//! Macro for creating the tests for the module. + +#[macro_export] +macro_rules! decl_tests { + ($test:ty, $ext_builder:ty, $existential_deposit:expr) => { + + use crate::*; + use sp_runtime::{Fixed64, traits::{SignedExtension, BadOrigin}}; + use frame_support::{ + assert_noop, assert_ok, assert_err, + traits::{LockableCurrency, LockIdentifier, WithdrawReason, WithdrawReasons, + Currency, ReservableCurrency, ExistenceRequirement::AllowDeath} + }; + use pallet_transaction_payment::ChargeTransactionPayment; + use frame_system::RawOrigin; + + const ID_1: LockIdentifier = *b"1 "; + const ID_2: LockIdentifier = *b"2 "; + + pub type System = frame_system::Module<$test>; + pub type Balances = Module<$test>; + + pub const CALL: &<$test as frame_system::Trait>::Call = &(); + + /// 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, pays_fee: true, ..Default::default() } + } + + #[test] + fn basic_locking_should_work() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + assert_eq!(Balances::free_balance(1), 10); + Balances::set_lock(ID_1, &1, 9, WithdrawReasons::all()); + assert_noop!( + >::transfer(&1, &2, 5, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + }); + } + + #[test] + fn partial_locking_should_work() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + }); + } + + #[test] + fn lock_removal_should_work() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + Balances::set_lock(ID_1, &1, u64::max_value(), WithdrawReasons::all()); + Balances::remove_lock(ID_1, &1); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + }); + } + + #[test] + fn lock_replacement_should_work() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + Balances::set_lock(ID_1, &1, u64::max_value(), WithdrawReasons::all()); + Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + }); + } + + #[test] + fn double_locking_should_work() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); + Balances::set_lock(ID_2, &1, 5, WithdrawReasons::all()); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + }); + } + + #[test] + fn combination_locking_should_work() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + Balances::set_lock(ID_1, &1, u64::max_value(), WithdrawReasons::none()); + Balances::set_lock(ID_2, &1, 0, WithdrawReasons::all()); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + }); + } + + #[test] + fn lock_value_extension_should_work() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + Balances::set_lock(ID_1, &1, 5, WithdrawReasons::all()); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + Balances::extend_lock(ID_1, &1, 2, WithdrawReasons::all()); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + Balances::extend_lock(ID_1, &1, 8, WithdrawReasons::all()); + assert_noop!( + >::transfer(&1, &2, 3, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + }); + } + + #[test] + fn lock_reasons_should_work() { + <$ext_builder>::default() + .existential_deposit(1) + .monied(true) + .build() + .execute_with(|| { + pallet_transaction_payment::NextFeeMultiplier::put(Fixed64::from_natural(1)); + Balances::set_lock(ID_1, &1, 10, WithdrawReason::Reserve.into()); + assert_noop!( + >::transfer(&1, &2, 1, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + assert_noop!( + >::reserve(&1, 1), + Error::<$test, _>::LiquidityRestrictions + ); + assert!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(1), + &1, + CALL, + info_from_weight(1), + 1, + ).is_err()); + assert!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(0), + &1, + CALL, + info_from_weight(1), + 1, + ).is_ok()); + + Balances::set_lock(ID_1, &1, 10, WithdrawReason::TransactionPayment.into()); + assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); + assert_ok!(>::reserve(&1, 1)); + assert!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(1), + &1, + CALL, + info_from_weight(1), + 1, + ).is_err()); + assert!( as SignedExtension>::pre_dispatch( + ChargeTransactionPayment::from(0), + &1, + CALL, + info_from_weight(1), + 1, + ).is_err()); + }); + } + + #[test] + fn lock_block_number_extension_should_work() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + Balances::set_lock(ID_1, &1, 10, WithdrawReasons::all()); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + System::set_block_number(2); + Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::all()); + assert_noop!( + >::transfer(&1, &2, 3, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + }); + } + + #[test] + fn lock_reasons_extension_should_work() { + <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { + Balances::set_lock(ID_1, &1, 10, WithdrawReason::Transfer.into()); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + Balances::extend_lock(ID_1, &1, 10, WithdrawReasons::none()); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + Balances::extend_lock(ID_1, &1, 10, WithdrawReason::Reserve.into()); + assert_noop!( + >::transfer(&1, &2, 6, AllowDeath), + Error::<$test, _>::LiquidityRestrictions + ); + }); + } + + #[test] + fn default_indexing_on_new_accounts_should_not_work2() { + <$ext_builder>::default() + .existential_deposit(10) + .monied(true) + .build() + .execute_with(|| { + assert_eq!(Balances::is_dead_account(&5), true); + // account 5 should not exist + // ext_deposit is 10, value is 9, not satisfies for ext_deposit + assert_noop!( + Balances::transfer(Some(1).into(), 5, 9), + Error::<$test, _>::ExistentialDeposit, + ); + assert_eq!(Balances::is_dead_account(&5), true); // account 5 should not exist + assert_eq!(Balances::free_balance(1), 100); + }); + } + + #[test] + fn reserved_balance_should_prevent_reclaim_count() { + <$ext_builder>::default() + .existential_deposit(256 * 1) + .monied(true) + .build() + .execute_with(|| { + System::inc_account_nonce(&2); + assert_eq!(Balances::is_dead_account(&2), false); + assert_eq!(Balances::is_dead_account(&5), true); + assert_eq!(Balances::total_balance(&2), 256 * 20); + + assert_ok!(Balances::reserve(&2, 256 * 19 + 1)); // account 2 becomes mostly reserved + assert_eq!(Balances::free_balance(2), 255); // "free" account deleted." + 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); + + // account 4 tries to take index 1 for account 5. + assert_ok!(Balances::transfer(Some(4).into(), 5, 256 * 1 + 0x69)); + assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69); + assert_eq!(Balances::is_dead_account(&5), false); + + 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 + assert_eq!(Balances::is_dead_account(&2), true); + + // account 4 tries to take index 1 again for account 6. + assert_ok!(Balances::transfer(Some(4).into(), 6, 256 * 1 + 0x69)); + assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69); + assert_eq!(Balances::is_dead_account(&6), false); + }); + } + + #[test] + fn reward_should_work() { + <$ext_builder>::default().monied(true).build().execute_with(|| { + assert_eq!(Balances::total_balance(&1), 10); + assert_ok!(Balances::deposit_into_existing(&1, 10).map(drop)); + assert_eq!(Balances::total_balance(&1), 20); + assert_eq!(>::get(), 120); + }); + } + + #[test] + fn dust_account_removal_should_work() { + <$ext_builder>::default() + .existential_deposit(100) + .monied(true) + .build() + .execute_with(|| { + System::inc_account_nonce(&2); + assert_eq!(System::account_nonce(&2), 1); + assert_eq!(Balances::total_balance(&2), 2000); + // index 1 (account 2) becomes zombie + assert_ok!(Balances::transfer(Some(2).into(), 5, 1901)); + assert_eq!(Balances::total_balance(&2), 0); + assert_eq!(Balances::total_balance(&5), 1901); + assert_eq!(System::account_nonce(&2), 0); + }); + } + + #[test] + fn balance_works() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 42); + assert_eq!(Balances::free_balance(1), 42); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(Balances::total_balance(&1), 42); + assert_eq!(Balances::free_balance(2), 0); + assert_eq!(Balances::reserved_balance(2), 0); + assert_eq!(Balances::total_balance(&2), 0); + }); + } + + #[test] + fn balance_transfer_works() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::transfer(Some(1).into(), 2, 69)); + assert_eq!(Balances::total_balance(&1), 42); + assert_eq!(Balances::total_balance(&2), 69); + }); + } + + #[test] + fn force_transfer_works() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_noop!( + Balances::force_transfer(Some(2).into(), 1, 2, 69), + BadOrigin, + ); + assert_ok!(Balances::force_transfer(RawOrigin::Root.into(), 1, 2, 69)); + assert_eq!(Balances::total_balance(&1), 42); + assert_eq!(Balances::total_balance(&2), 69); + }); + } + + #[test] + fn reserving_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + + assert_eq!(Balances::total_balance(&1), 111); + assert_eq!(Balances::free_balance(1), 111); + assert_eq!(Balances::reserved_balance(1), 0); + + assert_ok!(Balances::reserve(&1, 69)); + + assert_eq!(Balances::total_balance(&1), 111); + assert_eq!(Balances::free_balance(1), 42); + assert_eq!(Balances::reserved_balance(1), 69); + }); + } + + #[test] + fn balance_transfer_when_reserved_should_not_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::reserve(&1, 69)); + assert_noop!( + Balances::transfer(Some(1).into(), 2, 69), + Error::<$test, _>::InsufficientBalance, + ); + }); + } + + #[test] + fn deducting_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::reserve(&1, 69)); + assert_eq!(Balances::free_balance(1), 42); + }); + } + + #[test] + fn refunding_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 42); + Balances::mutate_account(&1, |a| a.reserved = 69); + Balances::unreserve(&1, 69); + assert_eq!(Balances::free_balance(1), 111); + assert_eq!(Balances::reserved_balance(1), 0); + }); + } + + #[test] + fn slashing_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::reserve(&1, 69)); + assert!(Balances::slash(&1, 69).1.is_zero()); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(1), 42); + assert_eq!(>::get(), 42); + }); + } + + #[test] + fn slashing_incomplete_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 42); + assert_ok!(Balances::reserve(&1, 21)); + assert_eq!(Balances::slash(&1, 69).1, 27); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(>::get(), 0); + }); + } + + #[test] + fn unreserving_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::reserve(&1, 111)); + Balances::unreserve(&1, 42); + assert_eq!(Balances::reserved_balance(1), 69); + assert_eq!(Balances::free_balance(1), 42); + }); + } + + #[test] + fn slashing_reserved_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::reserve(&1, 111)); + assert_eq!(Balances::slash_reserved(&1, 42).1, 0); + assert_eq!(Balances::reserved_balance(1), 69); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(>::get(), 69); + }); + } + + #[test] + fn slashing_incomplete_reserved_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::reserve(&1, 42)); + assert_eq!(Balances::slash_reserved(&1, 69).1, 27); + assert_eq!(Balances::free_balance(1), 69); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(>::get(), 69); + }); + } + + #[test] + fn repatriating_reserved_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 110); + let _ = Balances::deposit_creating(&2, 1); + assert_ok!(Balances::reserve(&1, 110)); + assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Status::Free), 0); + assert_eq!(Balances::reserved_balance(1), 69); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(2), 0); + assert_eq!(Balances::free_balance(2), 42); + }); + } + + #[test] + fn transferring_reserved_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 110); + let _ = Balances::deposit_creating(&2, 1); + assert_ok!(Balances::reserve(&1, 110)); + assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Status::Reserved), 0); + assert_eq!(Balances::reserved_balance(1), 69); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(2), 41); + assert_eq!(Balances::free_balance(2), 1); + }); + } + + #[test] + fn transferring_reserved_balance_to_nonexistent_should_fail() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 111); + assert_ok!(Balances::reserve(&1, 111)); + assert_noop!(Balances::repatriate_reserved(&1, &2, 42, Status::Free), Error::<$test, _>::DeadAccount); + }); + } + + #[test] + fn transferring_incomplete_reserved_balance_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 110); + let _ = Balances::deposit_creating(&2, 1); + assert_ok!(Balances::reserve(&1, 41)); + assert_ok!(Balances::repatriate_reserved(&1, &2, 69, Status::Free), 28); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(Balances::free_balance(1), 69); + assert_eq!(Balances::reserved_balance(2), 0); + assert_eq!(Balances::free_balance(2), 42); + }); + } + + #[test] + fn transferring_too_high_value_should_not_panic() { + <$ext_builder>::default().build().execute_with(|| { + Balances::make_free_balance_be(&1, u64::max_value()); + Balances::make_free_balance_be(&2, 1); + + assert_err!( + Balances::transfer(Some(1).into(), 2, u64::max_value()), + Error::<$test, _>::Overflow, + ); + + assert_eq!(Balances::free_balance(1), u64::max_value()); + assert_eq!(Balances::free_balance(2), 1); + }); + } + + #[test] + fn account_create_on_free_too_low_with_other() { + <$ext_builder>::default().existential_deposit(100).build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 100); + assert_eq!(>::get(), 100); + + // No-op. + let _ = Balances::deposit_creating(&2, 50); + assert_eq!(Balances::free_balance(2), 0); + assert_eq!(>::get(), 100); + }) + } + + #[test] + fn account_create_on_free_too_low() { + <$ext_builder>::default().existential_deposit(100).build().execute_with(|| { + // No-op. + let _ = Balances::deposit_creating(&2, 50); + assert_eq!(Balances::free_balance(2), 0); + assert_eq!(>::get(), 0); + }) + } + + #[test] + fn account_removal_on_free_too_low() { + <$ext_builder>::default().existential_deposit(100).build().execute_with(|| { + assert_eq!(>::get(), 0); + + // Setup two accounts with free balance above the existential threshold. + let _ = Balances::deposit_creating(&1, 110); + let _ = Balances::deposit_creating(&2, 110); + + assert_eq!(Balances::free_balance(1), 110); + assert_eq!(Balances::free_balance(2), 110); + assert_eq!(>::get(), 220); + + // Transfer funds from account 1 of such amount that after this transfer + // the balance of account 1 will be below the existential threshold. + // This should lead to the removal of all balance of this account. + assert_ok!(Balances::transfer(Some(1).into(), 2, 20)); + + // Verify free balance removal of account 1. + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::free_balance(2), 130); + + // Verify that TotalIssuance tracks balance removal when free balance is too low. + assert_eq!(>::get(), 130); + }); + } + + #[test] + fn burn_must_work() { + <$ext_builder>::default().monied(true).build().execute_with(|| { + let init_total_issuance = Balances::total_issuance(); + let imbalance = Balances::burn(10); + assert_eq!(Balances::total_issuance(), init_total_issuance - 10); + drop(imbalance); + assert_eq!(Balances::total_issuance(), init_total_issuance); + }); + } + + #[test] + fn transfer_keep_alive_works() { + <$ext_builder>::default().existential_deposit(1).build().execute_with(|| { + let _ = Balances::deposit_creating(&1, 100); + assert_noop!( + Balances::transfer_keep_alive(Some(1).into(), 2, 100), + Error::<$test, _>::KeepAlive + ); + assert_eq!(Balances::is_dead_account(&1), false); + assert_eq!(Balances::total_balance(&1), 100); + assert_eq!(Balances::total_balance(&2), 0); + }); + } + + #[test] + #[should_panic = "the balance of any account should always be more than existential deposit."] + fn cannot_set_genesis_value_below_ed() { + ($existential_deposit).with(|v| *v.borrow_mut() = 11); + let mut t = frame_system::GenesisConfig::default().build_storage::<$test>().unwrap(); + let _ = GenesisConfig::<$test> { + balances: vec![(1, 10)], + }.assimilate_storage(&mut t).unwrap(); + } + + #[test] + fn dust_moves_between_free_and_reserved() { + <$ext_builder>::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, 0)); + // Check balance + assert_eq!(Balances::free_balance(1), 100); + assert_eq!(Balances::reserved_balance(1), 0); + + // Reserve some free balance + assert_ok!(Balances::reserve(&1, 50)); + // Check balance, the account should be ok. + assert_eq!(Balances::free_balance(1), 50); + assert_eq!(Balances::reserved_balance(1), 50); + + // Reserve the rest of the free balance + assert_ok!(Balances::reserve(&1, 50)); + // Check balance, the account should be ok. + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(1), 100); + + // Unreserve everything + Balances::unreserve(&1, 100); + // Check balance, all 100 should move to free_balance + assert_eq!(Balances::free_balance(1), 100); + assert_eq!(Balances::reserved_balance(1), 0); + }); + } + + #[test] + fn account_deleted_when_just_dust() { + <$ext_builder>::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, 50, 50)); + // Check balance + assert_eq!(Balances::free_balance(1), 50); + assert_eq!(Balances::reserved_balance(1), 50); + + // Reserve some free balance + let _ = Balances::slash(&1, 1); + // The account should be dead. + assert!(Balances::is_dead_account(&1)); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(1), 0); + }); + } + } } diff --git a/frame/balances/src/mock.rs b/frame/balances/src/tests_composite.rs similarity index 79% rename from frame/balances/src/mock.rs rename to frame/balances/src/tests_composite.rs index 8a651a0ff7..c566c9a9d0 100644 --- a/frame/balances/src/mock.rs +++ b/frame/balances/src/tests_composite.rs @@ -23,7 +23,7 @@ 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 crate::{GenesisConfig, Module, Trait, decl_tests}; use frame_system as system; impl_outer_origin!{ @@ -31,8 +31,7 @@ impl_outer_origin!{ } thread_local! { - pub(crate) static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); - static CREATION_FEE: RefCell = RefCell::new(0); + static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); } pub struct ExistentialDeposit; @@ -40,11 +39,6 @@ impl Get for ExistentialDeposit { fn get() -> u64 { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow()) } } -pub struct CreationFee; -impl Get for CreationFee { - fn get() -> u64 { CREATION_FEE.with(|v| *v.borrow()) } -} - // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Test; @@ -71,6 +65,9 @@ impl frame_system::Trait for Test { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = super::AccountData; + type OnNewAccount = (); + type OnReapAccount = Module; } parameter_types! { pub const TransactionBaseFee: u64 = 0; @@ -86,25 +83,20 @@ impl pallet_transaction_payment::Trait for Test { } impl Trait for Test { type Balance = u64; - type OnReapAccount = System; - type OnNewAccount = (); - type Event = (); type DustRemoval = (); - type TransferPayment = (); + type Event = (); type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; + type AccountStore = system::Module; } pub struct ExtBuilder { existential_deposit: u64, - creation_fee: u64, monied: bool, } impl Default for ExtBuilder { fn default() -> Self { Self { existential_deposit: 1, - creation_fee: 0, monied: false, } } @@ -114,17 +106,12 @@ impl ExtBuilder { self.existential_deposit = existential_deposit; self } - pub fn creation_fee(mut self, creation_fee: u64) -> Self { - self.creation_fee = creation_fee; - self - } pub fn monied(mut self, monied: bool) -> Self { self.monied = monied; self } pub fn set_associated_consts(&self) { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); - CREATION_FEE.with(|v| *v.borrow_mut() = self.creation_fee); } pub fn build(self) -> sp_io::TestExternalities { self.set_associated_consts(); @@ -146,12 +133,4 @@ impl ExtBuilder { } } -pub type System = frame_system::Module; -pub type Balances = Module; - -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 { - DispatchInfo { weight: w, pays_fee: true, ..Default::default() } -} +decl_tests!{ Test, ExtBuilder, EXISTENTIAL_DEPOSIT } diff --git a/frame/balances/src/tests_local.rs b/frame/balances/src/tests_local.rs new file mode 100644 index 0000000000..a63046e901 --- /dev/null +++ b/frame/balances/src/tests_local.rs @@ -0,0 +1,144 @@ +// Copyright 2018-2020 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 utilities + +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, StorageMapShim}; +use frame_support::weights::{Weight, DispatchInfo}; +use std::cell::RefCell; +use crate::{GenesisConfig, Module, Trait, decl_tests}; + +use frame_system as system; +impl_outer_origin!{ + pub enum Origin for Test {} +} + +thread_local! { + static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); +} + +pub struct ExistentialDeposit; +impl Get for ExistentialDeposit { + fn get() -> u64 { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow()) } +} + +// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. +#[derive(Clone, PartialEq, Eq, Debug)] +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 Call = (); + type Hash = H256; + type Hashing = ::sp_runtime::traits::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 = (); + type AccountData = super::AccountData; + type OnNewAccount = (); + type OnReapAccount = Module; +} +parameter_types! { + pub const TransactionBaseFee: u64 = 0; + pub const TransactionByteFee: u64 = 1; +} +impl pallet_transaction_payment::Trait for Test { + type Currency = Module; + type OnTransactionPayment = (); + type TransactionBaseFee = TransactionBaseFee; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = ConvertInto; + type FeeMultiplierUpdate = (); +} +impl Trait for Test { + type Balance = u64; + type DustRemoval = (); + type Event = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = StorageMapShim< + super::Account, + system::CallOnCreatedAccount, + system::CallKillAccount, + u64, super::AccountData + >; +} + +pub struct ExtBuilder { + existential_deposit: u64, + monied: bool, +} +impl Default for ExtBuilder { + fn default() -> Self { + Self { + existential_deposit: 1, + monied: false, + } + } +} +impl ExtBuilder { + pub fn existential_deposit(mut self, existential_deposit: u64) -> Self { + self.existential_deposit = existential_deposit; + self + } + pub fn monied(mut self, monied: bool) -> Self { + self.monied = monied; + if self.existential_deposit == 0 { + self.existential_deposit = 1; + } + self + } + pub fn set_associated_consts(&self) { + EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); + } + pub fn build(self) -> sp_io::TestExternalities { + self.set_associated_consts(); + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + GenesisConfig:: { + balances: if self.monied { + vec![ + (1, 10 * self.existential_deposit), + (2, 20 * self.existential_deposit), + (3, 30 * self.existential_deposit), + (4, 40 * self.existential_deposit), + (12, 10 * self.existential_deposit) + ] + } else { + vec![] + }, + }.assimilate_storage(&mut t).unwrap(); + t.into() + } +} + +decl_tests!{ Test, ExtBuilder, EXISTENTIAL_DEPOSIT } diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index ffc62d976a..e9e6c75b83 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -433,6 +433,9 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } impl Trait for Test { type Origin = Origin; @@ -454,7 +457,7 @@ mod tests { NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system::{Module, Call, Event}, + System: system::{Module, Call, Event}, Collective: collective::::{Module, Call, Event, Origin, Config}, DefaultCollective: collective::{Module, Call, Event, Origin, Config}, } diff --git a/frame/contracts/src/account_db.rs b/frame/contracts/src/account_db.rs index efef02222d..5204f1003a 100644 --- a/frame/contracts/src/account_db.rs +++ b/frame/contracts/src/account_db.rs @@ -26,7 +26,7 @@ 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::traits::{Currency, Get, Imbalance, SignedImbalance}; use frame_support::{storage::child, StorageMap}; use frame_system; @@ -146,9 +146,11 @@ impl AccountDb for DirectAccountDb { let mut total_imbalance = SignedImbalance::zero(); for (address, changed) in s.into_iter() { if let Some(balance) = changed.balance() { - let (imbalance, outcome) = T::Currency::make_free_balance_be(&address, balance); + let existed = !T::Currency::total_balance(&address).is_zero(); + let imbalance = T::Currency::make_free_balance_be(&address, balance); + let exists = !T::Currency::total_balance(&address).is_zero(); total_imbalance = total_imbalance.merge(imbalance); - if let UpdateBalanceOutcome::AccountKilled = outcome { + if existed && !exists { // Account killed. This will ultimately lead to calling `OnReapAccount` callback // which will make removal of CodeHashOf and AccountStorage for this account. // In order to avoid writing over the deleted properties we `continue` here. diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index e84fded920..ec9fad93b4 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -554,7 +554,6 @@ where #[derive(Copy, Clone)] pub enum TransferFeeKind { ContractInstantiate, - AccountCreate, Transfer, } @@ -572,7 +571,6 @@ impl Token for TransferFeeToken> { fn calculate_amount(&self, metadata: &Config) -> Gas { let balance_fee = match self.kind { TransferFeeKind::ContractInstantiate => metadata.contract_account_instantiate_fee, - TransferFeeKind::AccountCreate => metadata.account_create_fee, TransferFeeKind::Transfer => return metadata.schedule.transfer_cost, }; approx_gas_for_balance(self.gas_price, balance_fee) @@ -612,28 +610,14 @@ fn transfer<'a, T: Trait, V: Vm, L: Loader>( use self::TransferCause::*; use self::TransferFeeKind::*; - let to_balance = ctx.overlay.get_balance(dest); - - // `would_create` indicates whether the account will be created if this transfer gets executed. - // This flag is orthogonal to `cause. - // For example, we can instantiate a contract at the address which already has some funds. In this - // `would_create` will be `false`. Another example would be when this function is called from `call`, - // and account with the address `dest` doesn't exist yet `would_create` will be `true`. - let would_create = to_balance.is_zero(); - let token = { let kind: TransferFeeKind = match cause { // If this function is called from `Instantiate` routine, then we always // charge contract account creation fee. Instantiate => ContractInstantiate, - // Otherwise the fee depends on whether we create a new account or transfer - // to an existing one. - Call => if would_create { - TransferFeeKind::AccountCreate - } else { - TransferFeeKind::Transfer - }, + // Otherwise the fee is to transfer to an account. + Call => TransferFeeKind::Transfer, }; TransferFeeToken { kind, @@ -651,7 +635,8 @@ fn transfer<'a, T: Trait, V: Vm, L: Loader>( Some(b) => b, None => Err("balance too low to send value")?, }; - if would_create && value < ctx.config.existential_deposit { + let to_balance = ctx.overlay.get_balance(dest); + if to_balance.is_zero() && value < ctx.config.existential_deposit { Err("value too low to create account")? } T::Currency::ensure_can_withdraw( @@ -1105,7 +1090,7 @@ mod tests { toks, ExecFeeToken::Call, TransferFeeToken { - kind: TransferFeeKind::AccountCreate, + kind: TransferFeeKind::Transfer, gas_price: 1u64 }, ); diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index bd1e91f1a9..19e070bd03 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -401,9 +401,6 @@ pub trait Trait: frame_system::Trait { /// to removal of a contract. type SurchargeReward: Get>; - /// The fee required to create an account. - type CreationFee: Get>; - /// The fee to be paid for making a transaction; the base. type TransactionBaseFee: Get>; @@ -517,9 +514,6 @@ decl_module! { /// to removal of a contract. const SurchargeReward: BalanceOf = T::SurchargeReward::get(); - /// The fee required to create an account. - const CreationFee: BalanceOf = T::CreationFee::get(); - /// The fee to be paid for making a transaction; the base. const TransactionBaseFee: BalanceOf = T::TransactionBaseFee::get(); @@ -966,7 +960,6 @@ pub struct Config { pub max_depth: u32, pub max_value_size: u32, pub contract_account_instantiate_fee: BalanceOf, - pub account_create_fee: BalanceOf, } impl Config { @@ -978,7 +971,6 @@ impl Config { max_depth: T::MaxDepth::get(), max_value_size: T::MaxValueSize::get(), contract_account_instantiate_fee: T::ContractFee::get(), - account_create_fee: T::CreationFee::get(), } } } diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 9ee44a767a..8cb854ac97 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -41,7 +41,7 @@ use std::{cell::RefCell, sync::atomic::{AtomicUsize, Ordering}}; use sp_core::storage::well_known_keys; use frame_system::{self as system, EventRecord, Phase}; -mod contract { +mod contracts { // 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!`. @@ -53,7 +53,9 @@ use pallet_balances as balances; impl_outer_event! { pub enum MetaEvent for Test { - balances, contract, + system, + balances, + contracts, } } impl_outer_origin! { @@ -62,7 +64,7 @@ impl_outer_origin! { impl_outer_dispatch! { pub enum Call for Test where origin: Origin { balances::Balances, - contract::Contract, + contracts::Contracts, } } @@ -83,11 +85,6 @@ impl Get for TransferFee { fn get() -> u64 { TRANSFER_FEE.with(|v| *v.borrow()) } } -pub struct CreationFee; -impl Get for CreationFee { - fn get() -> u64 { INSTANTIATION_FEE.with(|v| *v.borrow()) } -} - pub struct BlockGasLimit; impl Get for BlockGasLimit { fn get() -> u64 { BLOCK_GAS_LIMIT.with(|v| *v.borrow()) } @@ -118,16 +115,16 @@ impl frame_system::Trait for Test { type MaximumBlockLength = MaximumBlockLength; type Version = (); type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnReapAccount = (Balances, Contracts); } impl pallet_balances::Trait for Test { type Balance = u64; - type OnReapAccount = (System, Contract); - type OnNewAccount = (); type Event = MetaEvent; type DustRemoval = (); - type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; + type AccountStore = System; } parameter_types! { pub const MinimumPeriod: u64 = 1; @@ -169,7 +166,6 @@ impl Trait for Test { type RentByteFee = RentByteFee; type RentDepositOffset = RentDepositOffset; type SurchargeReward = SurchargeReward; - type CreationFee = CreationFee; type TransactionBaseFee = TransactionBaseFee; type TransactionByteFee = TransactionByteFee; type ContractFee = ContractFee; @@ -182,7 +178,7 @@ impl Trait for Test { type Balances = pallet_balances::Module; type Timestamp = pallet_timestamp::Module; -type Contract = Module; +type Contracts = Module; type System = frame_system::Module; type Randomness = pallet_randomness_collective_flip::Module; @@ -304,7 +300,7 @@ fn refunds_unused_gas() { ExtBuilder::default().gas_price(2).build().execute_with(|| { Balances::deposit_creating(&ALICE, 100_000_000); - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, Vec::new())); + assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, 100_000, Vec::new())); // 2 * 135 - gas price multiplied by the call base fee. assert_eq!(Balances::free_balance(ALICE), 100_000_000 - (2 * 135)); @@ -413,10 +409,10 @@ fn instantiate_and_call_and_deposit_event() { ExtBuilder::default().existential_deposit(100).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); // Check at the end to get hash on error easily - let creation = Contract::instantiate( + let creation = Contracts::instantiate( Origin::signed(ALICE), 100, 100_000, @@ -427,34 +423,44 @@ fn instantiate_and_call_and_deposit_event() { assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(pallet_balances::RawEvent::NewAccount(1, 1_000_000)), + event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), + event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::system(frame_system::RawEvent::NewAccount(BOB)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), event: MetaEvent::balances( - pallet_balances::RawEvent::NewAccount(BOB, 100) + pallet_balances::RawEvent::Endowed(BOB, 100) ), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Transfer(ALICE, BOB, 100)), + event: MetaEvent::contracts(RawEvent::Transfer(ALICE, BOB, 100)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::ContractExecution(BOB, vec![1, 2, 3, 4])), + event: MetaEvent::contracts(RawEvent::ContractExecution(BOB, vec![1, 2, 3, 4])), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Instantiated(ALICE, BOB)), + event: MetaEvent::contracts(RawEvent::Instantiated(ALICE, BOB)), topics: vec![], } ]); @@ -493,24 +499,29 @@ fn dispatch_call() { ExtBuilder::default().existential_deposit(50).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); // Let's keep this assert even though it's redundant. If you ever need to update the // wasm source this test will fail and will show you the actual hash. assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(pallet_balances::RawEvent::NewAccount(1, 1_000_000)), + event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), + event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), topics: vec![], }, ]); - assert_ok!(Contract::instantiate( + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), 100, 100_000, @@ -518,7 +529,7 @@ fn dispatch_call() { vec![], )); - assert_ok!(Contract::call( + assert_ok!(Contracts::call( Origin::signed(ALICE), BOB, // newly created account 0, @@ -529,44 +540,59 @@ fn dispatch_call() { assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(pallet_balances::RawEvent::NewAccount(1, 1_000_000)), + event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), + event: MetaEvent::system(frame_system::RawEvent::NewAccount(BOB)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), event: MetaEvent::balances( - pallet_balances::RawEvent::NewAccount(BOB, 100) + pallet_balances::RawEvent::Endowed(BOB, 100) ), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Transfer(ALICE, BOB, 100)), + event: MetaEvent::contracts(RawEvent::Transfer(ALICE, BOB, 100)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Instantiated(ALICE, BOB)), + event: MetaEvent::contracts(RawEvent::Instantiated(ALICE, BOB)), topics: vec![], }, // Dispatching the call. + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::system(frame_system::RawEvent::NewAccount(CHARLIE)), + topics: vec![], + }, EventRecord { phase: Phase::ApplyExtrinsic(0), event: MetaEvent::balances( - pallet_balances::RawEvent::NewAccount(CHARLIE, 50) + pallet_balances::RawEvent::Endowed(CHARLIE, 50) ), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), event: MetaEvent::balances( - pallet_balances::RawEvent::Transfer(BOB, CHARLIE, 50, 0) + pallet_balances::RawEvent::Transfer(BOB, CHARLIE, 50) ), topics: vec![], }, @@ -574,7 +600,7 @@ fn dispatch_call() { // Event emited as a result of dispatch. EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Dispatched(BOB, true)), + event: MetaEvent::contracts(RawEvent::Dispatched(BOB, true)), topics: vec![], } ]); @@ -611,24 +637,29 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { ExtBuilder::default().existential_deposit(50).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); // Let's keep this assert even though it's redundant. If you ever need to update the // wasm source this test will fail and will show you the actual hash. assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(pallet_balances::RawEvent::NewAccount(1, 1_000_000)), + event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), + event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), topics: vec![], }, ]); - assert_ok!(Contract::instantiate( + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), 100, 100_000, @@ -639,7 +670,7 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { // Call the newly instantiated contract. The contract is expected to dispatch a call // and then trap. assert_err!( - Contract::call( + Contracts::call( Origin::signed(ALICE), BOB, // newly created account 0, @@ -651,29 +682,39 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(pallet_balances::RawEvent::NewAccount(1, 1_000_000)), + event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), + event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::system(frame_system::RawEvent::NewAccount(BOB)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), event: MetaEvent::balances( - pallet_balances::RawEvent::NewAccount(BOB, 100) + pallet_balances::RawEvent::Endowed(BOB, 100) ), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Transfer(ALICE, BOB, 100)), + event: MetaEvent::contracts(RawEvent::Transfer(ALICE, BOB, 100)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Instantiated(ALICE, BOB)), + event: MetaEvent::contracts(RawEvent::Instantiated(ALICE, BOB)), topics: vec![], }, // ABSENCE of events which would be caused by dispatched Balances::transfer call @@ -810,19 +851,24 @@ fn test_set_rent_code_and_hash() { ExtBuilder::default().existential_deposit(50).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); // If you ever need to update the wasm source this test will fail // and will show you the actual hash. assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(pallet_balances::RawEvent::NewAccount(1, 1_000_000)), + event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(code_hash.into())), + event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), topics: vec![], }, ]); @@ -837,8 +883,8 @@ fn storage_size() { ExtBuilder::default().existential_deposit(50).build().execute_with(|| { // Create Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::instantiate( + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), 30_000, 100_000, code_hash.into(), @@ -847,11 +893,11 @@ fn storage_size() { let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4); - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::set_storage_4_byte())); + assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, 100_000, call::set_storage_4_byte())); let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4 + 4); - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::remove_storage_4_byte())); + assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, 100_000, call::remove_storage_4_byte())); let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4); }); @@ -874,8 +920,8 @@ fn deduct_blocks() { ExtBuilder::default().existential_deposit(50).build().execute_with(|| { // Create Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::instantiate( + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), 30_000, 100_000, code_hash.into(), @@ -890,7 +936,7 @@ fn deduct_blocks() { initialize_block(5); // Trigger rent through call - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); + assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); // Check result let rent = (8 + 4 - 3) // storage size = size_offset + deploy_set_storage - deposit_offset @@ -905,7 +951,7 @@ fn deduct_blocks() { initialize_block(12); // Trigger rent through call - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); + assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); // Check result let rent_2 = (8 + 4 - 2) // storage size = size_offset + deploy_set_storage - deposit_offset @@ -917,7 +963,7 @@ fn deduct_blocks() { assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); // Second call on same block should have no effect on rent - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); + assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); @@ -930,34 +976,34 @@ fn deduct_blocks() { fn call_contract_removals() { removals(|| { // Call on already-removed account might fail, and this is fine. - Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()); + Contracts::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()); true }); } #[test] fn inherent_claim_surcharge_contract_removals() { - removals(|| Contract::claim_surcharge(Origin::NONE, BOB, Some(ALICE)).is_ok()); + removals(|| Contracts::claim_surcharge(Origin::NONE, BOB, Some(ALICE)).is_ok()); } #[test] fn signed_claim_surcharge_contract_removals() { - removals(|| Contract::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok()); + removals(|| Contracts::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok()); } #[test] fn claim_surcharge_malus() { // Test surcharge malus for inherent - claim_surcharge(4, || Contract::claim_surcharge(Origin::NONE, BOB, Some(ALICE)).is_ok(), true); - claim_surcharge(3, || Contract::claim_surcharge(Origin::NONE, BOB, Some(ALICE)).is_ok(), true); - claim_surcharge(2, || Contract::claim_surcharge(Origin::NONE, BOB, Some(ALICE)).is_ok(), true); - claim_surcharge(1, || Contract::claim_surcharge(Origin::NONE, BOB, Some(ALICE)).is_ok(), false); + claim_surcharge(4, || Contracts::claim_surcharge(Origin::NONE, BOB, Some(ALICE)).is_ok(), true); + claim_surcharge(3, || Contracts::claim_surcharge(Origin::NONE, BOB, Some(ALICE)).is_ok(), true); + claim_surcharge(2, || Contracts::claim_surcharge(Origin::NONE, BOB, Some(ALICE)).is_ok(), true); + claim_surcharge(1, || Contracts::claim_surcharge(Origin::NONE, BOB, Some(ALICE)).is_ok(), false); // Test surcharge malus for signed - claim_surcharge(4, || Contract::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok(), true); - claim_surcharge(3, || Contract::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok(), false); - claim_surcharge(2, || Contract::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok(), false); - claim_surcharge(1, || Contract::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok(), false); + claim_surcharge(4, || Contracts::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok(), true); + claim_surcharge(3, || Contracts::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok(), false); + claim_surcharge(2, || Contracts::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok(), false); + claim_surcharge(1, || Contracts::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok(), false); } /// Claim surcharge with the given trigger_call at the given blocks. @@ -968,8 +1014,8 @@ fn claim_surcharge(blocks: u64, trigger_call: impl Fn() -> bool, removes: bool) ExtBuilder::default().existential_deposit(50).build().execute_with(|| { // Create Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::instantiate( + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), 100, 100_000, code_hash.into(), @@ -1001,8 +1047,8 @@ fn removals(trigger_call: impl Fn() -> bool) { ExtBuilder::default().existential_deposit(50).build().execute_with(|| { // Create Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); - assert_ok!(Contract::instantiate( + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), 100, 100_000, code_hash.into(), @@ -1037,8 +1083,8 @@ fn removals(trigger_call: impl Fn() -> bool) { ExtBuilder::default().existential_deposit(50).build().execute_with(|| { // Create Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); - assert_ok!(Contract::instantiate( + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), 1_000, 100_000, code_hash.into(), @@ -1072,8 +1118,8 @@ fn removals(trigger_call: impl Fn() -> bool) { ExtBuilder::default().existential_deposit(50).build().execute_with(|| { // Create Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); - assert_ok!(Contract::instantiate( + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), 50+Balances::minimum_balance(), 100_000, code_hash.into(), @@ -1086,7 +1132,7 @@ fn removals(trigger_call: impl Fn() -> bool) { assert_eq!(Balances::free_balance(BOB), 50 + Balances::minimum_balance()); // Transfer funds - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::transfer())); + assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, 100_000, call::transfer())); assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); assert_eq!(Balances::free_balance(BOB), Balances::minimum_balance()); @@ -1116,8 +1162,8 @@ fn call_removed_contract() { ExtBuilder::default().existential_deposit(50).build().execute_with(|| { // Create Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); - assert_ok!(Contract::instantiate( + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm.clone())); + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), 100, 100_000, code_hash.into(), @@ -1125,28 +1171,28 @@ fn call_removed_contract() { )); // Calling contract should succeed. - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); + assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); // Advance blocks initialize_block(10); // Calling contract should remove contract and fail. assert_err!( - Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()), + Contracts::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()), "contract has been evicted" ); // Calling a contract that is about to evict shall emit an event. assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Evicted(BOB, true)), + event: MetaEvent::contracts(RawEvent::Evicted(BOB, true)), topics: vec![], }, ]); // Subsequent contract calls should also fail. assert_err!( - Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()), + Contracts::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()), "contract has been evicted" ); }) @@ -1209,8 +1255,8 @@ fn default_rent_allowance_on_instantiate() { ExtBuilder::default().existential_deposit(50).build().execute_with(|| { // Create Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::instantiate( + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), 30_000, 100_000, @@ -1226,7 +1272,7 @@ fn default_rent_allowance_on_instantiate() { initialize_block(5); // Trigger rent through call - assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); + assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); // Check contract is still alive let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive(); @@ -1322,32 +1368,37 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: ExtBuilder::default().existential_deposit(50).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, restoration_wasm)); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, set_rent_wasm)); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, restoration_wasm)); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, set_rent_wasm)); // If you ever need to update the wasm source this test will fail // and will show you the actual hash. assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(pallet_balances::RawEvent::NewAccount(1, 1_000_000)), + event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(restoration_code_hash.into())), + event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::CodeStored(set_rent_code_hash.into())), + event: MetaEvent::contracts(RawEvent::CodeStored(restoration_code_hash.into())), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::contracts(RawEvent::CodeStored(set_rent_code_hash.into())), topics: vec![], }, ]); // Create an account with address `BOB` with code `CODE_SET_RENT`. // The input parameter sets the rent allowance to 0. - assert_ok!(Contract::instantiate( + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), 30_000, 100_000, @@ -1361,7 +1412,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: assert_eq!(bob_contract.rent_allowance, 0); if test_different_storage { - assert_ok!(Contract::call( + assert_ok!(Contracts::call( Origin::signed(ALICE), BOB, 0, 100_000, call::set_storage_4_byte()) @@ -1377,14 +1428,14 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: // Call `BOB`, which makes it pay rent. Since the rent allowance is set to 0 // we expect that it will get removed leaving tombstone. assert_err!( - Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()), + Contracts::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null()), "contract has been evicted" ); assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract( + event: MetaEvent::contracts( RawEvent::Evicted(BOB.clone(), true) ), topics: vec![], @@ -1396,7 +1447,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: /// Note that we can't use `ALICE` for creating `DJANGO` so we create yet another /// account `CHARLIE` and create `DJANGO` with it. Balances::deposit_creating(&CHARLIE, 1_000_000); - assert_ok!(Contract::instantiate( + assert_ok!(Contracts::instantiate( Origin::signed(CHARLIE), 30_000, 100_000, @@ -1415,7 +1466,7 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: // Perform a call to `DJANGO`. This should either perform restoration successfully or // fail depending on the test parameters. - assert_ok!(Contract::call( + assert_ok!(Contracts::call( Origin::signed(ALICE), DJANGO, 0, @@ -1437,7 +1488,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::contract( + event: MetaEvent::contracts( RawEvent::Restored(DJANGO, BOB, bob_code_hash, 50, false) ), topics: vec![], @@ -1448,32 +1499,42 @@ fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: assert_eq!(System::events(), vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Evicted(BOB, true)), + event: MetaEvent::contracts(RawEvent::Evicted(BOB, true)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::system(frame_system::RawEvent::NewAccount(CHARLIE)), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(CHARLIE, 1_000_000)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(pallet_balances::RawEvent::NewAccount(CHARLIE, 1_000_000)), + event: MetaEvent::system(frame_system::RawEvent::NewAccount(DJANGO)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::balances(pallet_balances::RawEvent::NewAccount(DJANGO, 30_000)), + event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(DJANGO, 30_000)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Transfer(CHARLIE, DJANGO, 30_000)), + event: MetaEvent::contracts(RawEvent::Transfer(CHARLIE, DJANGO, 30_000)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Instantiated(CHARLIE, DJANGO)), + event: MetaEvent::contracts(RawEvent::Instantiated(CHARLIE, DJANGO)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract(RawEvent::Restored( + event: MetaEvent::contracts(RawEvent::Restored( DJANGO, BOB, bob_code_hash, @@ -1500,12 +1561,12 @@ 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::ReapedAccount(DJANGO, 0)), + event: MetaEvent::system(system::RawEvent::ReapedAccount(DJANGO)), topics: vec![], }, EventRecord { phase: Phase::ApplyExtrinsic(0), - event: MetaEvent::contract( + event: MetaEvent::contracts( RawEvent::Restored(DJANGO, BOB, bob_contract.code_hash, 50, true) ), topics: vec![], @@ -1586,8 +1647,8 @@ fn storage_max_value_limit() { ExtBuilder::default().existential_deposit(50).build().execute_with(|| { // Create Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::instantiate( + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), 30_000, 100_000, @@ -1600,7 +1661,7 @@ fn storage_max_value_limit() { assert_eq!(bob_contract.rent_allowance, >::max_value()); // Call contract with allowed storage value. - assert_ok!(Contract::call( + assert_ok!(Contracts::call( Origin::signed(ALICE), BOB, 0, @@ -1610,7 +1671,7 @@ fn storage_max_value_limit() { // Call contract with too large a storage value. assert_err!( - Contract::call( + Contracts::call( Origin::signed(ALICE), BOB, 0, @@ -1950,10 +2011,10 @@ fn deploy_and_call_other_contract() { ExtBuilder::default().existential_deposit(50).build().execute_with(|| { // Create Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, callee_wasm)); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, caller_wasm)); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, callee_wasm)); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, caller_wasm)); - assert_ok!(Contract::instantiate( + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), 100_000, 100_000, @@ -1963,7 +2024,7 @@ fn deploy_and_call_other_contract() { // Call BOB contract, which attempts to instantiate and call the callee contract and // makes various assertions on the results from those calls. - assert_ok!(Contract::call( + assert_ok!(Contracts::call( Origin::signed(ALICE), BOB, 0, @@ -2077,10 +2138,10 @@ fn self_destruct_by_draining_balance() { let (wasm, code_hash) = compile_module::(CODE_SELF_DESTRUCT).unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); // Instantiate the BOB contract. - assert_ok!(Contract::instantiate( + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), 100_000, 100_000, @@ -2095,7 +2156,7 @@ fn self_destruct_by_draining_balance() { ); // Call BOB with no input data, forcing it to self-destruct. - assert_ok!(Contract::call( + assert_ok!(Contracts::call( Origin::signed(ALICE), BOB, 0, @@ -2113,10 +2174,10 @@ fn cannot_self_destruct_while_live() { let (wasm, code_hash) = compile_module::(CODE_SELF_DESTRUCT).unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); // Instantiate the BOB contract. - assert_ok!(Contract::instantiate( + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), 100_000, 100_000, @@ -2133,7 +2194,7 @@ fn cannot_self_destruct_while_live() { // Call BOB with input data, forcing it make a recursive call to itself to // self-destruct, resulting in a trap. assert_err!( - Contract::call( + Contracts::call( Origin::signed(ALICE), BOB, 0, @@ -2313,12 +2374,12 @@ fn destroy_contract_and_transfer_funds() { ExtBuilder::default().existential_deposit(50).build().execute_with(|| { // Create Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, callee_wasm)); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, caller_wasm)); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, callee_wasm)); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, caller_wasm)); // This deploys the BOB contract, which in turn deploys the CHARLIE contract during // construction. - assert_ok!(Contract::instantiate( + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), 200_000, 100_000, @@ -2333,7 +2394,7 @@ fn destroy_contract_and_transfer_funds() { ); // Call BOB, which calls CHARLIE, forcing CHARLIE to self-destruct. - assert_ok!(Contract::call( + assert_ok!(Contracts::call( Origin::signed(ALICE), BOB, 0, @@ -2408,12 +2469,12 @@ fn cannot_self_destruct_in_constructor() { let (wasm, code_hash) = compile_module::(CODE_SELF_DESTRUCTING_CONSTRUCTOR).unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); // Fail to instantiate the BOB contract since its final balance is below existential // deposit. assert_err!( - Contract::instantiate( + Contracts::instantiate( Origin::signed(ALICE), 100_000, 100_000, @@ -2529,15 +2590,15 @@ fn get_runtime_storage() { 0x14144020u32.to_le_bytes().to_vec().as_ref() ); - assert_ok!(Contract::put_code(Origin::signed(ALICE), 100_000, wasm)); - assert_ok!(Contract::instantiate( + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), 100, 100_000, code_hash.into(), vec![], )); - assert_ok!(Contract::call( + assert_ok!(Contracts::call( Origin::signed(ALICE), BOB, 0, diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index d2033fa8b3..33ddf69427 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -30,7 +30,7 @@ use frame_support::{ weights::SimpleDispatchInfo, traits::{ Currency, ReservableCurrency, LockableCurrency, WithdrawReason, LockIdentifier, Get, - OnReapAccount, OnUnbalanced + OnReapAccount, OnUnbalanced, BalanceStatus } }; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -802,7 +802,7 @@ decl_module! { let queue = >::get(); ensure!(!queue.iter().any(|item| &item.1 == &proposal_hash), Error::::Imminent); - let _ = T::Currency::repatriate_reserved(&old, &who, deposit); + let _ = T::Currency::repatriate_reserved(&old, &who, deposit, BalanceStatus::Free); >::remove(&proposal_hash); Self::deposit_event(RawEvent::PreimageReaped(proposal_hash, old, deposit, who)); } @@ -1227,20 +1227,19 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnReapAccount = Balances; } parameter_types! { pub const ExistentialDeposit: u64 = 1; - pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Test { type Balance = u64; - type OnReapAccount = System; - type OnNewAccount = (); type Event = (); - type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; + type AccountStore = System; } parameter_types! { pub const LaunchPeriod: u64 = 2; diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index f5ffd87537..f250e77121 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -91,7 +91,7 @@ use frame_support::{ decl_storage, decl_event, ensure, decl_module, decl_error, weights::SimpleDispatchInfo, traits::{ Currency, Get, LockableCurrency, LockIdentifier, ReservableCurrency, WithdrawReasons, - ChangeMembers, OnUnbalanced, WithdrawReason, Contains + ChangeMembers, OnUnbalanced, WithdrawReason, Contains, BalanceStatus } }; use sp_phragmen::ExtendedBalance; @@ -314,7 +314,7 @@ decl_module! { let valid = Self::is_defunct_voter(&target); if valid { // reporter will get the voting bond of the target - T::Currency::repatriate_reserved(&target, &reporter, T::VotingBond::get())?; + T::Currency::repatriate_reserved(&target, &reporter, T::VotingBond::get(), BalanceStatus::Free)?; // remove the target. They are defunct. Self::do_remove_voter(&target, false); } else { @@ -814,23 +814,22 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnReapAccount = Balances; } parameter_types! { pub const ExistentialDeposit: u64 = 1; - pub const CreationFee: u64 = 0; - } +} impl pallet_balances::Trait for Test { type Balance = u64; - type OnNewAccount = (); - type OnReapAccount = System; type Event = Event; - type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; - } + type AccountStore = frame_system::Module; +} parameter_types! { pub const CandidacyBond: u64 = 3; @@ -937,7 +936,7 @@ mod tests { NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system::{Module, Call, Event}, + System: system::{Module, Call, Event}, Balances: pallet_balances::{Module, Call, Event, Config}, Elections: elections::{Module, Call, Event}, } @@ -1427,7 +1426,7 @@ mod tests { assert_ok!(Elections::report_defunct_voter(Origin::signed(5), 3)); assert_eq!( - System::events()[1].event, + System::events()[7].event, Event::elections(RawEvent::VoterReported(3, 5, true)) ); @@ -1456,7 +1455,7 @@ mod tests { assert_ok!(Elections::report_defunct_voter(Origin::signed(5), 4)); assert_eq!( - System::events()[1].event, + System::events()[7].event, Event::elections(RawEvent::VoterReported(4, 5, false)) ); @@ -1867,7 +1866,7 @@ mod tests { assert_eq!(balances(&5), (45, 2)); assert_eq!( - System::events()[0].event, + System::events()[6].event, Event::elections(RawEvent::NewTerm(vec![(4, 40), (5, 50)])), ); }) diff --git a/frame/elections/src/lib.rs b/frame/elections/src/lib.rs index eb87057f95..a3fdd74426 100644 --- a/frame/elections/src/lib.rs +++ b/frame/elections/src/lib.rs @@ -32,7 +32,7 @@ use frame_support::{ decl_storage, decl_event, ensure, decl_module, decl_error, weights::SimpleDispatchInfo, traits::{ - Currency, ExistenceRequirement, Get, LockableCurrency, LockIdentifier, + Currency, ExistenceRequirement, Get, LockableCurrency, LockIdentifier, BalanceStatus, OnUnbalanced, ReservableCurrency, WithdrawReason, WithdrawReasons, ChangeMembers } }; @@ -501,7 +501,7 @@ decl_module! { if valid { // This only fails if `reporter` doesn't exist, which it clearly must do since its // the origin. Still, it's no more harmful to propagate any error at this point. - T::Currency::repatriate_reserved(&who, &reporter, T::VotingBond::get())?; + T::Currency::repatriate_reserved(&who, &reporter, T::VotingBond::get(), BalanceStatus::Free)?; Self::deposit_event(RawEvent::VoterReaped(who, reporter)); } else { let imbalance = T::Currency::slash_reserved(&reporter, T::VotingBond::get()).0; diff --git a/frame/elections/src/mock.rs b/frame/elections/src/mock.rs index 7cef8e3bdb..c5af6ba045 100644 --- a/frame/elections/src/mock.rs +++ b/frame/elections/src/mock.rs @@ -39,9 +39,9 @@ parameter_types! { } impl frame_system::Trait for Test { type Origin = Origin; + type Call = (); type Index = u64; type BlockNumber = u64; - type Call = (); type Hash = H256; type Hashing = BlakeTwo256; type AccountId = u64; @@ -54,21 +54,20 @@ impl frame_system::Trait for Test { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnReapAccount = Balances; } parameter_types! { pub const ExistentialDeposit: u64 = 1; - pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Test { type Balance = u64; - type OnNewAccount = (); - type OnReapAccount = System; - type Event = Event; - type TransferPayment = (); type DustRemoval = (); + type Event = Event; type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; + type AccountStore = System; } parameter_types! { @@ -151,7 +150,7 @@ frame_support::construct_runtime!( NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system::{Module, Call, Event}, + System: system::{Module, Call, Event}, Balances: pallet_balances::{Module, Call, Event, Config}, Elections: elections::{Module, Call, Event, Config}, } @@ -266,8 +265,7 @@ pub(crate) fn create_candidate(i: u64, index: u32) { } pub(crate) fn balances(who: &u64) -> (u64, u64) { - let a = Balances::account(who); - (a.free, a.reserved) + (Balances::free_balance(who), Balances::reserved_balance(who)) } pub(crate) fn locks(who: &u64) -> Vec { diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index 14f88fc5f9..fb8a162d41 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -688,20 +688,19 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnReapAccount = pallet_balances::Module; } parameter_types! { pub const ExistentialDeposit: u64 = 1; - pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Test { type Balance = u64; - type OnReapAccount = System; - type OnNewAccount = (); - type Event = (); - type TransferPayment = (); type DustRemoval = (); + type Event = (); type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; + type AccountStore = System; } impl Trait for Test { type Event = (); diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 72411c904b..2d1b306531 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -416,6 +416,7 @@ mod tests { impl_outer_event!{ pub enum MetaEvent for Runtime { + system, balances, } } @@ -451,20 +452,19 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type Version = (); type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnReapAccount = Balances; } parameter_types! { pub const ExistentialDeposit: u64 = 1; - pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Runtime { type Balance = u64; - type OnReapAccount = System; - type OnNewAccount = (); type Event = MetaEvent; type DustRemoval = (); - type TransferPayment = (); type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; + type AccountStore = System; } parameter_types! { @@ -559,7 +559,7 @@ mod tests { header: Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("a0b84fec49718caf59350dab6ec2993f12db399a7cccdb80f3cf79618ed93bd8").into(), + state_root: hex!("96797237079b6d6ffab7a47f90ee257a439a0e8268bdab3fe2f1e52572b101de").into(), extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(), digest: Digest { logs: vec![], }, }, diff --git a/frame/finality-tracker/src/lib.rs b/frame/finality-tracker/src/lib.rs index c9c9fbb0b5..f7bb7b8566 100644 --- a/frame/finality-tracker/src/lib.rs +++ b/frame/finality-tracker/src/lib.rs @@ -261,6 +261,9 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type Version = (); type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } parameter_types! { pub const WindowSize: u64 = 11; diff --git a/frame/generic-asset/src/lib.rs b/frame/generic-asset/src/lib.rs index 28986463e5..59535de447 100644 --- a/frame/generic-asset/src/lib.rs +++ b/frame/generic-asset/src/lib.rs @@ -166,7 +166,7 @@ use frame_support::{ decl_event, decl_module, decl_storage, ensure, decl_error, traits::{ Currency, ExistenceRequirement, Imbalance, LockIdentifier, LockableCurrency, ReservableCurrency, - SignedImbalance, UpdateBalanceOutcome, WithdrawReason, WithdrawReasons, TryDrop, + SignedImbalance, WithdrawReason, WithdrawReasons, TryDrop, BalanceStatus, }, Parameter, StorageMap, }; @@ -714,8 +714,8 @@ impl Module { } } - /// Move up to `amount` from reserved balance of account `who` to free balance of account - /// `beneficiary`. + /// Move up to `amount` from reserved balance of account `who` to balance of account + /// `beneficiary`, either free or reserved depending on `status`. /// /// As much funds up to `amount` will be moved as possible. If this is less than `amount`, then /// the `remaining` would be returned, else `Zero::zero()`. @@ -726,13 +726,23 @@ impl Module { who: &T::AccountId, beneficiary: &T::AccountId, amount: T::Balance, + status: BalanceStatus, ) -> T::Balance { let b = Self::reserved_balance(asset_id, who); 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; - Self::set_free_balance(asset_id, beneficiary, new_free_balance); + match status { + BalanceStatus::Free => { + let original_free_balance = Self::free_balance(asset_id, beneficiary); + let new_free_balance = original_free_balance + slash; + Self::set_free_balance(asset_id, beneficiary, new_free_balance); + } + BalanceStatus::Reserved => { + let original_reserved_balance = Self::reserved_balance(asset_id, beneficiary); + let new_reserved_balance = original_reserved_balance + slash; + Self::set_reserved_balance(asset_id, beneficiary, new_reserved_balance); + } + } let new_reserve_balance = b - slash; Self::set_reserved_balance(asset_id, who, new_reserve_balance); @@ -1080,8 +1090,8 @@ mod imbalances { // its type declaration). // This works as long as `increase_total_issuance_by` doesn't use the Imbalance // types (basically for charging fees). -// This should eventually be refactored so that the three type items that do -// depend on the Imbalance type (TransactionPayment, TransferPayment, DustRemoval) +// This should eventually be refactored so that the two type items that do +// depend on the Imbalance type (TransactionPayment, DustRemoval) // are placed in their own SRML module. struct ElevatedTrait(T); impl Clone for ElevatedTrait { @@ -1106,12 +1116,15 @@ impl frame_system::Trait for ElevatedTrait { type Lookup = T::Lookup; type Header = T::Header; type Event = (); + type BlockHashCount = T::BlockHashCount; type MaximumBlockWeight = T::MaximumBlockWeight; type MaximumBlockLength = T::MaximumBlockLength; type AvailableBlockRatio = T::AvailableBlockRatio; - type BlockHashCount = T::BlockHashCount; type Version = T::Version; type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } impl Trait for ElevatedTrait { type Balance = T::Balance; @@ -1189,7 +1202,7 @@ where } fn deposit_creating(who: &T::AccountId, value: Self::Balance) -> Self::PositiveImbalance { - let (imbalance, _) = Self::make_free_balance_be(who, Self::free_balance(who) + value); + let imbalance = Self::make_free_balance_be(who, Self::free_balance(who) + value); if let SignedImbalance::Positive(p) = imbalance { p } else { @@ -1201,10 +1214,7 @@ where fn make_free_balance_be( who: &T::AccountId, balance: Self::Balance, - ) -> ( - SignedImbalance, - UpdateBalanceOutcome, - ) { + ) -> SignedImbalance { let original = >::free_balance(&U::asset_id(), who); let imbalance = if original <= balance { SignedImbalance::Positive(PositiveImbalance::new(balance - original)) @@ -1212,7 +1222,7 @@ where SignedImbalance::Negative(NegativeImbalance::new(original - balance)) }; >::set_free_balance(&U::asset_id(), who, balance); - (imbalance, UpdateBalanceOutcome::Updated) + imbalance } fn can_slash(who: &T::AccountId, value: Self::Balance) -> bool { @@ -1288,8 +1298,9 @@ where slashed: &T::AccountId, beneficiary: &T::AccountId, value: Self::Balance, + status: BalanceStatus, ) -> result::Result { - Ok(>::repatriate_reserved(&U::asset_id(), slashed, beneficiary, value)) + Ok(>::repatriate_reserved(&U::asset_id(), slashed, beneficiary, value, status)) } } diff --git a/frame/generic-asset/src/mock.rs b/frame/generic-asset/src/mock.rs index 6fdf2d2d88..141f7d0030 100644 --- a/frame/generic-asset/src/mock.rs +++ b/frame/generic-asset/src/mock.rs @@ -31,7 +31,7 @@ use frame_support::{parameter_types, impl_outer_event, impl_outer_origin, weight use super::*; impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } // For testing the module, we construct most of a mock runtime. This means @@ -62,6 +62,9 @@ impl frame_system::Trait for Test { type BlockHashCount = BlockHashCount; type Version = (); type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } impl Trait for Test { @@ -77,6 +80,7 @@ mod generic_asset { use frame_system as system; impl_outer_event! { pub enum TestEvent for Test { + system, generic_asset, } } diff --git a/frame/generic-asset/src/tests.rs b/frame/generic-asset/src/tests.rs index 7c12c391bf..ad8fc2bf1b 100644 --- a/frame/generic-asset/src/tests.rs +++ b/frame/generic-asset/src/tests.rs @@ -556,7 +556,7 @@ fn slash_reserved_should_return_none() { fn repatriate_reserved_return_amount_substracted_by_slash_amount() { ExtBuilder::default().build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); - assert_eq!(GenericAsset::repatriate_reserved(&1, &0, &1, 130), 30); + assert_eq!(GenericAsset::repatriate_reserved(&1, &0, &1, 130, BalanceStatus::Free), 30); }); } @@ -571,7 +571,7 @@ fn repatriate_reserved_return_amount_substracted_by_slash_amount() { fn repatriate_reserved_return_none() { ExtBuilder::default().build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); - assert_eq!(GenericAsset::repatriate_reserved(&1, &0, &1, 90), 0); + assert_eq!(GenericAsset::repatriate_reserved(&1, &0, &1, 90, BalanceStatus::Free), 0); }); } diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index 0015dd1f50..77a19c7626 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -65,6 +65,9 @@ impl frame_system::Trait for Test { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } mod grandpa { @@ -73,6 +76,7 @@ mod grandpa { impl_outer_event!{ pub enum TestEvent for Test { + system, grandpa, } } diff --git a/frame/identity/src/benchmarking.rs b/frame/identity/src/benchmarking.rs index 86ec6b30c9..11e98101ec 100644 --- a/frame/identity/src/benchmarking.rs +++ b/frame/identity/src/benchmarking.rs @@ -148,7 +148,7 @@ impl BenchmarkingSetup, RawOrigin> for Judgement::Reasonable )?; } - + // Create identity info with x additional fields let x = components.iter().find(|&c| c.0 == BenchmarkParameter::X).unwrap().1; // 32 byte data that we reuse below @@ -171,7 +171,7 @@ impl BenchmarkingSetup, RawOrigin> for fn instance(&self, components: &[(BenchmarkParameter, u32)]) -> Result<(crate::Call, RawOrigin), &'static str> - { + { // Generic data to be used. let data = Data::Raw(vec![0; 32]); @@ -212,7 +212,7 @@ impl BenchmarkingSetup, RawOrigin> for fn instance(&self, components: &[(BenchmarkParameter, u32)]) -> Result<(crate::Call, RawOrigin), &'static str> - { + { // The target user let caller = account::("caller", 0); let caller_origin: ::Origin = RawOrigin::Signed(caller.clone()).into(); @@ -262,7 +262,7 @@ impl BenchmarkingSetup, RawOrigin> for fn instance(&self, components: &[(BenchmarkParameter, u32)]) -> Result<(crate::Call, RawOrigin), &'static str> - { + { // The target user let caller = account::("caller", 0); let caller_origin: ::Origin = RawOrigin::Signed(caller.clone()).into(); @@ -296,7 +296,7 @@ impl BenchmarkingSetup, RawOrigin> for fn instance(&self, components: &[(BenchmarkParameter, u32)]) -> Result<(crate::Call, RawOrigin), &'static str> - { + { // The target user let caller = account::("caller", 0); let caller_origin: ::Origin = RawOrigin::Signed(caller.clone()).into(); @@ -330,7 +330,7 @@ impl BenchmarkingSetup, RawOrigin> for fn instance(&self, components: &[(BenchmarkParameter, u32)]) -> Result<(crate::Call, RawOrigin), &'static str> - { + { // The target user let caller = account::("caller", 0); let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); @@ -359,7 +359,7 @@ impl BenchmarkingSetup, RawOrigin> for fn instance(&self, components: &[(BenchmarkParameter, u32)]) -> Result<(crate::Call, RawOrigin), &'static str> - { + { // The target user let caller = account::("caller", 0); let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); @@ -388,7 +388,7 @@ impl BenchmarkingSetup, RawOrigin> for fn instance(&self, components: &[(BenchmarkParameter, u32)]) -> Result<(crate::Call, RawOrigin), &'static str> - { + { // The target user let caller = account::("caller", 0); let _ = T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); @@ -410,7 +410,7 @@ impl BenchmarkingSetup, RawOrigin> for } } -// Benchmark `provide_judgement` extrinsic. +// Benchmark `provide_judgement` extrinsic.g struct ProvideJudgement; impl BenchmarkingSetup, RawOrigin> for ProvideJudgement { @@ -425,7 +425,7 @@ impl BenchmarkingSetup, RawOrigin> for fn instance(&self, components: &[(BenchmarkParameter, u32)]) -> Result<(crate::Call, RawOrigin), &'static str> - { + { // Add r registrars let r = components.iter().find(|&c| c.0 == BenchmarkParameter::R).unwrap().1; benchmarking::add_registrars::(r)?; @@ -477,7 +477,7 @@ impl BenchmarkingSetup, RawOrigin> for fn instance(&self, components: &[(BenchmarkParameter, u32)]) -> Result<(crate::Call, RawOrigin), &'static str> - { + { // The target user let caller = account::("caller", 0); let caller_origin: ::Origin = RawOrigin::Signed(caller.clone()).into(); @@ -550,8 +550,8 @@ impl Benchmarking for Module { sp_io::benchmarking::commit_db(); sp_io::benchmarking::wipe_db(); - // first one is set_identity. - let components = , RawOrigin>>::components(&selected_benchmark); + // first one is set_identity. + let components = , RawOrigin>>::components(&selected_benchmark); // results go here let mut results: Vec = Vec::new(); // Select the component we will be benchmarking. Each component will be benchmarked. diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index c69239350c..5470e3d4b0 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -73,7 +73,7 @@ use sp_runtime::{DispatchResult, RuntimeDebug}; use sp_runtime::traits::{StaticLookup, EnsureOrigin, Zero, AppendZerosInput}; use frame_support::{ decl_module, decl_event, decl_storage, ensure, decl_error, - traits::{Currency, ReservableCurrency, OnUnbalanced, Get}, + traits::{Currency, ReservableCurrency, OnUnbalanced, Get, BalanceStatus}, weights::SimpleDispatchInfo, }; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -823,7 +823,7 @@ decl_module! { 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); + let _ = T::Currency::repatriate_reserved(&target, &sender, fee, BalanceStatus::Free); } id.judgements[position] = item } @@ -924,20 +924,19 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnReapAccount = Balances; } parameter_types! { pub const ExistentialDeposit: u64 = 1; - pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Test { type Balance = u64; - type OnReapAccount = System; - type OnNewAccount = (); type Event = (); - type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; + type AccountStore = System; } parameter_types! { pub const BasicDeposit: u64 = 10; diff --git a/frame/im-online/src/mock.rs b/frame/im-online/src/mock.rs index 5c428c3858..7ee4c89ab4 100644 --- a/frame/im-online/src/mock.rs +++ b/frame/im-online/src/mock.rs @@ -115,6 +115,9 @@ impl frame_system::Trait for Runtime { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } parameter_types! { diff --git a/frame/indices/Cargo.toml b/frame/indices/Cargo.toml index 839f668819..eb5298dcfa 100644 --- a/frame/indices/Cargo.toml +++ b/frame/indices/Cargo.toml @@ -16,6 +16,9 @@ sp-core = { version = "2.0.0", default-features = false, path = "../../primitive frame-support = { version = "2.0.0", default-features = false, path = "../support" } frame-system = { version = "2.0.0", default-features = false, path = "../system" } +[dev-dependencies] +pallet-balances = { version = "2.0.0", path = "../balances" } + [features] default = ["std"] std = [ diff --git a/frame/indices/src/lib.rs b/frame/indices/src/lib.rs index 945095288a..ad1a7f300f 100644 --- a/frame/indices/src/lib.rs +++ b/frame/indices/src/lib.rs @@ -19,41 +19,24 @@ #![cfg_attr(not(feature = "std"), no_std)] -use sp_std::{prelude::*, marker::PhantomData, convert::TryInto}; -use codec::{Encode, Codec}; -use frame_support::{Parameter, decl_module, decl_event, decl_storage}; -use sp_runtime::traits::{One, AtLeast32Bit, StaticLookup, Member, LookupError}; -use frame_system::{IsDeadAccount, OnNewAccount}; - +use sp_std::prelude::*; +use codec::Codec; +use sp_runtime::traits::{ + StaticLookup, Member, LookupError, Zero, One, BlakeTwo256, Hash, Saturating, AtLeast32Bit +}; +use frame_support::{Parameter, decl_module, decl_error, decl_event, decl_storage, ensure}; +use frame_support::dispatch::DispatchResult; +use frame_support::traits::{Currency, ReservableCurrency, Get, BalanceStatus::Reserved}; +use frame_support::storage::migration::take_storage_value; +use frame_system::{ensure_signed, ensure_root}; use self::address::Address as RawAddress; mod mock; - pub mod address; mod tests; -/// Number of account IDs stored per enum set. -const ENUM_SET_SIZE: u32 = 64; - 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. -pub trait ResolveHint { - /// Turn an Id into an Index, or None for the purpose of getting - /// a hint at a possibly desired index. - fn resolve_hint(who: &AccountId) -> Option; -} - -/// Simple encode-based resolve hint implementation. -pub struct SimpleResolveHint(PhantomData<(AccountId, AccountIndex)>); -impl> - ResolveHint for SimpleResolveHint -{ - fn resolve_hint(who: &AccountId) -> Option { - Some(AccountIndex::from(who.using_encoded(|e| e[0] as u32 + e[1] as u32 * 256))) - } -} +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; /// The module's config trait. pub trait Trait: frame_system::Trait { @@ -61,19 +44,28 @@ pub trait Trait: frame_system::Trait { /// can hold. type AccountIndex: Parameter + Member + Codec + Default + AtLeast32Bit + Copy; - /// Whether an account is dead or not. - type IsDeadAccount: IsDeadAccount; + /// The currency trait. + type Currency: ReservableCurrency; - /// How to turn an id into an index. - type ResolveHint: ResolveHint; + /// The deposit needed for reserving an index. + type Deposit: Get>; /// The overarching event type. type Event: From> + Into<::Event>; } -decl_module! { - pub struct Module for enum Call where origin: T::Origin, system = frame_system { - fn deposit_event() = default; +decl_storage! { + trait Store for Module as Indices { + /// The lookup from index to account. + pub Accounts build(|config: &GenesisConfig| + config.indices.iter() + .cloned() + .map(|(a, b)| (a, (b, Zero::zero()))) + .collect::>() + ): map hasher(blake2_128_concat) T::AccountIndex => Option<(T::AccountId, BalanceOf)>; + } + add_extra_genesis { + config(indices): Vec<(T::AccountIndex, T::AccountId)>; } } @@ -82,36 +74,146 @@ decl_event!( ::AccountId, ::AccountIndex { - /// A new account index was assigned. - /// - /// This event is not triggered when an existing index is reassigned - /// to another `AccountId`. - NewAccountIndex(AccountId, AccountIndex), + /// A account index was assigned. + IndexAssigned(AccountId, AccountIndex), + /// A account index has been freed up (unassigned). + IndexFreed(AccountIndex), } ); -decl_storage! { - trait Store for Module as Indices { - /// The next free enumeration set. - pub NextEnumSet get(fn next_enum_set) build(|config: &GenesisConfig| { - (config.ids.len() as u32 / ENUM_SET_SIZE).into() - }): T::AccountIndex; - - /// The enumeration sets. - pub EnumSet get(fn enum_set) build(|config: &GenesisConfig| { - (0..((config.ids.len() as u32) + ENUM_SET_SIZE - 1) / ENUM_SET_SIZE) - .map(|i| ( - i.into(), - config.ids[ - (i * ENUM_SET_SIZE) as usize.. - config.ids.len().min(((i + 1) * ENUM_SET_SIZE) as usize) - ].to_owned(), - )) - .collect::>() - }): map hasher(blake2_256) T::AccountIndex => Vec; +decl_error! { + pub enum Error for Module { + /// The index was not already assigned. + NotAssigned, + /// The index is assigned to another account. + NotOwner, + /// The index was not available. + InUse, + /// The source and destination accounts are identical. + NotTransfer, } - add_extra_genesis { - config(ids): Vec; +} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin, system = frame_system { + fn deposit_event() = default; + + fn on_initialize() { + Self::migrations(); + } + + /// Assign an previously unassigned index. + /// + /// Payment: `Deposit` is reserved from the sender account. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// - `index`: the index to be claimed. This must not be in use. + /// + /// Emits `IndexAssigned` if successful. + /// + /// # + /// - `O(1)`. + /// - One storage mutation (codec `O(1)`). + /// - One reserve operation. + /// - One event. + /// # + fn claim(origin, index: T::AccountIndex) { + let who = ensure_signed(origin)?; + + Accounts::::try_mutate(index, |maybe_value| { + ensure!(maybe_value.is_none(), Error::::InUse); + *maybe_value = Some((who.clone(), T::Deposit::get())); + T::Currency::reserve(&who, T::Deposit::get()) + })?; + Self::deposit_event(RawEvent::IndexAssigned(who, index)); + } + + /// Assign an index already owned by the sender to another account. The balance reservation + /// is effectively transfered to the new account. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// - `index`: the index to be re-assigned. This must be owned by the sender. + /// - `new`: the new owner of the index. This function is a no-op if it is equal to sender. + /// + /// Emits `IndexAssigned` if successful. + /// + /// # + /// - `O(1)`. + /// - One storage mutation (codec `O(1)`). + /// - One transfer operation. + /// - One event. + /// # + fn transfer(origin, new: T::AccountId, index: T::AccountIndex) { + let who = ensure_signed(origin)?; + ensure!(who != new, Error::::NotTransfer); + + Accounts::::try_mutate(index, |maybe_value| -> DispatchResult { + let (account, amount) = maybe_value.take().ok_or(Error::::NotAssigned)?; + ensure!(&account == &who, Error::::NotOwner); + let lost = T::Currency::repatriate_reserved(&who, &new, amount, Reserved)?; + *maybe_value = Some((new.clone(), amount.saturating_sub(lost))); + Ok(()) + })?; + Self::deposit_event(RawEvent::IndexAssigned(new, index)); + } + + /// Free up an index owned by the sender. + /// + /// Payment: Any previous deposit placed for the index is unreserved in the sender account. + /// + /// The dispatch origin for this call must be _Signed_ and the sender must own the index. + /// + /// - `index`: the index to be freed. This must be owned by the sender. + /// + /// Emits `IndexFreed` if successful. + /// + /// # + /// - `O(1)`. + /// - One storage mutation (codec `O(1)`). + /// - One reserve operation. + /// - One event. + /// # + fn free(origin, index: T::AccountIndex) { + let who = ensure_signed(origin)?; + + Accounts::::try_mutate(index, |maybe_value| -> DispatchResult { + let (account, amount) = maybe_value.take().ok_or(Error::::NotAssigned)?; + ensure!(&account == &who, Error::::NotOwner); + T::Currency::unreserve(&who, amount); + Ok(()) + })?; + Self::deposit_event(RawEvent::IndexFreed(index)); + } + + /// Force an index to an account. This doesn't require a deposit. If the index is already + /// held, then any deposit is reimbursed to its current owner. + /// + /// The dispatch origin for this call must be _Root_. + /// + /// - `index`: the index to be (re-)assigned. + /// - `new`: the new owner of the index. This function is a no-op if it is equal to sender. + /// + /// Emits `IndexAssigned` if successful. + /// + /// # + /// - `O(1)`. + /// - One storage mutation (codec `O(1)`). + /// - Up to one reserve operation. + /// - One event. + /// # + fn force_transfer(origin, new: T::AccountId, index: T::AccountIndex) { + ensure_root(origin)?; + + Accounts::::mutate(index, |maybe_value| { + if let Some((account, amount)) = maybe_value.take() { + T::Currency::unreserve(&account, amount); + } + *maybe_value = Some((new.clone(), Zero::zero())); + }); + Self::deposit_event(RawEvent::IndexAssigned(new, index)); + } } } @@ -120,22 +222,7 @@ impl Module { /// Lookup an T::AccountIndex to get an Id, if there's one there. pub fn lookup_index(index: T::AccountIndex) -> Option { - let enum_set_size = Self::enum_set_size(); - let set = Self::enum_set(index / enum_set_size); - let i: usize = (index % enum_set_size).try_into().ok()?; - set.get(i).cloned() - } - - /// `true` if the account `index` is ready for reclaim. - pub fn can_reclaim(try_index: T::AccountIndex) -> bool { - let enum_set_size = Self::enum_set_size(); - let try_set = Self::enum_set(try_index / enum_set_size); - let maybe_usize: Result = (try_index % enum_set_size).try_into(); - if let Ok(i) = maybe_usize { - i < try_set.len() && T::IsDeadAccount::is_dead_account(&try_set[i]) - } else { - false - } + Accounts::::get(index).map(|x| x.0) } /// Lookup an address to get an Id, if there's one there. @@ -148,76 +235,28 @@ impl Module { } } - // PUBLIC MUTABLES (DANGEROUS) - - fn enum_set_size() -> T::AccountIndex { - ENUM_SET_SIZE.into() - } -} - -impl OnNewAccount for Module { - // Implementation of the config type managing the creation of new accounts. - // See Balances module for a concrete example. - // - // # - // - Independent of the arguments. - // - Given the correct value of `Self::next_enum_set`, it always has a limited - // number of reads and writes and no complex computation. - // - // As for storage, calling this function with _non-dead-indices_ will linearly grow the length of - // of `Self::enum_set`. Appropriate economic incentives should exist to make callers of this - // function provide a `who` argument that reclaims a dead account. - // - // At the time of this writing, only the Balances module calls this function upon creation - // of new accounts. - // # - fn on_new_account(who: &T::AccountId) { - let enum_set_size = Self::enum_set_size(); - let next_set_index = Self::next_enum_set(); - - if let Some(try_index) = T::ResolveHint::resolve_hint(who) { - // then check to see if this account id identifies a dead account index. - let set_index = try_index / enum_set_size; - let mut try_set = Self::enum_set(set_index); - if let Ok(item_index) = (try_index % enum_set_size).try_into() { - if item_index < try_set.len() { - if T::IsDeadAccount::is_dead_account(&try_set[item_index]) { - // yup - this index refers to a dead account. can be reused. - try_set[item_index] = who.clone(); - >::insert(set_index, try_set); - - return + /// Do any migrations. + fn migrations() { + if let Some(set_count) = take_storage_value::(b"Indices", b"NextEnumSet", b"") { + // migrations need doing. + let set_size: T::AccountIndex = 64.into(); + + let mut set_index: T::AccountIndex = Zero::zero(); + while set_index < set_count { + let maybe_accounts = take_storage_value::>(b"Indices", b"EnumSet", BlakeTwo256::hash_of(&set_index).as_ref()); + if let Some(accounts) = maybe_accounts { + for (item_index, target) in accounts.into_iter().enumerate() { + if target != T::AccountId::default() && !T::Currency::total_balance(&target).is_zero() { + let index = set_index * set_size + T::AccountIndex::from(item_index as u32); + Accounts::::insert(index, (target, BalanceOf::::zero())); + } } + } else { + break; } + set_index += One::one(); } } - - // insert normally as a back up - let mut set_index = next_set_index; - // defensive only: this loop should never iterate since we keep NextEnumSet up to date - // later. - let mut set = loop { - let set = Self::enum_set(set_index); - if set.len() < ENUM_SET_SIZE as usize { - break set; - } - set_index += One::one(); - }; - - let index = set_index * enum_set_size + T::AccountIndex::from(set.len() as u32); - - // update set. - set.push(who.clone()); - - // keep NextEnumSet up to date - if set.len() == ENUM_SET_SIZE as usize { - >::put(set_index + One::one()); - } - - // write set. - >::insert(set_index, set); - - Self::deposit_event(RawEvent::NewAccountIndex(who.clone(), index)); } } diff --git a/frame/indices/src/mock.rs b/frame/indices/src/mock.rs index b8c9b0a0ad..fe01b680bc 100644 --- a/frame/indices/src/mock.rs +++ b/frame/indices/src/mock.rs @@ -18,51 +18,29 @@ #![cfg(test)] -use std::{cell::RefCell, collections::HashSet}; 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}; +use frame_support::{impl_outer_origin, impl_outer_event, parameter_types, weights::Weight}; +use crate::{self as indices, Module, Trait}; +use frame_system as system; +use pallet_balances as balances; impl_outer_origin!{ - pub enum Origin for Runtime where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } - -thread_local! { - static ALIVE: RefCell> = Default::default(); -} - -pub fn make_account(who: u64) { - ALIVE.with(|a| a.borrow_mut().insert(who)); - Indices::on_new_account(&who); -} - -pub fn kill_account(who: u64) { - ALIVE.with(|a| a.borrow_mut().remove(&who)); -} - -pub struct TestIsDeadAccount {} -impl IsDeadAccount for TestIsDeadAccount { - fn is_dead_account(who: &u64) -> bool { - !ALIVE.with(|a| a.borrow_mut().contains(who)) - } -} - -pub struct TestResolveHint; -impl ResolveHint for TestResolveHint { - fn resolve_hint(who: &u64) -> Option { - if *who < 256 { - None - } else { - Some(*who - 256) - } +impl_outer_event!{ + pub enum MetaEvent for Test { + system, + balances, + indices, } } // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, Debug)] -pub struct Runtime; +pub struct Test; + parameter_types! { pub const BlockHashCount: u64 = 250; pub const MaximumBlockWeight: Weight = 1024; @@ -70,46 +48,59 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } -impl frame_system::Trait for Runtime { +impl frame_system::Trait for Test { type Origin = Origin; + type Call = (); type Index = u64; type BlockNumber = u64; - type Call = (); type Hash = H256; type Hashing = ::sp_runtime::traits::BlakeTwo256; type AccountId = u64; type Lookup = Indices; type Header = Header; - type Event = (); + type Event = MetaEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnReapAccount = Balances; +} + +parameter_types! { + pub const ExistentialDeposit: u64 = 1; +} + +impl pallet_balances::Trait for Test { + type Balance = u64; + type DustRemoval = (); + type Event = MetaEvent; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; } -impl Trait for Runtime { +parameter_types! { + pub const Deposit: u64 = 1; +} + +impl Trait for Test { type AccountIndex = u64; - type IsDeadAccount = TestIsDeadAccount; - type ResolveHint = TestResolveHint; - type Event = (); + type Currency = Balances; + type Deposit = Deposit; + type Event = MetaEvent; } pub fn new_test_ext() -> sp_io::TestExternalities { - { - ALIVE.with(|a| { - let mut h = a.borrow_mut(); - h.clear(); - for i in 1..5 { h.insert(i); } - }); - } - - let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - GenesisConfig:: { - ids: vec![1, 2, 3, 4] + 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)], }.assimilate_storage(&mut t).unwrap(); t.into() } -pub type Indices = Module; +pub type System = frame_system::Module; +pub type Balances = pallet_balances::Module; +pub type Indices = Module; diff --git a/frame/indices/src/tests.rs b/frame/indices/src/tests.rs index 95afcef734..9e434cfbe2 100644 --- a/frame/indices/src/tests.rs +++ b/frame/indices/src/tests.rs @@ -19,49 +19,85 @@ #![cfg(test)] use super::*; -use crate::mock::{Indices, new_test_ext, make_account, kill_account, TestIsDeadAccount}; +use super::mock::*; +use frame_support::{assert_ok, assert_noop}; +use pallet_balances::Error as BalancesError; #[test] -fn indexing_lookup_should_work() { +fn claiming_should_work() { new_test_ext().execute_with(|| { - assert_eq!(Indices::lookup_index(0), Some(1)); - assert_eq!(Indices::lookup_index(1), Some(2)); - assert_eq!(Indices::lookup_index(2), Some(3)); - assert_eq!(Indices::lookup_index(3), Some(4)); - assert_eq!(Indices::lookup_index(4), None); + assert_noop!(Indices::claim(Some(0).into(), 0), BalancesError::::InsufficientBalance); + assert_ok!(Indices::claim(Some(1).into(), 0)); + assert_noop!(Indices::claim(Some(2).into(), 0), Error::::InUse); + assert_eq!(Balances::reserved_balance(1), 1); }); } #[test] -fn default_indexing_on_new_accounts_should_work() { +fn freeing_should_work() { new_test_ext().execute_with(|| { - assert_eq!(Indices::lookup_index(4), None); - make_account(5); - assert_eq!(Indices::lookup_index(4), Some(5)); + assert_ok!(Indices::claim(Some(1).into(), 0)); + assert_ok!(Indices::claim(Some(2).into(), 1)); + assert_noop!(Indices::free(Some(0).into(), 0), Error::::NotOwner); + assert_noop!(Indices::free(Some(1).into(), 1), Error::::NotOwner); + assert_noop!(Indices::free(Some(1).into(), 2), Error::::NotAssigned); + assert_ok!(Indices::free(Some(1).into(), 0)); + assert_eq!(Balances::reserved_balance(1), 0); + assert_noop!(Indices::free(Some(1).into(), 0), Error::::NotAssigned); }); } #[test] -fn reclaim_indexing_on_new_accounts_should_work() { +fn indexing_lookup_should_work() { new_test_ext().execute_with(|| { + assert_ok!(Indices::claim(Some(1).into(), 0)); + assert_ok!(Indices::claim(Some(2).into(), 1)); + assert_eq!(Indices::lookup_index(0), Some(1)); assert_eq!(Indices::lookup_index(1), Some(2)); - assert_eq!(Indices::lookup_index(4), None); + assert_eq!(Indices::lookup_index(2), None); + }); +} - kill_account(2); // index 1 no longer locked to id 2 +#[test] +fn reclaim_index_on_accounts_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Indices::claim(Some(1).into(), 0)); + assert_ok!(Indices::free(Some(1).into(), 0)); + assert_ok!(Indices::claim(Some(2).into(), 0)); + assert_eq!(Indices::lookup_index(0), Some(2)); + assert_eq!(Balances::reserved_balance(2), 1); + }); +} - make_account(1 + 256); // id 257 takes index 1. - assert_eq!(Indices::lookup_index(1), Some(257)); +#[test] +fn transfer_index_on_accounts_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Indices::claim(Some(1).into(), 0)); + assert_noop!(Indices::transfer(Some(1).into(), 2, 1), Error::::NotAssigned); + assert_noop!(Indices::transfer(Some(2).into(), 3, 0), Error::::NotOwner); + assert_ok!(Indices::transfer(Some(1).into(), 3, 0)); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(Balances::reserved_balance(3), 1); + assert_eq!(Indices::lookup_index(0), Some(3)); }); } #[test] -fn alive_account_should_prevent_reclaim() { +fn force_transfer_index_on_preowned_should_work() { new_test_ext().execute_with(|| { - assert!(!TestIsDeadAccount::is_dead_account(&2)); - assert_eq!(Indices::lookup_index(1), Some(2)); - assert_eq!(Indices::lookup_index(4), None); + assert_ok!(Indices::claim(Some(1).into(), 0)); + assert_ok!(Indices::force_transfer(Origin::ROOT, 3, 0)); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(Balances::reserved_balance(3), 0); + assert_eq!(Indices::lookup_index(0), Some(3)); + }); +} - make_account(1 + 256); // id 257 takes index 1. - assert_eq!(Indices::lookup_index(4), Some(257)); +#[test] +fn force_transfer_index_on_free_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Indices::force_transfer(Origin::ROOT, 3, 0)); + assert_eq!(Balances::reserved_balance(3), 0); + assert_eq!(Indices::lookup_index(0), Some(3)); }); } diff --git a/frame/membership/src/lib.rs b/frame/membership/src/lib.rs index 3880b6cbb8..62d1315ee2 100644 --- a/frame/membership/src/lib.rs +++ b/frame/membership/src/lib.rs @@ -269,6 +269,9 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } ord_parameter_types! { pub const One: u64 = 1; diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index 814673a6ff..6a86f08093 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -285,20 +285,19 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnReapAccount = Balances; } parameter_types! { pub const ExistentialDeposit: u64 = 1; - pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Test { type Balance = u64; - type OnReapAccount = System; - type OnNewAccount = (); type Event = (); - type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; + type AccountStore = System; } parameter_types! { pub const ReservationFee: u64 = 2; diff --git a/frame/offences/src/mock.rs b/frame/offences/src/mock.rs index f344206f5c..f2e19b63f5 100644 --- a/frame/offences/src/mock.rs +++ b/frame/offences/src/mock.rs @@ -89,6 +89,9 @@ impl frame_system::Trait for Runtime { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } impl Trait for Runtime { @@ -103,6 +106,7 @@ mod offences { impl_outer_event! { pub enum TestEvent for Runtime { + system, offences, } } diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index 336b038c18..64d8f40099 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -191,6 +191,9 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type Version = (); type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } type System = frame_system::Module; diff --git a/frame/recovery/src/lib.rs b/frame/recovery/src/lib.rs index 668608c892..d293e1da9a 100644 --- a/frame/recovery/src/lib.rs +++ b/frame/recovery/src/lib.rs @@ -164,7 +164,7 @@ use frame_support::{ GetDispatchInfo, PaysFee, DispatchClass, ClassifyDispatch, Weight, WeighData, SimpleDispatchInfo, }, - traits::{Currency, ReservableCurrency, Get, OnReapAccount}, + traits::{Currency, ReservableCurrency, Get, OnReapAccount, BalanceStatus}, }; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -587,7 +587,7 @@ decl_module! { let active_recovery = >::take(&who, &rescuer).ok_or(Error::::NotStarted)?; // Move the reserved funds from the rescuer to the rescued account. // Acts like a slashing mechanism for those who try to maliciously recover accounts. - let _ = T::Currency::repatriate_reserved(&rescuer, &who, active_recovery.deposit); + let _ = T::Currency::repatriate_reserved(&rescuer, &who, active_recovery.deposit, BalanceStatus::Free); Self::deposit_event(RawEvent::RecoveryClosed(who, rescuer)); } diff --git a/frame/recovery/src/mock.rs b/frame/recovery/src/mock.rs index fa074e1faf..e6bc84f76b 100644 --- a/frame/recovery/src/mock.rs +++ b/frame/recovery/src/mock.rs @@ -36,6 +36,7 @@ impl_outer_origin! { impl_outer_event! { pub enum TestEvent for Test { + system, pallet_balances, recovery, } @@ -62,10 +63,10 @@ parameter_types! { impl frame_system::Trait for Test { type Origin = Origin; + type Call = Call; type Index = u64; type BlockNumber = u64; type Hash = H256; - type Call = Call; type Hashing = BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; @@ -77,22 +78,21 @@ impl frame_system::Trait for Test { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnReapAccount = (Balances, Recovery); } parameter_types! { pub const ExistentialDeposit: u64 = 1; - pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Test { type Balance = u128; - type OnReapAccount = (System, Recovery); - type OnNewAccount = (); - type Event = TestEvent; - type TransferPayment = (); type DustRemoval = (); + type Event = TestEvent; type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; + type AccountStore = System; } parameter_types! { diff --git a/frame/scored-pool/src/mock.rs b/frame/scored-pool/src/mock.rs index 58acc9c8d7..38a01a69af 100644 --- a/frame/scored-pool/src/mock.rs +++ b/frame/scored-pool/src/mock.rs @@ -47,7 +47,6 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); pub const ExistentialDeposit: u64 = 1; - pub const CreationFee: u64 = 0; } ord_parameter_types! { pub const KickOrigin: u64 = 2; @@ -71,17 +70,17 @@ impl frame_system::Trait for Test { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnReapAccount = Balances; } impl pallet_balances::Trait for Test { type Balance = u64; - type OnReapAccount = System; - type OnNewAccount = (); type Event = (); - type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; + type AccountStore = System; } thread_local! { diff --git a/frame/session/src/mock.rs b/frame/session/src/mock.rs index 9aae181771..0c92267069 100644 --- a/frame/session/src/mock.rs +++ b/frame/session/src/mock.rs @@ -176,6 +176,9 @@ impl frame_system::Trait for Test { type MaximumBlockLength = MaximumBlockLength; type Version = (); type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = Session; } impl pallet_timestamp::Trait for Test { diff --git a/frame/society/src/lib.rs b/frame/society/src/lib.rs index 0188ef7cb2..e803e54d4f 100644 --- a/frame/society/src/lib.rs +++ b/frame/society/src/lib.rs @@ -262,7 +262,7 @@ use sp_runtime::{Percent, ModuleId, RuntimeDebug, use frame_support::{decl_error, decl_module, decl_storage, decl_event, ensure, dispatch::DispatchResult}; use frame_support::weights::SimpleDispatchInfo; use frame_support::traits::{ - Currency, ReservableCurrency, Randomness, Get, ChangeMembers, + Currency, ReservableCurrency, Randomness, Get, ChangeMembers, BalanceStatus, ExistenceRequirement::AllowDeath, }; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -984,7 +984,7 @@ decl_module! { match kind { BidKind::Deposit(deposit) => { // Slash deposit and move it to the society account - let _ = T::Currency::repatriate_reserved(&who, &Self::account_id(), deposit); + let _ = T::Currency::repatriate_reserved(&who, &Self::account_id(), deposit, BalanceStatus::Free); } BidKind::Vouch(voucher, _) => { // Ban the voucher from vouching again diff --git a/frame/society/src/mock.rs b/frame/society/src/mock.rs index e3393080ca..081d68ada4 100644 --- a/frame/society/src/mock.rs +++ b/frame/society/src/mock.rs @@ -53,7 +53,6 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); pub const ExistentialDeposit: u64 = 1; - pub const CreationFee: u64 = 0; } ord_parameter_types! { @@ -78,17 +77,17 @@ impl frame_system::Trait for Test { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type OnNewAccount = (); + type OnReapAccount = Balances; + type AccountData = pallet_balances::AccountData; } impl pallet_balances::Trait for Test { type Balance = u64; - type OnNewAccount = (); type Event = (); - type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; - type OnReapAccount = System; + type AccountStore = System; } impl Trait for Test { diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index b4745c1fd3..447f655048 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -250,7 +250,6 @@ mod mock; #[cfg(test)] mod tests; -mod migration; mod slashing; pub mod inflation; @@ -761,9 +760,6 @@ decl_storage! { /// 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): @@ -795,8 +791,6 @@ decl_storage! { }, _ => Ok(()) }; } - - StorageVersion::put(migration::CURRENT_VERSION); }); } } @@ -1298,9 +1292,10 @@ impl Module { } /// Ensures storage is upgraded to most recent necessary state. - fn ensure_storage_upgraded() { - migration::perform_migrations::(); - } + /// + /// Right now it's a no-op as all networks that are supported by Substrate Frame Core are + /// running with the latest staking storage scheme. + fn ensure_storage_upgraded() {} /// Actually make a payment to a staker. This uses the currency's reward function /// to pay the right payee for the given staker account. diff --git a/frame/staking/src/migration.rs b/frame/staking/src/migration.rs deleted file mode 100644 index 6cb472375a..0000000000 --- a/frame/staking/src/migration.rs +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2019-2020 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 = 2; - -/// The inner logic of migrations. -#[cfg(any(test, feature = "migrate"))] -pub mod inner { - use crate::{Store, Module, Trait}; - use frame_support::{StorageLinkedMap, StoragePrefixedMap, StorageValue}; - use codec::{Encode, Decode}; - 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."); - } - - // migrate storage from v1 to v2: adds another field to the `SlashingSpans` - // struct. - pub fn to_v2(version: &mut VersionNumber) { - use crate::{EraIndex, slashing::SpanIndex}; - #[derive(Decode)] - struct V1SlashingSpans { - span_index: SpanIndex, - last_start: EraIndex, - prior: Vec, - } - - #[derive(Encode)] - struct V2SlashingSpans { - span_index: SpanIndex, - last_start: EraIndex, - last_nonzero_slash: EraIndex, - prior: Vec, - } - - if *version != 1 { return } - *version += 1; - - let prefix = as Store>::SlashingSpans::final_prefix(); - let mut current_key = prefix.to_vec(); - loop { - let maybe_next_key = sp_io::storage::next_key(¤t_key[..]) - .filter(|v| v.starts_with(&prefix[..])); - - match maybe_next_key { - Some(next_key) => { - let maybe_spans = sp_io::storage::get(&next_key[..]) - .and_then(|v| V1SlashingSpans::decode(&mut &v[..]).ok()); - if let Some(spans) = maybe_spans { - let new_val = V2SlashingSpans { - span_index: spans.span_index, - last_start: spans.last_start, - last_nonzero_slash: spans.last_start, - prior: spans.prior, - }.encode(); - - sp_io::storage::set(&next_key[..], &new_val[..]); - } - current_key = next_key; - } - None => break, - } - } - } - - 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); - to_v2::(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 7da30300f0..c5f3ef2508 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -138,19 +138,16 @@ impl frame_system::Trait for Test { type MaximumBlockLength = MaximumBlockLength; type Version = (); type ModuleToIndex = (); -} -parameter_types! { - pub const CreationFee: Balance = 0; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnReapAccount = (Balances, Staking, Session); } impl pallet_balances::Trait for Test { type Balance = Balance; - type OnReapAccount = (System, Staking); - type OnNewAccount = (); type Event = (); - type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; + type AccountStore = System; } parameter_types! { pub const Period: BlockNumber = 1; diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index e59f211b87..73f1afd634 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -18,7 +18,6 @@ use super::*; use mock::*; -use codec::Encode; use sp_runtime::{assert_eq_error_rate, traits::{OnInitialize, BadOrigin}}; use sp_staking::offence::OffenceDetails; use frame_support::{ @@ -2671,13 +2670,6 @@ fn remove_multi_deferred() { }) } -#[test] -fn version_initialized() { - ExtBuilder::default().build().execute_with(|| { - assert_eq!(::StorageVersion::get(), crate::migration::CURRENT_VERSION); - }); -} - #[test] fn slash_kicks_validators_not_nominators() { ExtBuilder::default().build().execute_with(|| { @@ -2717,56 +2709,6 @@ fn slash_kicks_validators_not_nominators() { }); } -#[test] -fn migration_v2() { - ExtBuilder::default().build().execute_with(|| { - use crate::{EraIndex, slashing::SpanIndex}; - - #[derive(Encode)] - struct V1SlashingSpans { - span_index: SpanIndex, - last_start: EraIndex, - prior: Vec, - } - - // inject old-style values directly into storage. - let set = |stash, spans: V1SlashingSpans| { - let key = ::SlashingSpans::hashed_key_for(stash); - sp_io::storage::set(&key, &spans.encode()); - }; - - let spans_11 = V1SlashingSpans { - span_index: 10, - last_start: 1, - prior: vec![0], - }; - - let spans_21 = V1SlashingSpans { - span_index: 1, - last_start: 5, - prior: vec![], - }; - - set(11, spans_11); - set(21, spans_21); - - ::StorageVersion::put(1); - - // perform migration. - crate::migration::inner::to_v2::(&mut 1); - - assert_eq!( - ::SlashingSpans::get(&11).unwrap().last_nonzero_slash(), - 1, - ); - - assert_eq!( - ::SlashingSpans::get(&21).unwrap().last_nonzero_slash(), - 5, - ); - }); -} - #[test] fn zero_slash_keeps_nominators() { ExtBuilder::default().build().execute_with(|| { diff --git a/frame/support/procedural/src/construct_runtime/mod.rs b/frame/support/procedural/src/construct_runtime/mod.rs index b4eaf09f6a..6c14f0ecfd 100644 --- a/frame/support/procedural/src/construct_runtime/mod.rs +++ b/frame/support/procedural/src/construct_runtime/mod.rs @@ -20,7 +20,7 @@ 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 proc_macro2::TokenStream as TokenStream2; use quote::quote; use syn::{Ident, Result, TypePath}; @@ -58,7 +58,7 @@ fn construct_runtime_parsed(definition: RuntimeDefinition) -> Result},`", )) } }; @@ -68,19 +68,17 @@ fn construct_runtime_parsed(definition: RuntimeDefinition) -> Result( ) } -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -enum DeclOuterKind { - Event, - Origin, +fn decl_outer_origin<'a>( + runtime_name: &'a Ident, + module_declarations: impl Iterator, + system_name: &'a Ident, + scrate: &'a TokenStream2, +) -> syn::Result { + let mut modules_tokens = TokenStream2::new(); + for module_declaration in module_declarations { + match module_declaration.find_part("Origin") { + 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 `Origin` cannot \ + be constructed: module `{}` must have generic `Origin`", + module_declaration.name + ); + return Err(syn::Error::new(module_declaration.name.span(), msg)); + } + let tokens = quote!(#module #instance #generics ,); + modules_tokens.extend(tokens); + } + None => {} + } + } + + Ok(quote!( + #scrate::impl_outer_origin! { + pub enum Origin for #runtime_name where system = #system_name { + #modules_tokens + } + } + )) } -fn decl_outer_event_or_origin<'a>( +fn decl_outer_event<'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) { + match module_declaration.find_part("Event") { 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 + "Instantiable module with no generic `Event` cannot \ + be constructed: module `{}` must have generic `Event`", + module_declaration.name, ); return Err(syn::Error::new(module_declaration.name.span(), msg)); } @@ -299,14 +325,10 @@ fn decl_outer_event_or_origin<'a>( 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 { + #scrate::impl_outer_event! { + pub enum Event for #runtime_name { #modules_tokens } } diff --git a/frame/support/src/event.rs b/frame/support/src/event.rs index 3ff6d4ab45..d30e6ddeea 100644 --- a/frame/support/src/event.rs +++ b/frame/support/src/event.rs @@ -337,30 +337,14 @@ macro_rules! impl_outer_event { ( $(#[$attr:meta])* pub enum $name:ident for $runtime:ident { - $( $rest_event_without_system:tt )* + $( $rest_events:tt )* } ) => { $crate::impl_outer_event!( $( #[$attr] )*; $name; $runtime; - system; - Modules { $( $rest_event_without_system )* }; - ; - ); - }; - ( - $(#[$attr:meta])* - pub enum $name:ident for $runtime:ident where system = $system:ident { - $( $rest_event_with_system:tt )* - } - ) => { - $crate::impl_outer_event!( - $( #[$attr] )*; - $name; - $runtime; - $system; - Modules { $( $rest_event_with_system )* }; + Modules { $( $rest_events )* }; ; ); }; @@ -369,7 +353,6 @@ macro_rules! impl_outer_event { $(#[$attr:meta])*; $name:ident; $runtime:ident; - $system:ident; Modules { $module:ident $instance:ident, $( $rest_event_generic_instance:tt )* @@ -380,7 +363,6 @@ macro_rules! impl_outer_event { $( #[$attr] )*; $name; $runtime; - $system; Modules { $( $rest_event_generic_instance )* }; $( $module_name::Event $( <$generic_param> )? $( { $generic_instance } )?, )* $module::Event<$runtime>{ $instance },; ); @@ -390,7 +372,6 @@ macro_rules! impl_outer_event { $(#[$attr:meta])*; $name:ident; $runtime:ident; - $system:ident; Modules { $module:ident $instance:ident, $( $rest_event_instance:tt )* @@ -401,7 +382,6 @@ macro_rules! impl_outer_event { $( #[$attr] )*; $name; $runtime; - $system; Modules { $( $rest_event_instance )* }; $( $module_name::Event $( <$generic_param> )* $( { $generic_instance } )?, )* $module::Event { $instance },; ); @@ -411,7 +391,6 @@ macro_rules! impl_outer_event { $(#[$attr:meta])*; $name:ident; $runtime:ident; - $system:ident; Modules { $module:ident, $( $rest_event_generic:tt )* @@ -422,7 +401,6 @@ macro_rules! impl_outer_event { $( #[$attr] )*; $name; $runtime; - $system; Modules { $( $rest_event_generic )* }; $( $module_name::Event $( <$generic_param> )? $( { $generic_instance } )?, )* $module::Event<$runtime>,; ); @@ -432,7 +410,6 @@ macro_rules! impl_outer_event { $(#[$attr:meta])*; $name:ident; $runtime:ident; - $system:ident; Modules { $module:ident, $( $rest_event_no_generic_no_instance:tt )* @@ -443,7 +420,6 @@ macro_rules! impl_outer_event { $( #[$attr] )*; $name; $runtime; - $system; Modules { $( $rest_event_no_generic_no_instance )* }; $( $module_name::Event $( <$generic_param> )? $( { $generic_instance } )?, )* $module::Event,; ); @@ -454,7 +430,6 @@ macro_rules! impl_outer_event { $(#[$attr:meta])*; $name:ident; $runtime:ident; - $system:ident; Modules {}; $( $module_name:ident::Event $( <$generic_param:ident> )? $( { $generic_instance:ident } )?, )*; ) => { @@ -468,18 +443,12 @@ macro_rules! impl_outer_event { $(#[$attr])* #[allow(non_camel_case_types)] pub enum $name { - system($system::Event), $( [< $module_name $(_ $generic_instance )? >]( $module_name::Event < $( $generic_param )? $(, $module_name::$generic_instance )? > ), )* } - impl From<$system::Event> for $name { - fn from(x: $system::Event) -> Self { - $name::system(x) - } - } $( impl From<$module_name::Event < $( $generic_param, )? $( $module_name::$generic_instance )? >> for $name { fn from(x: $module_name::Event < $( $generic_param, )? $( $module_name::$generic_instance )? >) -> Self { @@ -505,7 +474,6 @@ macro_rules! impl_outer_event { $crate::__impl_outer_event_json_metadata!( $runtime; $name; - $system; $( $module_name::Event < $( $generic_param )? $(, $module_name::$generic_instance )? > @@ -521,7 +489,6 @@ macro_rules! __impl_outer_event_json_metadata { ( $runtime:ident; $event_name:ident; - $system:ident; $( $module_name:ident::Event < $( $generic_params:path ),* > $( $instance:ident )?, )*; ) => { impl $runtime { @@ -530,22 +497,20 @@ 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)) $( - , ( + ( stringify!($module_name), $crate::event::FnEncode( $module_name::Event ::< $( $generic_params ),* > ::metadata ) ) - )* + ),* ]) } } $crate::__impl_outer_event_json_metadata! { @DECL_MODULE_EVENT_FNS - $system <> ; $( $module_name < $( $generic_params ),* > $( $instance )? ; )* } } @@ -717,6 +682,7 @@ mod tests { impl_outer_event! { pub enum TestEvent for TestRuntime { + system, event_module, event_module2, event_module3, @@ -727,7 +693,8 @@ mod tests { pub struct TestRuntime2; impl_outer_event! { - pub enum TestEventSystemRenamed for TestRuntime2 where system = system_renamed { + pub enum TestEventSystemRenamed for TestRuntime2 { + system_renamed, event_module, event_module2, event_module3, diff --git a/frame/support/src/metadata.rs b/frame/support/src/metadata.rs index f3c9945f88..46662e5354 100644 --- a/frame/support/src/metadata.rs +++ b/frame/support/src/metadata.rs @@ -404,6 +404,7 @@ mod tests { impl_outer_event! { pub enum TestEvent for TestRuntime { + system, event_module, event_module2, } diff --git a/frame/support/src/storage/generator/map.rs b/frame/support/src/storage/generator/map.rs index c1d9f1b149..497b3fd477 100644 --- a/frame/support/src/storage/generator/map.rs +++ b/frame/support/src/storage/generator/map.rs @@ -104,7 +104,7 @@ impl> storage::StorageMap } fn insert, ValArg: EncodeLike>(key: KeyArg, val: ValArg) { - unhashed::put(Self::storage_map_final_key(key).as_ref(), &val.borrow()) + unhashed::put(Self::storage_map_final_key(key).as_ref(), &val) } fn remove>(key: KeyArg) { @@ -117,12 +117,58 @@ impl> storage::StorageMap let ret = f(&mut val); match G::from_query_to_optional_value(val) { - Some(ref val) => unhashed::put(final_key.as_ref(), &val.borrow()), + Some(ref val) => unhashed::put(final_key.as_ref(), &val), None => unhashed::kill(final_key.as_ref()), } ret } + fn mutate_exists, R, F: FnOnce(&mut Option) -> R>(key: KeyArg, f: F) -> R { + let final_key = Self::storage_map_final_key(key); + let mut val = unhashed::get(final_key.as_ref()); + + let ret = f(&mut val); + match val { + Some(ref val) => unhashed::put(final_key.as_ref(), &val), + None => unhashed::kill(final_key.as_ref()), + } + ret + } + + fn try_mutate, R, E, F: FnOnce(&mut Self::Query) -> Result>( + key: KeyArg, + f: F + ) -> Result { + let final_key = Self::storage_map_final_key(key); + let mut val = G::from_optional_value_to_query(unhashed::get(final_key.as_ref())); + + let ret = f(&mut val); + if ret.is_ok() { + match G::from_query_to_optional_value(val) { + Some(ref val) => unhashed::put(final_key.as_ref(), &val.borrow()), + None => unhashed::kill(final_key.as_ref()), + } + } + ret + } + + fn try_mutate_exists, R, E, F: FnOnce(&mut Option) -> Result>( + key: KeyArg, + f: F + ) -> Result { + let final_key = Self::storage_map_final_key(key); + let mut val = unhashed::get(final_key.as_ref()); + + let ret = f(&mut val); + if ret.is_ok() { + match val { + Some(ref val) => unhashed::put(final_key.as_ref(), &val.borrow()), + None => unhashed::kill(final_key.as_ref()), + } + } + ret + } + fn take>(key: KeyArg) -> Self::Query { let key = Self::storage_map_final_key(key); let value = unhashed::take(key.as_ref()); diff --git a/frame/support/src/storage/generator/value.rs b/frame/support/src/storage/generator/value.rs index 44641b85f7..4083576e29 100644 --- a/frame/support/src/storage/generator/value.rs +++ b/frame/support/src/storage/generator/value.rs @@ -66,6 +66,10 @@ impl> storage::StorageValue for G { G::from_optional_value_to_query(value) } + fn try_get() -> Result { + unhashed::get(&Self::storage_value_final_key()).ok_or(()) + } + fn translate) -> Option>(f: F) -> Result, ()> { let key = Self::storage_value_final_key(); diff --git a/frame/balances/src/migration.rs b/frame/support/src/storage/migration.rs similarity index 75% rename from frame/balances/src/migration.rs rename to frame/support/src/storage/migration.rs index 4748cf3913..e8d58b46d4 100644 --- a/frame/balances/src/migration.rs +++ b/frame/support/src/storage/migration.rs @@ -18,8 +18,9 @@ use sp_std::prelude::*; use codec::{Encode, Decode}; -use frame_support::{StorageHasher, Twox128}; +use crate::{StorageHasher, Twox128}; +/// Utility to iterate through raw items in storage. pub struct StorageIterator { prefix: [u8; 32], previous_key: Vec, @@ -28,12 +29,14 @@ pub struct StorageIterator { } impl StorageIterator { + /// Construct iterator to iterate over map items in `module` for the map called `item`. pub fn new(module: &[u8], item: &[u8]) -> Self { let mut prefix = [0u8; 32]; prefix[0..16].copy_from_slice(&Twox128::hash(module)); prefix[16..32].copy_from_slice(&Twox128::hash(item)); Self { prefix, previous_key: prefix[..].to_vec(), drain: false, _phantom: Default::default() } } + /// Mutate this iterator into a draining iterator; items iterated are removed from storage. pub fn drain(mut self) -> Self { self.drain = true; self @@ -67,6 +70,7 @@ impl Iterator for StorageIterator { } } +/// Get a particular value in storage by the `module`, the map's `item` name and the key `hash`. pub fn get_storage_value(module: &[u8], item: &[u8], hash: &[u8]) -> Option { let mut key = vec![0u8; 32 + hash.len()]; key[0..16].copy_from_slice(&Twox128::hash(module)); @@ -75,6 +79,16 @@ pub fn get_storage_value(module: &[u8], item: &[u8], hash: &[ frame_support::storage::unhashed::get::(&key) } +/// Get a particular value in storage by the `module`, the map's `item` name and the key `hash`. +pub fn take_storage_value(module: &[u8], item: &[u8], hash: &[u8]) -> Option { + let mut key = vec![0u8; 32 + hash.len()]; + key[0..16].copy_from_slice(&Twox128::hash(module)); + key[16..32].copy_from_slice(&Twox128::hash(item)); + key[32..].copy_from_slice(hash); + frame_support::storage::unhashed::take::(&key) +} + +/// Put a particular value into storage by the `module`, the map's `item` name and the key `hash`. pub fn put_storage_value(module: &[u8], item: &[u8], hash: &[u8], value: T) { let mut key = vec![0u8; 32 + hash.len()]; key[0..16].copy_from_slice(&Twox128::hash(module)); diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index 3eb1a6f116..4bca5ea402 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -25,6 +25,7 @@ pub mod hashed; pub mod child; #[doc(hidden)] pub mod generator; +pub mod migration; /// A trait for working with macro-generated storage values under the substrate storage API. /// @@ -43,6 +44,10 @@ pub trait StorageValue { /// Load the value from the provided storage instance. fn get() -> Self::Query; + /// Try to get the underlying value from the provided storage instance; `Ok` if it exists, + /// `Err` if not. + fn try_get() -> Result; + /// Translate a value from some previous type (`O`) to the current type. /// /// `f: F` is the translation function. @@ -143,14 +148,28 @@ pub trait StorageMap { /// Mutate the value under a key. fn mutate, R, F: FnOnce(&mut Self::Query) -> R>(key: KeyArg, f: F) -> R; + /// Mutate the item, only if an `Ok` value is returned. + fn try_mutate, R, E, F: FnOnce(&mut Self::Query) -> Result>( + key: KeyArg, + f: F, + ) -> Result; + + /// Mutate the value under a key. Deletes the item if mutated to a `None`. + fn mutate_exists, R, F: FnOnce(&mut Option) -> R>(key: KeyArg, f: F) -> R; + + /// Mutate the item, only if an `Ok` value is returned. Deletes the item if mutated to a `None`. + fn try_mutate_exists, R, E, F: FnOnce(&mut Option) -> Result>( + key: KeyArg, + f: F, + ) -> Result; + /// Take the value under a key. fn take>(key: KeyArg) -> Self::Query; /// Append the given items to the value in the storage. /// /// `V` is required to implement `codec::EncodeAppend`. - fn append(key: KeyArg, items: Items) -> Result<(), &'static str> - where + fn append(key: KeyArg, items: Items) -> Result<(), &'static str> where KeyArg: EncodeLike, Item: Encode, EncodeLikeItem: EncodeLike, @@ -162,8 +181,7 @@ pub trait StorageMap { /// old (presumably corrupt) value is replaced with the given `items`. /// /// `V` is required to implement `codec::EncodeAppend`. - fn append_or_insert(key: KeyArg, items: Items) - where + fn append_or_insert(key: KeyArg, items: Items) where KeyArg: EncodeLike, Item: Encode, EncodeLikeItem: EncodeLike, diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index 0722012910..e12defcc54 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -28,6 +28,115 @@ use sp_runtime::{ }; use crate::dispatch::Parameter; +use crate::storage::StorageMap; + +/// An abstraction of a value stored within storage, but possibly as part of a larger composite +/// item. +pub trait StoredMap { + /// Get the item, or its default if it doesn't yet exist; we make no distinction between the + /// two. + fn get(k: &K) -> T; + /// Get whether the item takes up any storage. If this is `false`, then `get` will certainly + /// return the `T::default()`. If `true`, then there is no implication for `get` (i.e. it + /// may return any value, including the default). + /// + /// NOTE: This may still be `true`, even after `remove` is called. This is the case where + /// a single storage entry is shared between multiple `StoredMap` items single, without + /// additional logic to enforce it, deletion of any one them doesn't automatically imply + /// deletion of them all. + fn is_explicit(k: &K) -> bool; + /// Mutate the item. + fn mutate(k: &K, f: impl FnOnce(&mut T) -> R) -> R; + /// Mutate the item, removing or resetting to default value if it has been mutated to `None`. + fn mutate_exists(k: &K, f: impl FnOnce(&mut Option) -> R) -> R; + /// Maybe mutate the item only if an `Ok` value is returned from `f`. Do nothing if an `Err` is + /// returned. It is removed or reset to default value if it has been mutated to `None` + fn try_mutate_exists(k: &K, f: impl FnOnce(&mut Option) -> Result) -> Result; + /// Set the item to something new. + fn insert(k: &K, t: T) { Self::mutate(k, |i| *i = t); } + /// Remove the item or otherwise replace it with its default value; we don't care which. + fn remove(k: &K); +} + +/// A simple, generic one-parameter event notifier/handler. +pub trait Happened { + /// The thing happened. + fn happened(t: &T); +} + +/// A shim for placing around a storage item in order to use it as a `StoredValue`. Ideally this +/// wouldn't be needed as `StorageValue`s should blanket implement `StoredValue`s, however this +/// would break the ability to have custom impls of `StoredValue`. The other workaround is to +/// implement it directly in the macro. +/// +/// This form has the advantage that two additional types are provides, `Created` and `Removed`, +/// which are both generic events that can be tied to handlers to do something in the case of being +/// about to create an account where one didn't previously exist (at all; not just where it used to +/// be the default value), or where the account is being removed or reset back to the default value +/// where previously it did exist (though may have been in a default state). This works well with +/// system module's `CallOnCreatedAccount` and `CallKillAccount`. +pub struct StorageMapShim< + S, + Created, + Removed, + K, + T +>(sp_std::marker::PhantomData<(S, Created, Removed, K, T)>); +impl< + S: StorageMap, + Created: Happened, + Removed: Happened, + K: FullCodec, + T: FullCodec +> StoredMap for StorageMapShim { + fn get(k: &K) -> T { S::get(k) } + fn is_explicit(k: &K) -> bool { S::contains_key(k) } + fn insert(k: &K, t: T) { + S::insert(k, t); + if !S::contains_key(&k) { + Created::happened(k); + } + } + fn remove(k: &K) { + if S::contains_key(&k) { + Removed::happened(&k); + } + S::remove(k); + } + fn mutate(k: &K, f: impl FnOnce(&mut T) -> R) -> R { + let r = S::mutate(k, f); + if !S::contains_key(&k) { + Created::happened(k); + } + r + } + fn mutate_exists(k: &K, f: impl FnOnce(&mut Option) -> R) -> R { + let (existed, exists, r) = S::mutate_exists(k, |maybe_value| { + let existed = maybe_value.is_some(); + let r = f(maybe_value); + (existed, maybe_value.is_some(), r) + }); + if !existed && exists { + Created::happened(k); + } else if existed && !exists { + Removed::happened(k); + } + r + } + fn try_mutate_exists(k: &K, f: impl FnOnce(&mut Option) -> Result) -> Result { + S::try_mutate_exists(k, |maybe_value| { + let existed = maybe_value.is_some(); + f(maybe_value).map(|v| (existed, maybe_value.is_some(), v)) + }).map(|(existed, exists, v)| { + if !existed && exists { + Created::happened(k); + } else if existed && !exists { + Removed::happened(k); + } + v + }) + } +} /// Anything that can have a `::len()` method. pub trait Len { @@ -65,6 +174,25 @@ pub trait Contains { fn count() -> usize { Self::sorted_members().len() } } +/// Determiner to say whether a given account is unused. +pub trait IsDeadAccount { + /// Is the given account dead? + fn is_dead_account(who: &AccountId) -> bool; +} + +impl IsDeadAccount for () { + fn is_dead_account(_who: &AccountId) -> bool { + true + } +} + +/// Handler for when a new account has been created. +#[impl_trait_for_tuples::impl_for_tuples(30)] +pub trait OnNewAccount { + /// A new account `who` has been registered. + fn on_new_account(who: &AccountId); +} + /// The account with the given id was reaped. #[impl_trait_for_tuples::impl_for_tuples(30)] pub trait OnReapAccount { @@ -72,20 +200,6 @@ pub trait OnReapAccount { fn on_reap_account(who: &AccountId); } -/// Outcome of a balance update. -pub enum UpdateBalanceOutcome { - /// Account balance was simply updated. - Updated, - /// The update led to killing the account. - AccountKilled, - /// Free balance became zero as a result of this update. - FreeBalanceZero, - /// Reserved balance became zero as a result of this update. - ReservedBalanceZero, - /// The account started and ended non-existent. - StillDead, -} - /// A trait for finding the author of a block header based on the `PreRuntime` digests contained /// within it. pub trait FindAuthor { @@ -494,10 +608,15 @@ pub trait Currency { fn make_free_balance_be( who: &AccountId, balance: Self::Balance, - ) -> ( - SignedImbalance, - UpdateBalanceOutcome, - ); + ) -> SignedImbalance; +} + +/// Status of funds. +pub enum BalanceStatus { + /// Funds are free, as corresponding to `free` item in Balances. + Free, + /// Funds are reserved, as corresponding to `reserved` item in Balances. + Reserved, } /// A currency where funds can be reserved from the user. @@ -528,7 +647,6 @@ pub trait ReservableCurrency: Currency { /// collapsed to zero if it ever becomes less than `ExistentialDeposit`. fn reserved_balance(who: &AccountId) -> Self::Balance; - /// Moves `value` from balance to reserved balance. /// /// If the free balance is lower than `value`, then no funds will be moved and an `Err` will @@ -547,16 +665,18 @@ pub trait ReservableCurrency: Currency { /// invoke `on_reserved_too_low` and could reap the account. fn unreserve(who: &AccountId, value: Self::Balance) -> Self::Balance; - /// Moves up to `value` from reserved balance of account `slashed` to free balance of account + /// Moves up to `value` from reserved balance of account `slashed` to balance of account /// `beneficiary`. `beneficiary` must exist for this to succeed. If it does not, `Err` will be - /// returned. + /// returned. Funds will be placed in either the `free` balance or the `reserved` balance, + /// depending on the `status`. /// /// As much funds up to `value` will be deducted as possible. If this is less than `value`, /// then `Ok(non_zero)` will be returned. fn repatriate_reserved( slashed: &AccountId, beneficiary: &AccountId, - value: Self::Balance + value: Self::Balance, + status: BalanceStatus, ) -> result::Result; } 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 index 5964a8aa76..442af9c01f 100644 --- a/frame/support/test/tests/construct_runtime_ui/missing_system_module.stderr +++ b/frame/support/test/tests/construct_runtime_ui/missing_system_module.stderr @@ -1,4 +1,4 @@ -error: `System` module declaration is missing. Please add this line: `System: system::{Module, Call, Storage, Config, Event},` +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 | { diff --git a/frame/support/test/tests/decl_error.rs b/frame/support/test/tests/decl_error.rs index b90c870c31..39d7dbdb96 100644 --- a/frame/support/test/tests/decl_error.rs +++ b/frame/support/test/tests/decl_error.rs @@ -99,7 +99,7 @@ frame_support::construct_runtime!( NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system::{Module, Call, Event}, + System: system::{Module, Call, Event}, Module1_1: module1::::{Module, Call, Storage}, Module2: module2::{Module, Call, Storage}, Module1_2: module1::::{Module, Call, Storage}, diff --git a/frame/support/test/tests/instance.rs b/frame/support/test/tests/instance.rs index 4c509ae18f..48854baad9 100644 --- a/frame/support/test/tests/instance.rs +++ b/frame/support/test/tests/instance.rs @@ -247,7 +247,7 @@ frame_support::construct_runtime!( NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system::{Module, Call, Event}, + System: system::{Module, Call, Event}, Module1_1: module1::::{ Module, Call, Storage, Event, Config, Origin, Inherent }, diff --git a/frame/support/test/tests/issue2219.rs b/frame/support/test/tests/issue2219.rs index c0a253f22b..4537766981 100644 --- a/frame/support/test/tests/issue2219.rs +++ b/frame/support/test/tests/issue2219.rs @@ -173,7 +173,7 @@ frame_support::construct_runtime!( NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system::{Module, Call, Event}, + System: system::{Module, Call, Event}, Module: module::{Module, Call, Storage, Config}, } ); diff --git a/frame/support/test/tests/system.rs b/frame/support/test/tests/system.rs index c5b591642b..c7f60117bc 100644 --- a/frame/support/test/tests/system.rs +++ b/frame/support/test/tests/system.rs @@ -23,7 +23,7 @@ pub trait Trait: 'static + Eq + Clone { type BlockNumber: Decode + Encode + EncodeLike + Clone + Default; type Hash; type AccountId: Encode + EncodeLike + Decode; - type Event: From; + type Event: From>; type ModuleToIndex: frame_support::traits::ModuleToIndex; } @@ -36,9 +36,10 @@ impl Module { } frame_support::decl_event!( - pub enum Event { + pub enum Event where BlockNumber = ::BlockNumber { ExtrinsicSuccess, ExtrinsicFailed, + Ignore(BlockNumber), } ); diff --git a/frame/system/benches/bench.rs b/frame/system/benches/bench.rs index 49872ef7db..1e24cb2c05 100644 --- a/frame/system/benches/bench.rs +++ b/frame/system/benches/bench.rs @@ -46,6 +46,7 @@ impl_outer_origin!{ impl_outer_event! { pub enum Event for Runtime { + system, module, } } @@ -75,6 +76,9 @@ impl system::Trait for Runtime { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } impl module::Trait for Runtime { diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 58a6dbc56d..c351020a41 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -113,35 +113,19 @@ use sp_runtime::{ use sp_core::{ChangesTrieConfiguration, storage::well_known_keys}; use frame_support::{ decl_module, decl_event, decl_storage, decl_error, storage, Parameter, - traits::{Contains, Get, ModuleToIndex, OnReapAccount}, + traits::{ + Contains, Get, ModuleToIndex, OnNewAccount, OnReapAccount, IsDeadAccount, Happened, + StoredMap + }, weights::{Weight, DispatchInfo, DispatchClass, SimpleDispatchInfo}, }; -use codec::{Encode, Decode}; +use codec::{Encode, Decode, FullCodec, EncodeLike}; #[cfg(any(feature = "std", test))] use sp_io::TestExternalities; pub mod offchain; -/// Handler for when a new account has been created. -#[impl_trait_for_tuples::impl_for_tuples(30)] -pub trait OnNewAccount { - /// A new account `who` has been registered. - fn on_new_account(who: &AccountId); -} - -/// Determiner to say whether a given account is unused. -pub trait IsDeadAccount { - /// Is the given account dead? - fn is_dead_account(who: &AccountId) -> bool; -} - -impl IsDeadAccount for () { - fn is_dead_account(_who: &AccountId) -> bool { - true - } -} - /// Compute the trie root of a list of extrinsics. pub fn extrinsics_root(extrinsics: &[E]) -> H::Output { extrinsics_data_root::(extrinsics.iter().map(codec::Encode::encode).collect()) @@ -200,7 +184,7 @@ pub trait Trait: 'static + Eq + Clone { >; /// The aggregated event type of the runtime. - type Event: Parameter + Member + From + Debug; + type Event: Parameter + Member + From> + Debug; /// Maximum number of block number to block hash mappings to keep (oldest pruned first). type BlockHashCount: Get; @@ -224,6 +208,18 @@ pub trait Trait: 'static + Eq + Clone { /// 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; + + /// Data to be associated with an account (other than nonce/transaction counter, which this + /// module does regardless). + type AccountData: Member + FullCodec + Clone + Default; + + /// Handler for when a new account has just been created. + type OnNewAccount: OnNewAccount; + + /// A function that is invoked when an account has been determined to be dead. + /// + /// All resources should be cleaned up associated with the given account. + type OnReapAccount: OnReapAccount; } pub type DigestOf = generic::Digest<::Hash>; @@ -232,111 +228,6 @@ pub type DigestItemOf = generic::DigestItem<::Hash>; pub type Key = Vec; pub type KeyValue = (Vec, Vec); -decl_module! { - pub struct Module for enum Call where origin: T::Origin { - 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). - #[weight = SimpleDispatchInfo::MaxOperational] - fn fill_block(origin) { - ensure_root(origin)?; - } - - /// Make some on-chain remark. - #[weight = SimpleDispatchInfo::FixedNormal(10_000)] - fn remark(origin, _remark: Vec) { - ensure_signed(origin)?; - } - - /// Set the number of pages in the WebAssembly environment's heap. - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] - fn set_heap_pages(origin, pages: u64) { - ensure_root(origin)?; - storage::unhashed::put_raw(well_known_keys::HEAP_PAGES, &pages.encode()); - } - - /// Set the new runtime code. - #[weight = SimpleDispatchInfo::FixedOperational(200_000)] - pub fn set_code(origin, code: Vec) { - ensure_root(origin)?; - - let current_version = T::Version::get(); - let new_version = sp_io::misc::runtime_version(&code) - .and_then(|v| RuntimeVersion::decode(&mut &v[..]).ok()) - .ok_or_else(|| Error::::FailedToExtractRuntimeVersion)?; - - if new_version.spec_name != current_version.spec_name { - Err(Error::::InvalidSpecName)? - } - - if new_version.spec_version < current_version.spec_version { - Err(Error::::SpecVersionNotAllowedToDecrease)? - } else if new_version.spec_version == current_version.spec_version { - if new_version.impl_version < current_version.impl_version { - Err(Error::::ImplVersionNotAllowedToDecrease)? - } else if new_version.impl_version == current_version.impl_version { - Err(Error::::SpecOrImplVersionNeedToIncrease)? - } - } - - storage::unhashed::put_raw(well_known_keys::CODE, &code); - Self::deposit_event(Event::CodeUpdated); - } - - /// Set the new runtime code without doing any checks of the given `code`. - #[weight = SimpleDispatchInfo::FixedOperational(200_000)] - pub fn set_code_without_checks(origin, code: Vec) { - ensure_root(origin)?; - storage::unhashed::put_raw(well_known_keys::CODE, &code); - Self::deposit_event(Event::CodeUpdated); - } - - /// Set the new changes trie configuration. - #[weight = SimpleDispatchInfo::FixedOperational(20_000)] - pub fn set_changes_trie_config(origin, changes_trie_config: Option) { - ensure_root(origin)?; - match changes_trie_config.clone() { - Some(changes_trie_config) => storage::unhashed::put_raw( - well_known_keys::CHANGES_TRIE_CONFIG, - &changes_trie_config.encode(), - ), - None => storage::unhashed::kill(well_known_keys::CHANGES_TRIE_CONFIG), - } - - let log = generic::DigestItem::ChangesTrieSignal( - generic::ChangesTrieSignal::NewConfiguration(changes_trie_config), - ); - Self::deposit_log(log.into()); - } - - /// Set some items of storage. - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] - fn set_storage(origin, items: Vec) { - ensure_root(origin)?; - for i in &items { - storage::unhashed::put_raw(&i.0, &i.1); - } - } - - /// Kill some items from storage. - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] - fn kill_storage(origin, keys: Vec) { - ensure_root(origin)?; - for key in &keys { - storage::unhashed::kill(&key); - } - } - - /// Kill all storage items with a key that starts with the given prefix. - #[weight = SimpleDispatchInfo::FixedOperational(10_000)] - fn kill_prefix(origin, prefix: Key) { - ensure_root(origin)?; - storage::unhashed::kill_prefix(&prefix); - } - } -} - /// A phase of a block's execution. #[derive(Encode, Decode, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Serialize, PartialEq, Eq, Clone))] @@ -359,40 +250,6 @@ pub struct EventRecord { pub topics: Vec, } -decl_event!( - /// Event for the System module. - pub enum Event { - /// An extrinsic completed successfully. - ExtrinsicSuccess(DispatchInfo), - /// An extrinsic failed. - ExtrinsicFailed(DispatchError, DispatchInfo), - /// `:code` was updated. - CodeUpdated, - } -); - -decl_error! { - /// Error for the System module - pub enum Error for Module { - /// The name of specification does not match between the current runtime - /// and the new runtime. - InvalidSpecName, - /// The specification version is not allowed to decrease between the current runtime - /// and the new runtime. - SpecVersionNotAllowedToDecrease, - /// The implementation version is not allowed to decrease between the current runtime - /// and the new runtime. - ImplVersionNotAllowedToDecrease, - /// The specification or the implementation version need to increase between the - /// current runtime and the new runtime. - SpecOrImplVersionNeedToIncrease, - /// Failed to extract the runtime version from the new runtime. - /// - /// Either calling `Core_version` or decoding `RuntimeVersion` failed. - FailedToExtractRuntimeVersion, - } -} - /// Origin for the System module. #[derive(PartialEq, Eq, Clone, RuntimeDebug)] pub enum RawOrigin { @@ -435,29 +292,45 @@ type EventIndex = u32; decl_storage! { trait Store for Module as System { - /// Extrinsics nonce for accounts. - pub AccountNonce get(fn account_nonce): map hasher(blake2_256) T::AccountId => T::Index; + /// The full account information for a particular account ID. + // TODO: should be hasher(twox64_concat) - will need staged migration + // TODO: should not including T::Index (the nonce) + // https://github.com/paritytech/substrate/issues/4917 + pub Account get(fn account): map hasher(blake2_256) T::AccountId => (T::Index, T::AccountData); + /// Total extrinsics count for the current block. ExtrinsicCount: Option; + /// Total weight for all extrinsics put together, for the current block. AllExtrinsicsWeight: Option; + /// Total length (in bytes) for all extrinsics put together, for the current block. AllExtrinsicsLen: Option; + /// Map of block numbers to block hashes. + // TODO: should be hasher(twox64_concat) - will need one-off migration + // https://github.com/paritytech/substrate/issues/4917 pub BlockHash get(fn block_hash) build(|_| vec![(T::BlockNumber::zero(), hash69())]): map hasher(blake2_256) T::BlockNumber => T::Hash; + /// Extrinsics data for the current block (maps an extrinsic's index to its data). - ExtrinsicData get(fn extrinsic_data): map hasher(blake2_256) u32 => Vec; + ExtrinsicData get(fn extrinsic_data): map hasher(twox_64_concat) u32 => Vec; + /// The current block number being processed. Set by `execute_block`. Number get(fn block_number) build(|_| 1.into()): T::BlockNumber; + /// Hash of the previous block. ParentHash get(fn parent_hash) build(|_| hash69()): T::Hash; + /// Extrinsics root of the current block, also part of the block header. ExtrinsicsRoot get(fn extrinsics_root): T::Hash; + /// Digest of the current block, also part of the block header. Digest get(fn digest): DigestOf; + /// Events deposited for the current block. Events get(fn events): Vec>; + /// The number of events in the `Events` list. EventCount get(fn event_count): EventIndex; @@ -499,6 +372,150 @@ decl_storage! { } } +decl_event!( + /// Event for the System module. + pub enum Event where AccountId = ::AccountId { + /// An extrinsic completed successfully. + ExtrinsicSuccess(DispatchInfo), + /// An extrinsic failed. + ExtrinsicFailed(DispatchError, DispatchInfo), + /// `:code` was updated. + CodeUpdated, + /// A new account was created. + NewAccount(AccountId), + /// An account was reaped. + ReapedAccount(AccountId), + } +); + +decl_error! { + /// Error for the System module + pub enum Error for Module { + /// The name of specification does not match between the current runtime + /// and the new runtime. + InvalidSpecName, + /// The specification version is not allowed to decrease between the current runtime + /// and the new runtime. + SpecVersionNotAllowedToDecrease, + /// The implementation version is not allowed to decrease between the current runtime + /// and the new runtime. + ImplVersionNotAllowedToDecrease, + /// The specification or the implementation version need to increase between the + /// current runtime and the new runtime. + SpecOrImplVersionNeedToIncrease, + /// Failed to extract the runtime version from the new runtime. + /// + /// Either calling `Core_version` or decoding `RuntimeVersion` failed. + FailedToExtractRuntimeVersion, + } +} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + type Error = Error; + + /// A big dispatch that will disallow any other transaction to be included. + // TODO: This should only be available for testing, rather than in general usage, but + // that's not possible at present (since it's within the decl_module macro). + #[weight = SimpleDispatchInfo::MaxOperational] + fn fill_block(origin) { + ensure_root(origin)?; + } + + /// Make some on-chain remark. + #[weight = SimpleDispatchInfo::FixedNormal(10_000)] + fn remark(origin, _remark: Vec) { + ensure_signed(origin)?; + } + + /// Set the number of pages in the WebAssembly environment's heap. + #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + fn set_heap_pages(origin, pages: u64) { + ensure_root(origin)?; + storage::unhashed::put_raw(well_known_keys::HEAP_PAGES, &pages.encode()); + } + + /// Set the new runtime code. + #[weight = SimpleDispatchInfo::FixedOperational(200_000)] + pub fn set_code(origin, code: Vec) { + ensure_root(origin)?; + + let current_version = T::Version::get(); + let new_version = sp_io::misc::runtime_version(&code) + .and_then(|v| RuntimeVersion::decode(&mut &v[..]).ok()) + .ok_or_else(|| Error::::FailedToExtractRuntimeVersion)?; + + if new_version.spec_name != current_version.spec_name { + Err(Error::::InvalidSpecName)? + } + + if new_version.spec_version < current_version.spec_version { + Err(Error::::SpecVersionNotAllowedToDecrease)? + } else if new_version.spec_version == current_version.spec_version { + if new_version.impl_version < current_version.impl_version { + Err(Error::::ImplVersionNotAllowedToDecrease)? + } else if new_version.impl_version == current_version.impl_version { + Err(Error::::SpecOrImplVersionNeedToIncrease)? + } + } + + storage::unhashed::put_raw(well_known_keys::CODE, &code); + Self::deposit_event(RawEvent::CodeUpdated); + } + + /// Set the new runtime code without doing any checks of the given `code`. + #[weight = SimpleDispatchInfo::FixedOperational(200_000)] + pub fn set_code_without_checks(origin, code: Vec) { + ensure_root(origin)?; + storage::unhashed::put_raw(well_known_keys::CODE, &code); + Self::deposit_event(RawEvent::CodeUpdated); + } + + /// Set the new changes trie configuration. + #[weight = SimpleDispatchInfo::FixedOperational(20_000)] + pub fn set_changes_trie_config(origin, changes_trie_config: Option) { + ensure_root(origin)?; + match changes_trie_config.clone() { + Some(changes_trie_config) => storage::unhashed::put_raw( + well_known_keys::CHANGES_TRIE_CONFIG, + &changes_trie_config.encode(), + ), + None => storage::unhashed::kill(well_known_keys::CHANGES_TRIE_CONFIG), + } + + let log = generic::DigestItem::ChangesTrieSignal( + generic::ChangesTrieSignal::NewConfiguration(changes_trie_config), + ); + Self::deposit_log(log.into()); + } + + /// Set some items of storage. + #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + fn set_storage(origin, items: Vec) { + ensure_root(origin)?; + for i in &items { + storage::unhashed::put_raw(&i.0, &i.1); + } + } + + /// Kill some items from storage. + #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + fn kill_storage(origin, keys: Vec) { + ensure_root(origin)?; + for key in &keys { + storage::unhashed::kill(&key); + } + } + + /// Kill all storage items with a key that starts with the given prefix. + #[weight = SimpleDispatchInfo::FixedOperational(10_000)] + fn kill_prefix(origin, prefix: Key) { + ensure_root(origin)?; + storage::unhashed::kill_prefix(&prefix); + } + } +} + pub struct EnsureRoot(sp_std::marker::PhantomData); impl< O: Into, O>> + From>, @@ -622,7 +639,7 @@ impl Module { Self::deposit_event_indexed(&[], event.into()); } - /// Deposits an event into this block's event record adding this event + /// Deposits an event into this block's event record adding this event /// to the corresponding topic indexes. /// /// This will update storage entries that correspond to the specified topics. @@ -832,9 +849,14 @@ impl Module { /// Return the chain's current runtime version. pub fn runtime_version() -> RuntimeVersion { T::Version::get() } + /// Retrieve the account transaction counter from storage. + pub fn account_nonce(who: impl EncodeLike) -> T::Index { + Account::::get(who).0 + } + /// Increment a particular account's nonce by 1. - pub fn inc_account_nonce(who: &T::AccountId) { - >::insert(who, Self::account_nonce(who) + T::Index::one()); + pub fn inc_account_nonce(who: impl EncodeLike) { + Account::::mutate(who, |a| a.0 += T::Index::one()); } /// Note what the extrinsic data of the current extrinsic index is. If this @@ -851,10 +873,10 @@ impl Module { pub fn note_applied_extrinsic(r: &DispatchOutcome, _encoded_len: u32, info: DispatchInfo) { Self::deposit_event( match r { - Ok(()) => Event::ExtrinsicSuccess(info), + Ok(()) => RawEvent::ExtrinsicSuccess(info), Err(err) => { sp_runtime::print(err); - Event::ExtrinsicFailed(err.clone(), info) + RawEvent::ExtrinsicFailed(err.clone(), info) }, } ); @@ -879,12 +901,118 @@ impl Module { let xts_root = extrinsics_data_root::(extrinsics); >::put(xts_root); } + + /// An account is being created. + pub fn on_created_account(who: T::AccountId) { + T::OnNewAccount::on_new_account(&who); + Self::deposit_event(RawEvent::NewAccount(who)); + } + + /// Kill the account and reap any related information. + pub fn kill_account(who: T::AccountId) { + if Account::::contains_key(&who) { + Account::::remove(&who); + Self::on_killed_account(who); + } + } + + /// Do anything that needs to be done after an account has been killed. + fn on_killed_account(who: T::AccountId) { + T::OnReapAccount::on_reap_account(&who); + Self::deposit_event(RawEvent::ReapedAccount(who)); + } +} + +/// Event handler which calls on_created_account when it happens. +pub struct CallOnCreatedAccount(PhantomData); +impl Happened for CallOnCreatedAccount { + fn happened(who: &T::AccountId) { + Module::::on_created_account(who.clone()); + } +} + +/// Event handler which calls kill_account when it happens. +pub struct CallKillAccount(PhantomData); +impl Happened for CallKillAccount { + fn happened(who: &T::AccountId) { + Module::::kill_account(who.clone()); + } +} + +// Implement StoredMap for a simple single-item, kill-account-on-remove system. This works fine for +// storing a single item which is required to not be empty/default for the account to exist. +// Anything more complex will need more sophisticated logic. +impl StoredMap for Module { + fn get(k: &T::AccountId) -> T::AccountData { + Account::::get(k).1 + } + fn is_explicit(k: &T::AccountId) -> bool { + Account::::contains_key(k) + } + fn insert(k: &T::AccountId, t: T::AccountData) { + let existed = Account::::contains_key(k); + Account::::insert(k, (T::Index::default(), t)); + if !existed { + Self::on_created_account(k.clone()); + } + } + fn remove(k: &T::AccountId) { + if Account::::contains_key(&k) { + Self::kill_account(k.clone()); + } + } + fn mutate(k: &T::AccountId, f: impl FnOnce(&mut T::AccountData) -> R) -> R { + let existed = Account::::contains_key(k); + let r = Account::::mutate(k, |a| f(&mut a.1)); + if !existed { + Self::on_created_account(k.clone()); + } + r + } + fn mutate_exists(k: &T::AccountId, f: impl FnOnce(&mut Option) -> R) -> R { + let (existed, exists, r) = Account::::mutate_exists(k, |maybe_value| { + let existed = maybe_value.is_some(); + let (maybe_nonce, mut maybe_extra) = split_inner(maybe_value.take(), |v| v); + let r = f(&mut maybe_extra); + *maybe_value = maybe_extra.map(|extra| (maybe_nonce.unwrap_or_default(), extra)); + (existed, maybe_value.is_some(), r) + }); + if !existed && exists { + Self::on_created_account(k.clone()); + } else if existed && !exists { + Self::on_killed_account(k.clone()); + } + r + } + fn try_mutate_exists(k: &T::AccountId, f: impl FnOnce(&mut Option) -> Result) -> Result { + Account::::try_mutate_exists(k, |maybe_value| { + let existed = maybe_value.is_some(); + let (maybe_nonce, mut maybe_extra) = split_inner(maybe_value.take(), |v| v); + f(&mut maybe_extra).map(|v| { + *maybe_value = maybe_extra.map(|extra| (maybe_nonce.unwrap_or_default(), extra)); + (existed, maybe_value.is_some(), v) + }) + }).map(|(existed, exists, v)| { + if !existed && exists { + Self::on_created_account(k.clone()); + } else if existed && !exists { + Self::on_killed_account(k.clone()); + } + v + }) + } } -impl OnReapAccount for Module { - /// Remove the nonce for the account. Account is considered fully removed from the system. - fn on_reap_account(who: &T::AccountId) { - >::remove(who); +/// Split an `option` into two constituent options, as defined by a `splitter` function. +pub fn split_inner(option: Option, splitter: impl FnOnce(T) -> (R, S)) + -> (Option, Option) +{ + match option { + Some(inner) => { + let (r, s) = splitter(inner); + (Some(r), Some(s)) + } + None => (None, None), } } @@ -1052,7 +1180,7 @@ impl SignedExtension for CheckNonce { _info: Self::DispatchInfo, _len: usize, ) -> Result<(), TransactionValidityError> { - let expected = >::get(who); + let (expected, extra) = Account::::get(who); if self.0 != expected { return Err( if self.0 < expected { @@ -1062,8 +1190,7 @@ impl SignedExtension for CheckNonce { }.into() ) } - - >::insert(who, expected + T::Index::one()); + Account::::insert(who, (expected + T::Index::one(), extra)); Ok(()) } @@ -1075,7 +1202,7 @@ impl SignedExtension for CheckNonce { _len: usize, ) -> TransactionValidity { // check index - let expected = >::get(who); + let (expected, _extra) = Account::::get(who); if self.0 < expected { return InvalidTransaction::Stale.into() } @@ -1097,6 +1224,12 @@ impl SignedExtension for CheckNonce { } } +impl IsDeadAccount for Module { + fn is_dead_account(who: &T::AccountId) -> bool { + !Account::::contains_key(who) + } +} + /// Check for transaction mortality. #[derive(Encode, Decode, Clone, Eq, PartialEq)] pub struct CheckEra((Era, sp_std::marker::PhantomData)); @@ -1288,14 +1421,18 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type Version = Version; type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } - impl From for u16 { - fn from(e: Event) -> u16 { + impl From> for u16 { + fn from(e: Event) -> u16 { match e { - Event::ExtrinsicSuccess(..) => 100, - Event::ExtrinsicFailed(..) => 101, - Event::CodeUpdated => 102, + Event::::ExtrinsicSuccess(..) => 100, + Event::::ExtrinsicFailed(..) => 101, + Event::::CodeUpdated => 102, + _ => 103, } } } @@ -1475,7 +1612,7 @@ mod tests { #[test] fn signed_ext_check_nonce_works() { new_test_ext().execute_with(|| { - >::insert(1, 1); + Account::::insert(1, (1, ())); let info = DispatchInfo::default(); let len = 0_usize; // stale diff --git a/frame/system/src/offchain.rs b/frame/system/src/offchain.rs index f5fda34585..b26f4be4b4 100644 --- a/frame/system/src/offchain.rs +++ b/frame/system/src/offchain.rs @@ -20,8 +20,8 @@ use codec::Encode; use sp_std::convert::TryInto; use sp_std::prelude::Vec; use sp_runtime::app_crypto::{RuntimeAppPublic, AppPublic, AppSignature}; -use sp_runtime::traits::{Extrinsic as ExtrinsicT, IdentifyAccount}; -use frame_support::debug; +use sp_runtime::traits::{Extrinsic as ExtrinsicT, IdentifyAccount, One}; +use frame_support::{debug, storage::StorageMap}; /// Creates runtime-specific signed transaction. /// @@ -128,19 +128,19 @@ pub trait SignAndSubmitTransaction { fn sign_and_submit(call: impl Into, public: PublicOf) -> Result<(), ()> { let call = call.into(); let id = public.clone().into_account(); - let expected = >::account_nonce(&id); + let (expected_nonce, extra) = super::Account::::get(&id); debug::native::debug!( target: "offchain", "Creating signed transaction from account: {:?} (nonce: {:?})", id, - expected, + expected_nonce, ); let (call, signature_data) = Self::CreateTransaction - ::create_transaction::(call, public, id.clone(), expected) + ::create_transaction::(call, public, id.clone(), expected_nonce) .ok_or(())?; // increment the nonce. This is fine, since the code should always // be running in off-chain context, so we NEVER persists data. - >::inc_account_nonce(&id); + super::Account::::insert(&id, (expected_nonce + One::one(), extra)); let xt = Self::Extrinsic::new(call, Some(signature_data)).ok_or(())?; sp_io::offchain::submit_transaction(xt.encode()) diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index 6a4cdf92fa..95e1fc3a5e 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -276,6 +276,9 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type Version = (); type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } parameter_types! { pub const MinimumPeriod: u64 = 5; diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 2b9637651d..0d9cfc0b77 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -302,25 +302,23 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnReapAccount = Balances; } parameter_types! { - pub const CreationFee: u64 = 0; pub const ExistentialDeposit: u64 = 1; } impl pallet_balances::Trait for Runtime { type Balance = u64; - type OnReapAccount = System; - type OnNewAccount = (); type Event = (); - type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; + type AccountStore = System; } - - thread_local! { +thread_local! { static TRANSACTION_BASE_FEE: RefCell = RefCell::new(0); static TRANSACTION_BYTE_FEE: RefCell = RefCell::new(1); static WEIGHT_TO_FEE: RefCell = RefCell::new(1); diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index 44ce575f17..36f92c401e 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -758,20 +758,19 @@ mod tests { type MaximumBlockLength = MaximumBlockLength; type Version = (); type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnReapAccount = Balances; } parameter_types! { pub const ExistentialDeposit: u64 = 1; - pub const CreationFee: u64 = 0; - } +} impl pallet_balances::Trait for Test { type Balance = u64; - type OnNewAccount = (); - type OnReapAccount = System; type Event = (); - type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; + type AccountStore = System; } pub struct TenToFourteen; impl Contains for TenToFourteen { diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index 72f35745a4..414651659c 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -661,6 +661,7 @@ mod tests { impl_outer_event! { pub enum TestEvent for Test { + system, pallet_balances, utility, } @@ -700,20 +701,19 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnReapAccount = Balances; } parameter_types! { pub const ExistentialDeposit: u64 = 1; - pub const CreationFee: u64 = 0; } impl pallet_balances::Trait for Test { type Balance = u64; - type OnReapAccount = System; - type OnNewAccount = (); type Event = TestEvent; - type TransferPayment = (); type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; + type AccountStore = System; } parameter_types! { pub const MultisigDepositBase: u64 = 1; diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index e39e2ae3a5..3777475f3f 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -50,7 +50,7 @@ use sp_std::prelude::*; use sp_std::fmt::Debug; use codec::{Encode, Decode}; use sp_runtime::{DispatchResult, RuntimeDebug, traits::{ - StaticLookup, Zero, AtLeast32Bit, MaybeSerializeDeserialize, Saturating, Convert + StaticLookup, Zero, AtLeast32Bit, MaybeSerializeDeserialize, Convert }}; use frame_support::{decl_module, decl_event, decl_storage, decl_error}; use frame_support::traits::{ @@ -115,6 +115,7 @@ decl_storage! { add_extra_genesis { config(vesting): Vec<(T::AccountId, T::BlockNumber, T::BlockNumber, BalanceOf)>; build(|config: &GenesisConfig| { + use sp_runtime::traits::Saturating; // Generate initial vesting configuration // * who - Account which we are generating vesting configuration for // * begin - Block when the account will start to vest @@ -336,19 +337,16 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); - } - parameter_types! { - pub const CreationFee: u64 = 0; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnReapAccount = Balances; } impl pallet_balances::Trait for Test { type Balance = u64; - type OnReapAccount = System; - type OnNewAccount = (); - type Event = (); - type TransferPayment = (); type DustRemoval = (); + type Event = (); type ExistentialDeposit = ExistentialDeposit; - type CreationFee = CreationFee; + type AccountStore = System; } impl Trait for Test { type Event = (); diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index dac232b25c..c8dff15ef2 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -340,8 +340,8 @@ impl_outer_origin!{ #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug)] pub struct Event; -impl From for Event { - fn from(_evt: frame_system::Event) -> Self { +impl From> for Event { + fn from(_evt: frame_system::Event) -> Self { unimplemented!("Not required in tests!") } } @@ -371,6 +371,9 @@ impl frame_system::Trait for Runtime { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnReapAccount = (); } impl pallet_timestamp::Trait for Runtime { -- GitLab From a6e7c051242433a02b7d524a349f3dba084fa549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Thei=C3=9Fen?= Date: Fri, 14 Feb 2020 11:46:45 +0100 Subject: [PATCH 152/180] Allow to distinguish out of gas from other traps (#4883) * contracts: Allow to distinguish out of gas from other traps When a contract encounters a runtime error a wasm trap is triggered and the execution is halted. Currently, no matter what was the cause for the trap it is always reported as: DispatchError::Other("contract trapped during execution"). However, the trap that is triggered if a contract exhausts its gas budget is particulary interesting. Therefore we add a seperate error message for this cause: DispatchError::Other("ran out of gas during contract execution"). A test is added hat executes a contract that never terminates. Therefore it always exhausts is gas budget. * fixup! contracts: Allow to distinguish out of gas from other traps Remove overlong lines. * fixup! contracts: Allow to distinguish out of gas from other traps Rename Contract to Contracts --- bin/node/runtime/src/lib.rs | 2 +- frame/contracts/src/tests.rs | 45 +++++++++++++++++ frame/contracts/src/wasm/runtime.rs | 78 +++++++++++++++++++++++++---- 3 files changed, 113 insertions(+), 12 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index cdcf670c64..0281454215 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -82,7 +82,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 218, + spec_version: 219, impl_version: 0, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 8cb854ac97..0062e2bbd4 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -722,6 +722,51 @@ fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { }); } +const CODE_RUN_OUT_OF_GAS: &str = r#" +(module + (func (export "call") + (loop $inf (br $inf)) ;; just run out of gas + (unreachable) + ) + (func (export "deploy")) +) +"#; + +#[test] +fn run_out_of_gas() { + let (wasm, code_hash) = compile_module::(CODE_RUN_OUT_OF_GAS).unwrap(); + + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + Balances::deposit_creating(&ALICE, 1_000_000); + + assert_ok!(Contracts::put_code(Origin::signed(ALICE), 100_000, wasm)); + + assert_ok!(Contracts::instantiate( + Origin::signed(ALICE), + 100, + 100_000, + code_hash.into(), + vec![], + )); + + // Call the contract with a fixed gas limit. It must run out of gas because it just + // loops forever. + assert_err!( + Contracts::call( + Origin::signed(ALICE), + BOB, // newly created account + 0, + 1000, + vec![], + ), + "ran out of gas during contract execution" + ); + }); +} + const CODE_SET_RENT: &str = r#" (module (import "env" "ext_dispatch_call" (func $ext_dispatch_call (param i32 i32))) diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index 66ae8a4996..b6a8928180 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -39,6 +39,8 @@ const TRAP_RETURN_CODE: u32 = 0x0100; enum SpecialTrap { /// Signals that trap was generated in response to call `ext_return` host function. Return(Vec), + /// Signals that trap was generated because the contract exhausted its gas limit. + OutOfGas, } /// Can only be used for one call. @@ -74,9 +76,21 @@ pub(crate) fn to_execution_result( runtime: Runtime, 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 { - return Ok(ExecReturnValue { status: STATUS_SUCCESS, data }); + match runtime.special_trap { + // The trap was the result of the execution `return` host function. + Some(SpecialTrap::Return(data)) => { + return Ok(ExecReturnValue { + status: STATUS_SUCCESS, + data, + }) + } + Some(SpecialTrap::OutOfGas) => { + return Err(ExecError { + reason: "ran out of gas during contract execution".into(), + buffer: runtime.scratch_buf, + }) + } + _ => (), } // Check the exact type of the error. @@ -179,11 +193,15 @@ impl Token for RuntimeToken { fn charge_gas>( gas_meter: &mut GasMeter, metadata: &Tok::Metadata, + special_trap: &mut Option, token: Tok, ) -> Result<(), sp_sandbox::HostError> { match gas_meter.charge(metadata, token) { GasMeterResult::Proceed => Ok(()), - GasMeterResult::OutOfGas => Err(sp_sandbox::HostError), + GasMeterResult::OutOfGas => { + *special_trap = Some(SpecialTrap::OutOfGas); + Err(sp_sandbox::HostError) + }, } } @@ -200,7 +218,12 @@ fn read_sandbox_memory( ptr: u32, len: u32, ) -> Result, sp_sandbox::HostError> { - charge_gas(ctx.gas_meter, ctx.schedule, RuntimeToken::ReadMemory(len))?; + charge_gas( + ctx.gas_meter, + ctx.schedule, + &mut ctx.special_trap, + RuntimeToken::ReadMemory(len), + )?; let mut buf = vec![0u8; len as usize]; ctx.memory.get(ptr, buf.as_mut_slice()).map_err(|_| sp_sandbox::HostError)?; @@ -220,7 +243,12 @@ fn read_sandbox_memory_into_scratch( ptr: u32, len: u32, ) -> Result<(), sp_sandbox::HostError> { - charge_gas(ctx.gas_meter, ctx.schedule, RuntimeToken::ReadMemory(len))?; + charge_gas( + ctx.gas_meter, + ctx.schedule, + &mut ctx.special_trap, + RuntimeToken::ReadMemory(len), + )?; ctx.scratch_buf.resize(len as usize, 0); ctx.memory.get(ptr, ctx.scratch_buf.as_mut_slice()).map_err(|_| sp_sandbox::HostError)?; @@ -240,7 +268,12 @@ fn read_sandbox_memory_into_buf( ptr: u32, buf: &mut [u8], ) -> Result<(), sp_sandbox::HostError> { - charge_gas(ctx.gas_meter, ctx.schedule, RuntimeToken::ReadMemory(buf.len() as u32))?; + charge_gas( + ctx.gas_meter, + ctx.schedule, + &mut ctx.special_trap, + RuntimeToken::ReadMemory(buf.len() as u32), + )?; ctx.memory.get(ptr, buf).map_err(Into::into) } @@ -273,12 +306,18 @@ fn read_sandbox_memory_as( /// - designated area is not within the bounds of the sandbox memory. fn write_sandbox_memory( schedule: &Schedule, + special_trap: &mut Option, gas_meter: &mut GasMeter, memory: &sp_sandbox::Memory, ptr: u32, buf: &[u8], ) -> Result<(), sp_sandbox::HostError> { - charge_gas(gas_meter, schedule, RuntimeToken::WriteMemory(buf.len() as u32))?; + charge_gas( + gas_meter, + schedule, + special_trap, + RuntimeToken::WriteMemory(buf.len() as u32), + )?; memory.set(ptr, buf)?; @@ -300,7 +339,12 @@ define_env!(Env, , // // - amount: How much gas is used. gas(ctx, amount: u32) => { - charge_gas(&mut ctx.gas_meter, ctx.schedule, RuntimeToken::Explicit(amount))?; + charge_gas( + &mut ctx.gas_meter, + ctx.schedule, + &mut ctx.special_trap, + RuntimeToken::Explicit(amount) + )?; Ok(()) }, @@ -520,7 +564,12 @@ define_env!(Env, , // // This is the only way to return a data buffer to the caller. ext_return(ctx, data_ptr: u32, data_len: u32) => { - charge_gas(ctx.gas_meter, ctx.schedule, RuntimeToken::ReturnData(data_len))?; + charge_gas( + ctx.gas_meter, + ctx.schedule, + &mut ctx.special_trap, + RuntimeToken::ReturnData(data_len) + )?; read_sandbox_memory_into_scratch(ctx, data_ptr, data_len)?; let output_buf = mem::replace(&mut ctx.scratch_buf, Vec::new()); @@ -652,7 +701,12 @@ define_env!(Env, , let balance_fee = <::T as Trait>::ComputeDispatchFee::compute_dispatch_fee(&call); approx_gas_for_balance(ctx.gas_meter.gas_price(), balance_fee) }; - charge_gas(&mut ctx.gas_meter, ctx.schedule, RuntimeToken::ComputedDispatchFee(fee))?; + charge_gas( + &mut ctx.gas_meter, + ctx.schedule, + &mut ctx.special_trap, + RuntimeToken::ComputedDispatchFee(fee) + )?; ctx.ext.note_dispatch_call(call); @@ -756,6 +810,7 @@ define_env!(Env, , // Finally, perform the write. write_sandbox_memory( ctx.schedule, + &mut ctx.special_trap, ctx.gas_meter, &ctx.memory, dest_ptr, @@ -803,6 +858,7 @@ define_env!(Env, , charge_gas( ctx.gas_meter, ctx.schedule, + &mut ctx.special_trap, RuntimeToken::DepositEvent(topics.len() as u32, data_len) )?; ctx.ext.deposit_event(topics, event_data); -- GitLab From 16bb1926435d2a6c76b23ef2c5507c68b73748ba Mon Sep 17 00:00:00 2001 From: Seun Lanlege Date: Fri, 14 Feb 2020 14:44:58 +0100 Subject: [PATCH 153/180] Adds fork-awareness and finalization notifications to transaction pool watchers. (#4740) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * adds finalization support to sc-transaction-pool using MaintainedTransactionPool for finalization events * adds TransactionStatus::Retracted, notify watchers of retracted blocks, finalized now finalizes, transactions for current finalized -> last finalized block * adds last_finalized to ChainApi, use generic BlockT for ChainEvent * fix tests * Apply suggestions from code review Co-Authored-By: Tomasz Drwięga * tests * fix tests, docs, lazily dedupe pruned hashes * fix tests, Cargo.lock * Apply suggestions from code review Co-Authored-By: Tomasz Drwięga * remove tree_route, last_finalized from ChainApi, add block hash to Finalization and Retracted events * prune finality watchers * fix tests * remove HeaderBackend bound from FullChainApi * code style nits, terminate stream in finality_timeout Co-authored-by: Tomasz Drwięga --- Cargo.lock | 4 + client/consensus/manual-seal/src/lib.rs | 4 +- .../manual-seal/src/seal_new_block.rs | 2 +- client/rpc-api/Cargo.toml | 1 + client/service/src/builder.rs | 68 +++-- client/transaction-pool/graph/Cargo.toml | 2 + .../transaction-pool/graph/benches/basics.rs | 8 +- client/transaction-pool/graph/src/listener.rs | 58 +++- client/transaction-pool/graph/src/pool.rs | 113 +++----- .../graph/src/validated_pool.rs | 62 ++-- client/transaction-pool/graph/src/watcher.rs | 52 ++-- client/transaction-pool/src/api.rs | 3 +- client/transaction-pool/src/lib.rs | 188 ++++++------ client/transaction-pool/src/testing/pool.rs | 273 ++++++++++++++++-- primitives/blockchain/src/header_metadata.rs | 2 +- primitives/transaction-pool/src/pool.rs | 34 ++- .../runtime/transaction-pool/Cargo.toml | 1 + .../runtime/transaction-pool/src/lib.rs | 53 +++- 18 files changed, 642 insertions(+), 286 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7a44b0ed77..733f15b9cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6263,6 +6263,7 @@ dependencies = [ "serde_json", "sp-core", "sp-rpc", + "sp-runtime", "sp-transaction-pool", "sp-version", ] @@ -6424,11 +6425,13 @@ dependencies = [ "criterion 0.3.1", "derive_more", "futures 0.3.4", + "linked-hash-map", "log 0.4.8", "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.0", "serde", + "sp-blockchain", "sp-core", "sp-runtime", "sp-transaction-pool", @@ -7644,6 +7647,7 @@ dependencies = [ "parity-scale-codec", "parking_lot 0.10.0", "sc-transaction-graph", + "sp-blockchain", "sp-runtime", "sp-transaction-pool", "substrate-test-runtime-client", diff --git a/client/consensus/manual-seal/src/lib.rs b/client/consensus/manual-seal/src/lib.rs index 029f746e62..c820407e74 100644 --- a/client/consensus/manual-seal/src/lib.rs +++ b/client/consensus/manual-seal/src/lib.rs @@ -198,7 +198,7 @@ pub async fn run_instant_seal( { // instant-seal creates blocks as soon as transactions are imported // into the transaction pool. - let seal_block_channel = pool.import_notification_stream() + let seal_block_channel = pool.validated_pool().import_notification_stream() .map(|_| { EngineCommand::SealNewBlock { create_empty: false, @@ -260,7 +260,7 @@ mod tests { // this test checks that blocks are created as soon as transactions are imported into the pool. let (sender, receiver) = futures::channel::oneshot::channel(); let mut sender = Arc::new(Some(sender)); - let stream = pool.pool().import_notification_stream() + let stream = pool.pool().validated_pool().import_notification_stream() .map(move |_| { // we're only going to submit one tx so this fn will only be called once. let mut_sender = Arc::get_mut(&mut sender).unwrap(); diff --git a/client/consensus/manual-seal/src/seal_new_block.rs b/client/consensus/manual-seal/src/seal_new_block.rs index 53dc82d353..2b8d867ce3 100644 --- a/client/consensus/manual-seal/src/seal_new_block.rs +++ b/client/consensus/manual-seal/src/seal_new_block.rs @@ -92,7 +92,7 @@ pub async fn seal_new_block( SC: SelectChain, { let future = async { - if pool.status().ready == 0 && !create_empty { + if pool.validated_pool().status().ready == 0 && !create_empty { return Err(Error::EmptyTransactionPool) } diff --git a/client/rpc-api/Cargo.toml b/client/rpc-api/Cargo.toml index 4781c9d350..b9f4cbb015 100644 --- a/client/rpc-api/Cargo.toml +++ b/client/rpc-api/Cargo.toml @@ -17,6 +17,7 @@ log = "0.4.8" parking_lot = "0.10.0" sp-core = { version = "2.0.0", path = "../../primitives/core" } sp-version = { version = "2.0.0", path = "../../primitives/version" } +sp-runtime = { path = "../../primitives/runtime" } serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" sp-transaction-pool = { version = "2.0.0", path = "../../primitives/transaction-pool" } diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index e29c503402..5ca39856dc 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -51,7 +51,7 @@ use std::{ use wasm_timer::SystemTime; use sysinfo::{get_current_pid, ProcessExt, System, SystemExt}; use sc_telemetry::{telemetry, SUBSTRATE_INFO}; -use sp_transaction_pool::MaintainedTransactionPool; +use sp_transaction_pool::{MaintainedTransactionPool, ChainEvent}; use sp_blockchain; use grafana_data_source::{self, record_metrics}; @@ -882,42 +882,52 @@ ServiceBuilder< let network_state_info: Arc = network.clone(); let is_validator = config.roles.is_authority(); - let events = client.import_notification_stream() - .for_each(move |notification| { - let txpool = txpool.upgrade(); + let (import_stream, finality_stream) = ( + client.import_notification_stream().map(|n| ChainEvent::NewBlock { + id: BlockId::Hash(n.hash), + header: n.header, + retracted: n.retracted, + is_new_best: n.is_new_best, + }), + client.finality_notification_stream().map(|n| ChainEvent::Finalized { + hash: n.hash + }) + ); + let events = futures::stream::select(import_stream, finality_stream) + .for_each(move |event| { + // offchain worker is only interested in block import events + if let ChainEvent::NewBlock { ref header, is_new_best, .. } = event { + let offchain = offchain.as_ref().and_then(|o| o.upgrade()); + match offchain { + Some(offchain) if is_new_best => { + let future = offchain.on_block_imported( + &header, + network_state_info.clone(), + is_validator, + ); + let _ = to_spawn_tx_.unbounded_send(( + Box::pin(future), + From::from("offchain-on-block"), + )); + }, + Some(_) => log::debug!( + target: "sc_offchain", + "Skipping offchain workers for non-canon block: {:?}", + header, + ), + _ => {}, + } + }; + let txpool = txpool.upgrade(); if let Some(txpool) = txpool.as_ref() { - let future = txpool.maintain( - &BlockId::hash(notification.hash), - ¬ification.retracted, - ); + let future = txpool.maintain(event); let _ = to_spawn_tx_.unbounded_send(( Box::pin(future), From::from("txpool-maintain") )); } - let offchain = offchain.as_ref().and_then(|o| o.upgrade()); - match offchain { - Some(offchain) if notification.is_new_best => { - let future = offchain.on_block_imported( - ¬ification.header, - network_state_info.clone(), - is_validator, - ); - let _ = to_spawn_tx_.unbounded_send(( - Box::pin(future), - From::from("offchain-on-block"), - )); - }, - Some(_) => log::debug!( - target: "sc_offchain", - "Skipping offchain workers for non-canon block: {:?}", - notification.header, - ), - _ => {}, - } - ready(()) }); let _ = to_spawn_tx.unbounded_send(( diff --git a/client/transaction-pool/graph/Cargo.toml b/client/transaction-pool/graph/Cargo.toml index 3bbe46bc50..daec970a69 100644 --- a/client/transaction-pool/graph/Cargo.toml +++ b/client/transaction-pool/graph/Cargo.toml @@ -12,10 +12,12 @@ log = "0.4.8" parking_lot = "0.10.0" serde = { version = "1.0.101", features = ["derive"] } wasm-timer = "0.2" +sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" } 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" } parity-util-mem = { version = "0.5.1", default-features = false, features = ["primitive-types"] } +linked-hash-map = "0.5.2" [dev-dependencies] assert_matches = "1.3.0" diff --git a/client/transaction-pool/graph/benches/basics.rs b/client/transaction-pool/graph/benches/basics.rs index f3f67f1446..54bbe930b3 100644 --- a/client/transaction-pool/graph/benches/basics.rs +++ b/client/transaction-pool/graph/benches/basics.rs @@ -135,8 +135,8 @@ fn bench_configured(pool: Pool, number: u64) { let res = block_on(futures::future::join_all(futures.into_iter())); assert!(res.iter().all(Result::is_ok)); - assert_eq!(pool.status().future, 0); - assert_eq!(pool.status().ready, number as usize); + assert_eq!(pool.validated_pool().status().future, 0); + assert_eq!(pool.validated_pool().status().ready, number as usize); // Prune all transactions. let block_num = 6; @@ -147,8 +147,8 @@ fn bench_configured(pool: Pool, number: u64) { )).expect("Prune failed"); // pool is empty - assert_eq!(pool.status().ready, 0); - assert_eq!(pool.status().future, 0); + assert_eq!(pool.validated_pool().status().ready, 0); + assert_eq!(pool.validated_pool().status().future, 0); } fn benchmark_main(c: &mut Criterion) { diff --git a/client/transaction-pool/graph/src/listener.rs b/client/transaction-pool/graph/src/listener.rs index dab2a6f5aa..be6fb5c990 100644 --- a/client/transaction-pool/graph/src/listener.rs +++ b/client/transaction-pool/graph/src/listener.rs @@ -16,30 +16,34 @@ // along with Substrate. If not, see . use std::{ - collections::HashMap, - fmt, - hash, + collections::HashMap, hash, }; +use linked_hash_map::LinkedHashMap; use serde::Serialize; -use crate::watcher; -use sp_runtime::traits; +use crate::{watcher, ChainApi, BlockHash}; use log::{debug, trace, warn}; +use sp_runtime::traits; /// Extrinsic pool default listener. -pub struct Listener { - watchers: HashMap> +pub struct Listener { + watchers: HashMap>>, + finality_watchers: LinkedHashMap, Vec>, } -impl Default for Listener { +/// Maximum number of blocks awaiting finality at any time. +const MAX_FINALITY_WATCHERS: usize = 512; + +impl Default for Listener { fn default() -> Self { Listener { watchers: Default::default(), + finality_watchers: Default::default(), } } } -impl Listener { - fn fire(&mut self, hash: &H, fun: F) where F: FnOnce(&mut watcher::Sender) { +impl Listener { + fn fire(&mut self, hash: &H, fun: F) where F: FnOnce(&mut watcher::Sender>) { let clean = if let Some(h) = self.watchers.get_mut(hash) { fun(h); h.is_done() @@ -55,7 +59,7 @@ impl Listene /// Creates a new watcher for given verified extrinsic. /// /// The watcher can be used to subscribe to lifecycle events of that extrinsic. - pub fn create_watcher(&mut self, hash: H) -> watcher::Watcher { + pub fn create_watcher(&mut self, hash: H) -> watcher::Watcher> { let sender = self.watchers.entry(hash.clone()).or_insert_with(watcher::Sender::default); sender.new_watcher(hash) } @@ -101,8 +105,34 @@ impl Listene } /// 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.in_block(header_hash)) + pub fn pruned(&mut self, block_hash: BlockHash, tx: &H) { + debug!(target: "txpool", "[{:?}] Pruned at {:?}", tx, block_hash); + self.fire(tx, |s| s.in_block(block_hash)); + self.finality_watchers.entry(block_hash).or_insert(vec![]).push(tx.clone()); + + while self.finality_watchers.len() > MAX_FINALITY_WATCHERS { + if let Some((hash, txs)) = self.finality_watchers.pop_front() { + for tx in txs { + self.fire(&tx, |s| s.finality_timeout(hash.clone())); + } + } + } + } + + /// The block this transaction was included in has been retracted. + pub fn retracted(&mut self, block_hash: BlockHash) { + if let Some(hashes) = self.finality_watchers.remove(&block_hash) { + for hash in hashes { + self.fire(&hash, |s| s.retracted(block_hash)) + } + } + } + + /// Notify all watchers that transactions have been finalized + pub fn finalized(&mut self, block_hash: BlockHash, txs: Vec) { + self.finality_watchers.remove(&block_hash); + for h in txs { + self.fire(&h, |s| s.finalized(block_hash.clone())) + } } } diff --git a/client/transaction-pool/graph/src/pool.rs b/client/transaction-pool/graph/src/pool.rs index edcd211df9..392abdca48 100644 --- a/client/transaction-pool/graph/src/pool.rs +++ b/client/transaction-pool/graph/src/pool.rs @@ -33,7 +33,7 @@ use sp_runtime::{ traits::{self, SaturatedConversion}, transaction_validity::{TransactionValidity, TransactionTag as Tag, TransactionValidityError}, }; -use sp_transaction_pool::{error, PoolStatus}; +use sp_transaction_pool::error; use wasm_timer::Instant; use crate::validated_pool::{ValidatedPool, ValidatedTransaction}; @@ -338,34 +338,6 @@ impl Pool { ) } - /// 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> { - self.validated_pool.import_notification_stream() - } - - /// Invoked when extrinsics are broadcasted. - pub fn on_broadcasted(&self, propagated: HashMap, Vec>) { - self.validated_pool.on_broadcasted(propagated) - } - - /// Remove invalid transactions from the pool. - pub fn remove_invalid(&self, hashes: &[ExHash]) -> Vec> { - self.validated_pool.remove_invalid(hashes) - } - - /// Get an iterator for ready transactions ordered by priority - pub fn ready(&self) -> impl Iterator> { - self.validated_pool.ready() - } - - /// Returns pool status. - pub fn status(&self) -> PoolStatus { - self.validated_pool.status() - } - /// Returns transaction hash pub fn hash_of(&self, xt: &ExtrinsicFor) -> ExHash { self.validated_pool.api().hash_and_length(xt).0 @@ -454,9 +426,9 @@ impl Pool { (hash, validity) } - /// Get ready transaction by hash, if it present in the pool. - pub fn ready_transaction(&self, hash: &ExHash) -> Option> { - self.validated_pool.ready_by_hash(hash) + /// get a reference to the underlying validated pool. + pub fn validated_pool(&self) -> &ValidatedPool { + &self.validated_pool } } @@ -598,7 +570,7 @@ mod tests { }))).unwrap(); // then - assert_eq!(pool.ready().map(|v| v.hash).collect::>(), vec![hash]); + assert_eq!(pool.validated_pool().ready().map(|v| v.hash).collect::>(), vec![hash]); } #[test] @@ -615,8 +587,8 @@ mod tests { // when pool.validated_pool.rotator().ban(&Instant::now(), vec![pool.hash_of(&uxt)]); let res = block_on(pool.submit_one(&BlockId::Number(0), uxt)); - assert_eq!(pool.status().ready, 0); - assert_eq!(pool.status().future, 0); + assert_eq!(pool.validated_pool().status().ready, 0); + assert_eq!(pool.validated_pool().status().future, 0); // then assert_matches!(res.unwrap_err(), error::Error::TemporarilyBanned); @@ -627,7 +599,7 @@ mod tests { let stream = { // given let pool = pool(); - let stream = pool.import_notification_stream(); + let stream = pool.validated_pool().import_notification_stream(); // when let _hash = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { @@ -650,8 +622,8 @@ mod tests { nonce: 3, }))).unwrap(); - assert_eq!(pool.status().ready, 2); - assert_eq!(pool.status().future, 1); + assert_eq!(pool.validated_pool().status().ready, 2); + assert_eq!(pool.validated_pool().status().future, 1); stream }; @@ -689,9 +661,9 @@ mod tests { pool.validated_pool.clear_stale(&BlockId::Number(5)).unwrap(); // then - assert_eq!(pool.ready().count(), 0); - assert_eq!(pool.status().future, 0); - assert_eq!(pool.status().ready, 0); + assert_eq!(pool.validated_pool().ready().count(), 0); + assert_eq!(pool.validated_pool().status().future, 0); + assert_eq!(pool.validated_pool().status().ready, 0); // make sure they are temporarily banned as well assert!(pool.validated_pool.rotator().is_banned(&hash1)); assert!(pool.validated_pool.rotator().is_banned(&hash2)); @@ -735,7 +707,7 @@ mod tests { amount: 5, nonce: 1, }))).unwrap(); - assert_eq!(pool.status().future, 1); + assert_eq!(pool.validated_pool().status().future, 1); // when let hash2 = block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { @@ -746,7 +718,7 @@ mod tests { }))).unwrap(); // then - assert_eq!(pool.status().future, 1); + assert_eq!(pool.validated_pool().status().future, 1); assert!(pool.validated_pool.rotator().is_banned(&hash1)); assert!(!pool.validated_pool.rotator().is_banned(&hash2)); } @@ -773,8 +745,8 @@ mod tests { }))).unwrap_err(); // then - assert_eq!(pool.status().ready, 0); - assert_eq!(pool.status().future, 0); + assert_eq!(pool.validated_pool().status().ready, 0); + assert_eq!(pool.validated_pool().status().future, 0); } #[test] @@ -791,8 +763,8 @@ mod tests { }))).unwrap_err(); // then - assert_eq!(pool.status().ready, 0); - assert_eq!(pool.status().future, 0); + assert_eq!(pool.validated_pool().status().ready, 0); + assert_eq!(pool.validated_pool().status().future, 0); assert_matches!(err, error::Error::NoTagsProvided); } @@ -809,19 +781,18 @@ mod tests { amount: 5, nonce: 0, }))).unwrap(); - assert_eq!(pool.status().ready, 1); - assert_eq!(pool.status().future, 0); + assert_eq!(pool.validated_pool().status().ready, 1); + assert_eq!(pool.validated_pool().status().future, 0); // when block_on(pool.prune_tags(&BlockId::Number(2), vec![vec![0u8]], vec![])).unwrap(); - assert_eq!(pool.status().ready, 0); - assert_eq!(pool.status().future, 0); + assert_eq!(pool.validated_pool().status().ready, 0); + assert_eq!(pool.validated_pool().status().future, 0); // then let mut stream = futures::executor::block_on_stream(watcher.into_stream()); 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); } #[test] @@ -834,19 +805,18 @@ mod tests { amount: 5, nonce: 0, }))).unwrap(); - assert_eq!(pool.status().ready, 1); - assert_eq!(pool.status().future, 0); + assert_eq!(pool.validated_pool().status().ready, 1); + assert_eq!(pool.validated_pool().status().future, 0); // when block_on(pool.prune_tags(&BlockId::Number(2), vec![vec![0u8]], vec![2u64])).unwrap(); - assert_eq!(pool.status().ready, 0); - assert_eq!(pool.status().future, 0); + assert_eq!(pool.validated_pool().status().ready, 0); + assert_eq!(pool.validated_pool().status().future, 0); // then let mut stream = futures::executor::block_on_stream(watcher.into_stream()); 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); } #[test] @@ -859,8 +829,8 @@ mod tests { amount: 5, nonce: 1, }))).unwrap(); - assert_eq!(pool.status().ready, 0); - assert_eq!(pool.status().future, 1); + assert_eq!(pool.validated_pool().status().ready, 0); + assert_eq!(pool.validated_pool().status().future, 1); // when block_on(pool.submit_one(&BlockId::Number(0), uxt(Transfer { @@ -869,7 +839,7 @@ mod tests { amount: 5, nonce: 0, }))).unwrap(); - assert_eq!(pool.status().ready, 2); + assert_eq!(pool.validated_pool().status().ready, 2); // then let mut stream = futures::executor::block_on_stream(watcher.into_stream()); @@ -888,7 +858,7 @@ mod tests { nonce: 0, }); let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), uxt)).unwrap(); - assert_eq!(pool.status().ready, 1); + assert_eq!(pool.validated_pool().status().ready, 1); // when pool.validated_pool.remove_invalid(&[*watcher.hash()]); @@ -912,13 +882,13 @@ mod tests { nonce: 0, }); let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), uxt)).unwrap(); - assert_eq!(pool.status().ready, 1); + assert_eq!(pool.validated_pool().status().ready, 1); // when let mut map = HashMap::new(); let peers = vec!["a".into(), "b".into(), "c".into()]; map.insert(*watcher.hash(), peers.clone()); - pool.on_broadcasted(map); + pool.validated_pool().on_broadcasted(map); // then @@ -947,7 +917,7 @@ mod tests { nonce: 0, }); let watcher = block_on(pool.submit_and_watch(&BlockId::Number(0), xt)).unwrap(); - assert_eq!(pool.status().ready, 1); + assert_eq!(pool.validated_pool().status().ready, 1); // when let xt = uxt(Transfer { @@ -957,7 +927,7 @@ mod tests { nonce: 1, }); block_on(pool.submit_one(&BlockId::Number(1), xt)).unwrap(); - assert_eq!(pool.status().ready, 1); + assert_eq!(pool.validated_pool().status().ready, 1); // then let mut stream = futures::executor::block_on_stream(watcher.into_stream()); @@ -1000,11 +970,11 @@ mod tests { // The tag the above transaction provides (TestApi is using just nonce as u8) let provides = vec![0_u8]; block_on(pool.submit_one(&BlockId::Number(0), xt)).unwrap(); - assert_eq!(pool.status().ready, 1); + assert_eq!(pool.validated_pool().status().ready, 1); // Now block import happens before the second transaction is able to finish verification. block_on(pool.prune_tags(&BlockId::Number(1), vec![provides], vec![])).unwrap(); - assert_eq!(pool.status().ready, 0); + assert_eq!(pool.validated_pool().status().ready, 0); // so when we release the verification of the previous one it will have @@ -1014,8 +984,8 @@ mod tests { // then is_ready.recv().unwrap(); // wait for finish - assert_eq!(pool.status().ready, 1); - assert_eq!(pool.status().future, 0); + assert_eq!(pool.validated_pool().status().ready, 1); + assert_eq!(pool.validated_pool().status().future, 0); } } @@ -1047,7 +1017,7 @@ mod tests { 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); + assert_eq!(pool.validated_pool().status().ready, 5); // when pool.validated_pool.api().invalidate.lock().insert(hash3); @@ -1064,7 +1034,7 @@ mod tests { // // events for hash3 are: Ready, Invalid // events for hash4 are: Ready, Invalid - assert_eq!(pool.status().ready, 2); + assert_eq!(pool.validated_pool().status().ready, 2); assert_eq!( futures::executor::block_on_stream(watcher3.into_stream()).collect::>(), vec![TransactionStatus::Ready, TransactionStatus::Invalid], @@ -1095,4 +1065,3 @@ mod tests { ); } } - diff --git a/client/transaction-pool/graph/src/validated_pool.rs b/client/transaction-pool/graph/src/validated_pool.rs index d02bc0ec72..8752414637 100644 --- a/client/transaction-pool/graph/src/validated_pool.rs +++ b/client/transaction-pool/graph/src/validated_pool.rs @@ -16,12 +16,11 @@ use std::{ collections::{HashSet, HashMap}, - fmt, hash, sync::Arc, }; -use crate::base_pool as base; +use crate::{base_pool as base, BlockHash}; use crate::listener::Listener; use crate::rotator::PoolRotator; use crate::watcher::Watcher; @@ -39,7 +38,7 @@ use sp_transaction_pool::{error, PoolStatus}; use wasm_timer::Instant; use crate::base_pool::PruneStatus; -use crate::pool::{EventStream, Options, ChainApi, BlockHash, ExHash, ExtrinsicFor, TransactionFor}; +use crate::pool::{EventStream, Options, ChainApi, ExHash, ExtrinsicFor, TransactionFor}; /// Pre-validated transaction. Validated pool only accepts transactions wrapped in this enum. #[derive(Debug)] @@ -62,10 +61,10 @@ pub type ValidatedTransactionFor = ValidatedTransaction< >; /// Pool that deals with validated transactions. -pub(crate) struct ValidatedPool { +pub struct ValidatedPool { api: Arc, options: Options, - listener: RwLock, BlockHash>>, + listener: RwLock, B>>, pool: RwLock, ExtrinsicFor, @@ -91,9 +90,9 @@ impl ValidatedPool { pub fn new(options: Options, api: Arc) -> Self { let base_pool = base::BasePool::new(options.reject_future_transactions); ValidatedPool { - api, options, listener: Default::default(), + api, pool: RwLock::new(base_pool), import_notification_sinks: Default::default(), rotator: Default::default(), @@ -138,13 +137,14 @@ impl ValidatedPool { let imported = self.pool.write().import(tx)?; if let base::Imported::Ready { ref hash, .. } = imported { - self.import_notification_sinks.lock().retain(|sink| sink.unbounded_send(hash.clone()).is_ok()); + self.import_notification_sinks.lock() + .retain(|sink| sink.unbounded_send(hash.clone()).is_ok()); } let mut listener = self.listener.write(); fire_events(&mut *listener, &imported); Ok(imported.hash().clone()) - } + }, ValidatedTransaction::Invalid(hash, err) => { self.rotator.ban(&Instant::now(), std::iter::once(hash)); Err(err.into()) @@ -152,7 +152,7 @@ impl ValidatedPool { ValidatedTransaction::Unknown(hash, err) => { self.listener.write().invalid(&hash, false); Err(err.into()) - } + }, } } @@ -343,8 +343,7 @@ impl ValidatedPool { self.pool.read().by_hashes(&hashes) .into_iter() .map(|existing_in_pool| existing_in_pool - .map(|transaction| transaction.provides.iter().cloned() - .collect())) + .map(|transaction| transaction.provides.iter().cloned().collect())) .collect() } @@ -416,8 +415,14 @@ impl ValidatedPool { 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(); + let mut set = HashSet::with_capacity(hashes.size_hint().0); for h in hashes { - listener.pruned(header_hash, &h); + // `hashes` has possibly duplicate hashes. + // we'd like to send out the `InBlock` notification only once. + if !set.contains(&h) { + listener.pruned(header_hash, &h); + set.insert(h); + } } Ok(()) } @@ -468,7 +473,10 @@ impl ValidatedPool { &self.api } - /// Return an event stream of transactions imported to the pool. + /// 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> { let (sink, stream) = mpsc::unbounded(); self.import_notification_sinks.lock().push(sink); @@ -492,7 +500,7 @@ impl ValidatedPool { pub fn remove_invalid(&self, hashes: &[ExHash]) -> Vec> { // early exit in case there is no invalid transactions. if hashes.is_empty() { - return vec![] + return vec![]; } debug!(target: "txpool", "Removing invalid transactions: {:?}", hashes); @@ -521,14 +529,34 @@ impl ValidatedPool { pub fn status(&self) -> PoolStatus { self.pool.read().status() } + + /// Notify all watchers that transactions in the block with hash have been finalized + pub async fn on_block_finalized(&self, block_hash: BlockHash) -> Result<(), B::Error> { + debug!(target: "txpool", "Attempting to notify watchers of finalization for {}", block_hash); + // fetch all extrinsic hashes + if let Some(txs) = self.api.block_body(&BlockId::Hash(block_hash.clone())).await? { + let tx_hashes = txs.into_iter() + .map(|tx| self.api.hash_and_length(&tx).0) + .collect::>(); + // notify the watcher that these extrinsics have been finalized + self.listener.write().finalized(block_hash, tx_hashes); + } + + Ok(()) + } + + /// Notify the listener of retracted blocks + pub fn on_block_retracted(&self, block_hash: BlockHash) { + self.listener.write().retracted(block_hash) + } } -fn fire_events( - listener: &mut Listener, +fn fire_events( + listener: &mut Listener, imported: &base::Imported, ) where H: hash::Hash + Eq + traits::Member + Serialize, - H2: Clone + fmt::Debug, + B: ChainApi, { match *imported { base::Imported::Ready { ref promoted, ref failed, ref removed, ref hash } => { diff --git a/client/transaction-pool/graph/src/watcher.rs b/client/transaction-pool/graph/src/watcher.rs index f9c234f73c..d28f6814e4 100644 --- a/client/transaction-pool/graph/src/watcher.rs +++ b/client/transaction-pool/graph/src/watcher.rs @@ -26,12 +26,12 @@ use sp_transaction_pool::TransactionStatus; /// /// Represents a stream of status updates for particular extrinsic. #[derive(Debug)] -pub struct Watcher { - receiver: mpsc::UnboundedReceiver>, +pub struct Watcher { + receiver: mpsc::UnboundedReceiver>, hash: H, } -impl Watcher { +impl Watcher { /// Returns the transaction hash. pub fn hash(&self) -> &H { &self.hash @@ -40,30 +40,30 @@ 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 } } /// Sender part of the watcher. Exposed only for testing purposes. #[derive(Debug)] -pub struct Sender { - receivers: Vec>>, - finalized: bool, +pub struct Sender { + receivers: Vec>>, + is_finalized: bool, } -impl Default for Sender { +impl Default for Sender { fn default() -> Self { Sender { receivers: Default::default(), - finalized: false, + is_finalized: false, } } } -impl Sender { +impl Sender { /// Add a new watcher to this sender object. - pub fn new_watcher(&mut self, hash: H) -> Watcher { + pub fn new_watcher(&mut self, hash: H) -> Watcher { let (tx, receiver) = mpsc::unbounded(); self.receivers.push(tx); Watcher { @@ -85,26 +85,42 @@ impl Sender { /// Some state change (perhaps another extrinsic was included) rendered this extrinsic invalid. pub fn usurped(&mut self, hash: H) { self.send(TransactionStatus::Usurped(hash)); - self.finalized = true; + self.is_finalized = true; } /// Extrinsic has been included in block with given hash. - pub fn in_block(&mut self, hash: H2) { + pub fn in_block(&mut self, hash: BH) { self.send(TransactionStatus::InBlock(hash)); - self.finalized = true; + } + + /// Extrinsic has been finalized by a finality gadget. + pub fn finalized(&mut self, hash: BH) { + self.send(TransactionStatus::Finalized(hash)); + self.is_finalized = true; + } + + /// The block this extrinsic was included in has been retracted + pub fn finality_timeout(&mut self, hash: BH) { + self.send(TransactionStatus::FinalityTimeout(hash)); + self.is_finalized = true; + } + + /// The block this extrinsic was included in has been retracted + pub fn retracted(&mut self, hash: BH) { + self.send(TransactionStatus::Retracted(hash)); } /// Extrinsic has been marked as invalid by the block builder. pub fn invalid(&mut self) { self.send(TransactionStatus::Invalid); // we mark as finalized as there are no more notifications - self.finalized = true; + self.is_finalized = true; } /// Transaction has been dropped from the pool because of the limit. pub fn dropped(&mut self) { self.send(TransactionStatus::Dropped); - self.finalized = true; + self.is_finalized = true; } /// The extrinsic has been broadcast to the given peers. @@ -114,10 +130,10 @@ impl Sender { /// 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() + self.is_finalized || self.receivers.is_empty() } - fn send(&mut self, status: TransactionStatus) { + 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 bfc13c01fd..84e06cc33e 100644 --- a/client/transaction-pool/src/api.rs +++ b/client/transaction-pool/src/api.rs @@ -64,7 +64,8 @@ impl FullChainApi where impl sc_transaction_graph::ChainApi for FullChainApi where Block: BlockT, - Client: ProvideRuntimeApi + BlockBody + BlockIdTo + 'static + Send + Sync, + Client: ProvideRuntimeApi + BlockBody + BlockIdTo, + Client: Send + Sync + 'static, Client::Api: TaggedTransactionQueue, sp_api::ApiErrorFor: Send, { diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index f4895d9a11..fbfc6a24e6 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -37,9 +37,8 @@ use sp_runtime::{ traits::{Block as BlockT, NumberFor, AtLeast32Bit, Extrinsic}, }; use sp_transaction_pool::{ - TransactionPool, PoolStatus, ImportNotificationStream, - TxHash, TransactionFor, TransactionStatusStreamFor, BlockHash, - MaintainedTransactionPool, PoolFuture, + TransactionPool, PoolStatus, ImportNotificationStream, TxHash, TransactionFor, + TransactionStatusStreamFor, MaintainedTransactionPool, PoolFuture, ChainEvent, }; use wasm_timer::Instant; @@ -115,7 +114,6 @@ impl BasicPool } )), } - } /// Gets shared reference to the underlying pool. @@ -174,19 +172,19 @@ impl TransactionPool for BasicPool } fn remove_invalid(&self, hashes: &[TxHash]) -> Vec> { - self.pool.remove_invalid(hashes) + self.pool.validated_pool().remove_invalid(hashes) } fn status(&self) -> PoolStatus { - self.pool.status() + self.pool.validated_pool().status() } fn ready(&self) -> Box>> { - Box::new(self.pool.ready()) + Box::new(self.pool.validated_pool().ready()) } fn import_notification_stream(&self) -> ImportNotificationStream> { - self.pool.import_notification_stream() + self.pool.validated_pool().import_notification_stream() } fn hash_of(&self, xt: &TransactionFor) -> TxHash { @@ -194,11 +192,11 @@ impl TransactionPool for BasicPool } fn on_broadcasted(&self, propagations: HashMap, Vec>) { - self.pool.on_broadcasted(propagations) + self.pool.validated_pool().on_broadcasted(propagations) } fn ready_transaction(&self, hash: &TxHash) -> Option> { - self.pool.ready_transaction(hash) + self.pool.validated_pool().ready_by_hash(hash) } } @@ -214,7 +212,7 @@ enum RevalidationStatus { enum RevalidationStrategy { Always, - Light(RevalidationStatus) + Light(RevalidationStatus), } struct RevalidationAction { @@ -241,7 +239,7 @@ impl RevalidationStrategy { revalidate: status.next_required( block, revalidate_time_period, - revalidate_block_period + revalidate_block_period, ), resubmit: false, revalidate_amount: None, @@ -275,7 +273,7 @@ impl RevalidationStatus { revalidate_block_period.map(|period| block + period), ); false - }, + } Self::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); @@ -283,87 +281,105 @@ impl RevalidationStatus { *self = Self::InProgress; } is_required - }, + } Self::InProgress => false, } } } impl MaintainedTransactionPool for BasicPool -where - Block: BlockT, - PoolApi: 'static + sc_transaction_graph::ChainApi, + where + Block: BlockT, + PoolApi: 'static + sc_transaction_graph::ChainApi, { - fn maintain(&self, id: &BlockId, retracted: &[BlockHash]) - -> Pin + Send>> - { - let id = id.clone(); - let pool = self.pool.clone(); - let api = self.api.clone(); - - let block_number = match api.block_id_to_number(&id) { - Ok(Some(number)) => number, - _ => { - log::trace!(target: "txqueue", "Skipping chain event - no number for that block {:?}", id); - return Box::pin(ready(())); - } - }; - - let next_action = self.revalidation_strategy.lock().next( - block_number, - Some(std::time::Duration::from_secs(60)), - Some(20.into()), - ); - let revalidation_strategy = self.revalidation_strategy.clone(); - let retracted = retracted.to_vec(); - - async move { - // We don't query block if we won't prune anything - if !pool.status().is_empty() { - let hashes = api.block_body(&id).await - .unwrap_or_else(|e| { - log::warn!("Prune known transactions: error request {:?}!", e); - None - }) - .unwrap_or_default() - .into_iter() - .map(|tx| pool.hash_of(&tx)) - .collect::>(); - - if let Err(e) = pool.prune_known(&id, &hashes) { - log::error!("Cannot prune known in the pool {:?}!", e); - } - } - - if next_action.resubmit { - let mut resubmit_transactions = Vec::new(); - - for retracted_hash in retracted { - let block_transactions = api.block_body(&BlockId::hash(retracted_hash.clone())).await - .unwrap_or_else(|e| { - log::warn!("Failed to fetch block body {:?}!", e); - None - }) - .unwrap_or_default() - .into_iter() - .filter(|tx| tx.is_signed().unwrap_or(true)); - - resubmit_transactions.extend(block_transactions); - } - if let Err(e) = pool.submit_at(&id, resubmit_transactions, true).await { - log::debug!(target: "txpool", - "[{:?}] Error re-submitting transactions: {:?}", id, e - ) - } + fn maintain(&self, event: ChainEvent) -> Pin + Send>> { + match event { + ChainEvent::NewBlock { id, retracted, .. } => { + let id = id.clone(); + let pool = self.pool.clone(); + let api = self.api.clone(); + + let block_number = match api.block_id_to_number(&id) { + Ok(Some(number)) => number, + _ => { + log::trace!(target: "txqueue", "Skipping chain event - no number for that block {:?}", id); + return Box::pin(ready(())); + } + }; + + let next_action = self.revalidation_strategy.lock().next( + block_number, + Some(std::time::Duration::from_secs(60)), + Some(20.into()), + ); + let revalidation_strategy = self.revalidation_strategy.clone(); + let retracted = retracted.clone(); + + async move { + // We don't query block if we won't prune anything + if !pool.validated_pool().status().is_empty() { + let hashes = api.block_body(&id).await + .unwrap_or_else(|e| { + log::warn!("Prune known transactions: error request {:?}!", e); + None + }) + .unwrap_or_default() + .into_iter() + .map(|tx| pool.hash_of(&tx)) + .collect::>(); + + if let Err(e) = pool.prune_known(&id, &hashes) { + log::error!("Cannot prune known in the pool {:?}!", e); + } + } + + if next_action.resubmit { + let mut resubmit_transactions = Vec::new(); + + for retracted_hash in retracted { + // notify txs awaiting finality that it has been retracted + pool.validated_pool().on_block_retracted(retracted_hash.clone()); + + let block_transactions = api.block_body(&BlockId::hash(retracted_hash.clone())).await + .unwrap_or_else(|e| { + log::warn!("Failed to fetch block body {:?}!", e); + None + }) + .unwrap_or_default() + .into_iter() + .filter(|tx| tx.is_signed().unwrap_or(true)); + + resubmit_transactions.extend(block_transactions); + } + if let Err(e) = pool.submit_at(&id, resubmit_transactions, true).await { + log::debug!( + target: "txpool", + "[{:?}] Error re-submitting transactions: {:?}", id, e + ) + } + } + + if next_action.revalidate { + if let Err(e) = pool.revalidate_ready(&id, next_action.revalidate_amount).await { + log::warn!("Revalidate ready failed {:?}", e); + } + } + + revalidation_strategy.lock().clear(); + }.boxed() } - - if next_action.revalidate { - if let Err(e) = pool.revalidate_ready(&id, next_action.revalidate_amount).await { - log::warn!("Revalidate ready failed {:?}", e); - } + ChainEvent::Finalized { hash } => { + let pool = self.pool.clone(); + async move { + if let Err(e) = pool.validated_pool().on_block_finalized(hash).await { + log::warn!( + target: "txpool", + "Error [{}] occurred while attempting to notify watchers of finalization {}", + e, hash + ) + } + }.boxed() } - - revalidation_strategy.lock().clear(); - }.boxed() + } } } diff --git a/client/transaction-pool/src/testing/pool.rs b/client/transaction-pool/src/testing/pool.rs index fed02067b1..4a4f4638df 100644 --- a/client/transaction-pool/src/testing/pool.rs +++ b/client/transaction-pool/src/testing/pool.rs @@ -15,17 +15,18 @@ // along with Substrate. If not, see . use crate::*; -use sc_transaction_graph::Pool; use futures::executor::block_on; +use txpool::{self, Pool}; use sp_runtime::{ generic::BlockId, transaction_validity::ValidTransaction, }; use substrate_test_runtime_client::{ - runtime::{Block, Hash, Index}, + runtime::{Block, Hash, Index, Header}, AccountKeyring::*, }; use substrate_test_runtime_transaction_pool::{TestApi, uxt}; +use sp_transaction_pool::TransactionStatus; fn pool() -> Pool { Pool::new(Default::default(), TestApi::with_alice_nonce(209).into()) @@ -35,12 +36,22 @@ fn maintained_pool() -> BasicPool { BasicPool::new(Default::default(), std::sync::Arc::new(TestApi::with_alice_nonce(209))) } +fn header(number: u64) -> Header { + Header { + number, + digest: Default::default(), + extrinsics_root: Default::default(), + parent_hash: Default::default(), + state_root: Default::default(), + } +} + #[test] fn submission_should_work() { let pool = pool(); block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); - let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); + let pending: Vec<_> = pool.validated_pool().ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209]); } @@ -50,7 +61,7 @@ fn multiple_submission_should_work() { block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).unwrap(); - let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); + let pending: Vec<_> = pool.validated_pool().ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209, 210]); } @@ -59,7 +70,7 @@ fn early_nonce_should_be_culled() { let pool = pool(); block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 208))).unwrap(); - let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); + let pending: Vec<_> = pool.validated_pool().ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, Vec::::new()); } @@ -68,11 +79,11 @@ fn late_nonce_should_be_queued() { let pool = pool(); block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).unwrap(); - let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); + let pending: Vec<_> = pool.validated_pool().ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, Vec::::new()); block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); - let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); + let pending: Vec<_> = pool.validated_pool().ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209, 210]); } @@ -82,7 +93,7 @@ fn prune_tags_should_work() { let hash209 = block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).unwrap(); block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).unwrap(); - let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); + let pending: Vec<_> = pool.validated_pool().ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209, 210]); block_on( @@ -93,7 +104,7 @@ fn prune_tags_should_work() { ) ).expect("Prune tags"); - let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); + let pending: Vec<_> = pool.validated_pool().ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![210]); } @@ -102,11 +113,11 @@ fn should_ban_invalid_transactions() { let pool = pool(); let uxt = uxt(Alice, 209); let hash = block_on(pool.submit_one(&BlockId::number(0), uxt.clone())).unwrap(); - pool.remove_invalid(&[hash]); + pool.validated_pool().remove_invalid(&[hash]); block_on(pool.submit_one(&BlockId::number(0), uxt.clone())).unwrap_err(); // when - let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); + let pending: Vec<_> = pool.validated_pool().ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, Vec::::new()); // then @@ -122,29 +133,29 @@ fn should_correctly_prune_transactions_providing_more_than_one_tag() { let pool = Pool::new(Default::default(), api.clone()); let xt = uxt(Alice, 209); block_on(pool.submit_one(&BlockId::number(0), xt.clone())).expect("1. Imported"); - assert_eq!(pool.status().ready, 1); + assert_eq!(pool.validated_pool().status().ready, 1); // remove the transaction that just got imported. api.increment_nonce(Alice.into()); block_on(pool.prune_tags(&BlockId::number(1), vec![vec![209]], vec![])).expect("1. Pruned"); - assert_eq!(pool.status().ready, 0); + assert_eq!(pool.validated_pool().status().ready, 0); // it's re-imported to future - assert_eq!(pool.status().future, 1); + assert_eq!(pool.validated_pool().status().future, 1); // so now let's insert another transaction that also provides the 155 api.increment_nonce(Alice.into()); let xt = uxt(Alice, 211); block_on(pool.submit_one(&BlockId::number(2), xt.clone())).expect("2. Imported"); - assert_eq!(pool.status().ready, 1); - assert_eq!(pool.status().future, 1); - let pending: Vec<_> = pool.ready().map(|a| a.data.transfer().nonce).collect(); + assert_eq!(pool.validated_pool().status().ready, 1); + assert_eq!(pool.validated_pool().status().future, 1); + let pending: Vec<_> = pool.validated_pool().ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![211]); // prune it and make sure the pool is empty api.increment_nonce(Alice.into()); block_on(pool.prune_tags(&BlockId::number(3), vec![vec![155]], vec![])).expect("2. Pruned"); - assert_eq!(pool.status().ready, 0); - assert_eq!(pool.status().future, 2); + assert_eq!(pool.validated_pool().status().ready, 0); + assert_eq!(pool.validated_pool().status().future, 2); } #[test] @@ -158,7 +169,14 @@ fn should_prune_old_during_maintenance() { pool.api.push_block(1, vec![xt.clone()]); - block_on(pool.maintain(&BlockId::number(1), &[])); + let event = ChainEvent::NewBlock { + id: BlockId::number(1), + is_new_best: true, + retracted: vec![], + header: header(1), + }; + + block_on(pool.maintain(event)); assert_eq!(pool.status().ready, 0); } @@ -174,8 +192,14 @@ fn should_revalidate_during_maintenance() { assert_eq!(pool.api.validation_requests().len(), 2); pool.api.push_block(1, vec![xt1.clone()]); - - block_on(pool.maintain(&BlockId::number(1), &[])); + let event = ChainEvent::NewBlock { + id: BlockId::number(1), + is_new_best: true, + retracted: vec![], + header: header(1), + }; + + block_on(pool.maintain(event)); assert_eq!(pool.status().ready, 1); // test that pool revalidated transaction that left ready and not included in the block assert_eq!(pool.api.validation_requests().len(), 3); @@ -193,8 +217,14 @@ fn should_resubmit_from_retracted_during_maintaince() { pool.api.push_block(1, vec![]); pool.api.push_fork_block(retracted_hash, vec![xt.clone()]); - - block_on(pool.maintain(&BlockId::number(1), &[retracted_hash])); + let event = ChainEvent::NewBlock { + id: BlockId::Number(1), + is_new_best: true, + header: header(1), + retracted: vec![retracted_hash] + }; + + block_on(pool.maintain(event)); assert_eq!(pool.status().ready, 1); } @@ -212,7 +242,14 @@ fn should_not_retain_invalid_hashes_from_retracted() { pool.api.push_fork_block(retracted_hash, vec![xt.clone()]); pool.api.add_invalid(&xt); - block_on(pool.maintain(&BlockId::number(1), &[retracted_hash])); + let event = ChainEvent::NewBlock { + id: BlockId::Number(1), + is_new_best: true, + header: header(1), + retracted: vec![retracted_hash] + }; + + block_on(pool.maintain(event)); assert_eq!(pool.status().ready, 0); } @@ -225,4 +262,188 @@ fn can_track_heap_size() { block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 212))).expect("1. Imported"); assert!(parity_util_mem::malloc_size(&pool) > 3000); -} \ No newline at end of file +} + +#[test] +fn finalization() { + let xt = uxt(Alice, 209); + let api = TestApi::with_alice_nonce(209); + api.push_block(1, vec![]); + let pool = BasicPool::new(Default::default(), api.into()); + let watcher = block_on(pool.submit_and_watch(&BlockId::number(1), xt.clone())).expect("1. Imported"); + pool.api.push_block(2, vec![xt.clone()]); + + let header = pool.api.chain().read().header_by_number.get(&2).cloned().unwrap(); + let event = ChainEvent::NewBlock { + id: BlockId::Hash(header.hash()), + is_new_best: true, + header: header.clone(), + retracted: vec![] + }; + block_on(pool.maintain(event)); + + let event = ChainEvent::Finalized { hash: header.hash() }; + block_on(pool.maintain(event)); + + let mut stream = futures::executor::block_on_stream(watcher); + assert_eq!(stream.next(), Some(TransactionStatus::Ready)); + assert_eq!(stream.next(), Some(TransactionStatus::InBlock(header.hash()))); + assert_eq!(stream.next(), Some(TransactionStatus::Finalized(header.hash()))); + assert_eq!(stream.next(), None); +} + +#[test] +fn fork_aware_finalization() { + let api = TestApi::empty(); + // starting block A1 (last finalized.) + api.push_block(1, vec![]); + + let pool = BasicPool::new(Default::default(), api.into()); + let mut canon_watchers = vec![]; + + let from_alice = uxt(Alice, 1); + let from_dave = uxt(Dave, 1); + let from_bob = uxt(Bob, 1); + let from_charlie = uxt(Charlie, 1); + pool.api.increment_nonce(Alice.into()); + pool.api.increment_nonce(Dave.into()); + pool.api.increment_nonce(Charlie.into()); + pool.api.increment_nonce(Bob.into()); + + let from_dave_watcher; + let from_bob_watcher; + let b1; + let d1; + let c2; + let d2; + + + // block B1 + { + let watcher = block_on(pool.submit_and_watch(&BlockId::number(1), from_alice.clone())).expect("1. Imported"); + let header = pool.api.push_block(2, vec![from_alice.clone()]); + canon_watchers.push((watcher, header.hash())); + + let event = ChainEvent::NewBlock { + id: BlockId::Number(2), + is_new_best: true, + header: header.clone(), + retracted: vec![], + }; + b1 = header.hash(); + block_on(pool.maintain(event)); + let event = ChainEvent::Finalized { hash: b1 }; + block_on(pool.maintain(event)); + } + + // block C2 + { + let header = pool.api.push_fork_block_with_parent(b1, vec![from_dave.clone()]); + from_dave_watcher = block_on(pool.submit_and_watch(&BlockId::number(1), from_dave.clone())) + .expect("1. Imported"); + let event = ChainEvent::NewBlock { + id: BlockId::Hash(header.hash()), + is_new_best: true, + header: header.clone(), + retracted: vec![] + }; + c2 = header.hash(); + block_on(pool.maintain(event)); + } + + // block D2 + { + from_bob_watcher = block_on(pool.submit_and_watch(&BlockId::number(1), from_bob.clone())).expect("1. Imported"); + let header = pool.api.push_fork_block_with_parent(c2, vec![from_bob.clone()]); + + let event = ChainEvent::NewBlock { + id: BlockId::Hash(header.hash()), + is_new_best: true, + header: header.clone(), + retracted: vec![] + }; + d2 = header.hash(); + block_on(pool.maintain(event)); + } + + // block C1 + { + let watcher = block_on(pool.submit_and_watch(&BlockId::number(1), from_charlie.clone())).expect("1.Imported"); + let header = pool.api.push_block(3, vec![from_charlie.clone()]); + + canon_watchers.push((watcher, header.hash())); + let event = ChainEvent::NewBlock { + id: BlockId::Number(3), + is_new_best: true, + header: header.clone(), + retracted: vec![c2, d2], + }; + block_on(pool.maintain(event)); + let event = ChainEvent::Finalized { hash: header.hash() }; + block_on(pool.maintain(event)); + } + + // block D1 + { + let xt = uxt(Eve, 0); + let w = block_on(pool.submit_and_watch(&BlockId::number(1), xt.clone())).expect("1. Imported"); + let header = pool.api.push_block(4, vec![xt.clone()]); + canon_watchers.push((w, header.hash())); + + let event = ChainEvent::NewBlock { + id: BlockId::Hash(header.hash()), + is_new_best: true, + header: header.clone(), + retracted: vec![] + }; + d1 = header.hash(); + block_on(pool.maintain(event)); + let event = ChainEvent::Finalized { hash: d1 }; + block_on(pool.maintain(event)); + } + + let e1; + + // block e1 + { + let header = pool.api.push_block(5, vec![from_dave]); + e1 = header.hash(); + let event = ChainEvent::NewBlock { + id: BlockId::Hash(header.hash()), + is_new_best: true, + header: header.clone(), + retracted: vec![] + }; + block_on(pool.maintain(event)); + block_on(pool.maintain(ChainEvent::Finalized { hash: e1 })); + } + + + for (canon_watcher, h) in canon_watchers { + let mut stream = futures::executor::block_on_stream(canon_watcher); + assert_eq!(stream.next(), Some(TransactionStatus::Ready)); + assert_eq!(stream.next(), Some(TransactionStatus::InBlock(h.clone()))); + assert_eq!(stream.next(), Some(TransactionStatus::Finalized(h))); + assert_eq!(stream.next(), None); + } + + + { + let mut stream= futures::executor::block_on_stream(from_dave_watcher); + assert_eq!(stream.next(), Some(TransactionStatus::Ready)); + assert_eq!(stream.next(), Some(TransactionStatus::InBlock(c2.clone()))); + assert_eq!(stream.next(), Some(TransactionStatus::Retracted(c2))); + assert_eq!(stream.next(), Some(TransactionStatus::Ready)); + assert_eq!(stream.next(), Some(TransactionStatus::InBlock(e1))); + assert_eq!(stream.next(), Some(TransactionStatus::Finalized(e1.clone()))); + assert_eq!(stream.next(), None); + } + + { + let mut stream= futures::executor::block_on_stream(from_bob_watcher); + assert_eq!(stream.next(), Some(TransactionStatus::Ready)); + assert_eq!(stream.next(), Some(TransactionStatus::InBlock(d2.clone()))); + assert_eq!(stream.next(), Some(TransactionStatus::Retracted(d2))); + } + +} diff --git a/primitives/blockchain/src/header_metadata.rs b/primitives/blockchain/src/header_metadata.rs index fcd8062d1d..32dd0bcf06 100644 --- a/primitives/blockchain/src/header_metadata.rs +++ b/primitives/blockchain/src/header_metadata.rs @@ -151,7 +151,7 @@ pub fn tree_route>( } /// Hash and number of a block. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct HashAndNumber { /// The number of the block. pub number: NumberFor, diff --git a/primitives/transaction-pool/src/pool.rs b/primitives/transaction-pool/src/pool.rs index d4e6a5caf2..6912bc79d6 100644 --- a/primitives/transaction-pool/src/pool.rs +++ b/primitives/transaction-pool/src/pool.rs @@ -67,7 +67,7 @@ impl PoolStatus { /// 2. Inside `Ready` queue: /// - `Broadcast` /// 3. Leaving the pool: -/// - `InBlock` +/// - `Finalized` /// - `Invalid` /// - `Usurped` /// - `Dropped` @@ -100,6 +100,13 @@ pub enum TransactionStatus { /// Transaction has been included in block with given hash. #[serde(rename = "finalized")] // See #4438 InBlock(BlockHash), + /// The block this transaction was included in has been retracted. + Retracted(BlockHash), + /// Maximum number of finality watchers has been reached, + /// old watchers are being removed. + FinalityTimeout(BlockHash), + /// Transaction has been finalized by a finality-gadget, e.g GRANDPA + Finalized(BlockHash), /// Transaction has been replaced in the pool, by another transaction /// that provides the same tags. (e.g. same (sender, nonce)). Usurped(Hash), @@ -217,11 +224,30 @@ pub trait TransactionPool: Send + Sync { fn ready_transaction(&self, hash: &TxHash) -> Option>; } +/// Events that the transaction pool listens for. +pub enum ChainEvent { + /// New blocks have been added to the chain + NewBlock { + /// Is this the new best block. + is_new_best: bool, + /// Id of the just imported block. + id: BlockId, + /// Header of the just imported block + header: B::Header, + /// List of retracted blocks ordered by block number. + retracted: Vec, + }, + /// An existing block has been finalzied. + Finalized { + /// Hash of just finalized block + hash: B::Hash, + }, +} + /// Trait for transaction pool maintenance. -pub trait MaintainedTransactionPool : TransactionPool { +pub trait MaintainedTransactionPool: TransactionPool { /// Perform maintenance - fn maintain(&self, block: &BlockId, retracted: &[BlockHash]) - -> Pin + Send>>; + fn maintain(&self, event: ChainEvent) -> Pin + Send>>; } /// An abstraction for transaction pool. diff --git a/test-utils/runtime/transaction-pool/Cargo.toml b/test-utils/runtime/transaction-pool/Cargo.toml index 615886d987..72e81f5f19 100644 --- a/test-utils/runtime/transaction-pool/Cargo.toml +++ b/test-utils/runtime/transaction-pool/Cargo.toml @@ -9,6 +9,7 @@ license = "GPL-3.0" substrate-test-runtime-client = { version = "2.0.0", path = "../client" } parking_lot = "0.10.0" codec = { package = "parity-scale-codec", version = "1.0.0" } +sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" } sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } sp-transaction-pool = { version = "2.0.0", path = "../../../primitives/transaction-pool" } sc-transaction-graph = { version = "2.0.0", path = "../../../client/transaction-pool/graph" } diff --git a/test-utils/runtime/transaction-pool/src/lib.rs b/test-utils/runtime/transaction-pool/src/lib.rs index 58c801d8d6..aedc7dc4c3 100644 --- a/test-utils/runtime/transaction-pool/src/lib.rs +++ b/test-utils/runtime/transaction-pool/src/lib.rs @@ -50,7 +50,7 @@ impl std::error::Error for Error { } #[derive(Default)] -struct ChainState { +pub struct ChainState { pub block_by_number: HashMap>, pub block_by_hash: HashMap>, pub header_by_number: HashMap, @@ -96,16 +96,24 @@ impl TestApi { } /// Push block as a part of canonical chain under given number. - pub fn push_block(&self, block_number: BlockNumber, xts: Vec) { + pub fn push_block(&self, block_number: BlockNumber, xts: Vec) -> Header { let mut chain = self.chain.write(); - chain.block_by_number.insert(block_number, xts); - chain.header_by_number.insert(block_number, Header { + chain.block_by_number.insert(block_number, xts.clone()); + let header = Header { number: block_number, digest: Default::default(), extrinsics_root: Default::default(), - parent_hash: Default::default(), + parent_hash: block_number + .checked_sub(1) + .and_then(|num| { + chain.header_by_number.get(&num) + .cloned().map(|h| h.hash()) + }).unwrap_or_default(), state_root: Default::default(), - }); + }; + chain.block_by_hash.insert(header.hash(), xts); + chain.header_by_number.insert(block_number, header.clone()); + header } /// Push a block without a number. @@ -116,6 +124,20 @@ impl TestApi { chain.block_by_hash.insert(block_hash, xts); } + pub fn push_fork_block_with_parent(&self, parent: Hash, xts: Vec) -> Header { + let mut chain = self.chain.write(); + let blocknum = chain.block_by_number.keys().max().expect("block_by_number shouldn't be empty"); + let header = Header { + number: *blocknum, + digest: Default::default(), + extrinsics_root: Default::default(), + parent_hash: parent, + state_root: Default::default(), + }; + chain.block_by_hash.insert(header.hash(), xts); + header + } + fn hash_and_length_inner(ex: &Extrinsic) -> (Hash, usize) { let encoded = ex.encode(); (BlakeTwo256::hash(&encoded), encoded.len()) @@ -136,6 +158,11 @@ impl TestApi { self.validation_requests.read().clone() } + /// get a reference to the chain state + pub fn chain(&self) -> &RwLock { + &self.chain + } + /// Increment nonce in the inner state. pub fn increment_nonce(&self, account: AccountId) { let mut chain = self.chain.write(); @@ -197,7 +224,12 @@ impl sc_transaction_graph::ChainApi for TestApi { ) -> Result>, Error> { Ok(match at { generic::BlockId::Hash(x) => Some(x.clone()), - _ => Some(Default::default()), + generic::BlockId::Number(num) => { + self.chain.read() + .header_by_number.get(num) + .map(|h| h.hash()) + .or_else(|| Some(Default::default())) + }, }) } @@ -209,10 +241,9 @@ impl sc_transaction_graph::ChainApi for TestApi { } fn block_body(&self, id: &BlockId) -> Self::BodyFuture { - futures::future::ready(Ok(if let BlockId::Number(num) = id { - self.chain.read().block_by_number.get(num).cloned() - } else { - None + futures::future::ready(Ok(match id { + BlockId::Number(num) => self.chain.read().block_by_number.get(num).cloned(), + BlockId::Hash(hash) => self.chain.read().block_by_hash.get(hash).cloned(), })) } } -- GitLab From b27d50c4c7b7137f2de04c31092f63a58970d0cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Fri, 14 Feb 2020 15:46:41 +0100 Subject: [PATCH 154/180] Adds `with_pair!` macro to application-crypto (#4885) * Adds `with_pair!` macro to application-crypto This macro will "generate" the given code only when the crypto pair is available. So, when either the `std` or the `full_crypto` feature is enabled. * Fix example --- frame/im-online/src/lib.rs | 14 +++++++----- primitives/application-crypto/src/lib.rs | 27 +++++++++++++++++++++++ primitives/authority-discovery/src/lib.rs | 7 +++--- primitives/consensus/aura/src/lib.rs | 14 +++++++----- primitives/finality-grandpa/Cargo.toml | 7 ++---- primitives/finality-grandpa/src/lib.rs | 9 ++++---- 6 files changed, 54 insertions(+), 24 deletions(-) diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index 839996da32..9a3fc2430c 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -102,9 +102,10 @@ pub mod sr25519 { app_crypto!(sr25519, IM_ONLINE); } - /// An i'm online keypair using sr25519 as its crypto. - #[cfg(feature = "std")] - pub type AuthorityPair = app_sr25519::Pair; + sp_application_crypto::with_pair! { + /// An i'm online keypair using sr25519 as its crypto. + pub type AuthorityPair = app_sr25519::Pair; + } /// An i'm online signature using sr25519 as its crypto. pub type AuthoritySignature = app_sr25519::Signature; @@ -119,9 +120,10 @@ pub mod ed25519 { app_crypto!(ed25519, IM_ONLINE); } - /// An i'm online keypair using ed25519 as its crypto. - #[cfg(feature = "std")] - pub type AuthorityPair = app_ed25519::Pair; + sp_application_crypto::with_pair! { + /// An i'm online keypair using ed25519 as its crypto. + pub type AuthorityPair = app_ed25519::Pair; + } /// An i'm online signature using ed25519 as its crypto. pub type AuthoritySignature = app_ed25519::Signature; diff --git a/primitives/application-crypto/src/lib.rs b/primitives/application-crypto/src/lib.rs index fed4a6bf8e..b7c9ccaa98 100644 --- a/primitives/application-crypto/src/lib.rs +++ b/primitives/application-crypto/src/lib.rs @@ -436,3 +436,30 @@ macro_rules! wrap { } } } + +/// Generate the given code if the pair type is available. +/// +/// The pair type is available when `feature = "std"` || `feature = "full_crypto"`. +/// +/// # Example +/// +/// ``` +/// sp_application_crypto::with_pair! { +/// pub type Pair = (); +/// } +/// ``` +#[macro_export] +#[cfg(any(feature = "std", feature = "full_crypto"))] +macro_rules! with_pair { + ( $( $def:tt )* ) => { + $( $def )* + } +} + + +#[doc(hidden)] +#[macro_export] +#[cfg(all(not(feature = "std"), not(feature = "full_crypto")))] +macro_rules! with_pair { + ( $( $def:tt )* ) => {} +} diff --git a/primitives/authority-discovery/src/lib.rs b/primitives/authority-discovery/src/lib.rs index fc76da61af..8926825525 100644 --- a/primitives/authority-discovery/src/lib.rs +++ b/primitives/authority-discovery/src/lib.rs @@ -25,9 +25,10 @@ mod app { app_crypto!(sr25519, AUTHORITY_DISCOVERY); } -/// An authority discovery authority keypair. -#[cfg(feature = "std")] -pub type AuthorityPair = app::Pair; +sp_application_crypto::with_pair! { + /// An authority discovery authority keypair. + pub type AuthorityPair = app::Pair; +} /// An authority discovery authority identifier. pub type AuthorityId = app::Public; diff --git a/primitives/consensus/aura/src/lib.rs b/primitives/consensus/aura/src/lib.rs index 4f20456667..2dda5b28bf 100644 --- a/primitives/consensus/aura/src/lib.rs +++ b/primitives/consensus/aura/src/lib.rs @@ -30,9 +30,10 @@ pub mod sr25519 { app_crypto!(sr25519, AURA); } - /// An Aura authority keypair using S/R 25519 as its crypto. - #[cfg(feature = "std")] - pub type AuthorityPair = app_sr25519::Pair; + sp_application_crypto::with_pair! { + /// An Aura authority keypair using S/R 25519 as its crypto. + pub type AuthorityPair = app_sr25519::Pair; + } /// An Aura authority signature using S/R 25519 as its crypto. pub type AuthoritySignature = app_sr25519::Signature; @@ -47,9 +48,10 @@ pub mod ed25519 { app_crypto!(ed25519, AURA); } - /// An Aura authority keypair using Ed25519 as its crypto. - #[cfg(feature = "std")] - pub type AuthorityPair = app_ed25519::Pair; + sp_application_crypto::with_pair! { + /// An Aura authority keypair using Ed25519 as its crypto. + pub type AuthorityPair = app_ed25519::Pair; + } /// An Aura authority signature using Ed25519 as its crypto. pub type AuthoritySignature = app_ed25519::Signature; diff --git a/primitives/finality-grandpa/Cargo.toml b/primitives/finality-grandpa/Cargo.toml index 6498763e4c..6356ec82e5 100644 --- a/primitives/finality-grandpa/Cargo.toml +++ b/primitives/finality-grandpa/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "GPL-3.0" [dependencies] -app-crypto = { version = "2.0.0", default-features = false, package = "sp-application-crypto", path = "../application-crypto" } +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-std = { version = "2.0.0", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } @@ -16,13 +16,10 @@ sp-runtime = { version = "2.0.0", default-features = false, path = "../runtime" [features] default = ["std"] std = [ - "app-crypto/std", + "sp-application-crypto/std", "codec/std", "sp-std/std", "serde", "sp-api/std", "sp-runtime/std", ] -full_crypto = [ - "app-crypto/full_crypto" -] diff --git a/primitives/finality-grandpa/src/lib.rs b/primitives/finality-grandpa/src/lib.rs index 98fce45081..205fce0ce3 100644 --- a/primitives/finality-grandpa/src/lib.rs +++ b/primitives/finality-grandpa/src/lib.rs @@ -29,13 +29,14 @@ use sp_std::borrow::Cow; use sp_std::vec::Vec; mod app { - use app_crypto::{app_crypto, key_types::GRANDPA, ed25519}; + use sp_application_crypto::{app_crypto, key_types::GRANDPA, ed25519}; app_crypto!(ed25519, GRANDPA); } -/// The grandpa crypto scheme defined via the keypair type. -#[cfg(any(feature = "std", feature = "full_crypto"))] -pub type AuthorityPair = app::Pair; +sp_application_crypto::with_pair! { + /// The grandpa crypto scheme defined via the keypair type. + pub type AuthorityPair = app::Pair; +} /// Identity of a Grandpa authority. pub type AuthorityId = app::Public; -- GitLab From 877e193b314d42c9d77bb1740e70656b26bd0ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Sat, 15 Feb 2020 10:41:42 +0100 Subject: [PATCH 155/180] Remove rename for finalized event and add some docs. (#4930) * Remove rename for finalized event. * ADd some docs. * Document timeout. --- primitives/transaction-pool/src/pool.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/primitives/transaction-pool/src/pool.rs b/primitives/transaction-pool/src/pool.rs index 6912bc79d6..8d8ff47cbe 100644 --- a/primitives/transaction-pool/src/pool.rs +++ b/primitives/transaction-pool/src/pool.rs @@ -67,16 +67,22 @@ impl PoolStatus { /// 2. Inside `Ready` queue: /// - `Broadcast` /// 3. Leaving the pool: -/// - `Finalized` +/// - `InBlock` /// - `Invalid` /// - `Usurped` /// - `Dropped` +/// 4. Re-entering the pool: +/// - `Retracted` +/// 5. Block finalized: +/// - `Finalized` +/// - `FinalityTimeout` /// /// 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. +/// I.e. only one of the listed ones should be triggered. /// /// 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 @@ -86,8 +92,15 @@ impl PoolStatus { /// 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). +/// 4. `Retracted` transactions might be included in some next block. /// -/// However the user needs to re-subscribe to receive such notifications. +/// The stream is considered finished only when either `Finalized` or `FinalityTimeout` +/// event is triggered. You are however free to unsubscribe from notifications at any point. +/// The first one will be emitted when the block, in which transaction was included gets +/// finalized. The `FinalityTimeout` event will be emitted when the block did not reach finality +/// within 512 blocks. This either indicates that finality is not available for your chain, +/// or that finality gadget is lagging behind. If you choose to wait for finality longer, you can +/// re-subscribe for a particular transaction hash manually again. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub enum TransactionStatus { @@ -98,7 +111,6 @@ pub enum TransactionStatus { /// 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), /// The block this transaction was included in has been retracted. Retracted(BlockHash), -- GitLab From 2e8080e2902fc477bbce36512a8f5bcdc4b49f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20K=C3=B6cher?= Date: Sat, 15 Feb 2020 14:40:29 +0100 Subject: [PATCH 156/180] Remove default expansion from `construct_runtime!` (#4937) This removes the following syntactic sugar from `construct_runtime!`: - Expansion of `default` to the default set of module parts - Expansion of `System: system` to the default set of module parts The macro now requires the user to provide all the module parts of a pallet. --- bin/node-template/runtime/src/lib.rs | 2 +- bin/node/runtime/src/lib.rs | 6 +- .../procedural/src/construct_runtime/mod.rs | 4 +- .../procedural/src/construct_runtime/parse.rs | 294 ++++++++---------- frame/support/procedural/src/lib.rs | 19 +- .../default_module_invalid_arg.rs | 14 - .../default_module_invalid_arg.stderr | 5 - .../double_module_parts.rs | 2 +- .../double_module_parts_default.rs | 14 - .../double_module_parts_default.stderr | 5 - .../generics_in_invalid_module.rs | 2 +- .../invalid_module_details_keyword.stderr | 2 +- .../invalid_module_entry.rs | 2 +- .../invalid_module_entry.stderr | 2 +- .../invalid_token_after_module.stderr | 2 +- ...g_event_generic_on_module_with_instance.rs | 2 +- ..._origin_generic_on_module_with_instance.rs | 2 +- .../params_in_invalid_module.rs | 2 +- 18 files changed, 159 insertions(+), 222 deletions(-) delete mode 100644 frame/support/test/tests/construct_runtime_ui/default_module_invalid_arg.rs delete mode 100644 frame/support/test/tests/construct_runtime_ui/default_module_invalid_arg.stderr delete mode 100644 frame/support/test/tests/construct_runtime_ui/double_module_parts_default.rs delete mode 100644 frame/support/test/tests/construct_runtime_ui/double_module_parts_default.stderr diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 04394917f1..67510c4bf2 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -256,7 +256,7 @@ construct_runtime!( Indices: indices::{Module, Call, Storage, Event, Config}, Balances: balances::{Module, Call, Storage, Config, Event}, TransactionPayment: transaction_payment::{Module, Storage}, - Sudo: sudo, + Sudo: sudo::{Module, Call, Config, Storage, Event}, // Used for the module template in `./template.rs` TemplateModule: template::{Module, Call, Storage, Event}, RandomnessCollectiveFlip: randomness_collective_flip::{Module, Call, Storage}, diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 0281454215..97424950fc 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -608,7 +608,7 @@ construct_runtime!( Indices: pallet_indices::{Module, Call, Storage, Config, Event}, Balances: pallet_balances::{Module, Call, Storage, Config, Event}, TransactionPayment: pallet_transaction_payment::{Module, Storage}, - Staking: pallet_staking, + Staking: pallet_staking::{Module, Call, Config, Storage, Event}, 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}, @@ -618,8 +618,8 @@ construct_runtime!( 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, + Contracts: pallet_contracts::{Module, Call, Config, Storage, Event}, + Sudo: pallet_sudo::{Module, Call, Config, Storage, Event}, ImOnline: pallet_im_online::{Module, Call, Storage, Event, ValidateUnsigned, Config}, AuthorityDiscovery: pallet_authority_discovery::{Module, Call, Config}, Offences: pallet_offences::{Module, Call, Storage, Event}, diff --git a/frame/support/procedural/src/construct_runtime/mod.rs b/frame/support/procedural/src/construct_runtime/mod.rs index 6c14f0ecfd..942a47a533 100644 --- a/frame/support/procedural/src/construct_runtime/mod.rs +++ b/frame/support/procedural/src/construct_runtime/mod.rs @@ -217,8 +217,8 @@ fn decl_runtime_metadata<'a>( let filtered_names: Vec<_> = module_declaration .module_parts() .into_iter() - .filter(|part| part.name != "Module") - .map(|part| part.name.clone()) + .filter(|part| part.name() != "Module") + .map(|part| part.ident()) .collect(); (module_declaration, filtered_names) }) diff --git a/frame/support/procedural/src/construct_runtime/parse.rs b/frame/support/procedural/src/construct_runtime/parse.rs index 0559c45bbc..b7d60c7155 100644 --- a/frame/support/procedural/src/construct_runtime/parse.rs +++ b/frame/support/procedural/src/construct_runtime/parse.rs @@ -27,6 +27,14 @@ mod keyword { syn::custom_keyword!(Block); syn::custom_keyword!(NodeBlock); syn::custom_keyword!(UncheckedExtrinsic); + syn::custom_keyword!(Module); + syn::custom_keyword!(Call); + syn::custom_keyword!(Storage); + syn::custom_keyword!(Event); + syn::custom_keyword!(Config); + syn::custom_keyword!(Origin); + syn::custom_keyword!(Inherent); + syn::custom_keyword!(ValidateUnsigned); } #[derive(Debug)] @@ -145,7 +153,7 @@ pub struct ModuleDeclaration { pub name: Ident, pub module: Ident, pub instance: Option, - pub details: Option>>, + pub module_parts: Vec, } impl Parse for ModuleDeclaration { @@ -162,160 +170,183 @@ impl Parse for ModuleDeclaration { } else { None }; - let details = if input.peek(Token![::]) { - let _: Token![::] = input.parse()?; - Some(input.parse()?) - } else { - None - }; + + let _: Token![::] = input.parse()?; + let module_parts = parse_module_parts(input)?; + let parsed = Self { name, module, instance, - details, + module_parts, }; - 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 && 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)); - } - - 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()) - } + /// Get resolved module parts + pub fn module_parts(&self) -> &[ModulePart] { + &self.module_parts } - pub fn find_part(&self, name: &str) -> Option { - self.module_parts() - .into_iter() - .find(|part| part.name == name) + pub fn find_part(&self, name: &str) -> Option<&ModulePart> { + self.module_parts.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 +/// Parse [`ModulePart`]'s from a braces enclosed list that is split by commas, e.g. +/// +/// `{ Call, Event }` +fn parse_module_parts(input: ParseStream) -> Result> { + let module_parts :ext::Braces> = input.parse()?; + + let mut resolved = HashSet::new(); + for part in module_parts.content.inner.iter() { + if !resolved.insert(part.name()) { + let msg = format!( + "`{}` was already declared before. Please remove the duplicate declaration", + part.name(), + ); + return Err(Error::new(part.keyword.span(), msg)); + } } + + Ok(module_parts.content.inner.into_iter().collect()) } -#[derive(Debug)] -pub enum ModuleEntry { - Default(Token![default]), - Part(ModulePart), +#[derive(Debug, Clone)] +pub enum ModulePartKeyword { + Module(keyword::Module), + Call(keyword::Call), + Storage(keyword::Storage), + Event(keyword::Event), + Config(keyword::Config), + Origin(keyword::Origin), + Inherent(keyword::Inherent), + ValidateUnsigned(keyword::ValidateUnsigned), } -impl Parse for ModuleEntry { +impl Parse for ModulePartKeyword { 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()?)) + + if lookahead.peek(keyword::Module) { + Ok(Self::Module(input.parse()?)) + } else if lookahead.peek(keyword::Call) { + Ok(Self::Call(input.parse()?)) + } else if lookahead.peek(keyword::Storage) { + Ok(Self::Storage(input.parse()?)) + } else if lookahead.peek(keyword::Event) { + Ok(Self::Event(input.parse()?)) + } else if lookahead.peek(keyword::Config) { + Ok(Self::Config(input.parse()?)) + } else if lookahead.peek(keyword::Origin) { + Ok(Self::Origin(input.parse()?)) + } else if lookahead.peek(keyword::Inherent) { + Ok(Self::Inherent(input.parse()?)) + } else if lookahead.peek(keyword::ValidateUnsigned) { + Ok(Self::ValidateUnsigned(input.parse()?)) } else { Err(lookahead.error()) } } } -impl ModuleEntry { - pub fn is_default(&self) -> bool { +impl ModulePartKeyword { + /// Returns the name of `Self`. + fn name(&self) -> &'static str { + match self { + Self::Module(_) => "Module", + Self::Call(_) => "Call", + Self::Storage(_) => "Storage", + Self::Event(_) => "Event", + Self::Config(_) => "Config", + Self::Origin(_) => "Origin", + Self::Inherent(_) => "Inherent", + Self::ValidateUnsigned(_) => "ValidateUnsigned", + } + } + + /// Returns the name as `Ident`. + fn ident(&self) -> Ident { + Ident::new(self.name(), self.span()) + } + + /// Returns `true` if this module part allows to have an argument. + /// + /// For example `Inherent(Timestamp)`. + fn allows_arg(&self) -> bool { + Self::all_allow_arg().iter().any(|n| *n == self.name()) + } + + /// Returns the names of all module parts that allow to have an argument. + fn all_allow_arg() -> &'static [&'static str] { + &["Inherent"] + } + + /// Returns `true` if this module part is allowed to have generic arguments. + fn allows_generic(&self) -> bool { + Self::all_generic_arg().iter().any(|n| *n == self.name()) + } + + /// Returns the names of all module parts that allow to have a generic argument. + fn all_generic_arg() -> &'static [&'static str] { + &["Event", "Origin", "Config"] + } +} + +impl Spanned for ModulePartKeyword { + fn span(&self) -> Span { match self { - ModuleEntry::Default(_) => true, - _ => false, + Self::Module(inner) => inner.span(), + Self::Call(inner) => inner.span(), + Self::Storage(inner) => inner.span(), + Self::Event(inner) => inner.span(), + Self::Config(inner) => inner.span(), + Self::Origin(inner) => inner.span(), + Self::Inherent(inner) => inner.span(), + Self::ValidateUnsigned(inner) => inner.span(), } } } #[derive(Debug, Clone)] pub struct ModulePart { - pub name: Ident, + pub keyword: ModulePartKeyword, pub generics: syn::Generics, pub args: Option>>, } impl Parse for ModulePart { fn parse(input: ParseStream) -> Result { - let name: Ident = input.parse()?; - - if !ModulePart::all_allowed().iter().any(|n| name == n) { - return Err(syn::Error::new( - name.span(), - format!( - "Only the following modules are allowed: {}", - ModulePart::format_names(ModulePart::all_allowed()), - ), - )) - } + let keyword: ModulePartKeyword = 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()); + if !generics.params.is_empty() && !keyword.allows_generic() { + let valid_generics = ModulePart::format_names(ModulePartKeyword::all_generic_arg()); let msg = format!( "`{}` is not allowed to have generics. \ Only the following modules are allowed to have generics: {}.", - name, valid_generics + keyword.name(), + valid_generics, ); - return Err(syn::Error::new(name.span(), msg)); + return Err(syn::Error::new(keyword.span(), msg)); } let args = if input.peek(token::Paren) { - if !Self::is_allowed_arg(&name) { + if !keyword.allows_arg() { let syn::group::Parens { token: parens, .. } = syn::group::parse_parens(input)?; - let valid_names = ModulePart::format_names(ModulePart::allowed_args()); + let valid_names = ModulePart::format_names(ModulePartKeyword::all_allow_arg()); 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 + keyword.name(), + valid_names, ); return Err(syn::Error::new(parens.span, msg)); } @@ -325,7 +356,7 @@ impl Parse for ModulePart { }; Ok(Self { - name, + keyword, generics, args, }) @@ -333,70 +364,19 @@ impl Parse for ModulePart { } 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() -> &'static [&'static str] { - &["Event", "Origin", "Config"] - } - - pub fn allowed_args() -> &'static [&'static str] { - &["Inherent"] - } - - /// Returns all allowed names for module parts. - pub fn all_allowed() -> &'static [&'static str] { - &["Module", "Call", "Storage", "Event", "Config", "Origin", "Inherent", "ValidateUnsigned"] - } - pub fn format_names(names: &[&'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, - } + /// The name of this module part. + pub fn name(&self) -> &'static str { + self.keyword.name() } - /// 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, - } + /// The name of this module part as `Ident`. + pub fn ident(&self) -> Ident { + self.keyword.ident() } } diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index b4376915a2..c59d630928 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -268,8 +268,8 @@ pub fn decl_storage(input: TokenStream) -> TokenStream { /// NodeBlock = runtime::Block, /// UncheckedExtrinsic = UncheckedExtrinsic /// { -/// System: system, -/// Test: test::{default}, +/// System: system::{Module, Call, Event, Config}, +/// Test: test::{Module, Call}, /// Test2: test_with_long_module::{Module}, /// /// // Module with instances @@ -279,17 +279,12 @@ pub fn decl_storage(input: TokenStream) -> TokenStream { /// ) /// ``` /// -/// 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 identifier `System` is the name of the pallet and the lower case identifier `system` is the +/// name of the Rust module/crate for this Substrate module. The identifiers between the braces are +/// the module parts provided by the pallet. It is important to list these parts here to export +/// them correctly in the metadata or to make the pallet usable in the runtime. /// -/// 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: +/// We provide support for the following module parts in a pallet: /// /// - `Module` /// - `Call` diff --git a/frame/support/test/tests/construct_runtime_ui/default_module_invalid_arg.rs b/frame/support/test/tests/construct_runtime_ui/default_module_invalid_arg.rs deleted file mode 100644 index 92a5ffff73..0000000000 --- a/frame/support/test/tests/construct_runtime_ui/default_module_invalid_arg.rs +++ /dev/null @@ -1,14 +0,0 @@ -use frame_support::construct_runtime; - -construct_runtime! { - pub enum Runtime where - Block = Block, - NodeBlock = Block, - UncheckedExtrinsic = UncheckedExtrinsic - { - System: system, - Balance: balances::{default, Error}, - } -} - -fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/default_module_invalid_arg.stderr b/frame/support/test/tests/construct_runtime_ui/default_module_invalid_arg.stderr deleted file mode 100644 index d4a46a3491..0000000000 --- a/frame/support/test/tests/construct_runtime_ui/default_module_invalid_arg.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: Only the following modules are allowed: `Module`, `Call`, `Storage`, `Event`, `Config`, `Origin`, `Inherent`, `ValidateUnsigned` - --> $DIR/default_module_invalid_arg.rs:10:32 - | -10 | Balance: balances::{default, Error}, - | ^^^^^ 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 index 0907f0bfb3..ec37456e58 100644 --- a/frame/support/test/tests/construct_runtime_ui/double_module_parts.rs +++ b/frame/support/test/tests/construct_runtime_ui/double_module_parts.rs @@ -6,7 +6,7 @@ construct_runtime! { NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system, + System: system::{Module}, 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 deleted file mode 100644 index 3d61abebe8..0000000000 --- a/frame/support/test/tests/construct_runtime_ui/double_module_parts_default.rs +++ /dev/null @@ -1,14 +0,0 @@ -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 deleted file mode 100644 index d8205acc4a..0000000000 --- a/frame/support/test/tests/construct_runtime_ui/double_module_parts_default.stderr +++ /dev/null @@ -1,5 +0,0 @@ -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 index 5a9a4612ed..b79d73ff5c 100644 --- 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 @@ -6,7 +6,7 @@ construct_runtime! { NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system, + System: system::{Module}, Balance: balances::::{Call, Origin}, } } 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 index 4441f6dc0f..66c9fc95cb 100644 --- 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 @@ -1,4 +1,4 @@ -error: expected `default` or identifier +error: expected one of: `Module`, `Call`, `Storage`, `Event`, `Config`, `Origin`, `Inherent`, `ValidateUnsigned` --> $DIR/invalid_module_details_keyword.rs:9:20 | 9 | system: System::{enum}, diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_module_entry.rs b/frame/support/test/tests/construct_runtime_ui/invalid_module_entry.rs index db1250cdf4..3754d41d6e 100644 --- a/frame/support/test/tests/construct_runtime_ui/invalid_module_entry.rs +++ b/frame/support/test/tests/construct_runtime_ui/invalid_module_entry.rs @@ -6,7 +6,7 @@ construct_runtime! { NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system, + System: system::{Module}, Balance: balances::{Error}, } } diff --git a/frame/support/test/tests/construct_runtime_ui/invalid_module_entry.stderr b/frame/support/test/tests/construct_runtime_ui/invalid_module_entry.stderr index da38a82d7e..7442c6be3a 100644 --- a/frame/support/test/tests/construct_runtime_ui/invalid_module_entry.stderr +++ b/frame/support/test/tests/construct_runtime_ui/invalid_module_entry.stderr @@ -1,4 +1,4 @@ -error: Only the following modules are allowed: `Module`, `Call`, `Storage`, `Event`, `Config`, `Origin`, `Inherent`, `ValidateUnsigned` +error: expected one of: `Module`, `Call`, `Storage`, `Event`, `Config`, `Origin`, `Inherent`, `ValidateUnsigned` --> $DIR/invalid_module_entry.rs:10:23 | 10 | Balance: balances::{Error}, 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 index 8a6f15f791..3b967f96d7 100644 --- 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 @@ -1,4 +1,4 @@ -error: expected `,` +error: expected `::` --> $DIR/invalid_token_after_module.rs:9:18 | 9 | system: System ? 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 index 928871fab2..5eb7df5d18 100644 --- 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 @@ -6,7 +6,7 @@ construct_runtime! { NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system, + System: system::{Module}, Balance: balances::::{Event}, } } 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 index 35a5c8201b..5e44ae84d8 100644 --- 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 @@ -6,7 +6,7 @@ construct_runtime! { NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system, + System: system::{Module}, Balance: balances::::{Origin}, } } 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 index a739277d62..9c752a2f39 100644 --- 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 @@ -6,7 +6,7 @@ construct_runtime! { NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system, + System: system::{Module}, Balance: balances::::{Call(toto), Origin}, } } -- GitLab From f3acdac75e291ce079e4b85a52e88ae9e7b7bb78 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Mon, 17 Feb 2020 10:18:53 +0100 Subject: [PATCH 157/180] Refactor BlockImportParams to be non_exhaustive (#4936) * Refactor BlockImportParams to be non_exhaustive * Fix cargo check compile --- bin/node/cli/src/service.rs | 31 ++-- bin/node/testing/benches/import.rs | 19 +-- bin/node/transaction-factory/src/lib.rs | 17 +-- client/consensus/aura/src/lib.rs | 47 ++---- client/consensus/babe/src/lib.rs | 62 +++----- client/consensus/babe/src/tests.rs | 33 ++-- client/consensus/manual-seal/src/lib.rs | 19 +-- .../manual-seal/src/seal_new_block.rs | 18 +-- client/consensus/pow/src/lib.rs | 68 +++------ client/consensus/slots/src/lib.rs | 4 +- client/finality-grandpa/src/import.rs | 2 +- client/finality-grandpa/src/light_import.rs | 23 +-- client/finality-grandpa/src/tests.rs | 59 ++------ client/network/test/src/lib.rs | 20 +-- .../consensus/common/src/block_import.rs | 61 ++++---- test-utils/client/src/client_ext.rs | 142 ++++-------------- 16 files changed, 187 insertions(+), 438 deletions(-) diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index a88f2d1add..dd2684d50e 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -369,7 +369,7 @@ pub fn new_light(config: NodeConfiguration) #[cfg(test)] mod tests { - use std::{sync::Arc, collections::HashMap, borrow::Cow, any::Any}; + use std::{sync::Arc, borrow::Cow, any::Any}; use sc_consensus_babe::{ CompatibleDigestItem, BabeIntermediate, INTERMEDIATE_KEY }; @@ -557,27 +557,14 @@ mod tests { ); slot_num += 1; - let params = BlockImportParams { - origin: BlockOrigin::File, - header: new_header, - justification: None, - post_digests: vec![item], - body: Some(new_body), - storage_changes: None, - finalized: false, - auxiliary: Vec::new(), - intermediates: { - let mut intermediates = HashMap::new(); - intermediates.insert( - Cow::from(INTERMEDIATE_KEY), - Box::new(BabeIntermediate { epoch }) as Box, - ); - intermediates - }, - fork_choice: Some(ForkChoiceStrategy::LongestChain), - allow_missing_state: false, - import_existing: false, - }; + let mut params = BlockImportParams::new(BlockOrigin::File, new_header); + params.post_digests.push(item); + params.body = Some(new_body); + params.intermediates.insert( + Cow::from(INTERMEDIATE_KEY), + Box::new(BabeIntermediate { epoch }) as Box, + ); + params.fork_choice = Some(ForkChoiceStrategy::LongestChain); block_import.import_block(params, Default::default()) .expect("error importing test block"); diff --git a/bin/node/testing/benches/import.rs b/bin/node/testing/benches/import.rs index 86092a7836..8c8439fc92 100644 --- a/bin/node/testing/benches/import.rs +++ b/bin/node/testing/benches/import.rs @@ -358,20 +358,9 @@ fn generate_block_import(client: &Client, keyring: &BenchKeyring) -> Block { // Import generated block. fn import_block(client: &mut Client, block: Block) { - let import_params = BlockImportParams { - origin: BlockOrigin::NetworkBroadcast, - header: block.header().clone(), - post_digests: Default::default(), - body: Some(block.extrinsics().to_vec()), - storage_changes: Default::default(), - finalized: false, - justification: Default::default(), - auxiliary: Default::default(), - intermediates: Default::default(), - fork_choice: Some(ForkChoiceStrategy::LongestChain), - allow_missing_state: false, - import_existing: false, - }; + let mut import_params = BlockImportParams::new(BlockOrigin::NetworkBroadcast, block.header.clone()); + import_params.body = Some(block.extrinsics().to_vec()); + import_params.fork_choice = Some(ForkChoiceStrategy::LongestChain); assert_eq!(client.chain_info().best_number, 0); @@ -500,4 +489,4 @@ fn profile_block_import(c: &mut Criterion) { ); }, ); -} \ No newline at end of file +} diff --git a/bin/node/transaction-factory/src/lib.rs b/bin/node/transaction-factory/src/lib.rs index acee44625f..7dafeed406 100644 --- a/bin/node/transaction-factory/src/lib.rs +++ b/bin/node/transaction-factory/src/lib.rs @@ -156,20 +156,9 @@ where best_hash = block.header().hash(); best_block_id = BlockId::::hash(best_hash); - let import = BlockImportParams { - origin: BlockOrigin::File, - header: block.header().clone(), - post_digests: Vec::new(), - body: Some(block.extrinsics().to_vec()), - storage_changes: None, - finalized: false, - justification: None, - auxiliary: Vec::new(), - intermediates: Default::default(), - fork_choice: Some(ForkChoiceStrategy::LongestChain), - allow_missing_state: false, - import_existing: false, - }; + let mut import = BlockImportParams::new(BlockOrigin::File, block.header().clone()); + import.body = Some(block.extrinsics().to_vec()); + import.fork_choice = Some(ForkChoiceStrategy::LongestChain); client.clone().import_block(import, HashMap::new()).expect("Failed to import block"); info!("Imported block at {}", factory_state.block_number()); diff --git a/client/consensus/aura/src/lib.rs b/client/consensus/aura/src/lib.rs index 434314a853..db872f28c1 100644 --- a/client/consensus/aura/src/lib.rs +++ b/client/consensus/aura/src/lib.rs @@ -282,20 +282,13 @@ impl sc_consensus_slots::SimpleSlotWorker for AuraW let signature = pair.sign(header_hash.as_ref()); let signature_digest_item = as CompatibleDigestItem

>::aura_seal(signature); - BlockImportParams { - origin: BlockOrigin::Own, - header, - justification: None, - post_digests: vec![signature_digest_item], - body: Some(body), - storage_changes: Some(storage_changes), - finalized: false, - auxiliary: Vec::new(), - intermediates: Default::default(), - fork_choice: Some(ForkChoiceStrategy::LongestChain), - allow_missing_state: false, - import_existing: false, - } + let mut import_block = BlockImportParams::new(BlockOrigin::Own, header); + import_block.post_digests.push(signature_digest_item); + import_block.body = Some(body); + import_block.storage_changes = Some(storage_changes); + import_block.fork_choice = Some(ForkChoiceStrategy::LongestChain); + + import_block }) } @@ -637,22 +630,14 @@ impl Verifier for AuraVerifier where _ => None, }); - let block_import_params = BlockImportParams { - origin, - header: pre_header, - post_digests: vec![seal], - body, - storage_changes: None, - finalized: false, - justification, - auxiliary: Vec::new(), - intermediates: Default::default(), - fork_choice: Some(ForkChoiceStrategy::LongestChain), - allow_missing_state: false, - import_existing: false, - }; - - Ok((block_import_params, maybe_keys)) + let mut import_block = BlockImportParams::new(origin, pre_header); + import_block.post_digests.push(seal); + import_block.body = body; + import_block.justification = justification; + import_block.fork_choice = Some(ForkChoiceStrategy::LongestChain); + import_block.post_hash = Some(hash); + + Ok((import_block, maybe_keys)) } CheckedHeader::Deferred(a, b) => { debug!(target: "aura", "Checking {:?} failed; {:?}, {:?}.", hash, a, b); @@ -790,7 +775,7 @@ impl BlockImport for AuraBlockImport, new_cache: HashMap>, ) -> Result { - let hash = block.post_header().hash(); + let hash = block.post_hash(); let slot_number = find_pre_digest::(&block.header) .expect("valid Aura headers must contain a predigest; \ header has been already verified; qed"); diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index f9e3ef98d6..51ea37f6d5 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -487,27 +487,16 @@ impl sc_consensus_slots::SimpleSlotWorker for BabeWork let signature = pair.sign(header_hash.as_ref()); let digest_item = as CompatibleDigestItem>::babe_seal(signature); - BlockImportParams { - origin: BlockOrigin::Own, - header, - justification: None, - post_digests: vec![digest_item], - body: Some(body), - storage_changes: Some(storage_changes), - finalized: false, - auxiliary: Vec::new(), // block-weight is written in block import. - intermediates: { - let mut intermediates = HashMap::new(); - intermediates.insert( - Cow::from(INTERMEDIATE_KEY), - Box::new(BabeIntermediate { epoch }) as Box, - ); - intermediates - }, - fork_choice: None, - allow_missing_state: false, - import_existing: false, - } + let mut import_block = BlockImportParams::new(BlockOrigin::Own, header); + import_block.post_digests.push(digest_item); + import_block.body = Some(body); + import_block.storage_changes = Some(storage_changes); + import_block.intermediates.insert( + Cow::from(INTERMEDIATE_KEY), + Box::new(BabeIntermediate { epoch }) as Box, + ); + + import_block }) } @@ -861,30 +850,17 @@ impl Verifier for BabeVerifier ?pre_header); - let mut intermediates = HashMap::new(); - intermediates.insert( + let mut import_block = BlockImportParams::new(origin, pre_header); + import_block.post_digests.push(verified_info.seal); + import_block.body = body; + import_block.justification = justification; + import_block.intermediates.insert( Cow::from(INTERMEDIATE_KEY), - Box::new(BabeIntermediate { - epoch, - }) as Box, + Box::new(BabeIntermediate { epoch }) as Box, ); + import_block.post_hash = Some(hash); - let block_import_params = BlockImportParams { - origin, - header: pre_header, - post_digests: vec![verified_info.seal], - body, - storage_changes: None, - finalized: false, - justification, - auxiliary: Vec::new(), - intermediates, - fork_choice: None, - allow_missing_state: false, - import_existing: false, - }; - - Ok((block_import_params, Default::default())) + Ok((import_block, Default::default())) } CheckedHeader::Deferred(a, b) => { debug!(target: "babe", "Checking {:?} failed; {:?}, {:?}.", hash, a, b); @@ -981,7 +957,7 @@ impl BlockImport for BabeBlockImport, new_cache: HashMap>, ) -> Result { - let hash = block.post_header().hash(); + let hash = block.post_hash(); let number = block.header.number().clone(); // early exit if block already in chain, otherwise the check for diff --git a/client/consensus/babe/src/tests.rs b/client/consensus/babe/src/tests.rs index 687f23e646..1151b82d2e 100644 --- a/client/consensus/babe/src/tests.rs +++ b/client/consensus/babe/src/tests.rs @@ -593,30 +593,15 @@ fn propose_and_import_block( h }; - let import_result = block_import.import_block( - BlockImportParams { - origin: BlockOrigin::Own, - header: block.header, - justification: None, - post_digests: vec![seal], - body: Some(block.extrinsics), - storage_changes: None, - finalized: false, - auxiliary: Vec::new(), - intermediates: { - let mut intermediates = HashMap::new(); - intermediates.insert( - Cow::from(INTERMEDIATE_KEY), - Box::new(BabeIntermediate { epoch }) as Box, - ); - intermediates - }, - fork_choice: Some(ForkChoiceStrategy::LongestChain), - allow_missing_state: false, - import_existing: false, - }, - Default::default(), - ).unwrap(); + let mut import = BlockImportParams::new(BlockOrigin::Own, block.header); + import.post_digests.push(seal); + import.body = Some(block.extrinsics); + import.intermediates.insert( + Cow::from(INTERMEDIATE_KEY), + Box::new(BabeIntermediate { epoch }) as Box, + ); + import.fork_choice = Some(ForkChoiceStrategy::LongestChain); + let import_result = block_import.import_block(import, Default::default()).unwrap(); match import_result { ImportResult::Imported(_) => {}, diff --git a/client/consensus/manual-seal/src/lib.rs b/client/consensus/manual-seal/src/lib.rs index c820407e74..a334e7c72f 100644 --- a/client/consensus/manual-seal/src/lib.rs +++ b/client/consensus/manual-seal/src/lib.rs @@ -89,20 +89,11 @@ impl Verifier for ManualSealVerifier { justification: Option, body: Option>, ) -> Result<(BlockImportParams, Option)>>), String> { - let import_params = BlockImportParams { - origin, - header, - justification, - post_digests: Vec::new(), - body, - storage_changes: None, - finalized: true, - auxiliary: Vec::new(), - intermediates: HashMap::new(), - fork_choice: Some(ForkChoiceStrategy::LongestChain), - allow_missing_state: false, - import_existing: false, - }; + let mut import_params = BlockImportParams::new(origin, header); + import_params.justification = justification; + import_params.body = body; + import_params.finalized = true; + import_params.fork_choice = Some(ForkChoiceStrategy::LongestChain); Ok((import_params, None)) } diff --git a/client/consensus/manual-seal/src/seal_new_block.rs b/client/consensus/manual-seal/src/seal_new_block.rs index 2b8d867ce3..39d73e16ab 100644 --- a/client/consensus/manual-seal/src/seal_new_block.rs +++ b/client/consensus/manual-seal/src/seal_new_block.rs @@ -121,20 +121,10 @@ pub async fn seal_new_block( } let (header, body) = proposal.block.deconstruct(); - let params = BlockImportParams { - origin: BlockOrigin::Own, - header: header.clone(), - justification: None, - post_digests: Vec::new(), - body: Some(body), - finalized: finalize, - storage_changes: None, - auxiliary: Vec::new(), - intermediates: HashMap::new(), - fork_choice: Some(ForkChoiceStrategy::LongestChain), - allow_missing_state: false, - import_existing: false, - }; + let mut params = BlockImportParams::new(BlockOrigin::Own, header.clone()); + params.body = Some(body); + params.finalized = finalize; + params.fork_choice = Some(ForkChoiceStrategy::LongestChain); match block_import.import_block(params, HashMap::new())? { ImportResult::Imported(aux) => { diff --git a/client/consensus/pow/src/lib.rs b/client/consensus/pow/src/lib.rs index d656f71a15..49d2e64f60 100644 --- a/client/consensus/pow/src/lib.rs +++ b/client/consensus/pow/src/lib.rs @@ -111,9 +111,7 @@ fn aux_key>(hash: &T) -> Vec { /// Intermediate value passed to block importer. #[derive(Encode, Decode, Clone, Debug, Default)] -pub struct PowIntermediate { - /// The header hash with seal, used for auxiliary key. - pub hash: B::Hash, +pub struct PowIntermediate { /// Difficulty of the block, if known. pub difficulty: Option, } @@ -331,7 +329,7 @@ impl BlockImport for PowBlockImport return Err(Error::::HeaderUnsealed(block.header.hash()).into()), }; - let intermediate = block.take_intermediate::>( + let intermediate = block.take_intermediate::>( INTERMEDIATE_KEY )?; @@ -353,7 +351,7 @@ impl BlockImport for PowBlockImport Verifier for PowVerifier where let hash = header.hash(); let (checked_header, seal) = self.check_header(header)?; - let intermediate = PowIntermediate:: { - hash: hash, + let intermediate = PowIntermediate:: { difficulty: None, }; - let import_block = BlockImportParams { - origin, - header: checked_header, - post_digests: vec![seal], - body, - storage_changes: None, - finalized: false, - justification, - intermediates: { - let mut ret = HashMap::new(); - ret.insert(Cow::from(INTERMEDIATE_KEY), Box::new(intermediate) as Box); - ret - }, - auxiliary: vec![], - fork_choice: None, - allow_missing_state: false, - import_existing: false, - }; + let mut import_block = BlockImportParams::new(origin, checked_header); + import_block.post_digests.push(seal); + import_block.body = body; + import_block.justification = justification; + import_block.intermediates.insert( + Cow::from(INTERMEDIATE_KEY), + Box::new(intermediate) as Box + ); + import_block.post_hash = Some(hash); Ok((import_block, None)) } @@ -661,29 +649,19 @@ fn mine_loop( (hash, seal) }; - let intermediate = PowIntermediate:: { - hash, + let intermediate = PowIntermediate:: { difficulty: Some(difficulty), }; - let import_block = BlockImportParams { - origin: BlockOrigin::Own, - header, - justification: None, - post_digests: vec![seal], - body: Some(body), - storage_changes: Some(proposal.storage_changes), - intermediates: { - let mut ret = HashMap::new(); - ret.insert(Cow::from(INTERMEDIATE_KEY), Box::new(intermediate) as Box); - ret - }, - finalized: false, - auxiliary: vec![], - fork_choice: None, - allow_missing_state: false, - import_existing: false, - }; + let mut import_block = BlockImportParams::new(BlockOrigin::Own, header); + import_block.post_digests.push(seal); + import_block.body = Some(body); + import_block.storage_changes = Some(proposal.storage_changes); + import_block.intermediates.insert( + Cow::from(INTERMEDIATE_KEY), + Box::new(intermediate) as Box + ); + import_block.post_hash = Some(hash); block_import.import_block(import_block, HashMap::default()) .map_err(|e| Error::BlockBuiltError(best_hash, e))?; diff --git a/client/consensus/slots/src/lib.rs b/client/consensus/slots/src/lib.rs index 8bc2547a49..892c8b1364 100644 --- a/client/consensus/slots/src/lib.rs +++ b/client/consensus/slots/src/lib.rs @@ -287,13 +287,13 @@ pub trait SimpleSlotWorker { info!( "Pre-sealed block for proposal at {}. Hash now {:?}, previously {:?}.", header_num, - block_import_params.post_header().hash(), + block_import_params.post_hash(), header_hash, ); telemetry!(CONSENSUS_INFO; "slots.pre_sealed_block"; "header_num" => ?header_num, - "hash_now" => ?block_import_params.post_header().hash(), + "hash_now" => ?block_import_params.post_hash(), "hash_previously" => ?header_hash, ); diff --git a/client/finality-grandpa/src/import.rs b/client/finality-grandpa/src/import.rs index 64fc62bfe7..2eb1b4a7c8 100644 --- a/client/finality-grandpa/src/import.rs +++ b/client/finality-grandpa/src/import.rs @@ -398,7 +398,7 @@ impl BlockImport mut block: BlockImportParams, new_cache: HashMap>, ) -> Result { - let hash = block.post_header().hash(); + let hash = block.post_hash(); let number = block.header.number().clone(); // early exit if block already in chain, otherwise the check for diff --git a/client/finality-grandpa/src/light_import.rs b/client/finality-grandpa/src/light_import.rs index 4ae35167be..0181a93f10 100644 --- a/client/finality-grandpa/src/light_import.rs +++ b/client/finality-grandpa/src/light_import.rs @@ -257,7 +257,7 @@ fn do_import_block( DigestFor: Encode, J: ProvableJustification, { - let hash = block.post_header().hash(); + let hash = block.post_hash(); let number = block.header.number().clone(); // we don't want to finalize on `inner.import_block` @@ -682,26 +682,19 @@ pub mod tests { authority_set: LightAuthoritySet::genesis(vec![(AuthorityId::from_slice(&[1; 32]), 1)]), consensus_changes: ConsensusChanges::empty(), }; - let block = BlockImportParams { - origin: BlockOrigin::Own, - header: Header { + let mut block = BlockImportParams::new( + BlockOrigin::Own, + Header { number: 1, parent_hash: client.chain_info().best_hash, state_root: Default::default(), digest: Default::default(), extrinsics_root: Default::default(), }, - justification, - post_digests: Vec::new(), - body: None, - storage_changes: None, - finalized: false, - auxiliary: Vec::new(), - intermediates: Default::default(), - fork_choice: Some(ForkChoiceStrategy::LongestChain), - allow_missing_state: true, - import_existing: false, - }; + ); + block.justification = justification; + block.fork_choice = Some(ForkChoiceStrategy::LongestChain); + do_import_block::<_, _, _, TestJustification>( &client, &mut import_data, diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index cf340c6954..71cc72b059 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -1011,20 +1011,11 @@ fn allows_reimporting_change_blocks() { let block = || { let block = block.clone(); - BlockImportParams { - origin: BlockOrigin::File, - header: block.header, - justification: None, - post_digests: Vec::new(), - body: Some(block.extrinsics), - storage_changes: None, - finalized: false, - auxiliary: Vec::new(), - intermediates: Default::default(), - fork_choice: Some(ForkChoiceStrategy::LongestChain), - allow_missing_state: false, - import_existing: false, - } + let mut import = BlockImportParams::new(BlockOrigin::File, block.header); + import.body = Some(block.extrinsics); + import.fork_choice = Some(ForkChoiceStrategy::LongestChain); + + import }; assert_eq!( @@ -1071,20 +1062,12 @@ fn test_bad_justification() { let block = || { let block = block.clone(); - BlockImportParams { - origin: BlockOrigin::File, - header: block.header, - justification: Some(Vec::new()), - post_digests: Vec::new(), - body: Some(block.extrinsics), - storage_changes: None, - finalized: false, - auxiliary: Vec::new(), - intermediates: Default::default(), - fork_choice: Some(ForkChoiceStrategy::LongestChain), - allow_missing_state: false, - import_existing: false, - } + let mut import = BlockImportParams::new(BlockOrigin::File, block.header); + import.justification = Some(Vec::new()); + import.body = Some(block.extrinsics); + import.fork_choice = Some(ForkChoiceStrategy::LongestChain); + + import }; assert_eq!( @@ -1805,23 +1788,13 @@ fn imports_justification_for_regular_blocks_on_import() { }; // we import the block with justification attached - let block = BlockImportParams { - origin: BlockOrigin::File, - header: block.header, - justification: Some(justification.encode()), - post_digests: Vec::new(), - body: Some(block.extrinsics), - storage_changes: None, - finalized: false, - auxiliary: Vec::new(), - intermediates: Default::default(), - fork_choice: Some(ForkChoiceStrategy::LongestChain), - allow_missing_state: false, - import_existing: false, - }; + let mut import = BlockImportParams::new(BlockOrigin::File, block.header); + import.justification = Some(justification.encode()); + import.body = Some(block.extrinsics); + import.fork_choice = Some(ForkChoiceStrategy::LongestChain); assert_eq!( - block_import.import_block(block, HashMap::new()).unwrap(), + block_import.import_block(import, HashMap::new()).unwrap(), ImportResult::Imported(ImportedAux { needs_justification: false, clear_justification_requests: false, diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 22e340a2a8..94a64732e9 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -85,21 +85,13 @@ impl Verifier for PassThroughVerifier { .or_else(|| l.try_as_raw(OpaqueDigestItemId::Consensus(b"babe"))) ) .map(|blob| vec![(well_known_cache_keys::AUTHORITIES, blob.to_vec())]); + let mut import = BlockImportParams::new(origin, header); + import.body = body; + import.finalized = self.0; + import.justification = justification; + import.fork_choice = Some(ForkChoiceStrategy::LongestChain); - Ok((BlockImportParams { - origin, - header, - body, - storage_changes: None, - finalized: self.0, - justification, - post_digests: vec![], - auxiliary: Vec::new(), - intermediates: Default::default(), - fork_choice: Some(ForkChoiceStrategy::LongestChain), - allow_missing_state: false, - import_existing: false, - }, maybe_keys)) + Ok((import, maybe_keys)) } } diff --git a/primitives/consensus/common/src/block_import.rs b/primitives/consensus/common/src/block_import.rs index dabe6331e8..76655acbd6 100644 --- a/primitives/consensus/common/src/block_import.rs +++ b/primitives/consensus/common/src/block_import.rs @@ -113,6 +113,7 @@ pub struct BlockCheckParams { } /// Data required to import a Block. +#[non_exhaustive] pub struct BlockImportParams { /// Origin of the Block pub origin: BlockOrigin, @@ -162,46 +163,47 @@ pub struct BlockImportParams { pub allow_missing_state: bool, /// Re-validate existing block. pub import_existing: bool, + /// Cached full header hash (with post-digests applied). + pub post_hash: Option, } impl BlockImportParams { - /// Deconstruct the justified header into parts. - pub fn into_inner(self) - -> ( - BlockOrigin, - ::Header, - Option, - Vec>, - Option>, - Option, NumberFor>>, - bool, - Vec<(Vec, Option>)>, - ) { - ( - self.origin, - self.header, - self.justification, - self.post_digests, - self.body, - self.storage_changes, - self.finalized, - self.auxiliary, - ) + /// Create a new block import params. + pub fn new( + origin: BlockOrigin, + header: Block::Header, + ) -> Self { + Self { + origin, header, + justification: None, + post_digests: Vec::new(), + body: None, + storage_changes: None, + finalized: false, + intermediates: HashMap::new(), + auxiliary: Vec::new(), + fork_choice: None, + allow_missing_state: false, + import_existing: false, + post_hash: None, + } } - /// Get a handle to full header (with post-digests applied). - pub fn post_header(&self) -> Cow { - if self.post_digests.is_empty() { - Cow::Borrowed(&self.header) + /// Get the full header hash (with post-digests applied). + pub fn post_hash(&self) -> Block::Hash { + if let Some(hash) = self.post_hash { + hash } else { - Cow::Owned({ + if self.post_digests.is_empty() { + self.header.hash() + } else { let mut hdr = self.header.clone(); for digest_item in &self.post_digests { hdr.digest_mut().push(digest_item.clone()); } - hdr - }) + hdr.hash() + } } } @@ -223,6 +225,7 @@ impl BlockImportParams { allow_missing_state: self.allow_missing_state, fork_choice: self.fork_choice, import_existing: self.import_existing, + post_hash: self.post_hash, } } diff --git a/test-utils/client/src/client_ext.rs b/test-utils/client/src/client_ext.rs index e29ee787d0..6d6b539483 100644 --- a/test-utils/client/src/client_ext.rs +++ b/test-utils/client/src/client_ext.rs @@ -87,60 +87,28 @@ impl ClientBlockImportExt for std::sync::A { fn import(&mut self, origin: BlockOrigin, block: Block) -> Result<(), ConsensusError> { let (header, extrinsics) = block.deconstruct(); - let import = BlockImportParams { - origin, - header, - justification: None, - post_digests: vec![], - body: Some(extrinsics), - storage_changes: None, - finalized: false, - auxiliary: Vec::new(), - intermediates: Default::default(), - fork_choice: Some(ForkChoiceStrategy::LongestChain), - allow_missing_state: false, - import_existing: false, - }; + let mut import = BlockImportParams::new(origin, header); + import.body = Some(extrinsics); + import.fork_choice = Some(ForkChoiceStrategy::LongestChain); BlockImport::import_block(self, import, HashMap::new()).map(|_| ()) } fn import_as_best(&mut self, origin: BlockOrigin, block: Block) -> Result<(), ConsensusError> { let (header, extrinsics) = block.deconstruct(); - let import = BlockImportParams { - origin, - header, - justification: None, - post_digests: vec![], - body: Some(extrinsics), - storage_changes: None, - finalized: false, - auxiliary: Vec::new(), - intermediates: Default::default(), - fork_choice: Some(ForkChoiceStrategy::Custom(true)), - allow_missing_state: false, - import_existing: false, - }; + let mut import = BlockImportParams::new(origin, header); + import.body = Some(extrinsics); + import.fork_choice = Some(ForkChoiceStrategy::Custom(true)); BlockImport::import_block(self, import, HashMap::new()).map(|_| ()) } fn import_as_final(&mut self, origin: BlockOrigin, block: Block) -> Result<(), ConsensusError> { let (header, extrinsics) = block.deconstruct(); - let import = BlockImportParams { - origin, - header, - justification: None, - post_digests: vec![], - body: Some(extrinsics), - storage_changes: None, - finalized: true, - auxiliary: Vec::new(), - intermediates: Default::default(), - fork_choice: Some(ForkChoiceStrategy::Custom(true)), - allow_missing_state: false, - import_existing: false, - }; + let mut import = BlockImportParams::new(origin, header); + import.body = Some(extrinsics); + import.finalized = true; + import.fork_choice = Some(ForkChoiceStrategy::Custom(true)); BlockImport::import_block(self, import, HashMap::new()).map(|_| ()) } @@ -152,20 +120,11 @@ impl ClientBlockImportExt for std::sync::A justification: Justification, ) -> Result<(), ConsensusError> { let (header, extrinsics) = block.deconstruct(); - let import = BlockImportParams { - origin, - header, - justification: Some(justification), - post_digests: vec![], - body: Some(extrinsics), - storage_changes: None, - finalized: true, - auxiliary: Vec::new(), - intermediates: Default::default(), - fork_choice: Some(ForkChoiceStrategy::LongestChain), - allow_missing_state: false, - import_existing: false, - }; + let mut import = BlockImportParams::new(origin, header); + import.justification = Some(justification); + import.body = Some(extrinsics); + import.finalized = true; + import.fork_choice = Some(ForkChoiceStrategy::LongestChain); BlockImport::import_block(self, import, HashMap::new()).map(|_| ()) } @@ -177,60 +136,28 @@ impl ClientBlockImportExt for Client Result<(), ConsensusError> { let (header, extrinsics) = block.deconstruct(); - let import = BlockImportParams { - origin, - header, - justification: None, - post_digests: vec![], - body: Some(extrinsics), - storage_changes: None, - finalized: false, - auxiliary: Vec::new(), - intermediates: Default::default(), - fork_choice: Some(ForkChoiceStrategy::LongestChain), - allow_missing_state: false, - import_existing: false, - }; + let mut import = BlockImportParams::new(origin, header); + import.body = Some(extrinsics); + import.fork_choice = Some(ForkChoiceStrategy::LongestChain); BlockImport::import_block(self, import, HashMap::new()).map(|_| ()) } fn import_as_best(&mut self, origin: BlockOrigin, block: Block) -> Result<(), ConsensusError> { let (header, extrinsics) = block.deconstruct(); - let import = BlockImportParams { - origin, - header, - justification: None, - post_digests: vec![], - body: Some(extrinsics), - storage_changes: None, - finalized: false, - auxiliary: Vec::new(), - intermediates: Default::default(), - fork_choice: Some(ForkChoiceStrategy::Custom(true)), - allow_missing_state: false, - import_existing: false, - }; + let mut import = BlockImportParams::new(origin, header); + import.body = Some(extrinsics); + import.fork_choice = Some(ForkChoiceStrategy::Custom(true)); BlockImport::import_block(self, import, HashMap::new()).map(|_| ()) } fn import_as_final(&mut self, origin: BlockOrigin, block: Block) -> Result<(), ConsensusError> { let (header, extrinsics) = block.deconstruct(); - let import = BlockImportParams { - origin, - header, - justification: None, - post_digests: vec![], - body: Some(extrinsics), - storage_changes: None, - finalized: true, - auxiliary: Vec::new(), - intermediates: Default::default(), - fork_choice: Some(ForkChoiceStrategy::Custom(true)), - allow_missing_state: false, - import_existing: false, - }; + let mut import = BlockImportParams::new(origin, header); + import.body = Some(extrinsics); + import.finalized = true; + import.fork_choice = Some(ForkChoiceStrategy::Custom(true)); BlockImport::import_block(self, import, HashMap::new()).map(|_| ()) } @@ -242,20 +169,11 @@ impl ClientBlockImportExt for Client Result<(), ConsensusError> { let (header, extrinsics) = block.deconstruct(); - let import = BlockImportParams { - origin, - header, - justification: Some(justification), - post_digests: vec![], - body: Some(extrinsics), - storage_changes: None, - finalized: true, - auxiliary: Vec::new(), - intermediates: Default::default(), - fork_choice: Some(ForkChoiceStrategy::LongestChain), - allow_missing_state: false, - import_existing: false, - }; + let mut import = BlockImportParams::new(origin, header); + import.justification = Some(justification); + import.body = Some(extrinsics); + import.finalized = true; + import.fork_choice = Some(ForkChoiceStrategy::LongestChain); BlockImport::import_block(self, import, HashMap::new()).map(|_| ()) } -- GitLab From 579ea21495b27b3139ff67f8f7b29d56d5a53c07 Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Mon, 17 Feb 2020 10:49:40 +0100 Subject: [PATCH 158/180] Fix import queue thread pool shutdown (#4929) * Fix import queue thread pool shutdown * Make sure runtime is disposed before telemetry * Close channel istead of sending a message * Fixed test --- client/cli/src/runtime.rs | 2 + client/consensus/babe/src/tests.rs | 11 +++++- client/network/test/src/lib.rs | 38 +++++++++++++------ .../common/src/import_queue/basic_queue.rs | 36 +++++++++++++++++- .../common/src/import_queue/buffered_link.rs | 5 +++ 5 files changed, 78 insertions(+), 14 deletions(-) diff --git a/client/cli/src/runtime.rs b/client/cli/src/runtime.rs index 157b75f205..eccf240f20 100644 --- a/client/cli/src/runtime.rs +++ b/client/cli/src/runtime.rs @@ -128,12 +128,14 @@ where // we eagerly drop the service so that the internal exit future is fired, // but we need to keep holding a reference to the global telemetry guard + // and drop the runtime first. let _telemetry = service.telemetry(); let f = service.fuse(); pin_mut!(f); runtime.block_on(main(f)).map_err(|e| e.to_string())?; + drop(runtime); Ok(()) } diff --git a/client/consensus/babe/src/tests.rs b/client/consensus/babe/src/tests.rs index 1151b82d2e..67e9d707cf 100644 --- a/client/consensus/babe/src/tests.rs +++ b/client/consensus/babe/src/tests.rs @@ -229,7 +229,7 @@ impl Verifier for TestVerifier { ) -> Result<(BlockImportParams, Option)>>), String> { // apply post-sealing mutations (i.e. stripping seal, if desired). (self.mutator)(&mut header, Stage::PostSeal); - Ok(self.inner.verify(origin, header, justification, body).expect("verification failed!")) + self.inner.verify(origin, header, justification, body) } } @@ -423,7 +423,14 @@ fn run_one_test( } runtime.spawn(futures01::future::poll_fn(move || { - net.lock().poll(); + let mut net = net.lock(); + net.poll(); + for p in net.peers() { + for (h, e) in p.failed_verifications() { + panic!("Verification failed for {:?}: {}", h, e); + } + } + Ok::<_, ()>(futures01::Async::NotReady::<()>) })); diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 94a64732e9..82d1737e9e 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -183,7 +183,7 @@ pub struct Peer> { client: PeersClient, /// We keep a copy of the verifier so that we can invoke it for locally-generated blocks, /// instead of going through the import queue. - verifier: VerifierAdapter>, + verifier: VerifierAdapter, /// 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: BlockImportAdapter<()>, @@ -360,6 +360,11 @@ impl> Peer { |backend| backend.blocks_count() ).unwrap_or(0) } + + /// Return a collection of block hashes that failed verification + pub fn failed_verifications(&self) -> HashMap<::Hash, String> { + self.verifier.failed_verifications.lock().clone() + } } pub struct EmptyTransactionPool; @@ -485,15 +490,13 @@ impl BlockImport for BlockImportAdapter { } /// Implements `Verifier` on an `Arc>`. Used internally. -struct VerifierAdapter(Arc>>); - -impl Clone for VerifierAdapter { - fn clone(&self) -> Self { - VerifierAdapter(self.0.clone()) - } +#[derive(Clone)] +struct VerifierAdapter { + verifier: Arc>>>, + failed_verifications: Arc>>, } -impl> Verifier for VerifierAdapter { +impl Verifier for VerifierAdapter { fn verify( &mut self, origin: BlockOrigin, @@ -501,7 +504,20 @@ impl> Verifier for VerifierAdapter { justification: Option, body: Option> ) -> Result<(BlockImportParams, Option)>>), String> { - self.0.lock().verify(origin, header, justification, body) + let hash = header.hash(); + self.verifier.lock().verify(origin, header, justification, body).map_err(|e| { + self.failed_verifications.lock().insert(hash, e.clone()); + e + }) + } +} + +impl VerifierAdapter { + fn new(verifier: Arc>>>) -> VerifierAdapter { + VerifierAdapter { + verifier, + failed_verifications: Default::default(), + } } } @@ -592,7 +608,7 @@ pub trait TestNetFactory: Sized { config, &data, ); - let verifier = VerifierAdapter(Arc::new(Mutex::new(Box::new(verifier) as Box<_>))); + let verifier = VerifierAdapter::new(Arc::new(Mutex::new(Box::new(verifier) as Box<_>))); let import_queue = Box::new(BasicQueue::new( verifier.clone(), @@ -668,7 +684,7 @@ pub trait TestNetFactory: Sized { &config, &data, ); - let verifier = VerifierAdapter(Arc::new(Mutex::new(Box::new(verifier) as Box<_>))); + let verifier = VerifierAdapter::new(Arc::new(Mutex::new(Box::new(verifier) as Box<_>))); let import_queue = Box::new(BasicQueue::new( verifier.clone(), diff --git a/primitives/consensus/common/src/import_queue/basic_queue.rs b/primitives/consensus/common/src/import_queue/basic_queue.rs index 63ba16b658..bd42ebd685 100644 --- a/primitives/consensus/common/src/import_queue/basic_queue.rs +++ b/primitives/consensus/common/src/import_queue/basic_queue.rs @@ -14,9 +14,10 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use std::{mem, pin::Pin, time::Duration, marker::PhantomData}; +use std::{mem, pin::Pin, time::Duration, marker::PhantomData, sync::Arc}; use futures::{prelude::*, channel::mpsc, task::Context, task::Poll}; use futures_timer::Delay; +use parking_lot::{Mutex, Condvar}; use sp_runtime::{Justification, traits::{Block as BlockT, Header as HeaderT, NumberFor}}; use crate::block_import::BlockOrigin; @@ -40,9 +41,28 @@ pub struct BasicQueue { manual_poll: Option + Send>>>, /// A thread pool where the background worker is being run. pool: Option, + pool_guard: Arc<(Mutex, Condvar)>, _phantom: PhantomData, } +impl Drop for BasicQueue { + fn drop(&mut self) { + self.pool = None; + // Flush the queue and close the receiver to terminate the future. + self.sender.close_channel(); + self.result_port.close(); + + // Make sure all pool threads terminate. + // https://github.com/rust-lang/futures-rs/issues/1470 + // https://github.com/rust-lang/futures-rs/issues/1349 + let (ref mutex, ref condvar) = *self.pool_guard; + let mut lock = mutex.lock(); + while *lock != 0 { + condvar.wait(&mut lock); + } + } +} + impl BasicQueue { /// Instantiate a new basic queue, with given verifier. /// @@ -63,9 +83,22 @@ impl BasicQueue { finality_proof_import, ); + let guard = Arc::new((Mutex::new(0usize), Condvar::new())); + let guard_start = guard.clone(); + let guard_end = guard.clone(); + let mut pool = futures::executor::ThreadPool::builder() .name_prefix("import-queue-worker-") .pool_size(1) + .after_start(move |_| *guard_start.0.lock() += 1) + .before_stop(move |_| { + let (ref mutex, ref condvar) = *guard_end; + let mut lock = mutex.lock(); + *lock -= 1; + if *lock == 0 { + condvar.notify_one(); + } + }) .create() .ok(); @@ -82,6 +115,7 @@ impl BasicQueue { result_port, manual_poll, pool, + pool_guard: guard, _phantom: PhantomData, } } diff --git a/primitives/consensus/common/src/import_queue/buffered_link.rs b/primitives/consensus/common/src/import_queue/buffered_link.rs index 143ab0eef8..d0f6c87951 100644 --- a/primitives/consensus/common/src/import_queue/buffered_link.rs +++ b/primitives/consensus/common/src/import_queue/buffered_link.rs @@ -157,6 +157,11 @@ impl BufferedLinkReceiver { } } } + + /// Close the channel. + pub fn close(&mut self) { + self.rx.close() + } } #[cfg(test)] -- GitLab From c09f100b4585a2c8773d3c12165378430a942fd7 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Mon, 17 Feb 2020 11:32:37 +0100 Subject: [PATCH 159/180] Update libp2p to 0.16 (#4928) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update libp2p to 0.16 * Actually update to libp2p 0.16 🤦 * Fix missed updates * Fix peerset tests --- Cargo.lock | 165 ++++++++++++------ bin/utils/subkey/Cargo.toml | 2 +- client/authority-discovery/Cargo.toml | 2 +- client/network-gossip/Cargo.toml | 2 +- client/network/Cargo.toml | 2 +- client/network/src/behaviour.rs | 17 +- client/network/src/debug_info.rs | 15 +- client/network/src/discovery.rs | 17 +- client/network/src/protocol.rs | 22 +-- client/network/src/protocol/block_requests.rs | 24 +-- .../src/protocol/legacy_proto/behaviour.rs | 19 +- .../src/protocol/legacy_proto/handler.rs | 63 +++---- .../src/protocol/legacy_proto/tests.rs | 19 +- .../src/protocol/light_client_handler.rs | 35 ++-- client/network/src/protocol/light_dispatch.rs | 2 +- client/network/src/service.rs | 2 - client/network/test/Cargo.toml | 2 +- client/peerset/Cargo.toml | 2 +- client/peerset/src/peersstate.rs | 8 +- client/peerset/tests/fuzz.rs | 4 +- client/telemetry/Cargo.toml | 2 +- primitives/consensus/common/Cargo.toml | 2 +- utils/browser/Cargo.toml | 2 +- 23 files changed, 225 insertions(+), 205 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 733f15b9cb..30d75077d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -580,6 +580,15 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "chacha20-poly1305-aead" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77d2058ba29594f69c75e8a9018e0485e3914ca5084e3613cd64529042f5423b" +dependencies = [ + "constant_time_eq", +] + [[package]] name = "chain-spec-builder" version = "2.0.0" @@ -2634,9 +2643,9 @@ dependencies = [ [[package]] name = "libp2p" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84847789ab24b3fc5971a68656ac85886df640986d9ce3264c0327694eae471" +checksum = "a58becf0b9585fcfbb8215bbe6e6ac187fcc180fd1026925ca180c845aa5a6e8" dependencies = [ "bytes 0.5.4", "futures 0.3.4", @@ -2654,6 +2663,7 @@ dependencies = [ "libp2p-noise", "libp2p-ping", "libp2p-plaintext", + "libp2p-pnet", "libp2p-secio", "libp2p-swarm", "libp2p-tcp", @@ -2671,16 +2681,16 @@ dependencies = [ [[package]] name = "libp2p-core" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbafb2706b8082233f66dc13e196f9cf9b4c229f2cd7c96b2b16617ad6ee330b" +checksum = "3b874594c4b29de1a29f27871feba8e6cd13aa54a8a1e8f8c7cf3dfac5ca287c" dependencies = [ "asn1_der", "bs58", "ed25519-dalek", "fnv", "futures 0.3.4", - "futures-timer 2.0.2", + "futures-timer 3.0.1", "lazy_static", "libsecp256k1", "log 0.4.8", @@ -2698,16 +2708,15 @@ dependencies = [ "smallvec 1.2.0", "thiserror", "unsigned-varint", - "untrusted", "void", "zeroize 1.1.0", ] [[package]] name = "libp2p-core-derive" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c320266be0a7760e23484d635acdb83844b2d74d3612d93b41c393c9bcf004e" +checksum = "96d472e9d522f588805c77801de10b957be84e10f019ca5f869fa1825b15ea9b" dependencies = [ "quote 1.0.2", "syn", @@ -2715,9 +2724,9 @@ dependencies = [ [[package]] name = "libp2p-deflate" -version = "0.7.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be32697b42d040b325c3737f827ea04ede569ec956b7807700dd8d89d8210f9" +checksum = "2e25004d4d9837b44b22c5f1a69be1724a5168fef6cff1716b5176a972c3aa62" dependencies = [ "flate2", "futures 0.3.4", @@ -2726,9 +2735,9 @@ dependencies = [ [[package]] name = "libp2p-dns" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f11c979b882f25d85726b15637d5bbc722dfa1be576605c54e99b8cf56906be3" +checksum = "b99e552f9939b606eb4b59f7f64d9b01e3f96752f47e350fc3c5fc646ed3f649" dependencies = [ "futures 0.3.4", "libp2p-core", @@ -2737,11 +2746,10 @@ dependencies = [ [[package]] name = "libp2p-floodsub" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bdf6fba9272ad47dde94bade89540fdb16e24ae9ff7fb714c1c80a035165f28" +checksum = "1d3234f12e44f9a50351a9807b97fe7de11eb9ae4482370392ba10da6dc90722" dependencies = [ - "bs58", "cuckoofilter", "fnv", "futures 0.3.4", @@ -2755,12 +2763,11 @@ dependencies = [ [[package]] name = "libp2p-gossipsub" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e6ecd058bf769d27ebec530544b081e08b0a1088e3186da8cc58d59915784d0" +checksum = "d46cb3e0841bd951cbf4feae56cdc081e6347836a644fb260c3ec554149b4006" dependencies = [ "base64 0.11.0", - "bs58", "byteorder 1.3.4", "bytes 0.5.4", "fnv", @@ -2781,9 +2788,9 @@ dependencies = [ [[package]] name = "libp2p-identify" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1a6261b804111c2dbf53f8ca03f66edc5ad1c29b78a61cf0cc5354052e28e9" +checksum = "bfeb935a9bd41263e4f3a24b988e9f4a044f3ae89ac284e83c17fe2f84e0d66b" dependencies = [ "futures 0.3.4", "libp2p-core", @@ -2797,9 +2804,9 @@ dependencies = [ [[package]] name = "libp2p-kad" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6ea6fece0d99599afb1b2082ca8937944cdd6b0946a88d54cb3ae7a38d1253" +checksum = "b2efcff2af085e8181c421f68fe9c2b0a067379d146731925b3ac8f8e605c458" dependencies = [ "arrayvec 0.5.1", "bytes 0.5.4", @@ -2824,9 +2831,9 @@ dependencies = [ [[package]] name = "libp2p-mdns" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "074312353355df310affa105ec71b16fd7e52f5c6ae61d3dcbb3e79e8fdc9e5f" +checksum = "881fcfb360c2822db9f0e6bb6f89529621556ed9a8b038313414eda5107334de" dependencies = [ "async-std", "data-encoding", @@ -2846,9 +2853,9 @@ dependencies = [ [[package]] name = "libp2p-mplex" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d0b44dfdef80cc2be4b42d127de1c793905eca2459415a5c57d6b4fbd8ec30" +checksum = "d8507b37ad0eed275efcde67a023c3d85af6c80768b193845b9288e848e1af95" dependencies = [ "bytes 0.5.4", "fnv", @@ -2862,9 +2869,9 @@ dependencies = [ [[package]] name = "libp2p-noise" -version = "0.13.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0845e8208d814cd41c26c90a6a2f2b720c31b588209cecc49a44c881a09f417f" +checksum = "ac7d33809afdf6794f09fdb2f9f94e1550ae230be5bae6430a078eb96fc9e5a6" dependencies = [ "curve25519-dalek 1.2.3", "futures 0.3.4", @@ -2874,17 +2881,18 @@ dependencies = [ "prost", "prost-build", "rand 0.7.3", - "ring", + "sha2", "snow", - "x25519-dalek", + "static_assertions", + "x25519-dalek 0.5.2", "zeroize 1.1.0", ] [[package]] name = "libp2p-ping" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16ecced2949ae93b6ff29565303ecd1bef15c4e4efb689033ee744922561a36b" +checksum = "33d22f2f228b3a828dca1cb8aa9fa331e0bc9c36510cb2c1916956e20dc85e8c" dependencies = [ "futures 0.3.4", "libp2p-core", @@ -2897,9 +2905,9 @@ dependencies = [ [[package]] name = "libp2p-plaintext" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "195fda6b6a948a242fd30570e0e3418ae8e0a20055ea75d45458e1079a8efb05" +checksum = "56126a204d7b3382bac163143ff4125a14570b3ba76ba979103d1ae1abed1923" dependencies = [ "bytes 0.5.4", "futures 0.3.4", @@ -2913,11 +2921,25 @@ dependencies = [ "void", ] +[[package]] +name = "libp2p-pnet" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b916938a8868f75180aeeffcc6a516a922d165e8fa2a90b57bad989d1ccbb57a" +dependencies = [ + "futures 0.3.4", + "log 0.4.8", + "pin-project", + "rand 0.7.3", + "salsa20", + "sha3", +] + [[package]] name = "libp2p-secio" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceef68ca377b264f84d64c88739a8fa118b5db1e8f18297351dff75314504a5f" +checksum = "ec00eb9a3404ed76a0e14f637edcaa7f2b4a27a16884da4a56f2f21e166c2843" dependencies = [ "aes-ctr", "ctr", @@ -2945,9 +2967,9 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.5.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14ea00be81bc3985e36abad263ce2ad1b6aeb862aa743563eb70ad42880c05ae" +checksum = "f1e9f4fb84a4bfe3d3a361c1fbcd4af017ba68f0a46a77bfbcc48bf8a456d6ef" dependencies = [ "futures 0.3.4", "libp2p-core", @@ -2959,13 +2981,13 @@ dependencies = [ [[package]] name = "libp2p-tcp" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e65ef381570df31cb047dfbc11483ab0fe7e6abbdcf2bdc2c60b5d11133d241" +checksum = "f9e80ad4e3535345f3d666554ce347d3100453775611c05c60786bf9a1747a10" dependencies = [ "async-std", "futures 0.3.4", - "futures-timer 2.0.2", + "futures-timer 3.0.1", "get_if_addrs", "ipnet", "libp2p-core", @@ -2974,9 +2996,9 @@ dependencies = [ [[package]] name = "libp2p-uds" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e4f4f7989b35f33d4b9738aab2f031310eb20fec513cab44d12b1bc985a8074" +checksum = "76d329564a43da9d0e055a5b938633c4a8ceab1f59cec133fbc4647917c07341" dependencies = [ "async-std", "futures 0.3.4", @@ -2986,9 +3008,9 @@ dependencies = [ [[package]] name = "libp2p-wasm-ext" -version = "0.8.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b4d457adb91a5e2212343218a554394cd8ced64a79fb8e36e7aed2a16d49495" +checksum = "39703653caa36f4afd0def39cc49a3ac0fa1d4289ca1802e417af03e4f5ef950" dependencies = [ "futures 0.3.4", "js-sys", @@ -3000,9 +3022,9 @@ dependencies = [ [[package]] name = "libp2p-websocket" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bba425f2af1fdb7dece88b9ae05ca9430dfb0b72b2c078e73ded6f1556084509" +checksum = "5351ca9eea122081c1c0f9323164d2918cac29b5a6bfe5054d4ba8ec9447cf42" dependencies = [ "async-tls", "bytes 0.5.4", @@ -3021,13 +3043,12 @@ dependencies = [ [[package]] name = "libp2p-yamux" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca25b3aac78a3c93c2a567622abd3cfc16f96f26ae1bf6134f0056203d62d86" +checksum = "f72aa5a7273c29c6eaea09108a49feaefc7456164863f64f86a193f9e78a4b7f" dependencies = [ "futures 0.3.4", "libp2p-core", - "log 0.4.8", "parking_lot 0.10.0", "thiserror", "yamux", @@ -4533,9 +4554,9 @@ checksum = "0c276d76c5333b8c2579e02d49a06733a55b8282d2d9b13e8d53b6406bd7e30a" [[package]] name = "parity-multiaddr" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80878c27f90dd162d3143333d672e80b194d6b080f05c83440e3dfda42e409f2" +checksum = "26df883298bc3f4e92528b4c5cc9f806b791955b136da3e5e939ed9de0fd958b" dependencies = [ "arrayref", "bs58", @@ -4551,9 +4572,9 @@ dependencies = [ [[package]] name = "parity-multihash" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b11f42bbd3a021c5061b77154bd3334d5a57e1a03eb162de0b962681cc25800d" +checksum = "7a1cd2ba02391b81367bec529fb209019d718684fdc8ad6a712c2b536e46f775" dependencies = [ "blake2", "bytes 0.5.4", @@ -5490,6 +5511,26 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" +[[package]] +name = "salsa20" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2324b0e8c3bb9a586a571fdb3136f70e7e2c748de00a78043f86e0cff91f91fe" +dependencies = [ + "byteorder 1.3.4", + "salsa20-core", + "stream-cipher", +] + +[[package]] +name = "salsa20-core" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fe6cc1b9f5a5867853ade63099de70f042f7679e408d1ffe52821c9248e6e69" +dependencies = [ + "stream-cipher", +] + [[package]] name = "same-file" version = "1.0.6" @@ -6768,10 +6809,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afb767eee7d257ba202f0b9b08673bc13b22281632ef45267b19f13100accd2f" dependencies = [ "arrayref", + "blake2-rfc", + "chacha20-poly1305-aead", + "rand 0.7.3", "rand_core 0.5.1", "ring", "rustc_version", + "sha2", "subtle 2.2.2", + "x25519-dalek 0.6.0", ] [[package]] @@ -9019,6 +9065,17 @@ dependencies = [ "rand_core 0.3.1", ] +[[package]] +name = "x25519-dalek" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "637ff90c9540fa3073bb577e65033069e4bae7c79d49d74aa3ffdf5342a53217" +dependencies = [ + "curve25519-dalek 2.0.0", + "rand_core 0.5.1", + "zeroize 1.1.0", +] + [[package]] name = "xdg" version = "2.2.0" diff --git a/bin/utils/subkey/Cargo.toml b/bin/utils/subkey/Cargo.toml index e29ee9a6c5..ce3303c946 100644 --- a/bin/utils/subkey/Cargo.toml +++ b/bin/utils/subkey/Cargo.toml @@ -28,7 +28,7 @@ derive_more = { version = "0.99.2" } sc-rpc = { version = "2.0.0", path = "../../../client/rpc" } jsonrpc-core-client = { version = "14.0.3", features = ["http"] } hyper = "0.12.35" -libp2p = "0.15.0" +libp2p = "0.16.0" serde_json = "1.0" [features] diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index 40b1b30173..248304d137 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -15,7 +15,7 @@ codec = { package = "parity-scale-codec", default-features = false, version = "1 derive_more = "0.99.2" futures = "0.3.1" futures-timer = "3.0.1" -libp2p = { version = "0.15.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } +libp2p = { version = "0.16.0", default-features = false, features = ["secp256k1", "libp2p-websocket"] } log = "0.4.8" prost = "0.6.1" rand = "0.7.2" diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index 7258963e2a..98b2bd0590 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -12,7 +12,7 @@ futures = { version = "0.3.1", features = ["compat"] } wasm-timer = "0.2" futures-timer = "3.0.1" futures01 = { package = "futures", version = "0.1.29" } -libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] } +libp2p = { version = "0.16.0", default-features = false, features = ["libp2p-websocket"] } lru = "0.1.2" parking_lot = "0.10.0" sc-network = { version = "0.8", path = "../network" } diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index f6ff3bcb73..d16f3d81c1 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -22,7 +22,7 @@ futures = "0.3.1" futures_codec = "0.3.3" futures-timer = "3.0.1" wasm-timer = "0.2" -libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] } +libp2p = { version = "0.16.0", default-features = false, features = ["libp2p-websocket"] } linked-hash-map = "0.5.2" linked_hash_set = "0.1.3" log = "0.4.8" diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index 63cbea4da5..c8c5e59fe6 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -23,8 +23,7 @@ use crate::protocol::{self, light_client_handler, CustomMessageOutcome, Protocol use libp2p::NetworkBehaviour; use libp2p::core::{Multiaddr, PeerId, PublicKey}; use libp2p::kad::record; -use libp2p::swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess}; -use libp2p::core::{nodes::Substream, muxing::StreamMuxerBox}; +use libp2p::swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters}; use log::debug; use sp_consensus::{BlockOrigin, import_queue::{IncomingBlock, Origin}}; use sp_runtime::{traits::{Block as BlockT, NumberFor}, Justification}; @@ -39,13 +38,13 @@ pub struct Behaviour, H: ExHashT> { substrate: Protocol, /// Periodically pings and identifies the nodes we are connected to, and store information in a /// cache. - debug_info: debug_info::DebugInfoBehaviour>, + debug_info: debug_info::DebugInfoBehaviour, /// Discovers nodes of the network. - discovery: DiscoveryBehaviour>, + discovery: DiscoveryBehaviour, /// Block request handling. - block_requests: protocol::BlockRequests, B>, + block_requests: protocol::BlockRequests, /// Light client request handling. - light_client_handler: protocol::LightClientHandler, B>, + light_client_handler: protocol::LightClientHandler, /// Queue of events to produce for the outside. #[behaviour(ignore)] events: Vec>, @@ -69,8 +68,8 @@ impl, H: ExHashT> Behaviour { enable_mdns: bool, allow_private_ipv4: bool, discovery_only_if_under_num: u64, - block_requests: protocol::BlockRequests, B>, - light_client_handler: protocol::LightClientHandler, B>, + block_requests: protocol::BlockRequests, + light_client_handler: protocol::LightClientHandler, ) -> Self { Behaviour { substrate, @@ -223,7 +222,7 @@ impl, H: ExHashT> NetworkBehaviourEventPr } impl, H: ExHashT> Behaviour { - fn poll(&mut self, _: &mut Context) -> Poll>> { + fn poll(&mut self, _: &mut Context, _: &mut impl PollParameters) -> Poll>> { if !self.events.is_empty() { return Poll::Ready(NetworkBehaviourAction::GenerateEvent(self.events.remove(0))) } diff --git a/client/network/src/debug_info.rs b/client/network/src/debug_info.rs index a3d63333fa..17fb622f7c 100644 --- a/client/network/src/debug_info.rs +++ b/client/network/src/debug_info.rs @@ -39,11 +39,11 @@ const GARBAGE_COLLECT_INTERVAL: Duration = Duration::from_secs(2 * 60); /// Implementation of `NetworkBehaviour` that holds information about nodes in cache for diagnostic /// purposes. -pub struct DebugInfoBehaviour { +pub struct DebugInfoBehaviour { /// Periodically ping nodes, and close the connection if it's unresponsive. - ping: Ping, + ping: Ping, /// Periodically identifies the remote and responds to incoming requests. - identify: Identify, + identify: Identify, /// Information that we know about all nodes. nodes_info: FnvHashMap, /// Interval at which we perform garbage collection in `nodes_info`. @@ -64,7 +64,7 @@ struct NodeInfo { latest_ping: Option, } -impl DebugInfoBehaviour { +impl DebugInfoBehaviour { /// Builds a new `DebugInfoBehaviour`. pub fn new( user_agent: String, @@ -151,11 +151,10 @@ pub enum DebugInfoEvent { }, } -impl NetworkBehaviour for DebugInfoBehaviour -where TSubstream: AsyncRead + AsyncWrite + Unpin + Send + 'static { +impl NetworkBehaviour for DebugInfoBehaviour { type ProtocolsHandler = IntoProtocolsHandlerSelect< - as NetworkBehaviour>::ProtocolsHandler, - as NetworkBehaviour>::ProtocolsHandler + ::ProtocolsHandler, + ::ProtocolsHandler >; type OutEvent = DebugInfoEvent; diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index 2da69e1894..2d69e679ff 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -55,8 +55,6 @@ use libp2p::kad::record::{self, store::MemoryStore}; #[cfg(not(target_os = "unknown"))] use libp2p::{swarm::toggle::Toggle}; #[cfg(not(target_os = "unknown"))] -use libp2p::core::{nodes::Substream, muxing::StreamMuxerBox}; -#[cfg(not(target_os = "unknown"))] use libp2p::mdns::{Mdns, MdnsEvent}; use libp2p::multiaddr::Protocol; use log::{debug, info, trace, warn, error}; @@ -65,15 +63,15 @@ use std::task::{Context, Poll}; use sp_core::hexdisplay::HexDisplay; /// Implementation of `NetworkBehaviour` that discovers the nodes on the network. -pub struct DiscoveryBehaviour { +pub struct DiscoveryBehaviour { /// User-defined list of nodes and their addresses. Typically includes bootstrap nodes and /// reserved nodes. user_defined: Vec<(PeerId, Multiaddr)>, /// Kademlia requests and answers. - kademlia: Kademlia, + kademlia: Kademlia, /// Discovers nodes on the local network. #[cfg(not(target_os = "unknown"))] - mdns: Toggle>>, + mdns: Toggle, /// Stream that fires when we need to perform the next random Kademlia query. next_kad_random_query: Delay, /// After `next_kad_random_query` triggers, the next one triggers after this duration. @@ -91,7 +89,7 @@ pub struct DiscoveryBehaviour { discovery_only_if_under_num: u64, } -impl DiscoveryBehaviour { +impl DiscoveryBehaviour { /// Builds a new `DiscoveryBehaviour`. /// /// `user_defined` is a list of known address for nodes that never expire. @@ -207,11 +205,8 @@ pub enum DiscoveryOut { ValuePutFailed(record::Key), } -impl NetworkBehaviour for DiscoveryBehaviour -where - TSubstream: AsyncRead + AsyncWrite + Unpin, -{ - type ProtocolsHandler = as NetworkBehaviour>::ProtocolsHandler; +impl NetworkBehaviour for DiscoveryBehaviour { + type ProtocolsHandler = as NetworkBehaviour>::ProtocolsHandler; type OutEvent = DiscoveryOut; fn new_handler(&mut self) -> Self::ProtocolsHandler { diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 8e5f9d6e7b..0a909fe2fe 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -20,7 +20,7 @@ use crate::utils::interval; use bytes::{Bytes, BytesMut}; use futures::prelude::*; use libp2p::{Multiaddr, PeerId}; -use libp2p::core::{ConnectedPoint, nodes::{listeners::ListenerId, Substream}, muxing::StreamMuxerBox}; +use libp2p::core::{ConnectedPoint, nodes::listeners::ListenerId}; use libp2p::swarm::{ProtocolsHandler, IntoProtocolsHandler}; use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use sp_core::storage::{StorageKey, ChildInfo}; @@ -158,7 +158,7 @@ pub struct Protocol, H: ExHashT> { /// 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>, + behaviour: LegacyProto, /// List of notification protocols that have been registered. registered_notif_protocols: HashSet, } @@ -207,7 +207,7 @@ pub struct PeerInfo { } struct LightDispatchIn<'a> { - behaviour: &'a mut LegacyProto>, + behaviour: &'a mut LegacyProto, peerset: sc_peerset::PeersetHandle, } @@ -347,7 +347,7 @@ pub trait Context { /// Protocol context. struct ProtocolContext<'a, B: 'a + BlockT, H: 'a + ExHashT> { - behaviour: &'a mut LegacyProto>, + behaviour: &'a mut LegacyProto, context_data: &'a mut ContextData, peerset_handle: &'a sc_peerset::PeersetHandle, } @@ -355,7 +355,7 @@ struct ProtocolContext<'a, B: 'a + BlockT, H: 'a + ExHashT> { impl<'a, B: BlockT + 'a, H: 'a + ExHashT> ProtocolContext<'a, B, H> { fn new( context_data: &'a mut ContextData, - behaviour: &'a mut LegacyProto>, + behaviour: &'a mut LegacyProto, peerset_handle: &'a sc_peerset::PeersetHandle, ) -> Self { ProtocolContext { context_data, peerset_handle, behaviour } @@ -913,14 +913,14 @@ impl, H: ExHashT> Protocol { if peer.block_request.as_ref().map_or(false, |(t, _)| (tick - *t).as_secs() > REQUEST_TIMEOUT_SEC) { log!( target: "sync", - if self.important_peers.contains(&who) { Level::Warn } else { Level::Trace }, + if self.important_peers.contains(who) { Level::Warn } else { Level::Trace }, "Request timeout {}", who ); aborting.push(who.clone()); } else if peer.obsolete_requests.values().any(|t| (tick - *t).as_secs() > REQUEST_TIMEOUT_SEC) { log!( target: "sync", - if self.important_peers.contains(&who) { Level::Warn } else { Level::Trace }, + if self.important_peers.contains(who) { Level::Warn } else { Level::Trace }, "Obsolete timeout {}", who ); aborting.push(who.clone()); @@ -931,7 +931,7 @@ impl, H: ExHashT> Protocol { { log!( target: "sync", - if self.important_peers.contains(&who) { Level::Warn } else { Level::Trace }, + if self.important_peers.contains(who) { Level::Warn } else { Level::Trace }, "Handshake timeout {}", who ); aborting.push(who.clone()); @@ -1835,7 +1835,7 @@ pub enum CustomMessageOutcome { } fn send_request( - behaviour: &mut LegacyProto>, + behaviour: &mut LegacyProto, stats: &mut HashMap<&'static str, PacketStats>, peers: &mut HashMap>, who: &PeerId, @@ -1856,7 +1856,7 @@ fn send_request( } fn send_message( - behaviour: &mut LegacyProto>, + behaviour: &mut LegacyProto, stats: &mut HashMap<&'static str, PacketStats>, who: &PeerId, message: Message, @@ -1870,7 +1870,7 @@ fn send_message( impl, H: ExHashT> NetworkBehaviour for Protocol { - type ProtocolsHandler = > as NetworkBehaviour>::ProtocolsHandler; + type ProtocolsHandler = ::ProtocolsHandler; type OutEvent = CustomMessageOutcome; fn new_handler(&mut self) -> Self::ProtocolsHandler { diff --git a/client/network/src/protocol/block_requests.rs b/client/network/src/protocol/block_requests.rs index f8a905c288..ef970657c5 100644 --- a/client/network/src/protocol/block_requests.rs +++ b/client/network/src/protocol/block_requests.rs @@ -38,7 +38,14 @@ use libp2p::{ upgrade::{InboundUpgrade, ReadOneError, UpgradeInfo, Negotiated}, upgrade::{DeniedUpgrade, read_one, write_one} }, - swarm::{NetworkBehaviour, NetworkBehaviourAction, OneShotHandler, PollParameters, SubstreamProtocol} + swarm::{ + NegotiatedSubstream, + NetworkBehaviour, + NetworkBehaviourAction, + OneShotHandler, + PollParameters, + SubstreamProtocol + } }; use prost::Message; use sp_runtime::{generic::BlockId, traits::{Block, Header, One, Zero}}; @@ -111,20 +118,17 @@ impl Config { } /// The block request handling behaviour. -pub struct BlockRequests { +pub struct BlockRequests { /// This behaviour's configuration. config: Config, /// Blockchain client. chain: Arc>, /// Futures sending back the block request response. outgoing: FuturesUnordered>, - /// Type witness term. - _marker: std::marker::PhantomData } -impl BlockRequests +impl BlockRequests where - T: AsyncRead + AsyncWrite + Unpin + Send + 'static, B: Block, { pub fn new(cfg: Config, chain: Arc>) -> Self { @@ -132,7 +136,6 @@ where config: cfg, chain, outgoing: FuturesUnordered::new(), - _marker: std::marker::PhantomData } } @@ -243,12 +246,11 @@ where } } -impl NetworkBehaviour for BlockRequests +impl NetworkBehaviour for BlockRequests where - T: AsyncRead + AsyncWrite + Unpin + Send + 'static, B: Block { - type ProtocolsHandler = OneShotHandler>>; + type ProtocolsHandler = OneShotHandler>; type OutEvent = Void; fn new_handler(&mut self) -> Self::ProtocolsHandler { @@ -269,7 +271,7 @@ where fn inject_disconnected(&mut self, _peer: &PeerId, _info: ConnectedPoint) { } - fn inject_node_event(&mut self, peer: PeerId, Request(request, mut stream): Request>) { + fn inject_node_event(&mut self, peer: PeerId, Request(request, mut stream): Request) { match self.on_block_request(&peer, &request) { Ok(res) => { log::trace!("enqueueing block response {} for peer {} with {} blocks", res.id, peer, res.blocks.len()); diff --git a/client/network/src/protocol/legacy_proto/behaviour.rs b/client/network/src/protocol/legacy_proto/behaviour.rs index 1eb6b157dd..704b4947ed 100644 --- a/client/network/src/protocol/legacy_proto/behaviour.rs +++ b/client/network/src/protocol/legacy_proto/behaviour.rs @@ -25,7 +25,7 @@ use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use log::{debug, error, trace, warn}; use rand::distributions::{Distribution as _, Uniform}; use smallvec::SmallVec; -use std::{borrow::Cow, collections::hash_map::Entry, cmp, error, marker::PhantomData, mem, pin::Pin}; +use std::{borrow::Cow, collections::hash_map::Entry, cmp, error, mem, pin::Pin}; use std::time::Duration; use wasm_timer::Instant; use std::task::{Context, Poll}; @@ -60,7 +60,7 @@ use std::task::{Context, Poll}; /// Note that this "banning" system is not an actual ban. If a "banned" node tries to connect to /// us, we accept the connection. The "banning" system is only about delaying dialing attempts. /// -pub struct LegacyProto< TSubstream> { +pub struct LegacyProto { /// List of protocols to open with peers. Never modified. protocol: RegisteredProtocol, @@ -80,9 +80,6 @@ pub struct LegacyProto< TSubstream> { /// Events to produce from `poll()`. events: SmallVec<[NetworkBehaviourAction; 4]>, - - /// Marker to pin the generics. - marker: PhantomData, } /// State of a peer we're connected to. @@ -225,7 +222,7 @@ pub enum LegacyProtoOut { }, } -impl LegacyProto { +impl LegacyProto { /// Creates a `CustomProtos`. pub fn new( protocol: impl Into, @@ -241,7 +238,6 @@ impl LegacyProto { incoming: SmallVec::new(), next_incoming_index: sc_peerset::IncomingIndex(0), events: SmallVec::new(), - marker: PhantomData, } } @@ -605,7 +601,7 @@ impl LegacyProto { } } -impl DiscoveryNetBehaviour for LegacyProto { +impl DiscoveryNetBehaviour for LegacyProto { fn add_discovered_nodes(&mut self, peer_ids: impl Iterator) { self.peerset.discovered(peer_ids.into_iter().map(|peer_id| { debug!(target: "sub-libp2p", "PSM <= Discovered({:?})", peer_id); @@ -614,11 +610,8 @@ impl DiscoveryNetBehaviour for LegacyProto { } } -impl NetworkBehaviour for LegacyProto -where - TSubstream: AsyncRead + AsyncWrite + Unpin, -{ - type ProtocolsHandler = CustomProtoHandlerProto; +impl NetworkBehaviour for LegacyProto { + type ProtocolsHandler = CustomProtoHandlerProto; type OutEvent = LegacyProtoOut; fn new_handler(&mut self) -> Self::ProtocolsHandler { diff --git a/client/network/src/protocol/legacy_proto/handler.rs b/client/network/src/protocol/legacy_proto/handler.rs index 66fb0dca13..e3490993dd 100644 --- a/client/network/src/protocol/legacy_proto/handler.rs +++ b/client/network/src/protocol/legacy_proto/handler.rs @@ -18,7 +18,7 @@ use super::upgrade::{RegisteredProtocol, RegisteredProtocolEvent, RegisteredProt use bytes::BytesMut; use futures::prelude::*; use futures_timer::Delay; -use libp2p::core::{ConnectedPoint, Negotiated, PeerId, Endpoint}; +use libp2p::core::{ConnectedPoint, PeerId, Endpoint}; use libp2p::core::upgrade::{InboundUpgrade, OutboundUpgrade}; use libp2p::swarm::{ ProtocolsHandler, ProtocolsHandlerEvent, @@ -26,10 +26,11 @@ use libp2p::swarm::{ KeepAlive, ProtocolsHandlerUpgrErr, SubstreamProtocol, + NegotiatedSubstream, }; use log::{debug, error}; use smallvec::{smallvec, SmallVec}; -use std::{borrow::Cow, error, fmt, io, marker::PhantomData, mem, time::Duration}; +use std::{borrow::Cow, error, fmt, io, mem, time::Duration}; use std::{pin::Pin, task::{Context, Poll}}; /// Implements the `IntoProtocolsHandler` trait of libp2p. @@ -86,32 +87,22 @@ use std::{pin::Pin, task::{Context, Poll}}; /// We consider that we are now "closed" if the remote closes all the existing substreams. /// Re-opening it can then be performed by closing all active substream and re-opening one. /// -pub struct CustomProtoHandlerProto { +pub struct CustomProtoHandlerProto { /// Configuration for the protocol upgrade to negotiate. protocol: RegisteredProtocol, - - /// Marker to pin the generic type. - marker: PhantomData, } -impl CustomProtoHandlerProto -where - TSubstream: AsyncRead + AsyncWrite + Unpin, -{ +impl CustomProtoHandlerProto { /// Builds a new `CustomProtoHandlerProto`. pub fn new(protocol: RegisteredProtocol) -> Self { CustomProtoHandlerProto { protocol, - marker: PhantomData, } } } -impl IntoProtocolsHandler for CustomProtoHandlerProto -where - TSubstream: AsyncRead + AsyncWrite + Unpin, -{ - type Handler = CustomProtoHandler; +impl IntoProtocolsHandler for CustomProtoHandlerProto { + type Handler = CustomProtoHandler; fn inbound_protocol(&self) -> RegisteredProtocol { self.protocol.clone() @@ -132,12 +123,12 @@ where } /// The actual handler once the connection has been established. -pub struct CustomProtoHandler { +pub struct CustomProtoHandler { /// Configuration for the protocol upgrade to negotiate. protocol: RegisteredProtocol, /// State of the communications with the remote. - state: ProtocolState, + state: ProtocolState, /// Identifier of the node we're talking to. Used only for logging purposes and shouldn't have /// any influence on the behaviour. @@ -155,11 +146,11 @@ pub struct CustomProtoHandler { } /// State of the handler. -enum ProtocolState { +enum ProtocolState { /// Waiting for the behaviour to tell the handler whether it is enabled or disabled. Init { /// List of substreams opened by the remote but that haven't been processed yet. - substreams: SmallVec<[RegisteredProtocolSubstream>; 6]>, + substreams: SmallVec<[RegisteredProtocolSubstream; 6]>, /// Deadline after which the initialization is abnormally long. init_deadline: Delay, }, @@ -175,9 +166,9 @@ enum ProtocolState { /// If we are in this state, we have sent a `CustomProtocolOpen` message to the outside. Normal { /// The substreams where bidirectional communications happen. - substreams: SmallVec<[RegisteredProtocolSubstream>; 4]>, + substreams: SmallVec<[RegisteredProtocolSubstream; 4]>, /// Contains substreams which are being shut down. - shutdown: SmallVec<[RegisteredProtocolSubstream>; 4]>, + shutdown: SmallVec<[RegisteredProtocolSubstream; 4]>, }, /// We are disabled. Contains substreams that are being closed. @@ -185,7 +176,7 @@ enum ProtocolState { /// outside or we have never sent any `CustomProtocolOpen` in the first place. Disabled { /// List of substreams to shut down. - shutdown: SmallVec<[RegisteredProtocolSubstream>; 6]>, + shutdown: SmallVec<[RegisteredProtocolSubstream; 6]>, /// If true, we should reactivate the handler after all the substreams in `shutdown` have /// been closed. @@ -257,10 +248,7 @@ pub enum CustomProtoHandlerOut { }, } -impl CustomProtoHandler -where - TSubstream: AsyncRead + AsyncWrite + Unpin, -{ +impl CustomProtoHandler { /// Enables the handler. fn enable(&mut self) { self.state = match mem::replace(&mut self.state, ProtocolState::Poisoned) { @@ -459,7 +447,7 @@ where /// Called by `inject_fully_negotiated_inbound` and `inject_fully_negotiated_outbound`. fn inject_fully_negotiated( &mut self, - mut substream: RegisteredProtocolSubstream> + mut substream: RegisteredProtocolSubstream ) { self.state = match mem::replace(&mut self.state, ProtocolState::Poisoned) { ProtocolState::Poisoned => { @@ -515,11 +503,9 @@ where } } -impl ProtocolsHandler for CustomProtoHandler -where TSubstream: AsyncRead + AsyncWrite + Unpin { +impl ProtocolsHandler for CustomProtoHandler { type InEvent = CustomProtoHandlerIn; type OutEvent = CustomProtoHandlerOut; - type Substream = TSubstream; type Error = ConnectionKillError; type InboundProtocol = RegisteredProtocol; type OutboundProtocol = RegisteredProtocol; @@ -531,14 +517,14 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin { fn inject_fully_negotiated_inbound( &mut self, - proto: >>::Output + proto: >::Output ) { self.inject_fully_negotiated(proto); } fn inject_fully_negotiated_outbound( &mut self, - proto: >>::Output, + proto: >::Output, _: Self::OutboundOpenInfo ) { self.inject_fully_negotiated(proto); @@ -601,10 +587,7 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin { } } -impl fmt::Debug for CustomProtoHandler -where - TSubstream: AsyncRead + AsyncWrite + Unpin, -{ +impl fmt::Debug for CustomProtoHandler { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { f.debug_struct("CustomProtoHandler") .finish() @@ -613,10 +596,10 @@ where /// Given a list of substreams, tries to shut them down. The substreams that have been successfully /// shut down are removed from the list. -fn shutdown_list - (list: &mut SmallVec>>>, +fn shutdown_list + (list: &mut SmallVec>>, cx: &mut Context) -where TSubstream: AsyncRead + AsyncWrite + Unpin { +{ 'outer: for n in (0..list.len()).rev() { let mut substream = list.swap_remove(n); loop { diff --git a/client/network/src/protocol/legacy_proto/tests.rs b/client/network/src/protocol/legacy_proto/tests.rs index 4f523fa31d..89b0854d90 100644 --- a/client/network/src/protocol/legacy_proto/tests.rs +++ b/client/network/src/protocol/legacy_proto/tests.rs @@ -18,8 +18,8 @@ use futures::{prelude::*, ready}; use codec::{Encode, Decode}; -use libp2p::core::nodes::{Substream, listeners::ListenerId}; -use libp2p::core::{ConnectedPoint, transport::boxed::Boxed, muxing::StreamMuxerBox}; +use libp2p::core::nodes::listeners::ListenerId; +use libp2p::core::ConnectedPoint; use libp2p::swarm::{Swarm, ProtocolsHandler, IntoProtocolsHandler}; use libp2p::swarm::{PollParameters, NetworkBehaviour, NetworkBehaviourAction}; use libp2p::{PeerId, Multiaddr, Transport}; @@ -31,11 +31,7 @@ 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. -fn build_nodes() --> ( - Swarm, CustomProtoWithAddr>, - Swarm, CustomProtoWithAddr> -) { +fn build_nodes() -> (Swarm, Swarm) { let mut out = Vec::with_capacity(2); let keypairs: Vec<_> = (0..2).map(|_| libp2p::identity::Keypair::generate_ed25519()).collect(); @@ -115,12 +111,12 @@ fn build_nodes() /// Wraps around the `CustomBehaviour` network behaviour, and adds hardcoded node addresses to it. struct CustomProtoWithAddr { - inner: LegacyProto>, + inner: LegacyProto, addrs: Vec<(PeerId, Multiaddr)>, } impl std::ops::Deref for CustomProtoWithAddr { - type Target = LegacyProto>; + type Target = LegacyProto; fn deref(&self) -> &Self::Target { &self.inner @@ -134,9 +130,8 @@ impl std::ops::DerefMut for CustomProtoWithAddr { } impl NetworkBehaviour for CustomProtoWithAddr { - type ProtocolsHandler = - > as NetworkBehaviour>::ProtocolsHandler; - type OutEvent = > as NetworkBehaviour>::OutEvent; + type ProtocolsHandler = ::ProtocolsHandler; + type OutEvent = ::OutEvent; fn new_handler(&mut self) -> Self::ProtocolsHandler { self.inner.new_handler() diff --git a/client/network/src/protocol/light_client_handler.rs b/client/network/src/protocol/light_client_handler.rs index f5be23c0d4..63c1f8a443 100644 --- a/client/network/src/protocol/light_client_handler.rs +++ b/client/network/src/protocol/light_client_handler.rs @@ -40,7 +40,14 @@ use libp2p::{ upgrade::{InboundUpgrade, ReadOneError, UpgradeInfo, Negotiated}, upgrade::{OutboundUpgrade, read_one, write_one} }, - swarm::{NetworkBehaviour, NetworkBehaviourAction, OneShotHandler, PollParameters, SubstreamProtocol} + swarm::{ + NegotiatedSubstream, + NetworkBehaviour, + NetworkBehaviourAction, + OneShotHandler, + PollParameters, + SubstreamProtocol + } }; use nohash_hasher::IntMap; use prost::Message; @@ -220,7 +227,7 @@ enum PeerStatus { } /// The light client handler behaviour. -pub struct LightClientHandler { +pub struct LightClientHandler { /// This behaviour's configuration. config: Config, /// Blockchain client. @@ -239,13 +246,10 @@ pub struct LightClientHandler { next_request_id: u64, /// Handle to use for reporting misbehaviour of peers. peerset: sc_peerset::PeersetHandle, - /// Type witness term. - _marker: std::marker::PhantomData } -impl LightClientHandler +impl LightClientHandler where - T: AsyncRead + AsyncWrite + Unpin + Send + 'static, B: Block, { /// Construct a new light client handler. @@ -266,7 +270,6 @@ where outstanding: IntMap::default(), next_request_id: 1, peerset, - _marker: std::marker::PhantomData } } @@ -646,12 +649,11 @@ where } } -impl NetworkBehaviour for LightClientHandler +impl NetworkBehaviour for LightClientHandler where - T: AsyncRead + AsyncWrite + Unpin + Send + 'static, B: Block { - type ProtocolsHandler = OneShotHandler>>; + type ProtocolsHandler = OneShotHandler>; type OutEvent = Void; fn new_handler(&mut self) -> Self::ProtocolsHandler { @@ -690,7 +692,7 @@ where self.remove_peer(peer) } - fn inject_node_event(&mut self, peer: PeerId, event: Event>) { + fn inject_node_event(&mut self, peer: PeerId, event: Event) { match event { // An incoming request from remote has been received. Event::Request(request, mut stream) => { @@ -1144,8 +1146,8 @@ mod tests { const CHILD_INFO: ChildInfo<'static> = ChildInfo::new_default(b"foobarbaz"); type Block = sp_runtime::generic::Block, substrate_test_runtime::Extrinsic>; - type Handler = LightClientHandler>, Block>; - type Swarm = libp2p::swarm::Swarm, Handler>; + type Handler = LightClientHandler; + type Swarm = libp2p::swarm::Swarm; fn empty_proof() -> Vec { StorageProof::empty().encode() @@ -1210,7 +1212,7 @@ mod tests { ( ok: bool , ps: sc_peerset::PeersetHandle , cf: super::Config - ) -> LightClientHandler>, Block> + ) -> LightClientHandler { let client = Arc::new(substrate_test_runtime_client::new()); let checker = Arc::new(DummyFetchChecker::new(ok)); @@ -1221,10 +1223,7 @@ mod tests { ConnectedPoint::Dialer { address: Multiaddr::empty() } } - fn poll(mut b: &mut LightClientHandler) -> Poll> - where - T: AsyncRead + AsyncWrite + Unpin + Send + 'static - { + fn poll(mut b: &mut LightClientHandler) -> Poll> { let mut p = EmptyPollParams(PeerId::random()); match future::poll_fn(|cx| Pin::new(&mut b).poll(cx, &mut p)).now_or_never() { Some(a) => Poll::Ready(a), diff --git a/client/network/src/protocol/light_dispatch.rs b/client/network/src/protocol/light_dispatch.rs index 2eab0a5a3f..3402e7c329 100644 --- a/client/network/src/protocol/light_dispatch.rs +++ b/client/network/src/protocol/light_dispatch.rs @@ -504,7 +504,7 @@ impl LightDispatch where } pub fn is_light_response(&self, peer: &PeerId, request_id: message::RequestId) -> bool { - self.active_peers.get(&peer).map_or(false, |r| r.id == request_id) + self.active_peers.get(peer).map_or(false, |r| r.id == request_id) } fn remove(&mut self, peer: PeerId, id: u64) -> Option> { diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 156e2e3102..922333a9eb 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -35,7 +35,6 @@ use sp_consensus::import_queue::{BlockImportResult, BlockImportError}; use futures::{prelude::*, channel::mpsc}; use log::{warn, error, info, trace}; use libp2p::{PeerId, Multiaddr, kad::record}; -use libp2p::core::{transport::boxed::Boxed, muxing::StreamMuxerBox}; use libp2p::swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent}; use parking_lot::Mutex; use sc_peerset::PeersetHandle; @@ -854,7 +853,6 @@ impl, H: ExHashT> Unpin for Net /// The libp2p swarm, customized for our needs. type Swarm = libp2p::swarm::Swarm< - Boxed<(PeerId, StreamMuxerBox), io::Error>, Behaviour >; diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index ca4b0237cf..339279c704 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -14,7 +14,7 @@ futures = "0.1.29" futures03 = { package = "futures", version = "0.3.1", features = ["compat"] } futures-timer = "3.0.1" rand = "0.7.2" -libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] } +libp2p = { version = "0.16.0", default-features = false, features = ["libp2p-websocket"] } sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" } sc-client = { version = "0.8", path = "../../" } sc-client-api = { version = "2.0.0", path = "../../api" } diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index 2527b86795..c17ffdc385 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -9,7 +9,7 @@ edition = "2018" [dependencies] futures = "0.3.1" -libp2p = { version = "0.15.0", default-features = false } +libp2p = { version = "0.16.0", default-features = false } log = "0.4.8" serde_json = "1.0.41" wasm-timer = "0.2" diff --git a/client/peerset/src/peersstate.rs b/client/peerset/src/peersstate.rs index a27d6e616b..96a6698734 100644 --- a/client/peerset/src/peersstate.rs +++ b/client/peerset/src/peersstate.rs @@ -156,7 +156,7 @@ impl PeersState { pub fn priority_not_connected_peer(&mut self) -> Option { let id = self.priority_nodes.values() .flatten() - .find(|id| self.nodes.get(id).map_or(false, |node| !node.connection_state.is_connected())) + .find(|&id| self.nodes.get(id).map_or(false, |node| !node.connection_state.is_connected())) .cloned(); id.map(move |id| NotConnectedPeer { state: self, @@ -170,7 +170,7 @@ impl PeersState { pub fn priority_not_connected_peer_from_group(&mut self, group_id: &str) -> Option { let id = self.priority_nodes.get(group_id) .and_then(|group| group.iter() - .find(|id| self.nodes.get(id).map_or(false, |node| !node.connection_state.is_connected())) + .find(|&id| self.nodes.get(id).map_or(false, |node| !node.connection_state.is_connected())) .cloned()); id.map(move |id| NotConnectedPeer { state: self, @@ -300,7 +300,7 @@ impl PeersState { for id in &peers { // update slots for nodes that become priority - if !all_other_groups.contains(&id) { + if !all_other_groups.contains(id) { let peer = self.nodes.entry(id.clone()).or_default(); match peer.connection_state { ConnectionState::In => self.num_in -= 1, @@ -322,7 +322,7 @@ impl PeersState { /// Remove a peer from a priority group. pub fn remove_from_priority_group(&mut self, group_id: &str, peer_id: &PeerId) { let mut peers = self.priority_nodes.get(group_id).cloned().unwrap_or_default(); - peers.remove(&peer_id); + peers.remove(peer_id); self.set_priority_group(group_id, peers); } diff --git a/client/peerset/tests/fuzz.rs b/client/peerset/tests/fuzz.rs index b591d83d8f..c2b0b44a3a 100644 --- a/client/peerset/tests/fuzz.rs +++ b/client/peerset/tests/fuzz.rs @@ -108,7 +108,7 @@ fn test_once() { // If we generate 4, connect to a random node. 4 => if let Some(id) = known_nodes.iter() - .filter(|n| incoming_nodes.values().all(|m| m != *n) && !connected_nodes.contains(n)) + .filter(|n| incoming_nodes.values().all(|m| m != *n) && !connected_nodes.contains(*n)) .choose(&mut rng) { peerset.incoming(id.clone(), next_incoming_id.clone()); incoming_nodes.insert(next_incoming_id.clone(), id.clone()); @@ -120,7 +120,7 @@ fn test_once() { 6 => peerset_handle.set_reserved_only(false), // 7 and 8 are about switching a random node in or out of reserved mode. - 7 => if let Some(id) = known_nodes.iter().filter(|n| !reserved_nodes.contains(n)).choose(&mut rng) { + 7 => if let Some(id) = known_nodes.iter().filter(|n| !reserved_nodes.contains(*n)).choose(&mut rng) { peerset_handle.add_reserved_peer(id.clone()); reserved_nodes.insert(id.clone()); } diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index f75c6dd44e..10f4b188af 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -12,7 +12,7 @@ parking_lot = "0.10.0" futures = "0.3.1" futures-timer = "3.0.1" wasm-timer = "0.2.0" -libp2p = { version = "0.15.0", default-features = false, features = ["libp2p-websocket"] } +libp2p = { version = "0.16.0", default-features = false, features = ["libp2p-websocket"] } log = "0.4.8" pin-project = "0.4.6" rand = "0.7.2" diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index 2abc6f5617..d7c33a6452 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -8,7 +8,7 @@ license = "GPL-3.0" [dependencies] derive_more = "0.99.2" -libp2p = { version = "0.15.0", default-features = false } +libp2p = { version = "0.16.0", default-features = false } log = "0.4.8" sp-core = { path= "../../core" } sp-inherents = { version = "2.0.0", path = "../../inherents" } diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index e52f630cb5..7e101c438a 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -10,7 +10,7 @@ license = "GPL-3.0" futures = "0.3" futures01 = { package = "futures", version = "0.1.29" } log = "0.4.8" -libp2p = { version = "0.15.0", default-features = false } +libp2p = { version = "0.16.0", default-features = false } console_error_panic_hook = "0.1.6" console_log = "0.1.2" js-sys = "0.3.34" -- GitLab From 11b828292f3269c9baf89b88ce4e57df7488d972 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Mon, 17 Feb 2020 13:42:44 +0300 Subject: [PATCH 160/180] Update import benchmark parameters (#4941) * update benchmark arguments * even more samples since it is fast now --- bin/node/testing/benches/import.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/node/testing/benches/import.rs b/bin/node/testing/benches/import.rs index 8c8439fc92..c58e01c3c1 100644 --- a/bin/node/testing/benches/import.rs +++ b/bin/node/testing/benches/import.rs @@ -69,7 +69,7 @@ use criterion::{Criterion, criterion_group, criterion_main}; criterion_group!( name = benches; - config = Criterion::default().sample_size(10); + config = Criterion::default().sample_size(50).warm_up_time(std::time::Duration::from_secs(20)); targets = bench_block_import ); criterion_group!( -- GitLab From d802fe261fe847a85314200975062100a4738a0c Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Mon, 17 Feb 2020 14:26:10 +0300 Subject: [PATCH 161/180] Database & keyring generation for benchmarks optimised (#4945) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * reorganize and optimize * Update bin/node/testing/benches/import.rs Co-Authored-By: Bastian Köcher * Update bin/node/testing/benches/import.rs Co-Authored-By: Bastian Köcher * Update bin/node/testing/benches/import.rs Co-Authored-By: Bastian Köcher * review suggestions * fix build Co-authored-by: Bastian Köcher --- bin/node/testing/benches/import.rs | 329 +++++++++++++++-------------- 1 file changed, 172 insertions(+), 157 deletions(-) diff --git a/bin/node/testing/benches/import.rs b/bin/node/testing/benches/import.rs index c58e01c3c1..9ffeb4ffd7 100644 --- a/bin/node/testing/benches/import.rs +++ b/bin/node/testing/benches/import.rs @@ -92,15 +92,172 @@ fn genesis(keyring: &BenchKeyring) -> node_runtime::GenesisConfig { // //endowed-user//01 // ... // //endowed-user//N +#[derive(Clone)] struct BenchKeyring { accounts: BTreeMap, } +// This is prepared database with genesis and keyring +// that can be cloned and then used for any benchmarking. +struct BenchDb { + keyring: BenchKeyring, + directory_guard: Guard, +} + +impl Clone for BenchDb { + fn clone(&self) -> Self { + let keyring = self.keyring.clone(); + let dir = tempdir::TempDir::new("sub-bench").expect("temp dir creation failed"); + + let seed_dir = self.directory_guard.0.path(); + + log::trace!( + target: "bench-logistics", + "Copying seed db from {} to {}", + seed_dir.to_string_lossy(), + dir.path().to_string_lossy(), + ); + let seed_db_files = std::fs::read_dir(seed_dir) + .expect("failed to list file in seed dir") + .map(|f_result| + f_result.expect("failed to read file in seed db") + .path() + .clone() + ).collect(); + fs_extra::copy_items( + &seed_db_files, + dir.path(), + &fs_extra::dir::CopyOptions::new(), + ).expect("Copy of seed database is ok"); + + BenchDb { keyring, directory_guard: Guard(dir) } + } +} + +impl BenchDb { + fn new(keyring_length: usize) -> Self { + let keyring = BenchKeyring::new(keyring_length); + + let dir = tempdir::TempDir::new("sub-bench").expect("temp dir creation failed"); + log::trace!( + target: "bench-logistics", + "Created seed db at {}", + dir.path().to_string_lossy(), + ); + let (_client, _backend) = bench_client(dir.path(), Profile::Native, &keyring); + let directory_guard = Guard(dir); + + BenchDb { keyring, directory_guard } + } + + fn generate_block(&mut self) -> Block { + let (client, _backend) = bench_client( + self.directory_guard.path(), + Profile::Wasm, + &self.keyring, + ); + + let version = client.runtime_version_at(&BlockId::number(0)) + .expect("There should be runtime version at 0") + .spec_version; + + let genesis_hash = client.block_hash(Zero::zero()) + .expect("Database error?") + .expect("Genesis block always exists; qed") + .into(); + + let mut block = client + .new_block(Default::default()) + .expect("Block creation failed"); + + let timestamp = 1 * MinimumPeriod::get(); + + let mut inherent_data = InherentData::new(); + inherent_data.put_data(sp_timestamp::INHERENT_IDENTIFIER, ×tamp) + .expect("Put timestamb failed"); + inherent_data.put_data(sp_finality_tracker::INHERENT_IDENTIFIER, &0) + .expect("Put finality tracker failed"); + + for extrinsic in client.runtime_api() + .inherent_extrinsics_with_context( + &BlockId::number(0), + ExecutionContext::BlockConstruction, + inherent_data, + ).expect("Get inherents failed") + { + block.push(extrinsic).expect("Push inherent failed"); + } + + let mut iteration = 0; + let start = std::time::Instant::now(); + for _ in 0..100 { + + let sender = self.keyring.at(iteration); + let receiver = get_account_id_from_seed::( + &format!("random-user//{}", iteration) + ); + + let signed = self.keyring.sign( + CheckedExtrinsic { + signed: Some((sender, signed_extra(0, 1*DOLLARS))), + function: Call::Balances( + BalancesCall::transfer( + pallet_indices::address::Address::Id(receiver), + 1*DOLLARS + ) + ), + }, + version, + genesis_hash, + ); + + let encoded = Encode::encode(&signed); + + let opaque = OpaqueExtrinsic::decode(&mut &encoded[..]) + .expect("Failed to decode opaque"); + + match block.push(opaque) { + Err(sp_blockchain::Error::ApplyExtrinsicFailed( + sp_blockchain::ApplyExtrinsicFailed::Validity(e) + )) if e.exhausted_resources() => { + break; + }, + Err(err) => panic!("Error pushing transaction: {:?}", err), + Ok(_) => {}, + } + iteration += 1; + } + let block = block.build().expect("Block build failed").block; + + log::info!( + target: "bench-logistics", + "Block construction: {:#?} ({} tx)", + start.elapsed(), block.extrinsics.len() + ); + + block + } + + fn path(&self) -> &Path { + self.directory_guard.path() + } + + fn create_context(&self, profile: Profile) -> BenchContext { + let BenchDb { directory_guard, keyring } = self.clone(); + let (client, backend) = bench_client(directory_guard.path(), profile, &keyring); + + BenchContext { + client, backend, db_guard: directory_guard, + } + } +} + impl BenchKeyring { - fn new(num: usize) -> Self { + // `length` is the number of random accounts generated. + fn new(length: usize) -> Self { let mut accounts = BTreeMap::new(); - for n in 0..num { + for n in 0..length { let seed = format!("//endowed-user/{}", n); let pair = sr25519::Pair::from_string(&seed, None).expect("failed to generate pair"); let account_id = AccountPublic::from(pair.public()).into_account(); @@ -200,63 +357,16 @@ fn bench_client(dir: &std::path::Path, profile: Profile, keyring: &BenchKeyring) struct Guard(tempdir::TempDir); +impl Guard { + fn path(&self) -> &Path { + self.0.path() + } +} + struct BenchContext { client: Client, backend: Arc, db_guard: Guard, - keyring: BenchKeyring, -} - -impl BenchContext { - fn new(profile: Profile) -> BenchContext { - let keyring = BenchKeyring::new(128); - - let dir = tempdir::TempDir::new("sub-bench").expect("temp dir creation failed"); - log::trace!( - target: "bench-logistics", - "Created seed db at {}", - dir.path().to_string_lossy(), - ); - let (client, backend) = bench_client(dir.path(), profile, &keyring); - let db_guard = Guard(dir); - - - BenchContext { client, backend, db_guard, keyring } - } - - fn new_from_seed(profile: Profile, seed_dir: &Path) -> BenchContext { - let keyring = BenchKeyring::new(128); - - let dir = tempdir::TempDir::new("sub-bench").expect("temp dir creation failed"); - - log::trace!( - target: "bench-logistics", - "Copying seed db from {} to {}", - seed_dir.to_string_lossy(), - dir.path().to_string_lossy(), - ); - let seed_db_files = std::fs::read_dir(seed_dir) - .expect("failed to list file in seed dir") - .map(|f_result| - f_result.expect("failed to read file in seed db") - .path() - .clone() - ).collect(); - fs_extra::copy_items( - &seed_db_files, - dir.path(), - &fs_extra::dir::CopyOptions::new(), - ).expect("Copy of seed database is ok"); - - let (client, backend) = bench_client(dir.path(), profile, &keyring); - let db_guard = Guard(dir); - - BenchContext { client, backend, db_guard, keyring } - } - - fn keep_db(self) -> Guard { - self.db_guard - } } type AccountPublic = ::Signer; @@ -274,88 +384,6 @@ where AccountPublic::from(get_from_seed::(seed)).into_account() } -// Block generation. -fn generate_block_import(client: &Client, keyring: &BenchKeyring) -> Block { - let version = client.runtime_version_at(&BlockId::number(0)) - .expect("There should be runtime version at 0") - .spec_version; - let genesis_hash = client.block_hash(Zero::zero()) - .expect("Database error?") - .expect("Genesis block always exists; qed") - .into(); - - let mut block = client - .new_block(Default::default()) - .expect("Block creation failed"); - - let timestamp = 1 * MinimumPeriod::get(); - - let mut inherent_data = InherentData::new(); - inherent_data.put_data(sp_timestamp::INHERENT_IDENTIFIER, ×tamp) - .expect("Put timestamb failed"); - inherent_data.put_data(sp_finality_tracker::INHERENT_IDENTIFIER, &0) - .expect("Put finality tracker failed"); - - for extrinsic in client.runtime_api() - .inherent_extrinsics_with_context( - &BlockId::number(0), - ExecutionContext::BlockConstruction, - inherent_data, - ).expect("Get inherents failed") - { - block.push(extrinsic).expect("Push inherent failed"); - } - - let mut iteration = 0; - let start = std::time::Instant::now(); - for _ in 0..100 { - - let sender = keyring.at(iteration); - let receiver = get_account_id_from_seed::( - &format!("random-user//{}", iteration) - ); - - let signed = keyring.sign( - CheckedExtrinsic { - signed: Some((sender, signed_extra(0, 1*DOLLARS))), - function: Call::Balances( - BalancesCall::transfer( - pallet_indices::address::Address::Id(receiver), - 1*DOLLARS - ) - ), - }, - version, - genesis_hash, - ); - - let encoded = Encode::encode(&signed); - - let opaque = OpaqueExtrinsic::decode(&mut &encoded[..]) - .expect("Failed to decode opaque"); - - match block.push(opaque) { - Err(sp_blockchain::Error::ApplyExtrinsicFailed( - sp_blockchain::ApplyExtrinsicFailed::Validity(e) - )) if e.exhausted_resources() => { - break; - }, - Err(err) => panic!("Error pushing transaction: {:?}", err), - Ok(_) => {}, - } - iteration += 1; - } - let block = block.build().expect("Block build failed").block; - - log::info!( - target: "bench-logistics", - "Block construction: {:#?} ({} tx)", - start.elapsed(), block.extrinsics.len() - ); - - block -} - // Import generated block. fn import_block(client: &mut Client, block: Block) { let mut import_params = BlockImportParams::new(BlockOrigin::NetworkBroadcast, block.header.clone()); @@ -387,26 +415,20 @@ fn bench_block_import(c: &mut Criterion) { // for future uses, uncomment if something wrong. // sc_cli::init_logger("sc_client=debug"); - let (block, guard) = { - let context = BenchContext::new(Profile::Wasm); - let block = generate_block_import(&context.client, &context.keyring); - (block, context.keep_db()) - }; + let mut bench_db = BenchDb::new(128); + let block = bench_db.generate_block(); log::trace!( target: "bench-logistics", "Seed database directory: {}", - guard.0.path().to_string_lossy(), + bench_db.path().display(), ); c.bench_function_over_inputs("import block", move |bencher, profile| { bencher.iter_batched( || { - let context = BenchContext::new_from_seed( - *profile, - guard.0.path(), - ); + let context = bench_db.create_context(*profile); // mostly to just launch compiler before benching! let version = context.client.runtime_version_at(&BlockId::Number(0)) @@ -454,21 +476,14 @@ fn bench_block_import(c: &mut Criterion) { fn profile_block_import(c: &mut Criterion) { sc_cli::init_logger(""); - let (block, guard) = { - let context = BenchContext::new(Profile::Wasm); - let block = generate_block_import(&context.client, &context.keyring); - (block, context.keep_db()) - }; + let mut bench_db = BenchDb::new(128); + let block = bench_db.generate_block(); c.bench_function("profile block", move |bencher| { bencher.iter_batched( || { - let context = BenchContext::new_from_seed( - Profile::Native, - guard.0.path(), - ); - context + bench_db.create_context(Profile::Native) }, |mut context| { // until better osx signpost/callgrind signal is possible to use -- GitLab From d2f0979351dc9cd99473aa7e9873e8c1c1bd6569 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Mon, 17 Feb 2020 16:48:24 +0300 Subject: [PATCH 162/180] Revalidation queue for transaction pool (#4781) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Revalidation queeue. * add docs and license * move test * refactor worker to async/await * address review * fix warnings * update Cargo.lock * move background task to service * use tomusdrw loop * naming * return From::from * add doc comment * add more doc comments * fix merge bug * add doc comment for test function * Update client/transaction-pool/src/testing/pool.rs Co-Authored-By: Tomasz Drwięga * more review fixes * refactor to allow service keep background tasks from isntantiated subsystems * use const delay * fix fallout * remove fallout * remove already moved test * fix doc test * add valid_at helper Co-authored-by: Tomasz Drwięga --- Cargo.lock | 1 + bin/node-template/node/src/service.rs | 3 +- bin/node/cli/src/service.rs | 3 +- .../basic-authorship/src/basic_authorship.rs | 4 +- client/basic-authorship/src/lib.rs | 2 +- client/consensus/manual-seal/src/lib.rs | 6 +- client/offchain/src/lib.rs | 2 +- client/rpc/src/author/tests.rs | 2 +- client/service/src/builder.rs | 43 ++- client/service/src/lib.rs | 2 +- client/transaction-pool/Cargo.toml | 1 + client/transaction-pool/graph/src/lib.rs | 1 + client/transaction-pool/graph/src/pool.rs | 127 +------ .../graph/src/validated_pool.rs | 26 +- client/transaction-pool/src/lib.rs | 53 +-- client/transaction-pool/src/revalidation.rs | 313 ++++++++++++++++++ client/transaction-pool/src/testing/pool.rs | 158 ++++++--- utils/frame/rpc/system/src/lib.rs | 2 +- 18 files changed, 554 insertions(+), 195 deletions(-) create mode 100644 client/transaction-pool/src/revalidation.rs diff --git a/Cargo.lock b/Cargo.lock index 30d75077d1..383e2cdce3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6487,6 +6487,7 @@ dependencies = [ "derive_more", "futures 0.3.4", "futures-diagnose", + "futures-timer 2.0.2", "log 0.4.8", "parity-scale-codec", "parity-util-mem", diff --git a/bin/node-template/node/src/service.rs b/bin/node-template/node/src/service.rs index cf5cb361fc..5466f3e919 100644 --- a/bin/node-template/node/src/service.rs +++ b/bin/node-template/node/src/service.rs @@ -41,8 +41,7 @@ macro_rules! new_full_start { })? .with_transaction_pool(|config, client, _fetcher| { let pool_api = sc_transaction_pool::FullChainApi::new(client.clone()); - let pool = sc_transaction_pool::BasicPool::new(config, std::sync::Arc::new(pool_api)); - Ok(pool) + Ok(sc_transaction_pool::BasicPool::new(config, std::sync::Arc::new(pool_api))) })? .with_import_queue(|_config, client, mut select_chain, transaction_pool| { let select_chain = select_chain.take() diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index dd2684d50e..ff53b9aa3a 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -63,8 +63,7 @@ macro_rules! new_full_start { })? .with_transaction_pool(|config, client, _fetcher| { let pool_api = sc_transaction_pool::FullChainApi::new(client.clone()); - let pool = sc_transaction_pool::BasicPool::new(config, std::sync::Arc::new(pool_api)); - Ok(pool) + Ok(sc_transaction_pool::BasicPool::new(config, std::sync::Arc::new(pool_api))) })? .with_import_queue(|_config, client, mut select_chain, _transaction_pool| { let select_chain = select_chain.take() diff --git a/client/basic-authorship/src/basic_authorship.rs b/client/basic-authorship/src/basic_authorship.rs index a9e3d28e21..cab1231e87 100644 --- a/client/basic-authorship/src/basic_authorship.rs +++ b/client/basic-authorship/src/basic_authorship.rs @@ -308,7 +308,7 @@ mod tests { // given let client = Arc::new(substrate_test_runtime_client::new()); let txpool = Arc::new( - BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone()))) + BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone()))).0 ); futures::executor::block_on( @@ -350,7 +350,7 @@ mod tests { .build_with_backend(); let client = Arc::new(client); let txpool = Arc::new( - BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone()))) + BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone()))).0 ); let genesis_hash = client.info().best_hash; let block_id = BlockId::Hash(genesis_hash); diff --git a/client/basic-authorship/src/lib.rs b/client/basic-authorship/src/lib.rs index 9f2bc6a761..e9087c89e0 100644 --- a/client/basic-authorship/src/lib.rs +++ b/client/basic-authorship/src/lib.rs @@ -26,7 +26,7 @@ //! # 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(), Arc::new(FullChainApi::new(client.clone())))); +//! # let txpool = Arc::new(BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone()))).0); //! // The first step is to create a `ProposerFactory`. //! let mut proposer_factory = ProposerFactory { //! client: client.clone(), diff --git a/client/consensus/manual-seal/src/lib.rs b/client/consensus/manual-seal/src/lib.rs index a334e7c72f..c4336485a1 100644 --- a/client/consensus/manual-seal/src/lib.rs +++ b/client/consensus/manual-seal/src/lib.rs @@ -243,7 +243,7 @@ mod tests { let client = Arc::new(builder.build()); let select_chain = LongestChain::new(backend.clone()); let inherent_data_providers = InherentDataProviders::new(); - let pool = Arc::new(BasicPool::new(Options::default(), api())); + let pool = Arc::new(BasicPool::new(Options::default(), api()).0); let env = ProposerFactory { transaction_pool: pool.clone(), client: client.clone(), @@ -308,7 +308,7 @@ mod tests { let client = Arc::new(builder.build()); let select_chain = LongestChain::new(backend.clone()); let inherent_data_providers = InherentDataProviders::new(); - let pool = Arc::new(BasicPool::new(Options::default(), api())); + let pool = Arc::new(BasicPool::new(Options::default(), api()).0); let env = ProposerFactory { transaction_pool: pool.clone(), client: client.clone(), @@ -377,7 +377,7 @@ mod tests { let select_chain = LongestChain::new(backend.clone()); let inherent_data_providers = InherentDataProviders::new(); let pool_api = api(); - let pool = Arc::new(BasicPool::new(Options::default(), pool_api.clone())); + let pool = Arc::new(BasicPool::new(Options::default(), pool_api.clone()).0); let env = ProposerFactory { transaction_pool: pool.clone(), client: client.clone(), diff --git a/client/offchain/src/lib.rs b/client/offchain/src/lib.rs index fadfaa0134..ac8cc14861 100644 --- a/client/offchain/src/lib.rs +++ b/client/offchain/src/lib.rs @@ -204,7 +204,7 @@ mod tests { let pool = Arc::new(TestPool(BasicPool::new( Default::default(), Arc::new(FullChainApi::new(client.clone())), - ))); + ).0)); client.execution_extensions() .register_transaction_pool(Arc::downgrade(&pool.clone()) as _); let db = sc_client_db::offchain::LocalStorage::new_test(); diff --git a/client/rpc/src/author/tests.rs b/client/rpc/src/author/tests.rs index ba9b9d344c..41bfc46d38 100644 --- a/client/rpc/src/author/tests.rs +++ b/client/rpc/src/author/tests.rs @@ -64,7 +64,7 @@ impl Default for TestSetup { let pool = Arc::new(BasicPool::new( Default::default(), Arc::new(FullChainApi::new(client.clone())), - )); + ).0); TestSetup { runtime: runtime::Runtime::new().expect("Failed to create runtime in test setup"), client, diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 5ca39856dc..2ab212646a 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -55,6 +55,8 @@ use sp_transaction_pool::{MaintainedTransactionPool, ChainEvent}; use sp_blockchain; use grafana_data_source::{self, record_metrics}; +pub type BackgroundTask = Pin + Send>>; + /// Aggregator for the components required to build a service. /// /// # Usage @@ -90,6 +92,7 @@ pub struct ServiceBuilder>>, marker: PhantomData<(TBl, TRtApi)>, + background_tasks: Vec<(&'static str, BackgroundTask)>, } /// Full client type. @@ -265,6 +268,7 @@ where TGen: RuntimeGenesis, TCSExt: Extension { transaction_pool: Arc::new(()), rpc_extensions: Default::default(), remote_backend: None, + background_tasks: Default::default(), marker: PhantomData, }) } @@ -350,6 +354,7 @@ where TGen: RuntimeGenesis, TCSExt: Extension { transaction_pool: Arc::new(()), rpc_extensions: Default::default(), remote_backend: Some(remote_blockchain), + background_tasks: Default::default(), marker: PhantomData, }) } @@ -398,6 +403,7 @@ impl( - self, + mut self, transaction_pool_builder: impl FnOnce( sc_transaction_pool::txpool::Options, Arc, Option, - ) -> Result + ) -> Result<(UExPool, Option), Error> ) -> Result, Error> where TSc: Clone, TFchr: Clone { - let transaction_pool = transaction_pool_builder( + let (transaction_pool, background_task) = transaction_pool_builder( self.config.transaction_pool.clone(), self.client.clone(), self.fetcher.clone(), )?; + if let Some(background_task) = background_task{ + self.background_tasks.push(("txpool-background", background_task)); + } + Ok(ServiceBuilder { config: self.config, client: self.client, @@ -625,6 +639,7 @@ impl None, }; + // Spawn background tasks which were stacked during the + // service building. + for (title, background_task) in background_tasks { + let _ = to_spawn_tx.unbounded_send(( + background_task, + title.into(), + )); + } + { // block notifications let txpool = Arc::downgrade(&transaction_pool); @@ -930,9 +956,10 @@ ServiceBuilder< ready(()) }); + let _ = to_spawn_tx.unbounded_send(( Box::pin(select(events, exit.clone()).map(drop)), - From::from("txpool-and-offchain-notif") + From::from("txpool-and-offchain-notif"), )); } @@ -955,7 +982,7 @@ ServiceBuilder< let _ = to_spawn_tx.unbounded_send(( Box::pin(select(events, exit.clone()).map(drop)), - From::from("telemetry-on-block") + From::from("telemetry-on-block"), )); } @@ -1028,7 +1055,7 @@ ServiceBuilder< let _ = to_spawn_tx.unbounded_send(( Box::pin(select(tel_task, exit.clone()).map(drop)), - From::from("telemetry-periodic-send") + From::from("telemetry-periodic-send"), )); // Periodically send the network state to the telemetry. @@ -1044,7 +1071,7 @@ ServiceBuilder< }); let _ = to_spawn_tx.unbounded_send(( Box::pin(select(tel_task_2, exit.clone()).map(drop)), - From::from("telemetry-periodic-network-state") + From::from("telemetry-periodic-network-state"), )); // RPC @@ -1130,7 +1157,7 @@ ServiceBuilder< system_rpc_rx, has_bootnodes, ), exit.clone()).map(drop)), - From::from("network-worker") + From::from("network-worker"), )); let telemetry_connection_sinks: Arc>>> = Default::default(); diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 8c2f57dd7c..55fdba706b 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -716,7 +716,7 @@ mod tests { let pool = Arc::new(BasicPool::new( Default::default(), Arc::new(FullChainApi::new(client.clone())), - )); + ).0); let best = longest_chain.best_chain().unwrap(); let transaction = Transfer { amount: 5, diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index 27aec1b92e..7ccc98a9c0 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -20,6 +20,7 @@ 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" } +futures-timer = "2.0" parity-util-mem = { version = "0.5.1", default-features = false, features = ["primitive-types"] } [dev-dependencies] diff --git a/client/transaction-pool/graph/src/lib.rs b/client/transaction-pool/graph/src/lib.rs index 23970ba9b8..ed10ef38d2 100644 --- a/client/transaction-pool/graph/src/lib.rs +++ b/client/transaction-pool/graph/src/lib.rs @@ -39,4 +39,5 @@ pub use self::pool::{ Pool, Options, ChainApi, EventStream, ExtrinsicFor, BlockHash, ExHash, NumberFor, TransactionFor, + ValidatedTransaction, }; diff --git a/client/transaction-pool/graph/src/pool.rs b/client/transaction-pool/graph/src/pool.rs index 392abdca48..103f556d0e 100644 --- a/client/transaction-pool/graph/src/pool.rs +++ b/client/transaction-pool/graph/src/pool.rs @@ -36,7 +36,8 @@ use sp_runtime::{ use sp_transaction_pool::error; use wasm_timer::Instant; -use crate::validated_pool::{ValidatedPool, ValidatedTransaction}; +use crate::validated_pool::ValidatedPool; +pub use crate::validated_pool::ValidatedTransaction; /// Modification notification event stream type; pub type EventStream = mpsc::UnboundedReceiver; @@ -182,39 +183,19 @@ impl Pool { self.validated_pool.submit_and_watch(tx) } - /// Revalidate all ready transactions. - /// - /// Returns future that performs validation of all ready transactions and - /// then resubmits all transactions back to the pool. - pub async fn revalidate_ready( + /// Resubmit some transaction that were validated elsewhere. + pub fn resubmit( &self, - at: &BlockId, - max: Option, - ) -> Result<(), B::Error> { - 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(); - let revalidated_transactions = self.verify(at, ready, false).await?; - log::debug!(target: "txpool", - "Re-verified transactions, took {} ms. Resubmitting.", - now.elapsed().as_millis() - ); + revalidated_transactions: HashMap, ValidatedTransactionFor>, + ) { let now = Instant::now(); self.validated_pool.resubmit(revalidated_transactions); log::debug!(target: "txpool", "Resubmitted. Took {} ms. Status: {:?}", now.elapsed().as_millis(), - validated_pool.status() + self.validated_pool.status() ); - Ok(()) } /// Prunes known ready transactions. @@ -402,21 +383,15 @@ impl Pool { if validity.provides.is_empty() { ValidatedTransaction::Invalid(hash.clone(), error::Error::NoTagsProvided.into()) } else { - ValidatedTransaction::Valid(base::Transaction { - data: xt, + ValidatedTransaction::valid_at( + block_number.saturated_into::(), + hash.clone(), + xt, bytes, - hash: hash.clone(), - priority: validity.priority, - requires: validity.requires, - provides: validity.provides, - propagate: validity.propagate, - valid_till: block_number - .saturated_into::() - .saturating_add(validity.longevity), - }) + validity, + ) } }, - Err(TransactionValidityError::Invalid(e)) => ValidatedTransaction::Invalid(hash.clone(), error::Error::InvalidTransaction(e).into()), Err(TransactionValidityError::Unknown(e)) => @@ -988,80 +963,4 @@ mod tests { assert_eq!(pool.validated_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.validated_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.validated_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/validated_pool.rs b/client/transaction-pool/graph/src/validated_pool.rs index 8752414637..a62822a918 100644 --- a/client/transaction-pool/graph/src/validated_pool.rs +++ b/client/transaction-pool/graph/src/validated_pool.rs @@ -32,7 +32,7 @@ use parking_lot::{Mutex, RwLock}; use sp_runtime::{ generic::BlockId, traits::{self, SaturatedConversion}, - transaction_validity::TransactionTag as Tag, + transaction_validity::{TransactionTag as Tag, ValidTransaction}, }; use sp_transaction_pool::{error, PoolStatus}; use wasm_timer::Instant; @@ -53,6 +53,30 @@ pub enum ValidatedTransaction { Unknown(Hash, Error), } +impl ValidatedTransaction { + /// Consume validity result, transaction data and produce ValidTransaction. + pub fn valid_at( + at: u64, + hash: Hash, + data: Ex, + bytes: usize, + validity: ValidTransaction, + ) -> Self { + Self::Valid(base::Transaction { + data, + bytes, + hash, + priority: validity.priority, + requires: validity.requires, + provides: validity.provides, + propagate: validity.propagate, + valid_till: at + .saturated_into::() + .saturating_add(validity.longevity), + }) + } +} + /// A type of validated transaction stored in the pool. pub type ValidatedTransactionFor = ValidatedTransaction< ExHash, diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index fbfc6a24e6..a69323553f 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -21,6 +21,7 @@ mod api; pub mod error; +mod revalidation; #[cfg(any(feature = "test-helpers", test))] pub mod testing; @@ -51,6 +52,7 @@ pub struct BasicPool pool: Arc>, api: Arc, revalidation_strategy: Arc>>>, + revalidation_queue: Arc>, } #[cfg(not(target_os = "unknown"))] @@ -86,13 +88,16 @@ pub enum RevalidationType { impl BasicPool where Block: BlockT, - PoolApi: sc_transaction_graph::ChainApi, + PoolApi: sc_transaction_graph::ChainApi + 'static, { /// Create new basic transaction pool with provided api. + /// + /// It will also optionally return background task that might be started by the + /// caller. pub fn new( options: sc_transaction_graph::Options, pool_api: Arc, - ) -> Self { + ) -> (Self, Option + Send>>>) { Self::with_revalidation_type(options, pool_api, RevalidationType::Full) } @@ -102,18 +107,29 @@ impl BasicPool options: sc_transaction_graph::Options, pool_api: Arc, revalidation_type: RevalidationType, - ) -> Self { - let cloned_api = pool_api.clone(); - BasicPool { - api: cloned_api, - pool: Arc::new(sc_transaction_graph::Pool::new(options, pool_api)), - revalidation_strategy: Arc::new(Mutex::new( - match revalidation_type { - RevalidationType::Light => RevalidationStrategy::Light(RevalidationStatus::NotScheduled), - RevalidationType::Full => RevalidationStrategy::Always, - } - )), - } + ) -> (Self, Option + Send>>>) { + let pool = Arc::new(sc_transaction_graph::Pool::new(options, pool_api.clone())); + let (revalidation_queue, background_task) = match revalidation_type { + RevalidationType::Light => (revalidation::RevalidationQueue::new(pool_api.clone(), pool.clone()), None), + RevalidationType::Full => { + let (queue, background) = revalidation::RevalidationQueue::new_background(pool_api.clone(), pool.clone()); + (queue, Some(background)) + }, + }; + ( + BasicPool { + api: pool_api, + pool, + revalidation_queue: Arc::new(revalidation_queue), + revalidation_strategy: Arc::new(Mutex::new( + match revalidation_type { + RevalidationType::Light => RevalidationStrategy::Light(RevalidationStatus::NotScheduled), + RevalidationType::Full => RevalidationStrategy::Always, + } + )), + }, + background_task, + ) } /// Gets shared reference to the underlying pool. @@ -218,7 +234,6 @@ enum RevalidationStrategy { struct RevalidationAction { revalidate: bool, resubmit: bool, - revalidate_amount: Option, } impl RevalidationStrategy { @@ -242,12 +257,10 @@ impl RevalidationStrategy { revalidate_block_period, ), resubmit: false, - revalidate_amount: None, }, Self::Always => RevalidationAction { revalidate: true, resubmit: true, - revalidate_amount: Some(16), } } } @@ -314,6 +327,7 @@ impl MaintainedTransactionPool for BasicPool ); let revalidation_strategy = self.revalidation_strategy.clone(); let retracted = retracted.clone(); + let revalidation_queue = self.revalidation_queue.clone(); async move { // We don't query block if we won't prune anything @@ -360,9 +374,8 @@ impl MaintainedTransactionPool for BasicPool } if next_action.revalidate { - if let Err(e) = pool.revalidate_ready(&id, next_action.revalidate_amount).await { - log::warn!("Revalidate ready failed {:?}", e); - } + let hashes = pool.validated_pool().ready().map(|tx| tx.hash.clone()).collect(); + revalidation_queue.revalidate_later(block_number, hashes).await; } revalidation_strategy.lock().clear(); diff --git a/client/transaction-pool/src/revalidation.rs b/client/transaction-pool/src/revalidation.rs new file mode 100644 index 0000000000..dbf8a29354 --- /dev/null +++ b/client/transaction-pool/src/revalidation.rs @@ -0,0 +1,313 @@ +// Copyright 2018-2020 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 . + +//! Pool periodic revalidation. + +use std::{sync::Arc, pin::Pin, collections::{HashMap, HashSet, BTreeMap}}; + +use sc_transaction_graph::{ChainApi, Pool, ExHash, NumberFor, ValidatedTransaction}; +use sp_runtime::traits::{Zero, SaturatedConversion}; +use sp_runtime::generic::BlockId; +use sp_runtime::transaction_validity::TransactionValidityError; + +use futures::{prelude::*, channel::mpsc, stream::unfold}; +use std::time::Duration; +use futures_timer::Delay; + +#[cfg(not(test))] +const BACKGROUND_REVALIDATION_INTERVAL: Duration = Duration::from_millis(200); +#[cfg(test)] +pub const BACKGROUND_REVALIDATION_INTERVAL: Duration = Duration::from_millis(5); + +const BACKGROUND_REVALIDATION_BATCH_SIZE: usize = 20; + +/// Payload from queue to worker. +struct WorkerPayload { + at: NumberFor, + transactions: Vec>, +} + +/// Async revalidation worker. +/// +/// Implements future and can be spawned in place or in background. +struct RevalidationWorker { + api: Arc, + pool: Arc>, + best_block: NumberFor, + block_ordered: BTreeMap, HashSet>>, + members: HashMap, NumberFor>, +} + +impl Unpin for RevalidationWorker {} + +fn interval(duration: Duration) -> impl Stream + Unpin { + unfold((), move |_| { + Delay::new(duration).map(|_| Some(((), ()))) + }).map(drop) +} + +/// Revalidate batch of transaction. +/// +/// Each transaction is validated against chain, and invalid are +/// removed from the `pool`, while valid are resubmitted. +async fn batch_revalidate( + pool: Arc>, + api: Arc, + at: NumberFor, + batch: impl IntoIterator>, +) { + let mut invalid_hashes = Vec::new(); + let mut revalidated = HashMap::new(); + + for ext_hash in batch { + let ext = match pool.validated_pool().ready_by_hash(&ext_hash) { + Some(ext) => ext, + None => continue, + }; + + match api.validate_transaction(&BlockId::Number(at), ext.data.clone()).await { + Ok(Err(TransactionValidityError::Invalid(err))) => { + log::debug!(target: "txpool", "[{:?}]: Revalidation: invalid {:?}", ext_hash, err); + invalid_hashes.push(ext_hash); + }, + Ok(Err(TransactionValidityError::Unknown(err))) => { + // skipping unknown, they might be pushed by valid or invalid transaction + // when latter resubmitted. + log::trace!(target: "txpool", "[{:?}]: Unknown during revalidation: {:?}", ext_hash, err); + }, + Ok(Ok(validity)) => { + revalidated.insert( + ext_hash.clone(), + ValidatedTransaction::valid_at( + at.saturated_into::(), + ext_hash, + ext.data.clone(), + api.hash_and_length(&ext.data).1, + validity, + ) + ); + }, + Err(validation_err) => { + log::debug!( + target: "txpool", + "[{:?}]: Error during revalidation: {:?}. Removing.", + ext_hash, + validation_err + ); + invalid_hashes.push(ext_hash); + } + } + } + + pool.validated_pool().remove_invalid(&invalid_hashes); + pool.resubmit(revalidated); +} + +impl RevalidationWorker { + fn new( + api: Arc, + pool: Arc>, + ) -> Self { + Self { + api, + pool, + block_ordered: Default::default(), + members: Default::default(), + best_block: Zero::zero(), + } + } + + fn prepare_batch(&mut self) -> Vec> { + let mut queued_exts = Vec::new(); + let mut left = BACKGROUND_REVALIDATION_BATCH_SIZE; + + // Take maximum of count transaction by order + // which they got into the pool + while left > 0 { + let first_block = match self.block_ordered.keys().next().cloned() { + Some(bn) => bn, + None => break, + }; + let mut block_drained = false; + if let Some(extrinsics) = self.block_ordered.get_mut(&first_block) { + let to_queue = extrinsics.iter().take(left).cloned().collect::>(); + if to_queue.len() == extrinsics.len() { + block_drained = true; + } else { + for xt in &to_queue { + extrinsics.remove(xt); + } + } + left -= to_queue.len(); + queued_exts.extend(to_queue); + } + + if block_drained { + self.block_ordered.remove(&first_block); + } + } + + queued_exts + } + + fn push(&mut self, worker_payload: WorkerPayload) { + // we don't add something that already scheduled for revalidation + let transactions = worker_payload.transactions; + let block_number = worker_payload.at; + + for ext_hash in transactions { + // we don't add something that already scheduled for revalidation + if self.members.contains_key(&ext_hash) { continue; } + + self.block_ordered.entry(block_number) + .and_modify(|value| { value.insert(ext_hash.clone()); }) + .or_insert_with(|| { + let mut bt = HashSet::new(); + bt.insert(ext_hash.clone()); + bt + }); + self.members.insert(ext_hash.clone(), block_number); + } + } + + /// Background worker main loop. + /// + /// It does two things: periodically tries to process some transactions + /// from the queue and also accepts messages to enqueue some more + /// transactions from the pool. + pub async fn run(mut self, from_queue: mpsc::UnboundedReceiver>) { + let interval = interval(BACKGROUND_REVALIDATION_INTERVAL).fuse(); + let from_queue = from_queue.fuse(); + futures::pin_mut!(interval, from_queue); + let this = &mut self; + + loop { + futures::select! { + _ = interval.next() => { + let next_batch = this.prepare_batch(); + batch_revalidate(this.pool.clone(), this.api.clone(), this.best_block, next_batch).await; + }, + workload = from_queue.next() => { + match workload { + Some(worker_payload) => { + this.best_block = worker_payload.at; + this.push(worker_payload); + continue; + }, + // R.I.P. worker! + None => break, + } + } + } + } + } +} + + +/// Revalidation queue. +/// +/// Can be configured background (`new_background`) +/// or immediate (just `new`). +pub struct RevalidationQueue { + pool: Arc>, + api: Arc, + background: Option>>, +} + +impl RevalidationQueue +where + Api: 'static, +{ + /// New revalidation queue without background worker. + pub fn new(api: Arc, pool: Arc>) -> Self { + Self { + api, + pool, + background: None, + } + } + + /// New revalidation queue with background worker. + pub fn new_background(api: Arc, pool: Arc>) -> + (Self, Pin + Send>>) + { + let (to_worker, from_queue) = mpsc::unbounded(); + + let worker = RevalidationWorker::new(api.clone(), pool.clone()); + + let queue = + Self { + api, + pool, + background: Some(to_worker), + }; + + (queue, worker.run(from_queue).boxed()) + } + + /// Queue some transaction for later revalidation. + /// + /// If queue configured with background worker, this will return immediately. + /// If queue configured without background worker, this will resolve after + /// revalidation is actually done. + pub async fn revalidate_later(&self, at: NumberFor, transactions: Vec>) { + if let Some(ref to_worker) = self.background { + if let Err(e) = to_worker.unbounded_send(WorkerPayload { at, transactions }) { + log::warn!(target: "txpool", "Failed to update background worker: {:?}", e); + } + return; + } else { + let pool = self.pool.clone(); + let api = self.api.clone(); + batch_revalidate(pool, api, at, transactions).await + } + } +} + +#[cfg(test)] +mod tests { + + use super::*; + use sc_transaction_graph::Pool; + use substrate_test_runtime_transaction_pool::{TestApi, uxt}; + use futures::executor::block_on; + use substrate_test_runtime_client::{ + AccountKeyring::*, + }; + + fn setup() -> (Arc, Pool) { + let test_api = Arc::new(TestApi::empty()); + let pool = Pool::new(Default::default(), test_api.clone()); + (test_api, pool) + } + + #[test] + fn smoky() { + let (api, pool) = setup(); + let pool = Arc::new(pool); + let queue = Arc::new(RevalidationQueue::new(api.clone(), pool.clone())); + + let uxt = uxt(Alice, 0); + let uxt_hash = block_on(pool.submit_one(&BlockId::number(0), uxt.clone())).expect("Should be valid"); + + block_on(queue.revalidate_later(0, vec![uxt_hash])); + + // revalidated in sync offload 2nd time + assert_eq!(api.validation_requests().len(), 2); + // number of ready + assert_eq!(pool.validated_pool().status().ready, 1); + } +} \ No newline at end of file diff --git a/client/transaction-pool/src/testing/pool.rs b/client/transaction-pool/src/testing/pool.rs index 4a4f4638df..ed7c3e2d7a 100644 --- a/client/transaction-pool/src/testing/pool.rs +++ b/client/transaction-pool/src/testing/pool.rs @@ -15,6 +15,7 @@ // along with Substrate. If not, see . use crate::*; +use sp_transaction_pool::TransactionStatus; use futures::executor::block_on; use txpool::{self, Pool}; use sp_runtime::{ @@ -22,18 +23,22 @@ use sp_runtime::{ transaction_validity::ValidTransaction, }; use substrate_test_runtime_client::{ - runtime::{Block, Hash, Index, Header}, + runtime::{Block, Hash, Index, Header, Extrinsic}, AccountKeyring::*, }; use substrate_test_runtime_transaction_pool::{TestApi, uxt}; -use sp_transaction_pool::TransactionStatus; +use crate::revalidation::BACKGROUND_REVALIDATION_INTERVAL; fn pool() -> Pool { Pool::new(Default::default(), TestApi::with_alice_nonce(209).into()) } -fn maintained_pool() -> BasicPool { - BasicPool::new(Default::default(), std::sync::Arc::new(TestApi::with_alice_nonce(209))) +fn maintained_pool() -> (BasicPool, futures::executor::ThreadPool) { + let (pool, background_task) = BasicPool::new(Default::default(), std::sync::Arc::new(TestApi::with_alice_nonce(209))); + + let thread_pool = futures::executor::ThreadPool::new().unwrap(); + thread_pool.spawn_ok(background_task.expect("basic pool have background task")); + (pool, thread_pool) } fn header(number: u64) -> Header { @@ -158,25 +163,37 @@ fn should_correctly_prune_transactions_providing_more_than_one_tag() { assert_eq!(pool.validated_pool().status().future, 2); } +fn block_event(id: u64) -> ChainEvent { + ChainEvent::NewBlock { + id: BlockId::number(id), + is_new_best: true, + retracted: vec![], + header: header(id), + } +} + +fn block_event_with_retracted(id: u64, retracted: Vec) -> ChainEvent { + ChainEvent::NewBlock { + id: BlockId::number(id), + is_new_best: true, + retracted: retracted, + header: header(id), + } +} + + #[test] fn should_prune_old_during_maintenance() { let xt = uxt(Alice, 209); - let pool = maintained_pool(); + let (pool, _guard) = maintained_pool(); block_on(pool.submit_one(&BlockId::number(0), xt.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 1); pool.api.push_block(1, vec![xt.clone()]); - let event = ChainEvent::NewBlock { - id: BlockId::number(1), - is_new_best: true, - retracted: vec![], - header: header(1), - }; - - block_on(pool.maintain(event)); + block_on(pool.maintain(block_event(1))); assert_eq!(pool.status().ready, 0); } @@ -185,21 +202,20 @@ fn should_revalidate_during_maintenance() { let xt1 = uxt(Alice, 209); let xt2 = uxt(Alice, 210); - let pool = maintained_pool(); + let (pool, _guard) = maintained_pool(); block_on(pool.submit_one(&BlockId::number(0), xt1.clone())).expect("1. Imported"); block_on(pool.submit_one(&BlockId::number(0), xt2.clone())).expect("2. Imported"); assert_eq!(pool.status().ready, 2); assert_eq!(pool.api.validation_requests().len(), 2); pool.api.push_block(1, vec![xt1.clone()]); - let event = ChainEvent::NewBlock { - id: BlockId::number(1), - is_new_best: true, - retracted: vec![], - header: header(1), - }; - block_on(pool.maintain(event)); + block_on(pool.maintain(block_event(1))); + + // maintaince is in background + block_on(futures_timer::Delay::new(BACKGROUND_REVALIDATION_INTERVAL*2)); + + block_on(pool.maintain(block_event(1))); assert_eq!(pool.status().ready, 1); // test that pool revalidated transaction that left ready and not included in the block assert_eq!(pool.api.validation_requests().len(), 3); @@ -210,19 +226,15 @@ fn should_resubmit_from_retracted_during_maintaince() { let xt = uxt(Alice, 209); let retracted_hash = Hash::random(); - let pool = maintained_pool(); + let (pool, _guard) = maintained_pool(); block_on(pool.submit_one(&BlockId::number(0), xt.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 1); pool.api.push_block(1, vec![]); pool.api.push_fork_block(retracted_hash, vec![xt.clone()]); - let event = ChainEvent::NewBlock { - id: BlockId::Number(1), - is_new_best: true, - header: header(1), - retracted: vec![retracted_hash] - }; + + let event = block_event_with_retracted(1, vec![retracted_hash]); block_on(pool.maintain(event)); assert_eq!(pool.status().ready, 1); @@ -233,7 +245,7 @@ fn should_not_retain_invalid_hashes_from_retracted() { let xt = uxt(Alice, 209); let retracted_hash = Hash::random(); - let pool = maintained_pool(); + let (pool, _guard) = maintained_pool(); block_on(pool.submit_one(&BlockId::number(0), xt.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 1); @@ -242,20 +254,90 @@ fn should_not_retain_invalid_hashes_from_retracted() { pool.api.push_fork_block(retracted_hash, vec![xt.clone()]); pool.api.add_invalid(&xt); - let event = ChainEvent::NewBlock { - id: BlockId::Number(1), - is_new_best: true, - header: header(1), - retracted: vec![retracted_hash] - }; + let event = block_event_with_retracted(1, vec![retracted_hash]); + + block_on(pool.maintain(event)); + + // maintenance is in background + block_on(futures_timer::Delay::new(BACKGROUND_REVALIDATION_INTERVAL*2)); + + let event = block_event_with_retracted(1, vec![retracted_hash]); block_on(pool.maintain(event)); assert_eq!(pool.status().ready, 0); } +#[test] +fn should_push_watchers_during_maintaince() { + fn alice_uxt(nonce: u64) -> Extrinsic { + uxt(Alice, 209 + nonce) + } + + // given + let (pool, _guard) = maintained_pool(); + + let tx0 = alice_uxt(0); + let watcher0 = block_on(pool.submit_and_watch(&BlockId::Number(0), tx0.clone())).unwrap(); + let tx1 = alice_uxt(1); + let watcher1 = block_on(pool.submit_and_watch(&BlockId::Number(0), tx1.clone())).unwrap(); + let tx2 = alice_uxt(2); + let watcher2 = block_on(pool.submit_and_watch(&BlockId::Number(0), tx2.clone())).unwrap(); + let tx3 = alice_uxt(3); + let watcher3 = block_on(pool.submit_and_watch(&BlockId::Number(0), tx3.clone())).unwrap(); + let tx4 = alice_uxt(4); + let watcher4 = block_on(pool.submit_and_watch(&BlockId::Number(0), tx4.clone())).unwrap(); + assert_eq!(pool.status().ready, 5); + + // when + pool.api.add_invalid(&tx3); + pool.api.add_invalid(&tx4); + block_on(pool.maintain(block_event(0))); + + // revalidation is in background + block_on(futures_timer::Delay::new(BACKGROUND_REVALIDATION_INTERVAL*2)); + + // then + // hash3 is now invalid + // hash4 is now invalid + + assert_eq!(pool.status().ready, 3); + assert_eq!( + futures::executor::block_on_stream(watcher3).collect::>(), + vec![TransactionStatus::Ready, TransactionStatus::Invalid], + ); + assert_eq!( + futures::executor::block_on_stream(watcher4).collect::>(), + vec![TransactionStatus::Ready, TransactionStatus::Invalid], + ); + + // when + let header_hash = pool.api.push_block(1, vec![tx0, tx1, tx2]).hash(); + block_on(pool.maintain(block_event(1))); + + let event = ChainEvent::Finalized { hash: header_hash.clone() }; + block_on(pool.maintain(event)); + + // then + // events for hash0 are: Ready, InBlock + // events for hash1 are: Ready, InBlock + // events for hash2 are: Ready, InBlock + assert_eq!( + futures::executor::block_on_stream(watcher0).collect::>(), + vec![TransactionStatus::Ready, TransactionStatus::InBlock(header_hash.clone()), TransactionStatus::Finalized(header_hash.clone())], + ); + assert_eq!( + futures::executor::block_on_stream(watcher1).collect::>(), + vec![TransactionStatus::Ready, TransactionStatus::InBlock(header_hash.clone()), TransactionStatus::Finalized(header_hash.clone())], + ); + assert_eq!( + futures::executor::block_on_stream(watcher2).collect::>(), + vec![TransactionStatus::Ready, TransactionStatus::InBlock(header_hash.clone()), TransactionStatus::Finalized(header_hash.clone())], + ); +} + #[test] fn can_track_heap_size() { - let pool = maintained_pool(); + let (pool, _guard) = maintained_pool(); block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 209))).expect("1. Imported"); block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 210))).expect("1. Imported"); block_on(pool.submit_one(&BlockId::number(0), uxt(Alice, 211))).expect("1. Imported"); @@ -269,7 +351,7 @@ fn finalization() { let xt = uxt(Alice, 209); let api = TestApi::with_alice_nonce(209); api.push_block(1, vec![]); - let pool = BasicPool::new(Default::default(), api.into()); + let (pool, _background) = BasicPool::new(Default::default(), api.into()); let watcher = block_on(pool.submit_and_watch(&BlockId::number(1), xt.clone())).expect("1. Imported"); pool.api.push_block(2, vec![xt.clone()]); @@ -298,7 +380,7 @@ fn fork_aware_finalization() { // starting block A1 (last finalized.) api.push_block(1, vec![]); - let pool = BasicPool::new(Default::default(), api.into()); + let (pool, _background) = BasicPool::new(Default::default(), api.into()); let mut canon_watchers = vec![]; let from_alice = uxt(Alice, 1); diff --git a/utils/frame/rpc/system/src/lib.rs b/utils/frame/rpc/system/src/lib.rs index 9cc01fb6ec..46204082be 100644 --- a/utils/frame/rpc/system/src/lib.rs +++ b/utils/frame/rpc/system/src/lib.rs @@ -236,7 +236,7 @@ mod tests { let _ = env_logger::try_init(); let client = Arc::new(substrate_test_runtime_client::new()); let pool = Arc::new( - BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone()))) + BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone()))).0 ); let new_transaction = |nonce: u64| { -- GitLab From db1ab7d18fbe7876cdea43bbf30f147ddd263f94 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Mon, 17 Feb 2020 15:07:24 +0100 Subject: [PATCH 163/180] Fix various spelling errors (#4940) * meaningfull -> meaningful * initialise -> initialize * tokans -> tokens * incentivise -> incentivize * lenght -> length * incentivisation -> incentivization * doesnt't -> doesn't * overwriten -> overwritten * lifecycle -> life cycle * lifecycle -> life cycle * usefull -> useful * noone -> no one * spaming -> spamming * defered -> deferred * hieght -> height * sumation -> summation * ingore -> ignore * registed -> registered * Auxialary -> Auxiliary * loggin -> logging * independance -> independence * trailling -> trailing * responsability -> responsibility * trunkated -> truncated * Weither -> Whether * informations -> information * Runtume -> Runtime * choosen -> chosen * delcataion -> declaration * Unchekced -> Unchecked * defintion -> definition * scrach -> scratch * imput -> input * transfered -> transferred * endownment -> endowment * Determinator -> Determiner * relevent -> relevant * emited -> emitted * acocunt -> account * proprotional -> proportional * instantiaion -> instantiation * commited -> committed * tombstonedead -> tombstone * uwnrap -> unwrap * acount -> account * specialised -> specialized * existant -> existent * requried -> required * Anull -> Annul * AUTHORITES -> AUTHORITIES * underyling -> underlying * recognisable -> recognizable * Capitalise -> Capitalize * reportfor -> report for * hearbeat -> heartbeat * onlineness -> being online * creater -> creator * Bytearray -> Byte array * Despoit -> Deposit * substratced -> subtracted * Curent -> Current * imbalanes -> imbalances * countfown -> countdown * inexisting -> inexistent * additionaly -> additionally * substracted -> subtracted * auxilary -> auxiliary * parital -> partial * in't -> isn't * compatability -> compatibility * infomation -> information * etected -> detected * extrinsiscs -> extrinsics * reprensentation -> representation * coonfiguration -> configuration * primtives -> primitives * miscelanious -> miscellaneous * VERISON -> VERSION * endcoded -> encoded * Genrates -> Generates * miliseconds -> milliseconds * occured -> occurred * trully -> truely * truely -> truly * conjuction -> conjunction * encouters -> encounters * customised -> customized * deterministicly -> deterministically * finalisation -> finalization * pluggable -> plugable * wakeup -> wake-up * interemdiate -> intermediate * intepreting -> interpreting * finalzied -> finalized * throgh -> through * extinsic -> extrinsic * convient -> convenient * allocater -> allocator * propagateable -> propagatable * succesfuly -> successfully * finalising -> finalizing * publically -> publicly * phrasee -> phrase * substration -> substractions * substractions -> subtractions * neccessarily -> necessarily * Inlucde -> Include * unefficient -> inefficient * thay -> they * funtion -> function * datastructures -> data structures * infromation -> information * propagatable -> propagable * ecountered -> encountered * recognise -> recognize * intergration -> integration * lastet -> latest * datatypes -> data types * datatype -> data type * Strongarming -> Strong Arming * avaible -> available * Commiting -> Committing * Retreiving -> Retrieving * shoud -> should * canonicaliziation -> canonicalization * comitted -> committed * clonable -> cloneable * Uknown -> Unknown * reponse -> response * arbitary -> arbitrary * Capapbilities -> Capabilities * responsbile -> responsible * initialisation -> initialization * cames -> came * intemediate -> intermediate * reqeust -> request * intance -> instance * explcitly -> explicitly * neighor -> neighbor * reolving -> resolving * untill -> until * Validte -> Validate * deserailize -> deserialize * literaly -> literally * preceeding -> preceding * abpve -> above * chcecked -> checked * numbet -> number * Unknow -> Unknown * halfs -> halves * gossup -> gossip * givent -> given * immediatelly -> immediately * slicable -> sliceable * conensus -> consensus * Mimicks -> Mimics * acccept -> accept * serialise -> serialize * exstrinsics -> extrinsics * panicks -> panics * maintaince -> maintenance * repeatidely -> repeatedly * anecstor -> ancestor * becasue -> because * processer -> processor * Prunning -> Pruning * insterested -> interested * unuseful -> not useful * yeided -> yielded * descendfing -> descending * corresponts -> corresponds * survivew -> survive * keps -> keeps * ligh -> light * prerequisities -> prerequisites * positiion -> position * depedency -> dependency * extrinisic -> extrinsic * atomicaly -> atomically * staticly -> statically * resul -> result * timestamb -> timestamp * Utilites -> Utilities * ammount -> amount * pocess -> process * exteral -> external * Update client/finality-grandpa/src/tests.rs * Update primitives/io/src/lib.rs Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update primitives/blockchain/src/lib.rs Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/support/src/weights.rs Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update bin/node/cli/tests/common.rs Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update client/api/src/execution_extensions.rs Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update client/cli/src/params.rs Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update client/executor/common/src/sandbox.rs Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update client/api/src/execution_extensions.rs Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update client/finality-grandpa/src/communication/mod.rs Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update client/state-db/src/pruning.rs Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update frame/contracts/src/tests.rs Co-Authored-By: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update client/api/src/execution_extensions.rs * bump impl * timestamb -> timestamp Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> --- .maintain/kubernetes/templates/service.yaml | 2 +- .maintain/kubernetes/values.yaml | 2 +- bin/node-template/pallets/template/src/lib.rs | 2 +- .../pallets/template/src/tests.rs | 2 +- bin/node-template/runtime/src/lib.rs | 4 ++-- bin/node/cli/tests/common.rs | 2 +- .../tests/running_the_node_and_interrupt.rs | 2 +- bin/node/rpc-client/src/main.rs | 4 ++-- bin/node/runtime/src/lib.rs | 4 ++-- bin/node/testing/benches/import.rs | 2 +- bin/node/testing/src/client.rs | 2 +- bin/utils/subkey/src/main.rs | 4 ++-- client/api/src/execution_extensions.rs | 6 ++--- client/chain-spec/derive/src/impls.rs | 2 +- client/chain-spec/src/chain_spec.rs | 2 +- client/cli/src/params.rs | 5 ++-- client/consensus/babe/src/tests.rs | 4 ++-- client/consensus/epochs/src/lib.rs | 2 +- client/db/src/cache/list_cache.rs | 2 +- client/db/src/cache/list_entry.rs | 2 +- client/db/src/changes_tries_storage.rs | 2 +- client/db/src/children.rs | 4 ++-- client/db/src/lib.rs | 6 ++--- client/db/src/light.rs | 2 +- client/db/src/storage_cache.rs | 4 ++-- client/db/src/upgrade.rs | 2 +- client/executor/common/src/error.rs | 2 +- client/executor/common/src/sandbox.rs | 2 +- client/executor/wasmi/src/lib.rs | 2 +- .../executor/wasmtime/src/instance_wrapper.rs | 4 ++-- .../finality-grandpa/src/communication/mod.rs | 10 ++++---- client/finality-grandpa/src/finality_proof.rs | 6 ++--- client/finality-grandpa/src/tests.rs | 4 ++-- client/keystore/src/lib.rs | 2 +- client/network-gossip/src/state_machine.rs | 2 +- client/network/src/discovery.rs | 2 +- client/network/src/protocol.rs | 6 ++--- client/network/src/protocol/event.rs | 2 +- .../src/protocol/light_client_handler.rs | 8 +++---- client/network/src/protocol/light_dispatch.rs | 4 ++-- client/network/src/protocol/message.rs | 4 ++-- .../network/src/protocol/schema/api.v1.proto | 2 +- client/network/src/protocol/sync.rs | 4 ++-- .../src/protocol/sync/extra_requests.rs | 2 +- client/network/src/service.rs | 2 +- client/network/test/src/lib.rs | 2 +- client/offchain/src/api/http.rs | 16 ++++++------- client/offchain/src/api/http_dummy.rs | 12 +++++----- client/offchain/src/lib.rs | 2 +- client/rpc-api/src/author/mod.rs | 2 +- client/rpc-api/src/errors.rs | 2 +- client/rpc-api/src/subscriptions.rs | 2 +- client/service/src/lib.rs | 2 +- client/service/test/src/lib.rs | 2 +- client/src/client.rs | 4 ++-- client/state-db/src/lib.rs | 2 +- client/state-db/src/noncanonical.rs | 2 +- client/state-db/src/pruning.rs | 4 ++-- client/telemetry/src/lib.rs | 4 ++-- .../transaction-pool/graph/src/base_pool.rs | 8 +++---- client/transaction-pool/graph/src/listener.rs | 2 +- client/transaction-pool/graph/src/pool.rs | 2 +- client/transaction-pool/src/testing/pool.rs | 2 +- docs/CODE_OF_CONDUCT.adoc | 2 +- docs/CONTRIBUTING.adoc | 2 +- docs/README.adoc | 4 ++-- docs/SECURITY.md | 2 +- docs/Structure.adoc | 2 +- frame/balances/src/lib.rs | 2 +- frame/collective/src/lib.rs | 2 +- frame/contracts/COMPLEXITY.md | 4 ++-- frame/contracts/common/src/lib.rs | 2 +- frame/contracts/rpc/runtime-api/src/lib.rs | 2 +- frame/contracts/rpc/src/lib.rs | 2 +- frame/contracts/src/exec.rs | 2 +- frame/contracts/src/lib.rs | 8 +++---- frame/contracts/src/rent.rs | 2 +- frame/contracts/src/tests.rs | 12 +++++----- frame/contracts/src/wasm/runtime.rs | 4 ++-- frame/democracy/src/lib.rs | 4 ++-- frame/elections/src/lib.rs | 2 +- frame/evm/src/backend.rs | 2 +- frame/evm/src/lib.rs | 2 +- frame/example/src/lib.rs | 6 ++--- frame/generic-asset/src/lib.rs | 4 ++-- frame/generic-asset/src/tests.rs | 4 ++-- frame/grandpa/src/lib.rs | 4 ++-- frame/identity/src/lib.rs | 2 +- frame/im-online/src/lib.rs | 6 ++--- frame/im-online/src/tests.rs | 2 +- frame/indices/src/lib.rs | 2 +- frame/membership/src/lib.rs | 2 +- frame/metadata/src/lib.rs | 2 +- frame/nicks/src/lib.rs | 2 +- frame/offences/src/lib.rs | 2 +- frame/offences/src/tests.rs | 2 +- frame/randomness-collective-flip/src/lib.rs | 4 ++-- frame/recovery/src/lib.rs | 4 ++-- frame/recovery/src/tests.rs | 2 +- frame/scored-pool/src/mock.rs | 2 +- frame/session/src/lib.rs | 2 +- frame/society/src/lib.rs | 2 +- frame/society/src/mock.rs | 2 +- frame/society/src/tests.rs | 2 +- frame/staking/reward-curve/src/lib.rs | 4 ++-- frame/staking/src/inflation.rs | 2 +- frame/staking/src/lib.rs | 4 ++-- frame/staking/src/tests.rs | 24 +++++++++---------- .../procedural/src/construct_runtime/parse.rs | 2 +- frame/support/procedural/src/lib.rs | 4 ++-- .../genesis_config/genesis_config_def.rs | 2 +- frame/support/procedural/src/storage/mod.rs | 12 +++++----- frame/support/procedural/tools/src/syn_ext.rs | 2 +- frame/support/src/debug.rs | 2 +- frame/support/src/dispatch.rs | 2 +- frame/support/src/error.rs | 2 +- frame/support/src/event.rs | 2 +- frame/support/src/storage/child.rs | 2 +- frame/support/src/weights.rs | 2 +- .../abundant_where_param.stderr | 2 +- .../invalid_where_param.rs | 2 +- frame/support/test/tests/instance.rs | 2 +- frame/system/src/lib.rs | 2 +- frame/system/src/offchain.rs | 2 +- frame/treasury/src/lib.rs | 10 ++++---- frame/utility/src/lib.rs | 4 ++-- primitives/allocator/src/freeing_bump.rs | 4 ++-- primitives/arithmetic/fuzzer/src/biguint.rs | 2 +- .../arithmetic/fuzzer/src/rational128.rs | 2 +- primitives/block-builder/src/lib.rs | 4 ++-- primitives/blockchain/src/error.rs | 10 ++++---- primitives/blockchain/src/lib.rs | 2 +- .../consensus/common/src/block_import.rs | 2 +- primitives/consensus/common/src/error.rs | 2 +- .../common/src/import_queue/basic_queue.rs | 2 +- .../consensus/common/src/select_chain.rs | 6 ++--- primitives/core/src/crypto.rs | 2 +- primitives/core/src/ed25519.rs | 2 +- primitives/core/src/lib.rs | 2 +- primitives/core/src/offchain/mod.rs | 6 ++--- primitives/core/src/testing.rs | 2 +- primitives/externalities/src/lib.rs | 2 +- primitives/finality-grandpa/src/lib.rs | 8 +++---- primitives/inherents/src/lib.rs | 2 +- primitives/io/src/lib.rs | 2 +- primitives/rpc/src/list.rs | 2 +- .../runtime-interface/test-wasm/src/lib.rs | 2 +- primitives/runtime/src/curve.rs | 2 +- primitives/runtime/src/generic/digest.rs | 2 +- primitives/runtime/src/lib.rs | 4 ++-- primitives/runtime/src/offchain/http.rs | 2 +- primitives/runtime/src/offchain/storage.rs | 4 ++-- primitives/runtime/src/traits.rs | 2 +- primitives/sandbox/src/lib.rs | 2 +- primitives/state-machine/src/backend.rs | 2 +- .../state-machine/src/changes_trie/mod.rs | 4 ++-- primitives/state-machine/src/lib.rs | 2 +- .../state-machine/src/overlayed_changes.rs | 6 ++--- .../state-machine/src/proving_backend.rs | 2 +- primitives/std/without_std.rs | 2 +- primitives/transaction-pool/src/error.rs | 2 +- primitives/transaction-pool/src/pool.rs | 4 ++-- primitives/trie/src/node_header.rs | 2 +- test-utils/client/src/lib.rs | 2 +- test-utils/runtime/src/lib.rs | 4 ++-- utils/fork-tree/src/lib.rs | 4 ++-- utils/wasm-builder/README.md | 2 +- utils/wasm-builder/src/lib.rs | 2 +- utils/wasm-builder/src/wasm_project.rs | 2 +- 169 files changed, 281 insertions(+), 282 deletions(-) diff --git a/.maintain/kubernetes/templates/service.yaml b/.maintain/kubernetes/templates/service.yaml index 01ba9d5a56..b14bb74c10 100644 --- a/.maintain/kubernetes/templates/service.yaml +++ b/.maintain/kubernetes/templates/service.yaml @@ -33,7 +33,7 @@ spec: app: {{ .Values.GitlabEnvSlug | default .Values.app }} sessionAffinity: None type: NodePort - # don't route exteral traffic to non-local pods + # don't route external traffic to non-local pods externalTrafficPolicy: Local {{- else if .Values.validator.keys }} {{- $root := . -}} diff --git a/.maintain/kubernetes/values.yaml b/.maintain/kubernetes/values.yaml index 89a6445e00..4c3cb5c7d7 100644 --- a/.maintain/kubernetes/values.yaml +++ b/.maintain/kubernetes/values.yaml @@ -48,7 +48,7 @@ validator: {} # substrate-1-node-key # # pod names are canonical. changing these or providing different amount of - # keys than the replicas count will lead to behavior noone ever has + # keys than the replicas count will lead to behavior no one ever has # experienced before. diff --git a/bin/node-template/pallets/template/src/lib.rs b/bin/node-template/pallets/template/src/lib.rs index a1615b4c1f..aa4d2cbc99 100644 --- a/bin/node-template/pallets/template/src/lib.rs +++ b/bin/node-template/pallets/template/src/lib.rs @@ -41,7 +41,7 @@ decl_event!( pub enum Event where AccountId = ::AccountId { /// Just a dummy event. /// Event `Something` is declared with a parameter of the type `u32` and `AccountId` - /// To emit this event, we call the deposit funtion, from our runtime funtions + /// To emit this event, we call the deposit function, from our runtime functions SomethingStored(u32, AccountId), } ); diff --git a/bin/node-template/pallets/template/src/tests.rs b/bin/node-template/pallets/template/src/tests.rs index 44a423c948..ec123a50c7 100644 --- a/bin/node-template/pallets/template/src/tests.rs +++ b/bin/node-template/pallets/template/src/tests.rs @@ -6,7 +6,7 @@ use frame_support::{assert_ok, assert_noop}; #[test] fn it_works_for_default_value() { new_test_ext().execute_with(|| { - // Just a dummy test for the dummy funtion `do_something` + // Just a dummy test for the dummy function `do_something` // calling the `do_something` function with a value 42 assert_ok!(TemplateModule::do_something(Origin::signed(1), 42)); // asserting that the stored value is equal to what we stored diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 67510c4bf2..153d9cf49d 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -69,7 +69,7 @@ pub type DigestItem = generic::DigestItem; /// Opaque types. These are used by the CLI to instantiate machinery that don't need to know /// the specifics of the runtime. They can then be made to be agnostic over specific formats /// of data like extrinsics, allowing for them to continue syncing the network through upgrades -/// to even the core datastructures. +/// to even the core data structures. pub mod opaque { use super::*; @@ -109,7 +109,7 @@ pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); pub const HOURS: BlockNumber = MINUTES * 60; pub const DAYS: BlockNumber = HOURS * 24; -/// The version infromation used to identify this runtime when compiled natively. +/// The version information used to identify this runtime when compiled natively. #[cfg(feature = "std")] pub fn native_version() -> NativeVersion { NativeVersion { diff --git a/bin/node/cli/tests/common.rs b/bin/node/cli/tests/common.rs index 96060bf85d..4044f69d08 100644 --- a/bin/node/cli/tests/common.rs +++ b/bin/node/cli/tests/common.rs @@ -16,7 +16,7 @@ use std::{process::{Child, ExitStatus}, thread, time::Duration}; -/// Wait for the given `child` the given ammount of `secs`. +/// Wait for the given `child` the given number of `secs`. /// /// Returns the `Some(exit status)` or `None` if the process did not finish in the given time. pub fn wait_for(child: &mut Child, secs: usize) -> Option { diff --git a/bin/node/cli/tests/running_the_node_and_interrupt.rs b/bin/node/cli/tests/running_the_node_and_interrupt.rs index 6ab719de91..dbb57bdd21 100644 --- a/bin/node/cli/tests/running_the_node_and_interrupt.rs +++ b/bin/node/cli/tests/running_the_node_and_interrupt.rs @@ -38,7 +38,7 @@ fn running_the_node_works_and_can_be_interrupted() { assert_eq!( common::wait_for(&mut cmd, 30).map(|x| x.success()), Some(true), - "the pocess must exit gracefully after signal {}", + "the process must exit gracefully after signal {}", signal, ); } diff --git a/bin/node/rpc-client/src/main.rs b/bin/node/rpc-client/src/main.rs index b28c9f8ff6..c547d30002 100644 --- a/bin/node/rpc-client/src/main.rs +++ b/bin/node/rpc-client/src/main.rs @@ -19,7 +19,7 @@ //! Example substrate RPC client code. //! //! This module shows how you can write a Rust RPC client that connects to a running -//! substrate node and use staticly typed RPC wrappers. +//! substrate node and use statically typed RPC wrappers. use futures::Future; use hyper::rt; @@ -55,7 +55,7 @@ fn main() { /// 1. Calls the `pending_extrinsics` method to get all extrinsics in the pool. /// 2. Then calls `remove_extrinsic` passing the obtained raw extrinsics. /// -/// As the resul of running the code the entire content of the transaction pool is going +/// As the result of running the code the entire content of the transaction pool is going /// to be removed and the extrinsics are going to be temporarily banned. fn remove_all_extrinsics(client: AuthorClient) -> impl Future { client.pending_extrinsics() diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 97424950fc..d80986c0df 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 219, - impl_version: 0, + impl_version: 1, apis: RUNTIME_API_VERSIONS, }; @@ -419,7 +419,7 @@ impl pallet_contracts::Trait for Runtime { type Randomness = RandomnessCollectiveFlip; type Call = Call; type Event = Event; - type DetermineContractAddress = pallet_contracts::SimpleAddressDeterminator; + type DetermineContractAddress = pallet_contracts::SimpleAddressDeterminer; type ComputeDispatchFee = pallet_contracts::DefaultDispatchFeeComputor; type TrieIdGenerator = pallet_contracts::TrieIdFromParentCounter; type GasPayment = (); diff --git a/bin/node/testing/benches/import.rs b/bin/node/testing/benches/import.rs index 9ffeb4ffd7..b294ae3604 100644 --- a/bin/node/testing/benches/import.rs +++ b/bin/node/testing/benches/import.rs @@ -174,7 +174,7 @@ impl BenchDb { let mut inherent_data = InherentData::new(); inherent_data.put_data(sp_timestamp::INHERENT_IDENTIFIER, ×tamp) - .expect("Put timestamb failed"); + .expect("Put timestamp failed"); inherent_data.put_data(sp_finality_tracker::INHERENT_IDENTIFIER, &0) .expect("Put finality tracker failed"); diff --git a/bin/node/testing/src/client.rs b/bin/node/testing/src/client.rs index 29b086c3c1..963bac7041 100644 --- a/bin/node/testing/src/client.rs +++ b/bin/node/testing/src/client.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Utilites to build a `TestClient` for `node-runtime`. +//! Utilities to build a `TestClient` for `node-runtime`. use sp_runtime::BuildStorage; diff --git a/bin/utils/subkey/src/main.rs b/bin/utils/subkey/src/main.rs index 4d7e220642..33209692ca 100644 --- a/bin/utils/subkey/src/main.rs +++ b/bin/utils/subkey/src/main.rs @@ -280,7 +280,7 @@ fn get_app<'a, 'b>(usage: &'a str) -> App<'a, 'b> { SubCommand::with_name("transfer") .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 \ + -g, --genesis 'The genesis hash or a recognized \ chain identifier (dev, elm, alex).' 'The signing secret key URI.' 'The destination account public key URI.' @@ -572,7 +572,7 @@ fn read_genesis_hash(matches: &ArgMatches) -> Result { "elm" => hex!["10c08714a10c7da78f40a60f6f732cf0dba97acfb5e2035445b032386157d5c3"].into(), "alex" => hex!["dcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b"].into(), h => Decode::decode(&mut &decode_hex(h)?[..]) - .expect("Invalid genesis hash or unrecognised chain identifier"), + .expect("Invalid genesis hash or unrecognized chain identifier"), }; println!( "Using a genesis hash of {}", diff --git a/client/api/src/execution_extensions.rs b/client/api/src/execution_extensions.rs index 1a986a23a4..10d33c20e6 100644 --- a/client/api/src/execution_extensions.rs +++ b/client/api/src/execution_extensions.rs @@ -64,7 +64,7 @@ impl Default for ExecutionStrategies { /// Generate the starting set of ExternalitiesExtensions based upon the given capabilities pub trait ExtensionsFactory: Send + Sync { - /// Make `Extensions` for given Capapbilities + /// Make `Extensions` for given `Capabilities`. fn extensions_for(&self, capabilities: offchain::Capabilities) -> Extensions; } @@ -77,7 +77,7 @@ impl ExtensionsFactory for () { /// A producer of execution extensions for offchain calls. /// /// This crate aggregates extensions available for the offchain calls -/// and is responsbile to produce a right `Extensions` object +/// and is responsible for producing a correct `Extensions` object. /// for each call, based on required `Capabilities`. pub struct ExecutionExtensions { strategies: ExecutionStrategies, @@ -125,7 +125,7 @@ impl ExecutionExtensions { /// To break retain cycle between `Client` and `TransactionPool` we require this /// extension to be a `Weak` reference. /// That's also the reason why it's being registered lazily instead of - /// during initialisation. + /// during initialization. pub fn register_transaction_pool(&self, pool: Weak>) { *self.transaction_pool.write() = Some(pool); } diff --git a/client/chain-spec/derive/src/impls.rs b/client/chain-spec/derive/src/impls.rs index 2caf1c5a9c..43874241f6 100644 --- a/client/chain-spec/derive/src/impls.rs +++ b/client/chain-spec/derive/src/impls.rs @@ -108,7 +108,7 @@ pub fn derive( let err = || { let err = Error::new( Span::call_site(), - "ChainSpecGroup is only avaible for structs with named fields." + "ChainSpecGroup is only available for structs with named fields." ).to_compile_error(); quote!( #err ).into() }; diff --git a/client/chain-spec/src/chain_spec.rs b/client/chain-spec/src/chain_spec.rs index 81cbce5ea7..696fef5664 100644 --- a/client/chain-spec/src/chain_spec.rs +++ b/client/chain-spec/src/chain_spec.rs @@ -336,7 +336,7 @@ mod tests { type TestSpec = ChainSpec; #[test] - fn should_deserailize_example_chain_spec() { + fn should_deserialize_example_chain_spec() { let spec1 = TestSpec::from_json_bytes(Cow::Owned( include_bytes!("../res/chain_spec.json").to_vec() )).unwrap(); diff --git a/client/cli/src/params.rs b/client/cli/src/params.rs index 2ffa8bd61b..9ae7bd7748 100644 --- a/client/cli/src/params.rs +++ b/client/cli/src/params.rs @@ -718,7 +718,7 @@ pub struct BuildSpecCmd { pub node_key_params: NodeKeyParams, } -/// Wrapper type of `String` which holds an arbitary sized unsigned integer formatted as decimal. +/// Wrapper type of `String` that holds an unsigned integer of arbitrary size, formatted as a decimal. #[derive(Debug, Clone)] pub struct BlockNumber(String); @@ -908,7 +908,7 @@ pub enum Subcommand { /// Import blocks from file. ImportBlocks(ImportBlocksCmd), - /// Validte a single block. + /// Validate a single block. CheckBlock(CheckBlockCmd), /// Revert chain to the previous state. @@ -1266,4 +1266,3 @@ impl BenchmarkCmd { Ok(()) } } - diff --git a/client/consensus/babe/src/tests.rs b/client/consensus/babe/src/tests.rs index 67e9d707cf..6c1ffa2c3a 100644 --- a/client/consensus/babe/src/tests.rs +++ b/client/consensus/babe/src/tests.rs @@ -316,12 +316,12 @@ impl TestNetFactory for BabeTestNet { } fn peer(&mut self, i: usize) -> &mut Peer { - trace!(target: "babe", "Retreiving a peer"); + trace!(target: "babe", "Retrieving a peer"); &mut self.peers[i] } fn peers(&self) -> &Vec> { - trace!(target: "babe", "Retreiving peers"); + trace!(target: "babe", "Retrieving peers"); &self.peers } diff --git a/client/consensus/epochs/src/lib.rs b/client/consensus/epochs/src/lib.rs index cf3d9f5c4c..05ee611de1 100644 --- a/client/consensus/epochs/src/lib.rs +++ b/client/consensus/epochs/src/lib.rs @@ -141,7 +141,7 @@ impl ViableEpoch where } } -/// The datatype encoded on disk. +/// The data type encoded on disk. #[derive(Clone, Encode, Decode)] pub enum PersistedEpoch { /// Genesis persisted epoch data. epoch_0, epoch_1. diff --git a/client/db/src/cache/list_cache.rs b/client/db/src/cache/list_cache.rs index 72278a1e85..f3a8171342 100644 --- a/client/db/src/cache/list_cache.rs +++ b/client/db/src/cache/list_cache.rs @@ -357,7 +357,7 @@ impl> ListCache // it is possible that we're inserting extra (but still required) fork here let new_storage_entry = StorageEntry { prev_valid_from: Some(prev_valid_from), - value: value.expect("chcecked abpve that !value.is_none(); qed"), + value: value.expect("checked above that !value.is_none(); qed"), }; tx.insert_storage_entry(&block, &new_storage_entry); diff --git a/client/db/src/cache/list_entry.rs b/client/db/src/cache/list_entry.rs index d3f7dd5769..e184343290 100644 --- a/client/db/src/cache/list_entry.rs +++ b/client/db/src/cache/list_entry.rs @@ -69,7 +69,7 @@ impl Entry { .map(|(entry, next)| (entry.valid_from, next))) } - /// Searches the list, ending with THIS entry for the best entry preceeding (or at) + /// Searches the list, ending with THIS entry for the best entry preceding (or at) /// given block number. /// If the entry is found, result is the entry and the block id of next entry (if exists). /// NOTE that this function does not check that the passed block is actually linked to diff --git a/client/db/src/changes_tries_storage.rs b/client/db/src/changes_tries_storage.rs index 72163a5694..99488bbaed 100644 --- a/client/db/src/changes_tries_storage.rs +++ b/client/db/src/changes_tries_storage.rs @@ -48,7 +48,7 @@ pub fn extract_new_configuration(header: &Header) -> Option<&Op /// Opaque configuration cache transaction. During its lifetime, no-one should modify cache. This is currently /// guaranteed because import lock is held during block import/finalization. pub struct DbChangesTrieStorageTransaction { - /// Cache operations that must be performed after db transaction is comitted. + /// Cache operations that must be performed after db transaction is committed. cache_ops: DbCacheTransactionOps, /// New configuration (if changed at current block). new_config: Option>, diff --git a/client/db/src/children.rs b/client/db/src/children.rs index c90af66027..2ef67de6a8 100644 --- a/client/db/src/children.rs +++ b/client/db/src/children.rs @@ -100,7 +100,7 @@ mod tests { children2.push(1_6); write_children(&mut tx, 0, PREFIX, 1_2, children2); - db.write(tx.clone()).expect("(2) Commiting transaction failed"); + db.write(tx.clone()).expect("(2) Committing transaction failed"); let r1: Vec = read_children(&db, 0, PREFIX, 1_1).expect("(1) Getting r1 failed"); let r2: Vec = read_children(&db, 0, PREFIX, 1_2).expect("(1) Getting r2 failed"); @@ -109,7 +109,7 @@ mod tests { assert_eq!(r2, vec![1_4, 1_6]); remove_children(&mut tx, 0, PREFIX, 1_2); - db.write(tx).expect("(2) Commiting transaction failed"); + db.write(tx).expect("(2) Committing transaction failed"); let r1: Vec = read_children(&db, 0, PREFIX, 1_1).expect("(2) Getting r1 failed"); let r2: Vec = read_children(&db, 0, PREFIX, 1_2).expect("(2) Getting r2 failed"); diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index b641234281..5173497509 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -741,7 +741,7 @@ impl FrozenForDuration { /// Disk backend. /// -/// Disk backend keps data in a key-value store. In archive mode, trie nodes are kept from all blocks. +/// Disk backend keeps data in a key-value store. In archive mode, trie nodes are kept from all blocks. /// Otherwise, trie nodes are kept only from some recent blocks. pub struct Backend { storage: Arc>, @@ -878,7 +878,7 @@ impl Backend { inmem } - /// Returns total numbet of blocks (headers) in the block DB. + /// Returns total number of blocks (headers) in the block DB. #[cfg(feature = "test-helpers")] pub fn blocks_count(&self) -> u64 { self.blockchain.db.iter(columns::HEADER).count() as u64 @@ -1000,7 +1000,7 @@ impl Backend { Ok((*hash, number, false, true)) } - // performs forced canonicaliziation with a delay after importing a non-finalized block. + // performs forced canonicalization with a delay after importing a non-finalized block. fn force_delayed_canonicalize( &self, transaction: &mut DBTransaction, diff --git a/client/db/src/light.rs b/client/db/src/light.rs index bea08d6467..14ce6ac0f9 100644 --- a/client/db/src/light.rs +++ b/client/db/src/light.rs @@ -815,7 +815,7 @@ pub(crate) mod tests { } #[test] - fn get_cht_fails_for_non_existant_cht() { + fn get_cht_fails_for_non_existent_cht() { let cht_size: u64 = cht::size(); assert!(LightStorage::::new_test().header_cht_root(cht_size, cht_size / 2).unwrap().is_none()); } diff --git a/client/db/src/storage_cache.rs b/client/db/src/storage_cache.rs index fd85a899b6..6ef29f47b8 100644 --- a/client/db/src/storage_cache.rs +++ b/client/db/src/storage_cache.rs @@ -338,7 +338,7 @@ impl CacheChanges { is_best, ); let cache = &mut *cache; - // Filter out commiting block if any. + // Filter out committing block if any. let enacted: Vec<_> = enacted .iter() .filter(|h| commit_hash.as_ref().map_or(true, |p| *h != p)) @@ -1453,7 +1453,7 @@ mod qc { self.head_state( self.canon.last() - .expect("wasn't forking to emptiness so there shoud be one!") + .expect("wasn't forking to emptiness so there should be one!") .hash ) }, diff --git a/client/db/src/upgrade.rs b/client/db/src/upgrade.rs index 69230e7851..971acf8456 100644 --- a/client/db/src/upgrade.rs +++ b/client/db/src/upgrade.rs @@ -118,7 +118,7 @@ fn current_version(path: &Path) -> sp_blockchain::Result { } } -/// Opens database of givent type with given number of columns. +/// Opens database of given type with given number of columns. fn open_database(db_path: &Path, db_type: DatabaseType, db_columns: u32) -> sp_blockchain::Result { let db_path = db_path.to_str() .ok_or_else(|| sp_blockchain::Error::Backend("Invalid database path".into()))?; diff --git a/client/executor/common/src/error.rs b/client/executor/common/src/error.rs index b8d40d4d91..66d520e942 100644 --- a/client/executor/common/src/error.rs +++ b/client/executor/common/src/error.rs @@ -27,7 +27,7 @@ pub type Result = std::result::Result; pub enum Error { /// Unserializable Data InvalidData(sp_serializer::Error), - /// Trap occured during execution + /// Trap occurred during execution Trap(wasmi::Trap), /// Wasmi loading/instantiating error Wasmi(wasmi::Error), diff --git a/client/executor/common/src/sandbox.rs b/client/executor/common/src/sandbox.rs index f920a47ca7..ccfdc2f3e0 100644 --- a/client/executor/common/src/sandbox.rs +++ b/client/executor/common/src/sandbox.rs @@ -498,7 +498,7 @@ pub fn instantiate<'a, FE: SandboxCapabilities>( /// /// This is generic over a supervisor function reference type. pub struct Store { - // Memories and instances are `Some` untill torndown. + // Memories and instances are `Some` until torn down. instances: Vec>>>, memories: Vec>, } diff --git a/client/executor/wasmi/src/lib.rs b/client/executor/wasmi/src/lib.rs index b90c0f05f5..a0e11dfcf8 100644 --- a/client/executor/wasmi/src/lib.rs +++ b/client/executor/wasmi/src/lib.rs @@ -276,7 +276,7 @@ struct Resolver<'a> { /// Will be used as initial and maximum size of the imported memory. heap_pages: usize, /// By default, runtimes should import memory and this is `Some(_)` after - /// reolving. However, to be backwards compatible, we also support memory + /// resolving. However, to be backwards compatible, we also support memory /// exported by the WASM blob (this will be `None` after resolving). import_memory: RefCell>, } diff --git a/client/executor/wasmtime/src/instance_wrapper.rs b/client/executor/wasmtime/src/instance_wrapper.rs index 013651cd7a..159746801a 100644 --- a/client/executor/wasmtime/src/instance_wrapper.rs +++ b/client/executor/wasmtime/src/instance_wrapper.rs @@ -32,7 +32,7 @@ use wasmtime::{Instance, Module, Memory, Table, Val}; /// routines. pub struct InstanceWrapper { instance: Instance, - // The memory instance of the `intance`. + // The memory instance of the `instance`. // // It is important to make sure that we don't make any copies of this to make it easier to proof // See `memory_as_slice` and `memory_as_slice_mut`. @@ -142,7 +142,7 @@ impl InstanceWrapper { Val::I64(val) => Ok(Some(Value::I64(val))), Val::F32(val) => Ok(Some(Value::F32(val))), Val::F64(val) => Ok(Some(Value::F64(val))), - _ => Err("Unknow value type".into()), + _ => Err("Unknown value type".into()), } } } diff --git a/client/finality-grandpa/src/communication/mod.rs b/client/finality-grandpa/src/communication/mod.rs index 540923c1b1..050a3c8642 100644 --- a/client/finality-grandpa/src/communication/mod.rs +++ b/client/finality-grandpa/src/communication/mod.rs @@ -74,7 +74,7 @@ mod cost { 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 UNKNOWN_VOTER: Rep = Rep::new(-150, "Grandpa: Unknown voter"); pub(super) const INVALID_VIEW_CHANGE: Rep = Rep::new(-500, "Grandpa: Invalid view change"); pub(super) const PER_UNDECODABLE_BYTE: i32 = -5; @@ -83,7 +83,7 @@ mod cost { 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"); + pub(super) const CATCH_UP_REQUEST_TIMEOUT: Rep = Rep::new(-200, "Grandpa: Catch-up request timeout"); // cost of answering a catch up request pub(super) const CATCH_UP_REPLY: Rep = Rep::new(-200, "Grandpa: Catch-up reply"); @@ -153,14 +153,14 @@ pub(crate) struct NetworkBridge> { /// `NeighborPacketWorker` processing packets sent through the `NeighborPacketSender`. // - // `NetworkBridge` is required to be clonable, thus one needs to be able to clone its children, - // thus one has to wrap neighor_packet_worker with an `Arc` `Mutex`. + // `NetworkBridge` is required to be cloneable, thus one needs to be able to clone its children, + // thus one has to wrap `neighbor_packet_worker` with an `Arc` `Mutex`. neighbor_packet_worker: Arc>>, /// Receiver side of the peer report stream populated by the gossip validator, forwarded to the /// gossip engine. // - // `NetworkBridge` is required to be clonable, thus one needs to be able to clone its children, + // `NetworkBridge` is required to be cloneable, thus one needs to be able to clone its children, // thus one has to wrap gossip_validator_report_stream with an `Arc` `Mutex`. Given that it is // just an `UnboundedReceiver`, one could also switch to a multi-producer-*multi*-consumer // channel implementation. diff --git a/client/finality-grandpa/src/finality_proof.rs b/client/finality-grandpa/src/finality_proof.rs index fb0f7fd4a9..9da99ab531 100644 --- a/client/finality-grandpa/src/finality_proof.rs +++ b/client/finality-grandpa/src/finality_proof.rs @@ -920,7 +920,7 @@ pub(crate) mod tests { } #[test] - fn finality_proof_check_fails_when_intemediate_fragment_has_unknown_headers() { + fn finality_proof_check_fails_when_intermediate_fragment_has_unknown_headers() { let blockchain = test_blockchain(); // when intermediate (#0) fragment has non-empty unknown headers @@ -945,7 +945,7 @@ pub(crate) mod tests { } #[test] - fn finality_proof_check_fails_when_intemediate_fragment_has_no_authorities_proof() { + fn finality_proof_check_fails_when_intermediate_fragment_has_no_authorities_proof() { let blockchain = test_blockchain(); // when intermediate (#0) fragment has empty authorities proof @@ -1004,7 +1004,7 @@ pub(crate) mod tests { #[test] fn finality_proof_is_none_if_first_justification_is_generated_by_unknown_set() { // this is the case for forced change: set_id has been forcibly increased on full node - // and ligh node missed that + // and light node missed that // => justification verification will fail on light node anyways, so we do not return // finality proof at all let blockchain = test_blockchain(); diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index 71cc72b059..9b9063f2c1 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -147,7 +147,7 @@ impl TestNetFactory for GrandpaTestNet { use crate::light_import::tests::light_block_import_without_justifications; let authorities_provider = Arc::new(self.test_config.clone()); - // forbid direct finalization using justification that cames with the block + // forbid direct finalization using justification that came with the block // => light clients will try to fetch finality proofs let import = light_block_import_without_justifications( client.clone(), @@ -982,7 +982,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 + // the link-halves have the wrong AuthoritySet run_to_completion(&mut runtime, 25, net, peers_a); } diff --git a/client/keystore/src/lib.rs b/client/keystore/src/lib.rs index ef81c40c10..92c8f4f9a5 100644 --- a/client/keystore/src/lib.rs +++ b/client/keystore/src/lib.rs @@ -260,7 +260,7 @@ impl Store { /// Get public keys of all stored keys that match the key type. /// /// This will just use the type of the public key (a list of which to be returned) in order - /// to determine the key type. Unless you use a specialised application-type public key, then + /// to determine the key type. Unless you use a specialized application-type public key, then /// this only give you keys registered under generic cryptography, and will not return keys /// registered under the application type. pub fn public_keys(&self) -> Result> { diff --git a/client/network-gossip/src/state_machine.rs b/client/network-gossip/src/state_machine.rs index 2acfdc3785..26433e63ec 100644 --- a/client/network-gossip/src/state_machine.rs +++ b/client/network-gossip/src/state_machine.rs @@ -45,7 +45,7 @@ mod rep { 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"); + pub const UNKNOWN_GOSSIP: Rep = Rep::new(-(1 << 6), "Unknown gossip 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"); } diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index 2d69e679ff..a236ceb1a8 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -192,7 +192,7 @@ pub enum DiscoveryOut { /// e.g. obtained through the `identify` protocol. UnroutablePeer(PeerId), - /// The DHT yeided results for the record request, grouped in (key, value) pairs. + /// The DHT yielded results for the record request, grouped in (key, value) pairs. ValueFound(Vec<(record::Key, Vec)>), /// The record requested was not found in the DHT. diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 0a909fe2fe..9e098c27e9 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -81,7 +81,7 @@ pub use light_client_handler::LightClientHandler; const REQUEST_TIMEOUT_SEC: u64 = 40; /// Interval at which we perform time based maintenance const TICK_TIMEOUT: time::Duration = time::Duration::from_millis(1100); -/// Interval at which we propagate exstrinsics; +/// Interval at which we propagate extrinsics; const PROPAGATE_TIMEOUT: time::Duration = time::Duration::from_millis(2900); /// Maximim number of known block hashes to keep for a peer. @@ -97,7 +97,7 @@ pub(crate) const MIN_VERSION: u32 = 3; // Maximum allowed entries in `BlockResponse` const MAX_BLOCK_DATA_RESPONSE: u32 = 128; /// When light node connects to the full node and the full node is behind light node -/// for at least `LIGHT_MAXIMAL_BLOCKS_DIFFERENCE` blocks, we consider it unuseful +/// for at least `LIGHT_MAXIMAL_BLOCKS_DIFFERENCE` blocks, we consider it not useful /// and disconnect to free connection slot. const LIGHT_MAXIMAL_BLOCKS_DIFFERENCE: u64 = 8192; @@ -183,7 +183,7 @@ struct Peer { info: PeerInfo, /// Current block request, if any. block_request: Option<(Instant, message::BlockRequest)>, - /// Requests we are no longer insterested in. + /// Requests we are no longer interested in. obsolete_requests: HashMap, /// Holds a set of transactions known to this peer. known_extrinsics: LruHashSet, diff --git a/client/network/src/protocol/event.rs b/client/network/src/protocol/event.rs index e239e9d983..78490863be 100644 --- a/client/network/src/protocol/event.rs +++ b/client/network/src/protocol/event.rs @@ -36,7 +36,7 @@ pub enum DhtEvent { /// The record has been successfully inserted into the DHT. ValuePut(Key), - /// An error has occured while putting a record into the DHT. + /// An error has occurred while putting a record into the DHT. ValuePutFailed(Key), } diff --git a/client/network/src/protocol/light_client_handler.rs b/client/network/src/protocol/light_client_handler.rs index 63c1f8a443..b31877d928 100644 --- a/client/network/src/protocol/light_client_handler.rs +++ b/client/network/src/protocol/light_client_handler.rs @@ -836,10 +836,10 @@ where }; if let Some(peer) = available_peer { let id = self.next_request_id(); - let rq = serialise_request(id, &request.request); + let rq = serialize_request(id, &request.request); let mut buf = Vec::with_capacity(rq.encoded_len()); if let Err(e) = rq.encode(&mut buf) { - log::debug!("failed to serialise request {}: {}", id, e); + log::debug!("failed to serialize request {}: {}", id, e); send_reply(Err(ClientError::RemoteFetchFailed), request.request) } else { log::trace!("sending request {} to peer {}", id, peer); @@ -917,7 +917,7 @@ fn retries(request: &Request) -> usize { rc.unwrap_or(0) } -fn serialise_request(id: u64, request: &Request) -> api::v1::light::Request { +fn serialize_request(id: u64, request: &Request) -> api::v1::light::Request { let request = match request { Request::Header { request, .. } => { let r = api::v1::light::RemoteHeaderRequest { block: request.block.encode() }; @@ -1051,7 +1051,7 @@ where /// Sends a request to remote and awaits the response. #[derive(Debug, Clone)] pub struct OutboundProtocol { - /// The serialised protobuf request. + /// The serialized protobuf request. request: Vec, /// The max. request length in bytes. max_data_size: usize, diff --git a/client/network/src/protocol/light_dispatch.rs b/client/network/src/protocol/light_dispatch.rs index 3402e7c329..738847dbaf 100644 --- a/client/network/src/protocol/light_dispatch.rs +++ b/client/network/src/protocol/light_dispatch.rs @@ -227,7 +227,7 @@ impl FetchChecker for AlwaysBadChecker { impl LightDispatch where B::Header: HeaderT, { - /// Creates new light client requests processer. + /// Creates new light client requests processor. pub fn new(checker: Arc>) -> Self { LightDispatch { checker, @@ -567,7 +567,7 @@ impl LightDispatch where // return peer to the back of the queue self.idle_peers.push_back(peer.clone()); - // we have enumerated all peers and noone can handle request + // we have enumerated all peers and no one can handle request if Some(peer) == last_peer { let request = self.pending_requests.pop_front().expect("checked in loop condition; qed"); unhandled_requests.push_back(request); diff --git a/client/network/src/protocol/message.rs b/client/network/src/protocol/message.rs index ef7d550de6..a2261b2059 100644 --- a/client/network/src/protocol/message.rs +++ b/client/network/src/protocol/message.rs @@ -209,13 +209,13 @@ pub mod generic { RemoteHeaderResponse(RemoteHeaderResponse

), /// Remote changes request. RemoteChangesRequest(RemoteChangesRequest), - /// Remote changes reponse. + /// Remote changes response. RemoteChangesResponse(RemoteChangesResponse), /// Remote child storage read request. RemoteReadChildRequest(RemoteReadChildRequest), /// Finality proof request. FinalityProofRequest(FinalityProofRequest), - /// Finality proof reponse. + /// Finality proof response. FinalityProofResponse(FinalityProofResponse), /// Batch of consensus protocol messages. ConsensusBatch(Vec), diff --git a/client/network/src/protocol/schema/api.v1.proto b/client/network/src/protocol/schema/api.v1.proto index e4c32ec585..73128c53de 100644 --- a/client/network/src/protocol/schema/api.v1.proto +++ b/client/network/src/protocol/schema/api.v1.proto @@ -8,7 +8,7 @@ package api.v1; enum Direction { // Enumerate in ascending order (from child to parent). Ascending = 0; - // Enumerate in descendfing order (from parent to canonical child). + // Enumerate in descending order (from parent to canonical child). Descending = 1; } diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index a513d47ca4..3b909b3303 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -751,7 +751,7 @@ impl ChainSync { | PeerSyncState::DownloadingFinalityProof(..) => Vec::new() } } else { - // When request.is_none() just acccept blocks + // When request.is_none() just accept blocks blocks.into_iter().map(|b| { IncomingBlock { hash: b.hash, @@ -955,7 +955,7 @@ impl ChainSync { }, Err(BlockImportError::MissingState) => { // This may happen if the chain we were requesting upon has been discarded - // in the meantime becasue other chain has been finalized. + // in the meantime because other chain has been finalized. // Don't mark it as bad as it still may be synced if explicitly requested. trace!(target: "sync", "Obsolete block"); }, diff --git a/client/network/src/protocol/sync/extra_requests.rs b/client/network/src/protocol/sync/extra_requests.rs index a5fb232b8d..19c6b50743 100644 --- a/client/network/src/protocol/sync/extra_requests.rs +++ b/client/network/src/protocol/sync/extra_requests.rs @@ -469,7 +469,7 @@ mod tests { } #[test] - fn anecstor_roots_are_finalized_when_finality_notification_is_missed() { + fn ancestor_roots_are_finalized_when_finality_notification_is_missed() { let mut finality_proofs = ExtraRequests::::new("test"); let hash4 = [4; 32].into(); diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 922333a9eb..8d99028298 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -367,7 +367,7 @@ impl, H: ExHashT> NetworkWorker /// Get network state. /// - /// **Note**: Use this only for debugging. This API is unstable. There are warnings literaly + /// **Note**: Use this only for debugging. This API is unstable. There are warnings literally /// everywhere about this. Please don't use this function to retrieve actual information. pub fn network_state(&mut self) -> NetworkState { let swarm = &mut self.network_service; diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 82d1737e9e..c15bd33655 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -766,7 +766,7 @@ pub trait TestNetFactory: Sized { /// Blocks the current thread until we are sync'ed. /// - /// Calls `poll_until_sync` repeatidely with the runtime passed as parameter. + /// Calls `poll_until_sync` repeatedly with the runtime passed as parameter. fn block_until_sync(&mut self, runtime: &mut tokio::runtime::current_thread::Runtime) { runtime.block_on(futures::future::poll_fn::<(), (), _>(|| Ok(self.poll_until_sync()))).unwrap(); } diff --git a/client/offchain/src/api/http.rs b/client/offchain/src/api/http.rs index 84c3ecd69b..7aa0963fcf 100644 --- a/client/offchain/src/api/http.rs +++ b/client/offchain/src/api/http.rs @@ -18,7 +18,7 @@ //! function returns a pair of [`HttpApi`] and [`HttpWorker`] that share some state. //! //! The [`HttpApi`] is (indirectly) passed to the runtime when calling an offchain worker, while -//! the [`HttpWorker`] must be processed in the background. The [`HttpApi`] mimicks the API of the +//! the [`HttpWorker`] must be processed in the background. The [`HttpApi`] mimics the API of the //! HTTP-related methods available to offchain workers. //! //! The reason for this design is driven by the fact that HTTP requests should continue running @@ -110,7 +110,7 @@ struct HttpApiRequestRp { } impl HttpApi { - /// Mimicks the corresponding method in the offchain API. + /// Mimics the corresponding method in the offchain API. pub fn request_start( &mut self, method: &str, @@ -138,7 +138,7 @@ impl HttpApi { Ok(new_id) } - /// Mimicks the corresponding method in the offchain API. + /// Mimics the corresponding method in the offchain API. pub fn request_add_header( &mut self, request_id: HttpRequestId, @@ -158,7 +158,7 @@ impl HttpApi { Ok(()) } - /// Mimicks the corresponding method in the offchain API. + /// Mimics the corresponding method in the offchain API. pub fn request_write_body( &mut self, request_id: HttpRequestId, @@ -266,7 +266,7 @@ impl HttpApi { } } - /// Mimicks the corresponding method in the offchain API. + /// Mimics the corresponding method in the offchain API. pub fn response_wait( &mut self, ids: &[HttpRequestId], @@ -392,7 +392,7 @@ impl HttpApi { } } - /// Mimicks the corresponding method in the offchain API. + /// Mimics the corresponding method in the offchain API. pub fn response_headers( &mut self, request_id: HttpRequestId @@ -411,7 +411,7 @@ impl HttpApi { .collect() } - /// Mimicks the corresponding method in the offchain API. + /// Mimics the corresponding method in the offchain API. pub fn response_read_body( &mut self, request_id: HttpRequestId, @@ -947,7 +947,7 @@ mod tests { #[test] fn fuzzing() { - // Uses the API in random ways to try to trigger panicks. + // Uses the API in random ways to try to trigger panics. // Doesn't test some paths, such as waiting for multiple requests. Also doesn't test what // happens if the server force-closes our socket. diff --git a/client/offchain/src/api/http_dummy.rs b/client/offchain/src/api/http_dummy.rs index 8725c89899..5ff77a1068 100644 --- a/client/offchain/src/api/http_dummy.rs +++ b/client/offchain/src/api/http_dummy.rs @@ -33,7 +33,7 @@ pub struct HttpApi; pub struct HttpWorker; impl HttpApi { - /// Mimicks the corresponding method in the offchain API. + /// Mimics the corresponding method in the offchain API. pub fn request_start( &mut self, _: &str, @@ -43,7 +43,7 @@ impl HttpApi { Err(()) } - /// Mimicks the corresponding method in the offchain API. + /// Mimics the corresponding method in the offchain API. pub fn request_add_header( &mut self, _: HttpRequestId, @@ -54,7 +54,7 @@ impl HttpApi { never be called; qed") } - /// Mimicks the corresponding method in the offchain API. + /// Mimics the corresponding method in the offchain API. pub fn request_write_body( &mut self, _: HttpRequestId, @@ -65,7 +65,7 @@ impl HttpApi { never be called; qed") } - /// Mimicks the corresponding method in the offchain API. + /// Mimics the corresponding method in the offchain API. pub fn response_wait( &mut self, requests: &[HttpRequestId], @@ -79,7 +79,7 @@ impl HttpApi { } } - /// Mimicks the corresponding method in the offchain API. + /// Mimics the corresponding method in the offchain API. pub fn response_headers( &mut self, _: HttpRequestId @@ -88,7 +88,7 @@ impl HttpApi { never be called; qed") } - /// Mimicks the corresponding method in the offchain API. + /// Mimics the corresponding method in the offchain API. pub fn response_read_body( &mut self, _: HttpRequestId, diff --git a/client/offchain/src/lib.rs b/client/offchain/src/lib.rs index ac8cc14861..7fc9671fcb 100644 --- a/client/offchain/src/lib.rs +++ b/client/offchain/src/lib.rs @@ -217,6 +217,6 @@ mod tests { // then assert_eq!(pool.0.status().ready, 1); - assert_eq!(pool.0.ready().next().unwrap().is_propagateable(), false); + assert_eq!(pool.0.ready().next().unwrap().is_propagable(), false); } } diff --git a/client/rpc-api/src/author/mod.rs b/client/rpc-api/src/author/mod.rs index 4fbf0c73a3..49c4c996fa 100644 --- a/client/rpc-api/src/author/mod.rs +++ b/client/rpc-api/src/author/mod.rs @@ -77,7 +77,7 @@ pub trait AuthorApi { /// Submit an extrinsic to watch. /// /// See [`TransactionStatus`](sp_transaction_pool::TransactionStatus) for details on transaction - /// lifecycle. + /// life cycle. #[pubsub( subscription = "author_extrinsicUpdate", subscribe, diff --git a/client/rpc-api/src/errors.rs b/client/rpc-api/src/errors.rs index 9db41d0497..b75c34ead3 100644 --- a/client/rpc-api/src/errors.rs +++ b/client/rpc-api/src/errors.rs @@ -20,7 +20,7 @@ pub fn internal(e: E) -> jsonrpc_core::Error { warn!("Unknown error: {:?}", e); jsonrpc_core::Error { code: jsonrpc_core::ErrorCode::InternalError, - message: "Unknown error occured".into(), + message: "Unknown error occurred".into(), data: Some(format!("{:?}", e).into()), } } diff --git a/client/rpc-api/src/subscriptions.rs b/client/rpc-api/src/subscriptions.rs index 808c9d5ba4..54881bad51 100644 --- a/client/rpc-api/src/subscriptions.rs +++ b/client/rpc-api/src/subscriptions.rs @@ -71,7 +71,7 @@ impl Subscriptions { /// Borrows the internal task executor. /// - /// This can be used to spawn additional tasks on the underyling event loop. + /// This can be used to spawn additional tasks on the underlying event loop. pub fn executor(&self) -> &TaskExecutor { &self.executor } diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 55fdba706b..c358e5993e 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -625,7 +625,7 @@ where E: IntoPoolError + From, { pool.ready() - .filter(|t| t.is_propagateable()) + .filter(|t| t.is_propagable()) .map(|t| { let hash = t.hash().clone(); let ex: B::Extrinsic = t.data().clone(); diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 723c13ec82..b65bccc151 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -498,7 +498,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_with_prefix("substrate-conensus-test"); + let temp = tempdir_with_prefix("substrate-consensus-test"); let mut network = TestNet::new( &temp, spec.clone(), diff --git a/client/src/client.rs b/client/src/client.rs index d085b92025..e9a8f1228c 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -1192,7 +1192,7 @@ impl Client where // NOTE: we're setting the finalized block as best block, this might // be slightly inaccurate since we might have a "better" block // further along this chain, but since best chain selection logic is - // pluggable we cannot make a better choice here. usages that need + // plugable we cannot make a better choice here. usages that need // an accurate "best" block need to go through `SelectChain` // instead. operation.op.mark_head(BlockId::Hash(block))?; @@ -3041,7 +3041,7 @@ pub(crate) mod tests { .unwrap().build().unwrap().block; // we will finalize A2 which should make it impossible to import a new - // B3 at the same height but that doesnt't include it + // B3 at the same height but that doesn't include it ClientExt::finalize_block(&client, BlockId::Hash(a2.hash()), None).unwrap(); let import_err = client.import(BlockOrigin::Own, b3).err().unwrap(); diff --git a/client/state-db/src/lib.rs b/client/state-db/src/lib.rs index f2722ae308..0eab640de8 100644 --- a/client/state-db/src/lib.rs +++ b/client/state-db/src/lib.rs @@ -102,7 +102,7 @@ impl fmt::Debug for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Error::Db(e) => e.fmt(f), - Error::Decoding(e) => write!(f, "Error decoding slicable value: {}", e.what()), + Error::Decoding(e) => write!(f, "Error decoding sliceable value: {}", e.what()), Error::InvalidBlock => write!(f, "Trying to canonicalize invalid block"), Error::InvalidBlockNumber => write!(f, "Trying to insert block with invalid number"), Error::InvalidParent => write!(f, "Trying to insert block with unknown parent"), diff --git a/client/state-db/src/noncanonical.rs b/client/state-db/src/noncanonical.rs index 373c1aa0da..db2f58fa89 100644 --- a/client/state-db/src/noncanonical.rs +++ b/client/state-db/src/noncanonical.rs @@ -106,7 +106,7 @@ fn discard_descendants( // save to be discarded later. pinned_insertions.insert(overlay.hash.clone(), overlay.inserted); } else { - // discard immediatelly. + // discard immediately. parents.remove(&overlay.hash); discard_values(&mut values, overlay.inserted); } diff --git a/client/state-db/src/pruning.rs b/client/state-db/src/pruning.rs index a993df4f11..71d018087b 100644 --- a/client/state-db/src/pruning.rs +++ b/client/state-db/src/pruning.rs @@ -36,7 +36,7 @@ pub struct RefWindow { death_rows: VecDeque>, /// An index that maps each key from `death_rows` to block number. death_index: HashMap, - /// Block number that corresponts to the front of `death_rows` + /// Block number that corresponds to the front of `death_rows`. pending_number: u64, /// Number of call of `note_canonical` after /// last call `apply_pending` or `revert_pending` @@ -348,7 +348,7 @@ mod tests { } #[test] - fn reinserted_survivew_pending() { + fn reinserted_survive_pending() { let mut db = make_db(&[1, 2, 3]); let mut pruning: RefWindow = RefWindow::new(&db).unwrap(); let mut commit = make_commit(&[], &[2]); diff --git a/client/telemetry/src/lib.rs b/client/telemetry/src/lib.rs index 1c6f1425d6..f8ca6d5c73 100644 --- a/client/telemetry/src/lib.rs +++ b/client/telemetry/src/lib.rs @@ -126,7 +126,7 @@ 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 +/// Note that ideally we wouldn't have to make the `Telemetry` cloneable, as that would remove the /// 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. @@ -195,7 +195,7 @@ impl Stream for Telemetry { fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll> { let before = Instant::now(); - // Because the `Telemetry` is clonable, we need to put the actual fields behind a `Mutex`. + // Because the `Telemetry` is cloneable, we need to put the actual fields behind a `Mutex`. // However, the user is only ever supposed to poll from one instance of `Telemetry`, while // the other instances are used only for RAII purposes. // We assume that the user is following this advice and therefore that the `Mutex` is only diff --git a/client/transaction-pool/graph/src/base_pool.rs b/client/transaction-pool/graph/src/base_pool.rs index 8a33d8244e..33b7a51f94 100644 --- a/client/transaction-pool/graph/src/base_pool.rs +++ b/client/transaction-pool/graph/src/base_pool.rs @@ -138,7 +138,7 @@ impl InPoolTransaction for Transaction { &self.provides } - fn is_propagateable(&self) -> bool { + fn is_propagable(&self) -> bool { self.propagate } } @@ -1058,7 +1058,7 @@ requires: [03,02], provides: [04], data: [4]}".to_owned() requires: vec![vec![3], vec![2]], provides: vec![vec![4]], propagate: true, - }.is_propagateable(), true); + }.is_propagable(), true); assert_eq!(Transaction { data: vec![4u8], @@ -1069,7 +1069,7 @@ requires: [03,02], provides: [04], data: [4]}".to_owned() requires: vec![vec![3], vec![2]], provides: vec![vec![4]], propagate: false, - }.is_propagateable(), false); + }.is_propagable(), false); } #[test] @@ -1126,7 +1126,7 @@ requires: [03,02], provides: [04], data: [4]}".to_owned() } #[test] - fn should_accept_future_transactions_when_explcitly_asked_to() { + fn should_accept_future_transactions_when_explicitly_asked_to() { // given let mut pool = pool(); pool.reject_future_transactions = true; diff --git a/client/transaction-pool/graph/src/listener.rs b/client/transaction-pool/graph/src/listener.rs index be6fb5c990..92ba71007e 100644 --- a/client/transaction-pool/graph/src/listener.rs +++ b/client/transaction-pool/graph/src/listener.rs @@ -58,7 +58,7 @@ impl Listener { /// Creates a new watcher for given verified extrinsic. /// - /// The watcher can be used to subscribe to lifecycle events of that extrinsic. + /// The watcher can be used to subscribe to life-cycle events of that extrinsic. pub fn create_watcher(&mut self, hash: H) -> watcher::Watcher> { let sender = self.watchers.entry(hash.clone()).or_insert_with(watcher::Sender::default); sender.new_watcher(hash) diff --git a/client/transaction-pool/graph/src/pool.rs b/client/transaction-pool/graph/src/pool.rs index 103f556d0e..12601bb8d2 100644 --- a/client/transaction-pool/graph/src/pool.rs +++ b/client/transaction-pool/graph/src/pool.rs @@ -308,7 +308,7 @@ impl Pool { let reverified_transactions = self.verify(at, pruned_transactions, false).await?; - log::trace!(target: "txpool", "Prunning at {:?}. Resubmitting transactions.", at); + log::trace!(target: "txpool", "Pruning at {:?}. Resubmitting transactions.", at); // And finally - submit reverified transactions back to the pool self.validated_pool.resubmit_pruned( diff --git a/client/transaction-pool/src/testing/pool.rs b/client/transaction-pool/src/testing/pool.rs index ed7c3e2d7a..c194a8615b 100644 --- a/client/transaction-pool/src/testing/pool.rs +++ b/client/transaction-pool/src/testing/pool.rs @@ -222,7 +222,7 @@ fn should_revalidate_during_maintenance() { } #[test] -fn should_resubmit_from_retracted_during_maintaince() { +fn should_resubmit_from_retracted_during_maintenance() { let xt = uxt(Alice, 209); let retracted_hash = Hash::random(); diff --git a/docs/CODE_OF_CONDUCT.adoc b/docs/CODE_OF_CONDUCT.adoc index 7cb0210e8e..0f7de7c7ef 100644 --- a/docs/CODE_OF_CONDUCT.adoc +++ b/docs/CODE_OF_CONDUCT.adoc @@ -22,7 +22,7 @@ Examples of unacceptable behavior by participants include: * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting -=== Facilitation, Not Strongarming +=== Facilitation, Not Strong Arming We recognize that this software is merely a tool for users to create and maintain their blockchain of preference. We see that blockchains are naturally community platforms with users being the ultimate decision makers. We assert that good software will maximize user agency by facilitate user-expression on the network. As such: diff --git a/docs/CONTRIBUTING.adoc b/docs/CONTRIBUTING.adoc index 817e1d7489..c83b686b09 100644 --- a/docs/CONTRIBUTING.adoc +++ b/docs/CONTRIBUTING.adoc @@ -52,7 +52,7 @@ If your PR changes the external APIs or interfaces used by Polkadot, **a corresp To update a corresponding Polkadot PR: -0. Pull lastet Polkadot master (or clone it, if you haven't yet). +0. Pull latest Polkadot master (or clone it, if you haven't yet). 1. Replace `polkadot-master` in all `Cargo.toml` with the name of the PR-branch - e.g. by running `find . -name "Cargo.toml" -exec sed -i "s/polkadot-master/PR_BRANCH/g" {}` (and to your repo, if the branch is not on mainline); Commit this change. 2. Make the changes required to pass the build again. 3. Submit all this as a PR against the Polkadot Repo, link that new PR in the existing substrate PR for reference diff --git a/docs/README.adoc b/docs/README.adoc index d8c582296c..bbc2713fbe 100644 --- a/docs/README.adoc +++ b/docs/README.adoc @@ -24,13 +24,13 @@ Substrate is designed for use in one of three ways: **1. Trivial**: By running the Substrate binary `substrate` and configuring it with a genesis block that includes the current demonstration runtime. In this case, you just build Substrate, configure a JSON file, and launch your own blockchain. This affords you the least amount of customizability, primarily allowing you to change the genesis parameters of the various included runtime modules such as balances, staking, block-period, fees, and governance. -**2. Modular**: By hacking together pallets built with Substrate FRAME into a new runtime and possibly altering or reconfiguring the Substrate client's block authoring logic. This affords you a very large amount of freedom over your blockchain's logic, letting you change datatypes, add or remove modules, and crucially, add your own modules. Much can be changed without touching the block authoring logic (since it is generic). If this is the case, then the existing Substrate binary can be used for block authoring and syncing. If the block authoring logic needs to be tweaked, then a new, altered block authoring binary must be built as a separate project and used by validators. This is how the Polkadot relay chain is built and should suffice for almost all circumstances in the near to mid-term. +**2. Modular**: By hacking together pallets built with Substrate FRAME into a new runtime and possibly altering or reconfiguring the Substrate client's block authoring logic. This affords you a very large amount of freedom over your blockchain's logic, letting you change data types, add or remove modules, and crucially, add your own modules. Much can be changed without touching the block authoring logic (since it is generic). If this is the case, then the existing Substrate binary can be used for block authoring and syncing. If the block authoring logic needs to be tweaked, then a new, altered block authoring binary must be built as a separate project and used by validators. This is how the Polkadot relay chain is built and should suffice for almost all circumstances in the near to mid-term. **3. Generic**: The entire SRML can be ignored and the entire runtime designed and implemented from scratch. If desired, this can be done in a language other than Rust, provided it can target WebAssembly. If the runtime can be made compatible with the existing client's block authoring logic, then you can simply construct a new genesis block from your Wasm blob and launch your chain with the existing Rust-based Substrate client. If not, then you'll need to alter the client's block authoring logic accordingly. This is probably a useless option for most projects right now, but provides complete flexibility allowing for a long-term, far-reaching upgrade path for the Substrate paradigm. === The Basics of Substrate -Substrate is a blockchain platform with a completely generic state transition function. That said, it does come with both standards and conventions (particularly regarding the Runtime Module Library) regarding underlying data structures. Roughly speaking, these core datatypes correspond to +trait+s in terms of the actual non-negotiable standard and generic +struct+s in terms of the convention. +Substrate is a blockchain platform with a completely generic state transition function. That said, it does come with both standards and conventions (particularly regarding the Runtime Module Library) regarding underlying data structures. Roughly speaking, these core data types correspond to +trait+s in terms of the actual non-negotiable standard and generic +struct+s in terms of the convention. ``` Header := Parent + ExtrinsicsRoot + StorageRoot + Digest diff --git a/docs/SECURITY.md b/docs/SECURITY.md index b850e5462e..7240218fa8 100644 --- a/docs/SECURITY.md +++ b/docs/SECURITY.md @@ -36,7 +36,7 @@ Responsible investigation and reporting includes, but isn't limited to, the foll ## Bug Bounty Program -Our Bug Bounty Program allows us to recognise and reward members of the Parity community for helping us find and address significant bugs, in accordance with the terms of the Parity Bug Bounty Program. A detailed description on eligibility, rewards, legal information and terms & conditions for contributors can be found on [our website](https://paritytech.io/bug-bounty.html). +Our Bug Bounty Program allows us to recognize and reward members of the Parity community for helping us find and address significant bugs, in accordance with the terms of the Parity Bug Bounty Program. A detailed description on eligibility, rewards, legal information and terms & conditions for contributors can be found on [our website](https://paritytech.io/bug-bounty.html). diff --git a/docs/Structure.adoc b/docs/Structure.adoc index cb0e4b28cb..c8cd63506a 100644 --- a/docs/Structure.adoc +++ b/docs/Structure.adoc @@ -67,7 +67,7 @@ There are a few crates with the `frame-` prefix. These do not contain domain-spe ** only helpers may be published ** purely testing crates must be `publish = false` -All tests that have to pull (dev)-dependencies out of their subtree and would thus break the dependency rules are considered intergration tests and should be stored in here. Only helper-crates in here shall be published, everything else is expected to be non-publish. +All tests that have to pull (dev)-dependencies out of their subtree and would thus break the dependency rules are considered integration tests and should be stored in here. Only helper-crates in here shall be published, everything else is expected to be non-publish. === Binaries and template diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index fc2294dd51..2c8ae3e18f 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -1224,7 +1224,7 @@ impl, I: Instance> ReservableCurrency for Module let actual = cmp::min(account.reserved, value); account.reserved -= actual; // defensive only: this can never fail since total issuance which is at least free+reserved - // fits into the same datatype. + // fits into the same data type. account.free = account.free.saturating_add(actual); value - actual }) diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index e9e6c75b83..a3ea901a6f 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -15,7 +15,7 @@ // along with Substrate. If not, see . //! Collective system: Members of a set of account IDs can make their collective feelings known -//! through dispatched calls from one of two specialised origins. +//! through dispatched calls from one of two specialized origins. //! //! The membership can be provided in one of two ways: either directly, using the Root-dispatchable //! function `set_members`, or indirectly, through implementing the `ChangeMembers` diff --git a/frame/contracts/COMPLEXITY.md b/frame/contracts/COMPLEXITY.md index a29127f778..e44d3006c8 100644 --- a/frame/contracts/COMPLEXITY.md +++ b/frame/contracts/COMPLEXITY.md @@ -141,7 +141,7 @@ Note that in case of storage modification we need to construct a key in the unde - then perform `blake2_256` hashing of the storage key. - concatenation of these hashes will constitute the key in the underlying storage. -There is also a special case to think of: if the balance of some account goes below `existential_deposit`, then all storage entries of that account will be erased, which requires time proprotional to the number of storage entries that account has. +There is also a special case to think of: if the balance of some account goes below `existential_deposit`, then all storage entries of that account will be erased, which requires time proportional to the number of storage entries that account has. **complexity**: `N` inserts into a `Map` or eventually into the storage (if committed). Every deleted account will induce removal of all its storage which is proportional to the number of storage entries that account has. @@ -236,7 +236,7 @@ This function takes the code of the constructor and input data. Instantiation of **Note** that the complexity of executing the constructor code should be considered separately. -**Note** that the complexity of `DetermineContractAddress` hook should be considered separately as well. Most likely it will use some kind of hashing over the code of the constructor and input data. The default `SimpleAddressDeterminator` does precisely that. +**Note** that the complexity of `DetermineContractAddress` hook should be considered separately as well. Most likely it will use some kind of hashing over the code of the constructor and input data. The default `SimpleAddressDeterminer` does precisely that. **Note** that the constructor returns code in the owned form and it's obtained via return facilities, which should have take fee for the return value. diff --git a/frame/contracts/common/src/lib.rs b/frame/contracts/common/src/lib.rs index e54b4c8d55..6a74a417fa 100644 --- a/frame/contracts/common/src/lib.rs +++ b/frame/contracts/common/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 . -//! A crate that hosts a common definitions that are relevent for the pallet-contracts. +//! A crate that hosts a common definitions that are relevant for the pallet-contracts. #![cfg_attr(not(feature = "std"), no_std)] diff --git a/frame/contracts/rpc/runtime-api/src/lib.rs b/frame/contracts/rpc/runtime-api/src/lib.rs index fd83ba6534..6fb629b024 100644 --- a/frame/contracts/rpc/runtime-api/src/lib.rs +++ b/frame/contracts/rpc/runtime-api/src/lib.rs @@ -76,7 +76,7 @@ sp_api::decl_runtime_apis! { /// Returns the projected time a given contract will be able to sustain paying its rent. /// - /// The returned projection is relevent for the current block, i.e. it is as if the contract + /// The returned projection is relevant for the current block, i.e. it is as if the contract /// was accessed at the current block. /// /// Returns `Err` if the contract is in a tombstone state or doesn't exist. diff --git a/frame/contracts/rpc/src/lib.rs b/frame/contracts/rpc/src/lib.rs index b0d6037416..52dddb177b 100644 --- a/frame/contracts/rpc/src/lib.rs +++ b/frame/contracts/rpc/src/lib.rs @@ -138,7 +138,7 @@ pub trait ContractsApi { /// Returns the projected time a given contract will be able to sustain paying its rent. /// - /// The returned projection is relevent for the given block, i.e. it is as if the contract was + /// The returned projection is relevant for the given block, i.e. it is as if the contract was /// accessed at the beginning of that block. /// /// Returns `None` if the contract is exempted from rent. diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index ec9fad93b4..53a6c484fc 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -1122,7 +1122,7 @@ mod tests { ); }); - // This test sends 50 units of currency as an endownment to a newly + // This test sends 50 units of currency as an endowment to a newly // instantiated contract. ExtBuilder::default().existential_deposit(15).build().execute_with(|| { let mut loader = MockLoader::empty(); diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index 19e070bd03..42cbaa3a7c 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -143,7 +143,7 @@ pub trait ComputeDispatchFee { fn compute_dispatch_fee(call: &Call) -> Balance; } -/// Information for managing an acocunt and its sub trie abstraction. +/// Information for managing an account and its sub trie abstraction. /// This is the required info to cache for an account #[derive(Encode, Decode, RuntimeDebug)] pub enum ContractInfo { @@ -432,8 +432,8 @@ pub trait Trait: frame_system::Trait { /// and the account id that requested the account creation. /// /// Formula: `blake2_256(blake2_256(code) + blake2_256(data) + origin)` -pub struct SimpleAddressDeterminator(PhantomData); -impl ContractAddressFor, T::AccountId> for SimpleAddressDeterminator +pub struct SimpleAddressDeterminer(PhantomData); +impl ContractAddressFor, T::AccountId> for SimpleAddressDeterminer where T::AccountId: UncheckedFrom + AsRef<[u8]> { @@ -494,7 +494,7 @@ decl_module! { /// The minimum amount required to generate a tombstone. const TombstoneDeposit: BalanceOf = T::TombstoneDeposit::get(); - /// Size of a contract at the time of instantiaion. This is a simple way to ensure that + /// Size of a contract at the time of instantiation. This is a simple way to ensure that /// empty contracts eventually gets deleted. const StorageSizeOffset: u32 = T::StorageSizeOffset::get(); diff --git a/frame/contracts/src/rent.rs b/frame/contracts/src/rent.rs index 49beebbf0c..8b6825419c 100644 --- a/frame/contracts/src/rent.rs +++ b/frame/contracts/src/rent.rs @@ -327,7 +327,7 @@ pub fn snitch_contract_should_be_evicted( } /// Returns the projected time a given contract will be able to sustain paying its rent. The -/// returned projection is relevent for the current block, i.e. it is as if the contract was +/// returned projection is relevant for the current block, i.e. it is as if the contract was /// accessed at the beginning of the current block. Returns `None` in case if the contract was /// evicted before or as a result of the rent collection. /// diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 0062e2bbd4..ddd532334c 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -597,7 +597,7 @@ fn dispatch_call() { topics: vec![], }, - // Event emited as a result of dispatch. + // Event emitted as a result of dispatch. EventRecord { phase: Phase::ApplyExtrinsic(0), event: MetaEvent::contracts(RawEvent::Dispatched(BOB, true)), @@ -1052,7 +1052,7 @@ fn claim_surcharge_malus() { } /// Claim surcharge with the given trigger_call at the given blocks. -/// if removes is true then assert that the contract is a tombstonedead +/// If `removes` is true then assert that the contract is a tombstone. fn claim_surcharge(blocks: u64, trigger_call: impl Fn() -> bool, removes: bool) { let (wasm, code_hash) = compile_module::(CODE_SET_RENT).unwrap(); @@ -2119,11 +2119,11 @@ const CODE_SELF_DESTRUCT: &str = r#" ;; Read own address into memory. (call $ext_scratch_read (i32.const 16) ;; Pointer to write address to - (i32.const 0) ;; Offset into scrach buffer + (i32.const 0) ;; Offset into scratch buffer (i32.const 8) ;; Length of encoded address ) - ;; Recursively call self with empty imput data. + ;; Recursively call self with empty input data. (call $assert (i32.eq (call $ext_call @@ -2155,7 +2155,7 @@ const CODE_SELF_DESTRUCT: &str = r#" ;; Read balance into memory. (call $ext_scratch_read (i32.const 8) ;; Pointer to write balance to - (i32.const 0) ;; Offset into scrach buffer + (i32.const 0) ;; Offset into scratch buffer (i32.const 8) ;; Length of encoded balance ) @@ -2484,7 +2484,7 @@ const CODE_SELF_DESTRUCTING_CONSTRUCTOR: &str = r#" ;; Read balance into memory. (call $ext_scratch_read (i32.const 8) ;; Pointer to write balance to - (i32.const 0) ;; Offset into scrach buffer + (i32.const 0) ;; Offset into scratch buffer (i32.const 8) ;; Length of encoded balance ) diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index b6a8928180..a84556d884 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -716,10 +716,10 @@ define_env!(Env, , // Record a request to restore the caller contract to the specified contract. // // At the finalization stage, i.e. when all changes from the extrinsic that invoked this - // contract are commited, this function will compute a tombstone hash from the caller's + // contract are committed, this function will compute a tombstone hash from the caller's // storage and the given code hash and if the hash matches the hash found in the tombstone at // the specified address - kill the caller contract and restore the destination contract and set - // the specified `rent_allowance`. All caller's funds are transfered to the destination. + // the specified `rent_allowance`. All caller's funds are transferred to the destination. // // This function doesn't perform restoration right away but defers it to the end of the // transaction. If there is no tombstone in the destination address or if the hashes don't match diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index 33ddf69427..c2c44918b0 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -2066,7 +2066,7 @@ mod tests { } #[test] - /// If transactor already voted, delegated vote is overwriten. + /// If transactor already voted, delegated vote is overwritten. fn single_proposal_should_work_with_vote_and_delegation() { new_test_ext().execute_with(|| { System::set_block_number(0); @@ -2121,7 +2121,7 @@ mod tests { } #[test] - /// If transactor voted, delegated vote is overwriten. + /// If transactor voted, delegated vote is overwritten. fn single_proposal_should_work_with_delegation_and_vote() { new_test_ext().execute_with(|| { System::set_block_number(0); diff --git a/frame/elections/src/lib.rs b/frame/elections/src/lib.rs index a3fdd74426..95d1858476 100644 --- a/frame/elections/src/lib.rs +++ b/frame/elections/src/lib.rs @@ -81,7 +81,7 @@ mod tests; // for B blocks following, there's a counting period whereby each of the candidates that believe // they fall in the top K+C voted can present themselves. they get the total stake -// recorded (based on the snapshot); an ordered list is maintained (the leaderboard). Noone may +// recorded (based on the snapshot); an ordered list is maintained (the leaderboard). No one may // present themselves that, if elected, would result in being included twice in the collective // (important since existing members will have their approval votes as it may be that they // don't get removed), nor if existing presenters would mean they're not in the top K+C. diff --git a/frame/evm/src/backend.rs b/frame/evm/src/backend.rs index b6c3078a33..d72c8b785e 100644 --- a/frame/evm/src/backend.rs +++ b/frame/evm/src/backend.rs @@ -29,7 +29,7 @@ pub struct Log { pub address: H160, /// Topics of the log. pub topics: Vec, - /// Bytearray data of the log. + /// Byte array data of the log. pub data: Vec, } diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index a12d06c69b..abf20114f2 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -177,7 +177,7 @@ decl_module! { fn deposit_event() = default; - /// Despoit balance from currency/balances module into EVM. + /// Deposit balance from currency/balances module into EVM. #[weight = SimpleDispatchInfo::FixedNormal(10_000)] fn deposit_balance(origin, value: BalanceOf) { let sender = ensure_signed(origin)?; diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index fb8a162d41..dbdc2efcf8 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -32,7 +32,7 @@ //! not the internals of the module implementation. Only state inputs, //! outputs, and a brief description that mentions whether calling it //! requires root, but without repeating the source code details. -//! Capitalise the first word of each documentation comment and end it with +//! Capitalize the first word of each documentation comment and end it with //! a full stop. See //! Generic example of annotating source code with documentation comments @@ -383,7 +383,7 @@ decl_event!( // - Unsigned calls that can be of two kinds: // * "Inherent extrinsics" that are opinions generally held by the block // authors that build child blocks. -// * Unsigned Transactions that are of intrinsic recognisable utility to the +// * Unsigned Transactions that are of intrinsic recognizable utility to the // network, and are validated by the runtime. // // Information about where this dispatch initiated from is provided as the first argument @@ -572,7 +572,7 @@ impl Module { // method. This example will not cover this type of extension. See `CheckRuntime` in system module // for an example. // -// Using the extension, you can add some hooks to the lifecycle of each transaction. Note that by +// Using the extension, you can add some hooks to the life cycle of each transaction. Note that by // default, an extension is applied to all `Call` functions (i.e. all transactions). the `Call` enum // variant is given to each function of `SignedExtension`. Hence, you can filter based on module or // a particular call if needed. diff --git a/frame/generic-asset/src/lib.rs b/frame/generic-asset/src/lib.rs index 59535de447..233054dd9d 100644 --- a/frame/generic-asset/src/lib.rs +++ b/frame/generic-asset/src/lib.rs @@ -208,7 +208,7 @@ impl Subtrait for T { /// Asset creation options. #[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug)] pub struct AssetOptions { - /// Initial issuance of this asset. All deposit to the creater of the asset. + /// Initial issuance of this asset. All deposit to the creator of the asset. #[codec(compact)] pub initial_issuance: Balance, /// Which accounts are allowed to possess this asset. @@ -898,7 +898,7 @@ pub trait AssetIdProvider { fn asset_id() -> Self::AssetId; } -// wrapping these imbalanes in a private module is necessary to ensure absolute privacy +// wrapping these imbalances in a private module is necessary to ensure absolute privacy // of the inner member. mod imbalances { use super::{ diff --git a/frame/generic-asset/src/tests.rs b/frame/generic-asset/src/tests.rs index ad8fc2bf1b..d5c0a877df 100644 --- a/frame/generic-asset/src/tests.rs +++ b/frame/generic-asset/src/tests.rs @@ -440,7 +440,7 @@ fn reserve_should_not_moves_amount_from_balance_to_reserved_balance() { // Then // - unreserved should return 20. #[test] -fn unreserve_should_return_substratced_value_from_unreserved_amount_by_actual_acount_balance() { +fn unreserve_should_return_subtracted_value_from_unreserved_amount_by_actual_account_balance() { ExtBuilder::default().free_balance((1, 0, 100)).build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::unreserve(&1, &0, 120), 20); @@ -553,7 +553,7 @@ fn slash_reserved_should_return_none() { // Then // - Should not return None. #[test] -fn repatriate_reserved_return_amount_substracted_by_slash_amount() { +fn repatriate_reserved_return_amount_subtracted_by_slash_amount() { ExtBuilder::default().build().execute_with(|| { GenericAsset::set_reserved_balance(&1, &0, 100); assert_eq!(GenericAsset::repatriate_reserved(&1, &0, &1, 130, BalanceStatus::Free), 30); diff --git a/frame/grandpa/src/lib.rs b/frame/grandpa/src/lib.rs index 6164e5ab4b..6d3223f094 100644 --- a/frame/grandpa/src/lib.rs +++ b/frame/grandpa/src/lib.rs @@ -154,7 +154,7 @@ decl_storage! { /// DEPRECATED /// /// This used to store the current authority set, which has been migrated to the well-known - /// GRANDPA_AUTHORITES_KEY unhashed key. + /// GRANDPA_AUTHORITIES_KEY unhashed key. #[cfg(feature = "migrate-authorities")] pub(crate) Authorities get(fn authorities): AuthorityList; @@ -435,7 +435,7 @@ impl pallet_session::OneSessionHandler for Module where I: Iterator { // Always issue a change if `session` says that the validators have changed. - // Even if their session keys are the same as before, the underyling economic + // Even if their session keys are the same as before, the underlying economic // identities have changed. let current_set_id = if changed { let next_authorities = validators.map(|(_, k)| (k, 1)).collect::>(); diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index 5470e3d4b0..341356394d 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -627,7 +627,7 @@ decl_module! { /// - `max_fee`: The maximum fee that may be paid. This should just be auto-populated as: /// /// ```nocompile - /// Self::registrars(reg_index).uwnrap().fee + /// Self::registrars(reg_index).unwrap().fee /// ``` /// /// Emits `JudgementRequested` if successful. diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index 9a3fc2430c..a050ad3d8a 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -233,7 +233,7 @@ pub trait Trait: frame_system::Trait + pallet_session::historical::Trait { /// An expected duration of the session. /// /// This parameter is used to determine the longevity of `heartbeat` transaction - /// and a rough time when we should start considering sending hearbeats, + /// and a rough time when we should start considering sending heartbeats, /// since the workers avoids sending them at the very beginning of the session, assuming /// there is a chance the authority will produce a block and they won't be necessary. type SessionDuration: Get; @@ -369,7 +369,7 @@ decl_module! { type OffchainResult = Result::BlockNumber>>; /// Keep track of number of authored blocks per authority, uncles are counted as -/// well since they're a valid proof of onlineness. +/// well since they're a valid proof of being online. impl pallet_authorship::EventHandler for Module { fn note_author(author: T::ValidatorId) { Self::note_authorship(author); @@ -576,7 +576,7 @@ impl pallet_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 heartbeat is defered a bit to prevent spaming. + // the heartbeat is deferred a bit to prevent spamming. let block_number = >::block_number(); let half_session = T::SessionDuration::get() / 2.into(); >::put(block_number + half_session); diff --git a/frame/im-online/src/tests.rs b/frame/im-online/src/tests.rs index adc126094b..808978d403 100644 --- a/frame/im-online/src/tests.rs +++ b/frame/im-online/src/tests.rs @@ -328,7 +328,7 @@ fn should_not_send_a_report_if_already_online() { // then let transaction = pool_state.write().transactions.pop().unwrap(); - // All validators have `0` as their session key, but we should only produce 1 hearbeat. + // All validators have `0` as their session key, but we should only produce 1 heartbeat. assert_eq!(pool_state.read().transactions.len(), 0); // check stuff about the transaction. let ex: Extrinsic = Decode::decode(&mut &*transaction).unwrap(); diff --git a/frame/indices/src/lib.rs b/frame/indices/src/lib.rs index ad1a7f300f..d59a501793 100644 --- a/frame/indices/src/lib.rs +++ b/frame/indices/src/lib.rs @@ -130,7 +130,7 @@ decl_module! { } /// Assign an index already owned by the sender to another account. The balance reservation - /// is effectively transfered to the new account. + /// is effectively transferred to the new account. /// /// The dispatch origin for this call must be _Signed_. /// diff --git a/frame/membership/src/lib.rs b/frame/membership/src/lib.rs index 62d1315ee2..c275bb783b 100644 --- a/frame/membership/src/lib.rs +++ b/frame/membership/src/lib.rs @@ -233,7 +233,7 @@ mod tests { }; 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. + // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup, BadOrigin}, testing::Header}; use frame_system::EnsureSignedBy; diff --git a/frame/metadata/src/lib.rs b/frame/metadata/src/lib.rs index a7410bbfbc..5ecb9f3443 100644 --- a/frame/metadata/src/lib.rs +++ b/frame/metadata/src/lib.rs @@ -33,7 +33,7 @@ use sp_core::RuntimeDebug; #[cfg(feature = "std")] type StringBuf = String; -/// Curent prefix of metadata +/// Current prefix of metadata pub const META_RESERVED: u32 = 0x6174656d; // 'meta' warn endianness /// On `no_std` we do not support `Decode` and thus `StringBuf` is just `&'static str`. diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index 6a86f08093..16797ffdef 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -104,7 +104,7 @@ decl_error! { TooShort, /// A name is too long. TooLong, - /// An account in't named. + /// An account isn't named. Unnamed, } } diff --git a/frame/offences/src/lib.rs b/frame/offences/src/lib.rs index ea6f96cbc3..7831ba65a3 100644 --- a/frame/offences/src/lib.rs +++ b/frame/offences/src/lib.rs @@ -187,7 +187,7 @@ struct TriageOutcome { concurrent_offenders: Vec>, } -/// An auxilary struct for working with storage of indexes localized for a specific offence +/// An auxiliary struct for working with storage of indexes localized for a specific offence /// kind (specified by the `O` type parameter). /// /// This struct is responsible for aggregating storage writes and the underlying storage should not diff --git a/frame/offences/src/tests.rs b/frame/offences/src/tests.rs index 703361f77f..f2f82cf7a8 100644 --- a/frame/offences/src/tests.rs +++ b/frame/offences/src/tests.rs @@ -98,7 +98,7 @@ fn should_report_in_different_time_slot() { }); // when - // reportfor the second time + // report for the second time offence.time_slot += 1; Offences::report_offence(vec![], offence); diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index 64d8f40099..53d640688e 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -135,7 +135,7 @@ impl Randomness for Module { let hash_series = >::get(); if !hash_series.is_empty() { - // Always the case after block 1 is initialised. + // Always the case after block 1 is initialized. hash_series.iter() .cycle() .skip(index) @@ -231,7 +231,7 @@ mod tests { } #[test] - fn test_random_material_parital() { + fn test_random_material_partial() { new_test_ext().execute_with(|| { let genesis_hash = System::parent_hash(); diff --git a/frame/recovery/src/lib.rs b/frame/recovery/src/lib.rs index d293e1da9a..b456d17c68 100644 --- a/frame/recovery/src/lib.rs +++ b/frame/recovery/src/lib.rs @@ -44,9 +44,9 @@ //! the number of friends chosen. This deposit is returned in full when the account //! owner removes their recovery configuration. //! -//! ### Recovery Lifecycle +//! ### Recovery Life Cycle //! -//! The intended lifecycle of a successful recovery takes the following steps: +//! The intended life cycle of a successful recovery takes the following steps: //! 1. The account owner calls `create_recovery` to set up a recovery configuration //! for their account. //! 2. At some later time, the account owner loses access to their account and wants diff --git a/frame/recovery/src/tests.rs b/frame/recovery/src/tests.rs index af4eadb58f..97d4791cce 100644 --- a/frame/recovery/src/tests.rs +++ b/frame/recovery/src/tests.rs @@ -56,7 +56,7 @@ fn set_recovered_works() { } #[test] -fn recovery_lifecycle_works() { +fn recovery_life_cycle_works() { new_test_ext().execute_with(|| { let friends = vec![2, 3, 4]; let threshold = 3; diff --git a/frame/scored-pool/src/mock.rs b/frame/scored-pool/src/mock.rs index 38a01a69af..cccb3c2b4c 100644 --- a/frame/scored-pool/src/mock.rs +++ b/frame/scored-pool/src/mock.rs @@ -22,7 +22,7 @@ use std::cell::RefCell; use frame_support::{impl_outer_origin, parameter_types, weights::Weight, ord_parameter_types}; 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. +// or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sp_runtime::{ Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header, }; diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index a18d55d26c..5226415400 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -168,7 +168,7 @@ impl SessionManager for () { fn end_session(_: SessionIndex) {} } -/// Handler for session lifecycle events. +/// Handler for session life cycle events. pub trait SessionHandler { /// All the key type ids this session handler can process. /// diff --git a/frame/society/src/lib.rs b/frame/society/src/lib.rs index e803e54d4f..38dc491b80 100644 --- a/frame/society/src/lib.rs +++ b/frame/society/src/lib.rs @@ -834,7 +834,7 @@ decl_module! { Self::deposit_event(RawEvent::Founded(founder)); } - /// Anull the founding of the society. + /// Annul the founding of the society. /// /// The dispatch origin for this call must be Signed, and the signing account must be both /// the `Founder` and the `Head`. This implies that it may only be done when there is one diff --git a/frame/society/src/mock.rs b/frame/society/src/mock.rs index 081d68ada4..84b2343fae 100644 --- a/frame/society/src/mock.rs +++ b/frame/society/src/mock.rs @@ -21,7 +21,7 @@ use super::*; use frame_support::{impl_outer_origin, parameter_types, ord_parameter_types}; 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. +// or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sp_runtime::{ Perbill, testing::Header, diff --git a/frame/society/src/tests.rs b/frame/society/src/tests.rs index 47d13d8361..8b10dc32e7 100644 --- a/frame/society/src/tests.rs +++ b/frame/society/src/tests.rs @@ -282,7 +282,7 @@ fn slash_payout_multi_works() { } #[test] -fn suspended_member_lifecycle_works() { +fn suspended_member_life_cycle_works() { EnvBuilder::new().execute(|| { // Add 20 to members, who is not the head and can be suspended/removed. assert_ok!(Society::add_member(&20)); diff --git a/frame/staking/reward-curve/src/lib.rs b/frame/staking/reward-curve/src/lib.rs index 3c31cecc21..51af0a33a3 100644 --- a/frame/staking/reward-curve/src/lib.rs +++ b/frame/staking/reward-curve/src/lib.rs @@ -27,7 +27,7 @@ use syn::parse::{Parse, ParseStream}; /// Expressed in millionth, must be between 0_100_000 and 0_900_000. /// /// - `falloff`: Known as `decay_rate` in the literature. A co-efficient dictating the strength of -/// the global incentivisation to get the `ideal_stake`. A higher number results in less typical +/// the global incentivization to get the `ideal_stake`. A higher number results in less typical /// inflation at the cost of greater volatility for validators. /// Expressed in millionth, must be between 0 and 1_000_000. /// @@ -271,7 +271,7 @@ fn compute_points(input: &INposInput) -> Vec<(u32, u32)> { points.push((0, inpos.i_0)); points.push((inpos.x_ideal, inpos.i_ideal_times_x_ideal)); - // For each point p: (next_p.0 - p.0) < segment_lenght && (next_p.1 - p.1) < segment_lenght. + // For each point p: (next_p.0 - p.0) < segment_length && (next_p.1 - p.1) < segment_length. // This ensures that the total number of segment doesn't overflow max_piece_count. let max_length = (input.max_inflation - input.min_inflation + 1_000_000 - inpos.x_ideal) / (input.max_piece_count - 1); diff --git a/frame/staking/src/inflation.rs b/frame/staking/src/inflation.rs index d5135fcc1f..e75ac3af2b 100644 --- a/frame/staking/src/inflation.rs +++ b/frame/staking/src/inflation.rs @@ -24,7 +24,7 @@ use sp_runtime::{Perbill, PerThing, traits::AtLeast32Bit, curve::PiecewiseLinear /// The total payout to all validators (and their nominators) per era. /// /// Defined as such: -/// `payout = yearly_inflation(npos_token_staked / total_tokens) * total_tokans / era_per_year` +/// `payout = yearly_inflation(npos_token_staked / total_tokens) * total_tokens / era_per_year` /// /// `era_duration` is expressed in millisecond. pub fn compute_total_payout( diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 447f655048..3f84597912 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -171,7 +171,7 @@ //! //! Validators and nominators are rewarded at the end of each era. The total reward of an era is //! 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 +//! nominators and validators, divided by the total token supply). It aims to incentivize toward a //! defined staking rate. The full specification can be found //! [here](https://research.web3.foundation/en/latest/polkadot/Token%20Economics.html#inflation-model). //! @@ -1360,7 +1360,7 @@ impl Module { Self::new_era(session_index) } - /// Initialise the first session (and consequently the first era) + /// Initialize the first session (and consequently the first era) fn initial_session() -> Option> { // note: `CurrentEraStart` is set in `on_finalize` of the first block because now is not // available yet. diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index 73f1afd634..73215d6117 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -235,7 +235,7 @@ fn multi_era_reward_should_work() { // Compute now as other parameter won't change let total_payout_0 = current_total_payout_for_duration(3000); - assert!(total_payout_0 > 10); // Test is meaningfull if reward something + assert!(total_payout_0 > 10); // Test is meaningful if reward something >::reward_by_ids(vec![(11, 1)]); start_session(0); @@ -249,7 +249,7 @@ fn multi_era_reward_should_work() { start_session(4); let total_payout_1 = current_total_payout_for_duration(3000); - assert!(total_payout_1 > 10); // Test is meaningfull if reward something + assert!(total_payout_1 > 10); // Test is meaningful if reward something >::reward_by_ids(vec![(11, 101)]); // new era is triggered here. @@ -458,7 +458,7 @@ fn nominating_and_rewards_should_work() { // the total reward for era 0 let total_payout_0 = current_total_payout_for_duration(3000); - assert!(total_payout_0 > 100); // Test is meaningfull if reward something + assert!(total_payout_0 > 100); // Test is meaningful if reward something >::reward_by_ids(vec![(41, 1)]); >::reward_by_ids(vec![(31, 1)]); >::reward_by_ids(vec![(21, 10)]); // must be no-op @@ -506,7 +506,7 @@ fn nominating_and_rewards_should_work() { // the total reward for era 1 let total_payout_1 = current_total_payout_for_duration(3000); - assert!(total_payout_1 > 100); // Test is meaningfull if reward something + assert!(total_payout_1 > 100); // Test is meaningful if reward something >::reward_by_ids(vec![(41, 10)]); // must be no-op >::reward_by_ids(vec![(31, 10)]); // must be no-op >::reward_by_ids(vec![(21, 2)]); @@ -575,7 +575,7 @@ fn nominators_also_get_slashed() { assert_ok!(Staking::nominate(Origin::signed(2), vec![20, 10])); let total_payout = current_total_payout_for_duration(3000); - assert!(total_payout > 100); // Test is meaningfull if reward something + assert!(total_payout > 100); // Test is meaningful if reward something >::reward_by_ids(vec![(11, 1)]); // new era, pay rewards, @@ -850,7 +850,7 @@ fn reward_destination_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_0 = current_total_payout_for_duration(3000); - assert!(total_payout_0 > 100); // Test is meaningfull if reward something + assert!(total_payout_0 > 100); // Test is meaningful if reward something >::reward_by_ids(vec![(11, 1)]); start_era(1); @@ -872,7 +872,7 @@ fn reward_destination_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_1 = current_total_payout_for_duration(3000); - assert!(total_payout_1 > 100); // Test is meaningfull if reward something + assert!(total_payout_1 > 100); // Test is meaningful if reward something >::reward_by_ids(vec![(11, 1)]); start_era(2); @@ -899,7 +899,7 @@ fn reward_destination_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_2 = current_total_payout_for_duration(3000); - assert!(total_payout_2 > 100); // Test is meaningfull if reward something + assert!(total_payout_2 > 100); // Test is meaningful if reward something >::reward_by_ids(vec![(11, 1)]); start_era(3); @@ -949,7 +949,7 @@ fn validator_payment_prefs_work() { // Compute total payout now for whole duration as other parameter won't change let total_payout_0 = current_total_payout_for_duration(3000); - assert!(total_payout_0 > 100); // Test is meaningfull if reward something + assert!(total_payout_0 > 100); // Test is meaningful if reward something >::reward_by_ids(vec![(11, 1)]); start_era(1); @@ -1393,7 +1393,7 @@ fn slot_stake_is_least_staked_validator_and_exposure_defines_maximum_punishment( // Compute total payout now for whole duration as other parameter won't change let total_payout_0 = current_total_payout_for_duration(3000); - assert!(total_payout_0 > 100); // Test is meaningfull if reward something + assert!(total_payout_0 > 100); // Test is meaningful if reward something >::reward_by_ids(vec![(11, 1)]); >::reward_by_ids(vec![(21, 1)]); @@ -1678,7 +1678,7 @@ fn bond_with_little_staked_value_bounded_by_slot_stake() { assert_ok!(Staking::validate(Origin::signed(2), ValidatorPrefs::default())); let total_payout_0 = current_total_payout_for_duration(3000); - assert!(total_payout_0 > 100); // Test is meaningfull if reward something + assert!(total_payout_0 > 100); // Test is meaningful if reward something reward_all_elected(); start_era(1); @@ -1693,7 +1693,7 @@ fn bond_with_little_staked_value_bounded_by_slot_stake() { assert_eq!(Balances::free_balance(2), init_balance_2); let total_payout_1 = current_total_payout_for_duration(3000); - assert!(total_payout_1 > 100); // Test is meaningfull if reward something + assert!(total_payout_1 > 100); // Test is meaningful if reward something reward_all_elected(); start_era(2); diff --git a/frame/support/procedural/src/construct_runtime/parse.rs b/frame/support/procedural/src/construct_runtime/parse.rs index b7d60c7155..4a81a7efd6 100644 --- a/frame/support/procedural/src/construct_runtime/parse.rs +++ b/frame/support/procedural/src/construct_runtime/parse.rs @@ -91,7 +91,7 @@ impl Parse for WhereSection { }) = definitions.first() { let msg = format!( - "`{:?}` was declared above. Please use exactly one delcataion for `{:?}`.", + "`{:?}` was declared above. Please use exactly one declaration for `{:?}`.", kind, kind ); return Err(Error::new(*kind_span, msg)); diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index c59d630928..8849e52c79 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -123,7 +123,7 @@ use proc_macro::TokenStream; /// 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 +/// [`Hashable`](../frame_support/trait.Hashable.html) trait. They must be chosen with care, see /// generator documentation. /// /// If the first key is untrusted, a cryptographic `hasher` such as `blake2_256` or @@ -200,7 +200,7 @@ use proc_macro::TokenStream; /// /// ```nocompile /// construct_runtime!( -/// pub enum Runtume with ... { +/// pub enum Runtime with ... { /// ..., /// Example: example::{Module, Storage, ..., Config}, /// ..., diff --git a/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs b/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs index 100907b292..ae7ffa64bf 100644 --- a/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs +++ b/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Genesis config defintion. +//! Genesis config definition. use frame_support_procedural_tools::syn_ext as ext; use proc_macro2::TokenStream; diff --git a/frame/support/procedural/src/storage/mod.rs b/frame/support/procedural/src/storage/mod.rs index 453cb9c467..3345c5a123 100644 --- a/frame/support/procedural/src/storage/mod.rs +++ b/frame/support/procedural/src/storage/mod.rs @@ -29,7 +29,7 @@ use frame_support_procedural_tools::{ generate_crate_access, generate_hidden_includes, syn_ext as ext }; -/// All informations contained in input of decl_storage +/// All information contained in input of decl_storage pub struct DeclStorageDef { /// Name of the module used to import hidden imports. hidden_crate: Option, @@ -219,9 +219,9 @@ pub struct StorageLineDefExt { storage_trait: proc_macro2::TokenStream, /// Full trait, for example: `storage::generator::StorageMap`. storage_generator_trait: proc_macro2::TokenStream, - /// Weither the storage is generic. + /// Whether the storage is generic. is_generic: bool, - /// Weither the storage value is an option. + /// Whether the storage value is an option. is_option: bool, } @@ -283,7 +283,7 @@ impl StorageLineDefExt { None }; - let storage_trait_trunkated = match &storage_def.storage_type { + let storage_trait_truncated = match &storage_def.storage_type { StorageLineTypeDef::Simple(_) => { quote!( StorageValue<#value_type> ) }, @@ -302,8 +302,8 @@ impl StorageLineDefExt { }, }; - let storage_trait = quote!( storage::#storage_trait_trunkated ); - let storage_generator_trait = quote!( storage::generator::#storage_trait_trunkated ); + let storage_trait = quote!( storage::#storage_trait_truncated ); + let storage_generator_trait = quote!( storage::generator::#storage_trait_truncated ); let doc_attrs = storage_def.attrs.iter() .filter_map(|a| a.parse_meta().ok()) diff --git a/frame/support/procedural/tools/src/syn_ext.rs b/frame/support/procedural/tools/src/syn_ext.rs index 7b0a2cb93f..4577437232 100644 --- a/frame/support/procedural/tools/src/syn_ext.rs +++ b/frame/support/procedural/tools/src/syn_ext.rs @@ -180,7 +180,7 @@ pub fn extract_type_option(typ: &syn::Type) -> Option { None } -/// Auxialary structure to check if a given `Ident` is contained in an ast. +/// Auxiliary structure to check if a given `Ident` is contained in an ast. struct ContainsIdent<'a> { ident: &'a Ident, result: bool, diff --git a/frame/support/src/debug.rs b/frame/support/src/debug.rs index 29847b70e5..4b7ff6cc39 100644 --- a/frame/support/src/debug.rs +++ b/frame/support/src/debug.rs @@ -24,7 +24,7 @@ //! and size of the blob. Luckily there are some ways to mitigate //! this that are described below. //! -//! First component to utilize debug-printing and loggin is actually +//! First component to utilize debug-printing and logging is actually //! 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 diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index c2f42fd561..2a3e638de3 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -819,7 +819,7 @@ macro_rules! decl_module { // TODO: this probably should be a different macro? (@call - $ingore:ident + $ignore:ident $mod_type:ident<$trait_instance:ident $(, $instance:ident)?> $fn_name:ident $origin:ident $system:ident [ $( $param_name:ident),* ] ) => { <$mod_type<$trait_instance $(, $instance)?>>::$fn_name( $origin $(, $param_name )* ) diff --git a/frame/support/src/error.rs b/frame/support/src/error.rs index 34de38108f..3b105e979d 100644 --- a/frame/support/src/error.rs +++ b/frame/support/src/error.rs @@ -28,7 +28,7 @@ pub use frame_metadata::{ModuleErrorMetadata, ErrorMetadata, DecodeDifferent}; /// 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 +/// It is required that the error type is registered in `decl_module!` to make the error /// exported in the metadata. /// /// # Usage diff --git a/frame/support/src/event.rs b/frame/support/src/event.rs index d30e6ddeea..8b7de01159 100644 --- a/frame/support/src/event.rs +++ b/frame/support/src/event.rs @@ -641,7 +641,7 @@ mod tests { } decl_event!( - /// Event finish formatting on an unnamed one with trailling comma + /// Event finish formatting on an unnamed one with trailing comma pub enum Event where ::Balance, ::Origin, diff --git a/frame/support/src/storage/child.rs b/frame/support/src/storage/child.rs index f549ffc25f..d4d046a9d4 100644 --- a/frame/support/src/storage/child.rs +++ b/frame/support/src/storage/child.rs @@ -22,7 +22,7 @@ //! //! 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. +//! This unique id management and generation responsibility 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::sp_std::prelude::*; diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index 34166c368c..60f0d4a8b2 100644 --- a/frame/support/src/weights.rs +++ b/frame/support/src/weights.rs @@ -67,7 +67,7 @@ pub trait ClassifyDispatch { fn classify_dispatch(&self, target: T) -> DispatchClass; } -/// Means of determining the weight of a block's lifecycle hooks: on_initialize, on_finalize and +/// Means of determining the weight of a block's life cycle hooks: `on_initialize`, `on_finalize` and /// such. pub trait WeighBlock { /// Return the weight of the block's on_initialize hook. 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 index 4bac57d63c..b622adbfe6 100644 --- a/frame/support/test/tests/construct_runtime_ui/abundant_where_param.stderr +++ b/frame/support/test/tests/construct_runtime_ui/abundant_where_param.stderr @@ -1,4 +1,4 @@ -error: `Block` was declared above. Please use exactly one delcataion for `Block`. +error: `Block` was declared above. Please use exactly one declaration for `Block`. --> $DIR/abundant_where_param.rs:7:3 | 7 | Block = Block1, 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 index 13536338e0..dc1dc430ed 100644 --- a/frame/support/test/tests/construct_runtime_ui/invalid_where_param.rs +++ b/frame/support/test/tests/construct_runtime_ui/invalid_where_param.rs @@ -5,7 +5,7 @@ construct_runtime! { Block = Block, NodeBlock = Block, TypeX = Block, - UnchekcedExtrinsic = UnchekcedExtrinsic, + UncheckedExtrinsic = UncheckedExtrinsic, {} } diff --git a/frame/support/test/tests/instance.rs b/frame/support/test/tests/instance.rs index 48854baad9..6fa2806dd3 100644 --- a/frame/support/test/tests/instance.rs +++ b/frame/support/test/tests/instance.rs @@ -300,7 +300,7 @@ fn new_test_ext() -> sp_io::TestExternalities { } #[test] -fn storage_instance_independance() { +fn storage_instance_independence() { let mut storage = sp_core::storage::Storage { top: std::collections::BTreeMap::new(), children: std::collections::HashMap::new() diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index c351020a41..57be7b157c 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -720,7 +720,7 @@ impl Module { /// Even more dangerous is to note that this function does NOT take any action, if the new sum /// of block weight is more than the block weight limit. This is what the _unchecked_. /// - /// Another potential use-case could be for the `on_initialise` and `on_finalize` hooks. + /// Another potential use-case could be for the `on_initialize` and `on_finalize` hooks. /// /// If no previous weight exists, the function initializes the weight to zero. pub fn register_extra_weight_unchecked(weight: Weight) { diff --git a/frame/system/src/offchain.rs b/frame/system/src/offchain.rs index b26f4be4b4..507092f626 100644 --- a/frame/system/src/offchain.rs +++ b/frame/system/src/offchain.rs @@ -68,7 +68,7 @@ pub trait Signer { /// A `Signer` implementation for any `AppPublic` type. /// -/// This implementation additionaly supports conversion to/from multi-signature/multi-signer +/// This implementation additionally supports conversion to/from multi-signature/multi-signer /// wrappers. /// If the wrapped crypto doesn't match `AppPublic`s crypto `None` is returned. impl Signer for TAnyAppPublic where diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index 36f92c401e..192dd1aff6 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -38,7 +38,7 @@ //! should be paid. //! //! A group of `Tippers` is determined through the config `Trait`. After half of these have declared -//! some amount that they believe a particular reported reason deserves, then a countfown period is +//! some amount that they believe a particular reported reason deserves, then a countdown period is //! entered where any remaining members can declare their tip amounts also. After the close of the //! countdown period, the median of all declared tips is paid to the reported beneficiary, along //! with any finders fee, in case of a public (and bonded) original report. @@ -1052,14 +1052,14 @@ mod tests { } #[test] - fn reject_non_existant_spend_proposal_fails() { + fn reject_non_existent_spend_proposal_fails() { new_test_ext().execute_with(|| { assert_noop!(Treasury::reject_proposal(Origin::ROOT, 0), Error::::InvalidProposalIndex); }); } #[test] - fn accept_non_existant_spend_proposal_fails() { + fn accept_non_existent_spend_proposal_fails() { new_test_ext().execute_with(|| { assert_noop!(Treasury::approve_proposal(Origin::ROOT, 0), Error::::InvalidProposalIndex); }); @@ -1135,9 +1135,9 @@ mod tests { } // In case treasury account is not existing then it works fine. - // This is usefull for chain that will just update runtime. + // This is useful for chain that will just update runtime. #[test] - fn inexisting_account_works() { + fn inexistent_account_works() { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); pallet_balances::GenesisConfig::{ balances: vec![(0, 100), (1, 99), (2, 1)], diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index 414651659c..c19b044ad7 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -105,7 +105,7 @@ pub trait Trait: frame_system::Trait { /// composite was created to be uniquely identified. #[derive(Copy, Clone, Eq, PartialEq, Encode, Decode, Default, RuntimeDebug)] pub struct Timepoint { - /// The hieght of the chain at the point in time. + /// The height of the chain at the point in time. height: BlockNumber, /// The index of the extrinsic at the point in time. index: u32, @@ -210,7 +210,7 @@ impl PaysFee<(&u16, &Box)> for Passthrough { } } -/// Sumation pass-through for the weight function of the batch call. +/// Summation pass-through for the weight function of the batch call. /// /// This just adds all of the weights together of all of the calls. struct BatchPassthrough(sp_std::marker::PhantomData); diff --git a/primitives/allocator/src/freeing_bump.rs b/primitives/allocator/src/freeing_bump.rs index caac9dd6c4..0d15ed11f7 100644 --- a/primitives/allocator/src/freeing_bump.rs +++ b/primitives/allocator/src/freeing_bump.rs @@ -37,7 +37,7 @@ //! allocation size is capped, therefore the number of orders and thus the linked lists is as well //! limited. //! -//! When the allocater serves an allocation request it first checks the linked list for the respective +//! When the allocator serves an allocation request it first checks the linked list for the respective //! order. If it doesn't have any free chunks, the allocator requests memory from the bump allocator. //! In any case the order is stored in the header of the allocation. //! @@ -48,7 +48,7 @@ use crate::Error; use sp_std::{convert::{TryFrom, TryInto}, ops::{Range, Index, IndexMut}}; use sp_wasm_interface::{Pointer, WordSize}; -/// The minimal alignment guaranteed by this allocator. The alignment of 8 is choosen because it is +/// The minimal alignment guaranteed by this allocator. The alignment of 8 is chosen because it is /// the alignment guaranteed by wasm32. const ALIGNMENT: u32 = 8; diff --git a/primitives/arithmetic/fuzzer/src/biguint.rs b/primitives/arithmetic/fuzzer/src/biguint.rs index 1e2ec2a502..f217b080d2 100644 --- a/primitives/arithmetic/fuzzer/src/biguint.rs +++ b/primitives/arithmetic/fuzzer/src/biguint.rs @@ -22,7 +22,7 @@ //! Once a panic is found, it can be debugged with //! `cargo hfuzz run-debug biguint hfuzz_workspace/biguint/*.fuzz`. //! -//! # More infomation +//! # More information //! More information about `honggfuzz` can be found //! [here](https://docs.rs/honggfuzz/). diff --git a/primitives/arithmetic/fuzzer/src/rational128.rs b/primitives/arithmetic/fuzzer/src/rational128.rs index 60aa315c18..586a165272 100644 --- a/primitives/arithmetic/fuzzer/src/rational128.rs +++ b/primitives/arithmetic/fuzzer/src/rational128.rs @@ -22,7 +22,7 @@ //! Once a panic is found, it can be debugged with //! `cargo hfuzz run-debug rational128 hfuzz_workspace/rational128/*.fuzz`. //! -//! # More infomation +//! # More information //! More information about `honggfuzz` can be found //! [here](https://docs.rs/honggfuzz/). diff --git a/primitives/block-builder/src/lib.rs b/primitives/block-builder/src/lib.rs index d963fb7e30..f050979bd8 100644 --- a/primitives/block-builder/src/lib.rs +++ b/primitives/block-builder/src/lib.rs @@ -26,7 +26,7 @@ use sp_inherents::{InherentData, CheckInherentsResult}; /// /// These definitions are taken from the 2c58e30246a029b53d51e5b24c31974ac539ee8b git revision. #[deprecated(note = "These definitions here are only for compatibility reasons")] -pub mod compatability_v3 { +pub mod compatibility_v3 { use sp_runtime::{DispatchOutcome, transaction_validity}; use codec::{Encode, Decode}; @@ -51,7 +51,7 @@ sp_api::decl_runtime_apis! { #[changed_in(4)] #[allow(deprecated)] fn apply_extrinsic(extrinsic: ::Extrinsic) - -> self::compatability_v3::ApplyResult; + -> self::compatibility_v3::ApplyResult; /// Apply the given extrinsic. /// diff --git a/primitives/blockchain/src/error.rs b/primitives/blockchain/src/error.rs index 24872448ab..ece20d1cf8 100644 --- a/primitives/blockchain/src/error.rs +++ b/primitives/blockchain/src/error.rs @@ -20,7 +20,7 @@ use std::{self, error, result}; use sp_state_machine; use sp_runtime::transaction_validity::TransactionValidityError; #[allow(deprecated)] -use sp_block_builder::compatability_v3; +use sp_block_builder::compatibility_v3; use sp_consensus; use derive_more::{Display, From}; use codec::Error as CodecError; @@ -37,7 +37,7 @@ pub enum ApplyExtrinsicFailed { /// 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 is used for miscellaneous 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)] @@ -151,9 +151,9 @@ impl<'a> From<&'a str> for Error { } #[allow(deprecated)] -impl From for ApplyExtrinsicFailed { - fn from(e: compatability_v3::ApplyError) -> Self { - use self::compatability_v3::ApplyError::*; +impl From for ApplyExtrinsicFailed { + fn from(e: compatibility_v3::ApplyError) -> Self { + use self::compatibility_v3::ApplyError::*; match e { Validity(tx_validity) => Self::Validity(tx_validity), e => Self::Msg(format!("Apply extrinsic failed: {:?}", e)), diff --git a/primitives/blockchain/src/lib.rs b/primitives/blockchain/src/lib.rs index 21c5bc99d2..8f83c7aec5 100644 --- a/primitives/blockchain/src/lib.rs +++ b/primitives/blockchain/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 . -//! Substrate blockchain traits and primtives +//! Substrate blockchain traits and primitives. mod backend; mod header_metadata; diff --git a/primitives/consensus/common/src/block_import.rs b/primitives/consensus/common/src/block_import.rs index 76655acbd6..3000477ded 100644 --- a/primitives/consensus/common/src/block_import.rs +++ b/primitives/consensus/common/src/block_import.rs @@ -229,7 +229,7 @@ impl BlockImportParams { } } - /// Take interemdiate by given key, and remove it from the processing list. + /// Take intermediate by given key, and remove it from the processing list. pub fn take_intermediate(&mut self, key: &[u8]) -> Result, Error> { let (k, v) = self.intermediates.remove_entry(key).ok_or(Error::NoIntermediate)?; diff --git a/primitives/consensus/common/src/error.rs b/primitives/consensus/common/src/error.rs index c802831d65..d7e396223a 100644 --- a/primitives/consensus/common/src/error.rs +++ b/primitives/consensus/common/src/error.rs @@ -37,7 +37,7 @@ pub enum Error { /// Intermediate is of wrong type. #[display(fmt="Invalid intermediate.")] InvalidIntermediate, - /// Unable to schedule wakeup. + /// Unable to schedule wake-up. #[display(fmt="Timer error: {}", _0)] FaultyTimer(std::io::Error), /// Error while working with inherent data. diff --git a/primitives/consensus/common/src/import_queue/basic_queue.rs b/primitives/consensus/common/src/import_queue/basic_queue.rs index bd42ebd685..0d1aed7fb1 100644 --- a/primitives/consensus/common/src/import_queue/basic_queue.rs +++ b/primitives/consensus/common/src/import_queue/basic_queue.rs @@ -29,7 +29,7 @@ use crate::import_queue::{ }; /// Interface to a basic block import queue that is importing blocks sequentially in a separate -/// task, with pluggable verification. +/// task, with plugable verification. pub struct BasicQueue { /// Channel to send messages to the background task. sender: mpsc::UnboundedSender>, diff --git a/primitives/consensus/common/src/select_chain.rs b/primitives/consensus/common/src/select_chain.rs index 3ce2c6ccd0..d94511c110 100644 --- a/primitives/consensus/common/src/select_chain.rs +++ b/primitives/consensus/common/src/select_chain.rs @@ -22,16 +22,16 @@ use sp_runtime::traits::{Block as BlockT, NumberFor}; /// if multiple forks are present for an opaque definition of "best" in the /// specific chain build. /// -/// The Strategy can be customised for the two use cases of authoring new blocks +/// The Strategy can be customized for the two use cases of authoring new blocks /// upon the best chain or which fork to finalise. Unless implemented differently -/// by default finalisation methods fall back to use authoring, so as a minimum +/// by default finalization methods fall back to use authoring, so as a minimum /// `_authoring`-functions must be implemented. /// /// Any particular user must make explicit, however, whether they intend to finalise /// or author through the using the right function call, as these might differ in /// some implementations. /// -/// Non-deterministicly finalising chains may only use the `_authoring` functions. +/// Non-deterministically finalizing chains may only use the `_authoring` functions. pub trait SelectChain: Sync + Send + Clone { /// Get all leaves of the chain: block hashes that have no children currently. diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index 5ad5e19813..3833c8a912 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -882,7 +882,7 @@ pub trait CryptoType { /// An identifier for a type of cryptographic key. /// -/// To avoid clashes with other modules when distributing your module publically, register your +/// To avoid clashes with other modules when distributing your module publicly, register your /// `KeyTypeId` on the list here by making a PR. /// /// Values whose first character is `_` are reserved for private use and won't conflict with any diff --git a/primitives/core/src/ed25519.rs b/primitives/core/src/ed25519.rs index f3aba47c20..5e04dcceff 100644 --- a/primitives/core/src/ed25519.rs +++ b/primitives/core/src/ed25519.rs @@ -433,7 +433,7 @@ impl TraitPair for Pair { /// Make a new key pair from secret seed material. /// - /// You should never need to use this; generate(), generate_with_phrasee + /// You should never need to use this; generate(), generate_with_phrase fn from_seed(seed: &Seed) -> Pair { Self::from_seed_slice(&seed[..]).expect("seed has valid length; qed") } diff --git a/primitives/core/src/lib.rs b/primitives/core/src/lib.rs index b1a5916c92..f8c48ee970 100644 --- a/primitives/core/src/lib.rs +++ b/primitives/core/src/lib.rs @@ -201,7 +201,7 @@ impl PartialEq for NativeOrEncoded { } /// A value that is never in a native representation. -/// This is type is useful in conjuction with `NativeOrEncoded`. +/// This is type is useful in conjunction with `NativeOrEncoded`. #[cfg(feature = "std")] #[derive(PartialEq)] pub enum NeverNativeValue {} diff --git a/primitives/core/src/offchain/mod.rs b/primitives/core/src/offchain/mod.rs index 425957a21f..c393b0f9f8 100644 --- a/primitives/core/src/offchain/mod.rs +++ b/primitives/core/src/offchain/mod.rs @@ -135,7 +135,7 @@ pub enum HttpRequestStatus { /// Note the deadline is controlled by the calling part, it not necessarily /// means that the request has timed out. DeadlineReached, - /// An error has occured during the request, for example a timeout or the + /// An error has occurred during the request, for example a timeout or the /// remote has closed our socket. /// /// The request is now considered destroyed. To retry the request you need @@ -226,7 +226,7 @@ impl Duration { } impl Timestamp { - /// Creates new `Timestamp` given unix timestamp in miliseconds. + /// Creates new `Timestamp` given unix timestamp in milliseconds. pub fn from_unix_millis(millis: u64) -> Self { Timestamp(millis) } @@ -335,7 +335,7 @@ pub trait Externalities: Send { /// Returns a random seed. /// - /// This is a trully random non deterministic seed generated by host environment. + /// This is a truly random non deterministic seed generated by host environment. /// Obviously fine in the off-chain worker context. fn random_seed(&mut self) -> [u8; 32]; diff --git a/primitives/core/src/testing.rs b/primitives/core/src/testing.rs index 0def3454bc..247323f970 100644 --- a/primitives/core/src/testing.rs +++ b/primitives/core/src/testing.rs @@ -245,7 +245,7 @@ mod tests { let public = store.write() .ed25519_generate_new(ED25519, None) - .expect("Genrates key"); + .expect("Generates key"); let store_key_pair = store.read() .ed25519_key_pair(ED25519, &public) diff --git a/primitives/externalities/src/lib.rs b/primitives/externalities/src/lib.rs index 75193a4b9c..431e449846 100644 --- a/primitives/externalities/src/lib.rs +++ b/primitives/externalities/src/lib.rs @@ -196,7 +196,7 @@ pub trait Externalities: ExtensionStore { ) -> Vec; /// Get the change trie root of the current storage overlay at a block with given parent. - /// `parent` is expects a SCALE endcoded hash. + /// `parent` is expects a SCALE encoded hash. /// /// The hash is defined by the `Block`. /// diff --git a/primitives/finality-grandpa/src/lib.rs b/primitives/finality-grandpa/src/lib.rs index 205fce0ce3..9dcb1c2363 100644 --- a/primitives/finality-grandpa/src/lib.rs +++ b/primitives/finality-grandpa/src/lib.rs @@ -164,7 +164,7 @@ pub const AUTHORITIES_CALL: &str = "grandpa_authorities"; /// The current version of the stored AuthorityList type. The encoding version MUST be updated any /// time the AuthorityList type changes. -const AUTHORITIES_VERISON: u8 = 1; +const AUTHORITIES_VERSION: u8 = 1; /// An AuthorityList that is encoded with a version specifier. The encoding version is updated any /// time the AuthorityList type changes. This ensures that encodings of different versions of an @@ -193,18 +193,18 @@ impl<'a> Into for VersionedAuthorityList<'a> { impl<'a> Encode for VersionedAuthorityList<'a> { fn size_hint(&self) -> usize { - (AUTHORITIES_VERISON, self.0.as_ref()).size_hint() + (AUTHORITIES_VERSION, self.0.as_ref()).size_hint() } fn using_encoded R>(&self, f: F) -> R { - (AUTHORITIES_VERISON, self.0.as_ref()).using_encoded(f) + (AUTHORITIES_VERSION, self.0.as_ref()).using_encoded(f) } } impl<'a> Decode for VersionedAuthorityList<'a> { fn decode(value: &mut I) -> Result { let (version, authorities): (u8, AuthorityList) = Decode::decode(value)?; - if version != AUTHORITIES_VERISON { + if version != AUTHORITIES_VERSION { return Err("unknown Grandpa authorities version".into()); } Ok(authorities.into()) diff --git a/primitives/inherents/src/lib.rs b/primitives/inherents/src/lib.rs index f1b8db982d..e8df2c49e5 100644 --- a/primitives/inherents/src/lib.rs +++ b/primitives/inherents/src/lib.rs @@ -312,7 +312,7 @@ impl InherentDataProviders { /// Converts a given encoded error into a `String`. /// - /// Useful if the implementation encouters an error for an identifier it does not know. + /// Useful if the implementation encounters an error for an identifier it does not know. pub fn error_to_string(&self, identifier: &InherentIdentifier, error: &[u8]) -> String { let res = self.providers.read().iter().filter_map(|p| if p.inherent_identifier() == identifier { diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index ce8a546e86..a1e9181f28 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -594,7 +594,7 @@ pub trait Offchain { /// Returns a random seed. /// - /// This is a trully random non deterministic seed generated by host environment. + /// This is a truly random, non-deterministic seed generated by host environment. /// Obviously fine in the off-chain worker context. fn random_seed(&mut self) -> [u8; 32] { self.extension::() diff --git a/primitives/rpc/src/list.rs b/primitives/rpc/src/list.rs index b8b7c537c4..469eae3d14 100644 --- a/primitives/rpc/src/list.rs +++ b/primitives/rpc/src/list.rs @@ -23,7 +23,7 @@ use serde::{Serialize, Deserialize}; /// 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 +/// 1. Less convenient 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 diff --git a/primitives/runtime-interface/test-wasm/src/lib.rs b/primitives/runtime-interface/test-wasm/src/lib.rs index 467f58cb30..4e99c0f06c 100644 --- a/primitives/runtime-interface/test-wasm/src/lib.rs +++ b/primitives/runtime-interface/test-wasm/src/lib.rs @@ -25,7 +25,7 @@ use sp_std::{vec, vec::Vec, mem, convert::TryFrom}; use sp_core::{sr25519::Public, wasm_export_functions}; -// Inlucde the WASM binary +// Include the WASM binary #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); diff --git a/primitives/runtime/src/curve.rs b/primitives/runtime/src/curve.rs index a230e2f32d..e04ce77fb2 100644 --- a/primitives/runtime/src/curve.rs +++ b/primitives/runtime/src/curve.rs @@ -65,7 +65,7 @@ impl<'a> PiecewiseLinear<'a> { next.0.deconstruct().saturating_sub(prev.0.deconstruct()), ); - // If both substration are same sign then result is positive + // If both subtractions are same sign then result is positive if (n > prev.0 * d.clone()) == (next.1.deconstruct() > prev.1.deconstruct()) { (prev.1 * d).saturating_add(delta_y) // Otherwise result is negative diff --git a/primitives/runtime/src/generic/digest.rs b/primitives/runtime/src/generic/digest.rs index 9d4fbe48d5..dad3e1fc26 100644 --- a/primitives/runtime/src/generic/digest.rs +++ b/primitives/runtime/src/generic/digest.rs @@ -365,7 +365,7 @@ impl<'a, Hash> DigestItemRef<'a, Hash> { } /// Try to match this digest item to the given opaque item identifier; if it matches, then - /// try to cast to the given datatype; if that works, return it. + /// try to cast to the given data type; if that works, return it. pub fn try_to(&self, id: OpaqueDigestItemId) -> Option { self.try_as_raw(id).and_then(|mut x| Decode::decode(&mut x).ok()) } diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index 517141a210..4d6739bb13 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -214,7 +214,7 @@ impl Default for MultiSigner { } } -/// NOTE: This implementations is required by `SimpleAddressDeterminator`, +/// NOTE: This implementations is required by `SimpleAddressDeterminer`, /// we convert the hash into some AccountId, it's fine to use any scheme. impl> crypto::UncheckedFrom for MultiSigner { fn unchecked_from(x: T) -> Self { @@ -458,7 +458,7 @@ pub type DispatchOutcome = Result<(), DispatchError>; /// /// Examples of reasons preventing inclusion in a block: /// - More block weight is required to process the extrinsic than is left in the block being built. -/// This doesn't neccessarily mean that the extrinsic is invalid, since it can still be +/// This doesn't necessarily mean that the extrinsic is invalid, since it can still be /// included in the next block if it has enough spare weight available. /// - The sender doesn't have enough funds to pay the transaction inclusion fee. Including such /// a transaction in the block doesn't make sense. diff --git a/primitives/runtime/src/offchain/http.rs b/primitives/runtime/src/offchain/http.rs index 50c4a5eae6..88f4323ad7 100644 --- a/primitives/runtime/src/offchain/http.rs +++ b/primitives/runtime/src/offchain/http.rs @@ -257,7 +257,7 @@ pub enum Error { DeadlineReached, /// Request had timed out. IoError, - /// Unknown error has been ecountered. + /// Unknown error has been encountered. Unknown, } diff --git a/primitives/runtime/src/offchain/storage.rs b/primitives/runtime/src/offchain/storage.rs index d5c2b47298..681bc14451 100644 --- a/primitives/runtime/src/offchain/storage.rs +++ b/primitives/runtime/src/offchain/storage.rs @@ -61,11 +61,11 @@ impl<'a> StorageValueRef<'a> { .map(|val| T::decode(&mut &*val).ok()) } - /// Retrieve & decode the value and set it to a new one atomicaly. + /// Retrieve & decode the value and set it to a new one atomically. /// /// Function `f` should return a new value that we should attempt to write to storage. /// This function returns: - /// 1. `Ok(Ok(T))` in case the value has been succesfuly set. + /// 1. `Ok(Ok(T))` in case the value has been successfully set. /// 2. `Ok(Err(T))` in case the value was returned, but it couldn't have been set. /// 3. `Err(_)` in case `f` returns an error. pub fn mutate(&self, f: F) -> Result, E> where diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 4cb9cb3212..1b9b9eec70 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -955,7 +955,7 @@ pub trait ValidateUnsigned { fn validate_unsigned(call: &Self::Call) -> TransactionValidity; } -/// Opaque datatype that may be destructured into a series of raw byte slices (which represent +/// Opaque data type that may be destructured into a series of raw byte slices (which represent /// individual keys). pub trait OpaqueKeys: Clone { /// Types bound to this opaque keys that provide the key type ids returned. diff --git a/primitives/sandbox/src/lib.rs b/primitives/sandbox/src/lib.rs index e7cd684b45..1ef30ca5db 100755 --- a/primitives/sandbox/src/lib.rs +++ b/primitives/sandbox/src/lib.rs @@ -193,7 +193,7 @@ impl Instance { /// - This module doesn't have an exported function with the given name, /// - If types of the arguments passed to the function doesn't match function signature /// then trap occurs (as if the exported function was called via call_indirect), - /// - Trap occured at the execution time. + /// - Trap occurred at the execution time. pub fn invoke( &mut self, name: &str, diff --git a/primitives/state-machine/src/backend.rs b/primitives/state-machine/src/backend.rs index 396ef6575a..ca6612a5e9 100644 --- a/primitives/state-machine/src/backend.rs +++ b/primitives/state-machine/src/backend.rs @@ -209,7 +209,7 @@ pub trait Backend: std::fmt::Debug { /// Query backend usage statistics (i/o, memory) /// /// Not all implementations are expected to be able to do this. In the - /// case when thay don't, empty statistics is returned. + /// case when they don't, empty statistics is returned. fn usage_info(&self) -> UsageInfo { UsageInfo::empty() } diff --git a/primitives/state-machine/src/changes_trie/mod.rs b/primitives/state-machine/src/changes_trie/mod.rs index 12074b7261..d614992df3 100644 --- a/primitives/state-machine/src/changes_trie/mod.rs +++ b/primitives/state-machine/src/changes_trie/mod.rs @@ -16,7 +16,7 @@ //! Changes trie related structures and functions. //! -//! Changes trie is a trie built of { storage key => extrinsiscs } pairs +//! Changes trie is a trie built of { storage key => extrinsics } pairs //! at the end of each block. For every changed storage key it contains //! a pair, mapping key to the set of extrinsics where it has been changed. //! @@ -130,7 +130,7 @@ pub struct AnchorBlockId { pub struct State<'a, H, Number> { /// Configuration that is active at given block. pub config: Configuration, - /// Configuration activation block number. Zero if it is the first coonfiguration on the chain, + /// Configuration activation block number. Zero if it is the first configuration on the chain, /// or number of the block that have emit NewConfiguration signal (thus activating configuration /// starting from the **next** block). pub zero: Number, diff --git a/primitives/state-machine/src/lib.rs b/primitives/state-machine/src/lib.rs index bb62df6da4..bb2bb2c52c 100644 --- a/primitives/state-machine/src/lib.rs +++ b/primitives/state-machine/src/lib.rs @@ -377,7 +377,7 @@ impl<'a, B, H, N, Exec> StateMachine<'a, B, H, N, Exec> where /// Note: changes to code will be in place if this call is made again. For running partial /// blocks (e.g. a transaction at a time), ensure a different method is used. /// - /// Returns the result of the executed function either in native reprensentation `R` or + /// Returns the result of the executed function either in native representation `R` or /// in SCALE encoded representation. pub fn execute_using_consensus_failure_handler( &mut self, diff --git a/primitives/state-machine/src/overlayed_changes.rs b/primitives/state-machine/src/overlayed_changes.rs index 37187e163f..4eb44de7c5 100644 --- a/primitives/state-machine/src/overlayed_changes.rs +++ b/primitives/state-machine/src/overlayed_changes.rs @@ -55,7 +55,7 @@ pub struct OverlayedChanges { pub(crate) prospective: OverlayedChangeSet, /// Committed changes. pub(crate) committed: OverlayedChangeSet, - /// True if extrinsiscs stats must be collected. + /// True if extrinsics stats must be collected. pub(crate) collect_extrinsics: bool, } @@ -65,7 +65,7 @@ pub struct OverlayedChanges { pub struct OverlayedValue { /// Current value. None if value has been deleted. pub value: Option, - /// The set of extinsic indices where the values has been changed. + /// The set of extrinsic indices where the values has been changed. /// Is filled only if runtime has announced changes trie support. pub extrinsics: Option>, } @@ -371,7 +371,7 @@ impl OverlayedChanges { } if let Some((child_committed, _child_info)) = self.committed.children.get(storage_key) { - // Then do the same with keys from commited changes. + // Then do the same with keys from committed changes. // NOTE that we are making changes in the prospective change set. for key in child_committed.keys() { if key.starts_with(prefix) { diff --git a/primitives/state-machine/src/proving_backend.rs b/primitives/state-machine/src/proving_backend.rs index 70124927fd..672ec6ea79 100644 --- a/primitives/state-machine/src/proving_backend.rs +++ b/primitives/state-machine/src/proving_backend.rs @@ -436,7 +436,7 @@ mod tests { } #[test] - fn passes_throgh_backend_calls() { + fn passes_through_backend_calls() { let trie_backend = test_trie(); let proving_backend = test_proving(&trie_backend); assert_eq!(trie_backend.storage(b"key").unwrap(), proving_backend.storage(b"key").unwrap()); diff --git a/primitives/std/without_std.rs b/primitives/std/without_std.rs index 4424ca0e7d..6b28f66b43 100755 --- a/primitives/std/without_std.rs +++ b/primitives/std/without_std.rs @@ -35,7 +35,7 @@ pub use core::ops; pub use core::ptr; pub use core::result; pub use core::slice; -// Allow intepreting vectors of bytes as strings, but not constructing them. +// Allow interpreting vectors of bytes as strings, but not constructing them. pub use core::str; // We are trying to avoid certain things here, such as `core::string` // (if you need `String` you are probably doing something wrong, since diff --git a/primitives/transaction-pool/src/error.rs b/primitives/transaction-pool/src/error.rs index ecce202d7d..1a456ca4fd 100644 --- a/primitives/transaction-pool/src/error.rs +++ b/primitives/transaction-pool/src/error.rs @@ -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/primitives/transaction-pool/src/pool.rs b/primitives/transaction-pool/src/pool.rs index 8d8ff47cbe..89f327a523 100644 --- a/primitives/transaction-pool/src/pool.rs +++ b/primitives/transaction-pool/src/pool.rs @@ -169,7 +169,7 @@ pub trait InPoolTransaction { /// 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; + fn is_propagable(&self) -> bool; } /// Transaction pool interface. @@ -249,7 +249,7 @@ pub enum ChainEvent { /// List of retracted blocks ordered by block number. retracted: Vec, }, - /// An existing block has been finalzied. + /// An existing block has been finalized. Finalized { /// Hash of just finalized block hash: B::Hash, diff --git a/primitives/trie/src/node_header.rs b/primitives/trie/src/node_header.rs index edcd28a568..7aa1629254 100644 --- a/primitives/trie/src/node_header.rs +++ b/primitives/trie/src/node_header.rs @@ -69,7 +69,7 @@ impl Decode for NodeHeader { } /// Returns an iterator over encoded bytes for node header and size. -/// Size encoding allows unlimited, length unefficient, representation, but +/// Size encoding allows unlimited, length inefficient, 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 = sp_std::cmp::min(trie_constants::NIBBLE_SIZE_BOUND, size); diff --git a/test-utils/client/src/lib.rs b/test-utils/client/src/lib.rs index e95c5ad162..afe11903d5 100644 --- a/test-utils/client/src/lib.rs +++ b/test-utils/client/src/lib.rs @@ -50,7 +50,7 @@ pub type LightBackend = sc_client::light::backend::Backend< Blake2Hasher, >; -/// A genesis storage initialisation trait. +/// A genesis storage initialization trait. pub trait GenesisInit: Default { /// Construct genesis storage. fn genesis_storage(&self) -> Storage; diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index c8dff15ef2..ed32cbef9c 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -55,7 +55,7 @@ use sp_core::storage::ChildType; pub use sp_consensus_babe::AuthorityId; pub type AuraId = sp_consensus_aura::sr25519::AuthorityId; -// Inlucde the WASM binary +// Include the WASM binary #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); @@ -114,7 +114,7 @@ pub enum Extrinsic { ChangesTrieConfigUpdate(Option), } -parity_util_mem::malloc_size_of_is_0!(Extrinsic); // non-opaque extrinisic does not need this +parity_util_mem::malloc_size_of_is_0!(Extrinsic); // non-opaque extrinsic does not need this #[cfg(feature = "std")] impl serde::Serialize for Extrinsic { diff --git a/utils/fork-tree/src/lib.rs b/utils/fork-tree/src/lib.rs index 8ce0b729c6..d0cf9c9f37 100644 --- a/utils/fork-tree/src/lib.rs +++ b/utils/fork-tree/src/lib.rs @@ -23,7 +23,7 @@ use std::cmp::Reverse; use std::fmt; use codec::{Decode, Encode}; -/// Error occured when iterating with the tree. +/// Error occurred when iterating with the tree. #[derive(Clone, Debug, PartialEq)] pub enum Error { /// Adding duplicate node to tree. @@ -283,7 +283,7 @@ impl ForkTree where .map(|position| self.finalize_root_at(position)) } - /// Finalize root at given positiion. See `finalize_root` comment for details. + /// Finalize root at given position. See `finalize_root` comment for details. fn finalize_root_at(&mut self, position: usize) -> V { let node = self.roots.swap_remove(position); self.roots = node.children; diff --git a/utils/wasm-builder/README.md b/utils/wasm-builder/README.md index b21c588ac3..2fd9a6ab4c 100644 --- a/utils/wasm-builder/README.md +++ b/utils/wasm-builder/README.md @@ -57,7 +57,7 @@ be `NODE_RUNTIME`. ## Prerequisites: -WASM builder requires the following prerequisities for building the WASM binary: +WASM builder requires the following prerequisites for building the WASM binary: - rust nightly + `wasm32-unknown-unknown` toolchain diff --git a/utils/wasm-builder/src/lib.rs b/utils/wasm-builder/src/lib.rs index 80192eb361..8500eba4a0 100644 --- a/utils/wasm-builder/src/lib.rs +++ b/utils/wasm-builder/src/lib.rs @@ -73,7 +73,7 @@ //! //! ## Prerequisites: //! -//! WASM builder requires the following prerequisities for building the WASM binary: +//! WASM builder requires the following prerequisites for building the WASM binary: //! //! - rust nightly + `wasm32-unknown-unknown` toolchain //! diff --git a/utils/wasm-builder/src/wasm_project.rs b/utils/wasm-builder/src/wasm_project.rs index c9b573ff19..60be4684ba 100644 --- a/utils/wasm-builder/src/wasm_project.rs +++ b/utils/wasm-builder/src/wasm_project.rs @@ -431,7 +431,7 @@ fn generate_rerun_if_changed_instructions( .exec() .expect("`cargo metadata` can not fail!"); - // Make sure that if any file/folder of a depedency change, we need to rerun the `build.rs` + // Make sure that if any file/folder of a dependency change, we need to rerun the `build.rs` metadata.packages.into_iter() .filter(|package| !package.manifest_path.starts_with(wasm_workspace)) .for_each(|package| { -- GitLab From 35866b03896c3c67b9790395161556fcf090bbec Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Mon, 17 Feb 2020 17:30:49 +0100 Subject: [PATCH 164/180] Add passthrough weight to Sudo (#4946) * Add passthrough weight to Sudo * Bump spec version * Passthrough `pays_fee` * Sudo always pays fee * Use `FunctionOf` * Add support for closure in dispatch classification * Update docs --- bin/node-template/runtime/src/lib.rs | 2 +- bin/node/runtime/src/lib.rs | 6 ++-- frame/sudo/src/lib.rs | 32 +++++++++++------ frame/support/src/weights.rs | 51 ++++++++++++++++++++++------ 4 files changed, 66 insertions(+), 25 deletions(-) diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 153d9cf49d..a9944199b8 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -235,7 +235,7 @@ impl transaction_payment::Trait for Runtime { impl sudo::Trait for Runtime { type Event = Event; - type Proposal = Call; + type Call = Call; } /// Used for the module template in `./template.rs` diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index d80986c0df..1807952af6 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -82,8 +82,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 219, - impl_version: 1, + spec_version: 220, + impl_version: 0, apis: RUNTIME_API_VERSIONS, }; @@ -442,7 +442,7 @@ impl pallet_contracts::Trait for Runtime { impl pallet_sudo::Trait for Runtime { type Event = Event; - type Proposal = Call; + type Call = Call; } /// A runtime transaction submitter. diff --git a/frame/sudo/src/lib.rs b/frame/sudo/src/lib.rs index e69840e158..8ee09ba223 100644 --- a/frame/sudo/src/lib.rs +++ b/frame/sudo/src/lib.rs @@ -90,8 +90,8 @@ use sp_runtime::{traits::{StaticLookup, Dispatchable}, DispatchError}; use frame_support::{ Parameter, decl_module, decl_event, decl_storage, decl_error, ensure, - weights::SimpleDispatchInfo, }; +use frame_support::weights::{GetDispatchInfo, FunctionOf}; use frame_system::{self as system, ensure_signed}; pub trait Trait: frame_system::Trait { @@ -99,7 +99,7 @@ pub trait Trait: frame_system::Trait { type Event: From> + Into<::Event>; /// A sudo-able call. - type Proposal: Parameter + Dispatchable; + type Call: Parameter + Dispatchable + GetDispatchInfo; } decl_module! { @@ -117,15 +117,19 @@ decl_module! { /// - O(1). /// - Limited storage reads. /// - One DB write (event). - /// - Unknown weight of derivative `proposal` execution. + /// - Weight of derivative `call` execution + 10,000. /// # - #[weight = SimpleDispatchInfo::FixedNormal(50_000)] - fn sudo(origin, proposal: Box) { + #[weight = FunctionOf( + |args: (&Box<::Call>,)| args.0.get_dispatch_info().weight + 10_000, + |args: (&Box<::Call>,)| args.0.get_dispatch_info().class, + true + )] + fn sudo(origin, call: Box<::Call>) { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; ensure!(sender == Self::key(), Error::::RequireSudo); - let res = match proposal.dispatch(frame_system::RawOrigin::Root.into()) { + let res = match call.dispatch(frame_system::RawOrigin::Root.into()) { Ok(_) => true, Err(e) => { let e: DispatchError = e.into(); @@ -165,17 +169,25 @@ decl_module! { /// - O(1). /// - Limited storage reads. /// - One DB write (event). - /// - Unknown weight of derivative `proposal` execution. + /// - Weight of derivative `call` execution + 10,000. /// # - #[weight = SimpleDispatchInfo::FixedOperational(0)] - fn sudo_as(origin, who: ::Source, proposal: Box) { + #[weight = FunctionOf( + |args: (&::Source, &Box<::Call>,)| { + args.1.get_dispatch_info().weight + 10_000 + }, + |args: (&::Source, &Box<::Call>,)| { + args.1.get_dispatch_info().class + }, + true + )] + fn sudo_as(origin, who: ::Source, call: Box<::Call>) { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; ensure!(sender == Self::key(), Error::::RequireSudo); let who = T::Lookup::lookup(who)?; - let res = match proposal.dispatch(frame_system::RawOrigin::Signed(who).into()) { + let res = match call.dispatch(frame_system::RawOrigin::Signed(who).into()) { Ok(_) => true, Err(e) => { let e: DispatchError = e.into(); diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index 60f0d4a8b2..c46cca683b 100644 --- a/frame/support/src/weights.rs +++ b/frame/support/src/weights.rs @@ -234,32 +234,61 @@ impl SimpleDispatchInfo { /// A struct to represent a weight which is a function of the input arguments. The given items have /// the following types: /// -/// - `F`: a closure with the same argument list as the dispatched, wrapped in a tuple. -/// - `DispatchClass`: class of the dispatch. -/// - `bool`: whether this dispatch pays fee or not. -pub struct FunctionOf(pub F, pub DispatchClass, pub bool); +/// - `WD`: a raw `Weight` value or a closure that returns a `Weight` with the same +/// argument list as the dispatched, wrapped in a tuple. +/// - `CD`: a raw `DispatchClass` value or a closure that returns a `DispatchClass` +/// with the same argument list as the dispatched, wrapped in a tuple. +/// - `PF`: a `bool` for whether this dispatch pays fee or not or a closure that +/// returns a bool with the same argument list as the dispatched, wrapped in a tuple. +pub struct FunctionOf(pub WD, pub CD, pub PF); + +// `WeighData` as a raw value +impl WeighData for FunctionOf { + fn weigh_data(&self, _: Args) -> Weight { + self.0 + } +} -impl WeighData for FunctionOf -where - F : Fn(Args) -> Weight +// `WeighData` as a closure +impl WeighData for FunctionOf where + WD : Fn(Args) -> Weight { fn weigh_data(&self, args: Args) -> Weight { (self.0)(args) } } -impl ClassifyDispatch for FunctionOf { +// `ClassifyDispatch` as a raw value +impl ClassifyDispatch for FunctionOf { fn classify_dispatch(&self, _: Args) -> DispatchClass { - self.1.clone() + self.1 } } -impl PaysFee for FunctionOf { - fn pays_fee(&self, _: T) -> bool { +// `ClassifyDispatch` as a raw value +impl ClassifyDispatch for FunctionOf where + CD : Fn(Args) -> DispatchClass +{ + fn classify_dispatch(&self, args: Args) -> DispatchClass { + (self.1)(args) + } +} + +// `PaysFee` as a raw value +impl PaysFee for FunctionOf { + fn pays_fee(&self, _: Args) -> bool { self.2 } } +// `PaysFee` as a closure +impl PaysFee for FunctionOf where + PF : Fn(Args) -> bool +{ + fn pays_fee(&self, args: Args) -> bool { + (self.2)(args) + } +} /// Implementation for unchecked extrinsic. impl GetDispatchInfo -- GitLab From c50844a3e2e3d313bb2bcf0c315251ec3ad9ad4c Mon Sep 17 00:00:00 2001 From: Seun Lanlege Date: Mon, 17 Feb 2020 19:05:30 +0100 Subject: [PATCH 165/180] Adds babe rpc support (#4729) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * babe_epochAuthorship remove test-helpers from sp-keyring, bump spec_version, impl_version * bump Cargo.lock * add BabeRPC to node-rpc * rename to BabeApi, remove err_derive * pass &ServiceBuilder to with_rpc_extensions callback * sc-consensus-babe-rpc * Update client/consensus/babe/src/lib.rs Co-Authored-By: Tomasz Drwięga * Better docs, code style chanegs Co-Authored-By: André Silva * new line at the end of Cargo.toml Co-authored-by: Tomasz Drwięga Co-authored-by: André Silva --- Cargo.lock | 33 ++++ Cargo.toml | 1 + bin/node/cli/src/service.rs | 34 +++- bin/node/rpc/Cargo.toml | 9 +- bin/node/rpc/src/lib.rs | 135 +++++++++---- bin/node/runtime/src/lib.rs | 6 +- client/consensus/babe/Cargo.toml | 1 + client/consensus/babe/rpc/Cargo.toml | 30 +++ client/consensus/babe/rpc/src/lib.rs | 248 ++++++++++++++++++++++++ client/consensus/babe/src/authorship.rs | 2 +- client/consensus/babe/src/lib.rs | 2 +- client/keystore/src/lib.rs | 3 - client/service/src/builder.rs | 40 ++-- frame/babe/src/lib.rs | 2 +- primitives/consensus/babe/src/lib.rs | 3 + test-utils/runtime/src/lib.rs | 10 +- 16 files changed, 490 insertions(+), 69 deletions(-) create mode 100644 client/consensus/babe/rpc/Cargo.toml create mode 100644 client/consensus/babe/rpc/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 383e2cdce3..e9b9ca337c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3501,7 +3501,14 @@ dependencies = [ "pallet-contracts-rpc", "pallet-transaction-payment-rpc", "sc-client", + "sc-consensus-babe", + "sc-consensus-babe-rpc", + "sc-consensus-epochs", + "sc-keystore", "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-consensus-babe", "sp-runtime", "sp-transaction-pool", "substrate-frame-rpc-system", @@ -5840,6 +5847,7 @@ dependencies = [ "sc-service", "sc-telemetry", "schnorrkel", + "serde", "sp-api", "sp-application-crypto", "sp-block-builder", @@ -5858,6 +5866,31 @@ dependencies = [ "tokio 0.1.22", ] +[[package]] +name = "sc-consensus-babe-rpc" +version = "0.8.0" +dependencies = [ + "derive_more", + "futures 0.3.4", + "jsonrpc-core", + "jsonrpc-core-client", + "jsonrpc-derive", + "sc-consensus-babe", + "sc-consensus-epochs", + "sc-keystore", + "serde", + "sp-api", + "sp-application-crypto", + "sp-blockchain", + "sp-consensus", + "sp-consensus-babe", + "sp-core", + "sp-keyring", + "sp-runtime", + "substrate-test-runtime-client", + "tempfile", +] + [[package]] name = "sc-consensus-epochs" version = "0.8.0" diff --git a/Cargo.toml b/Cargo.toml index 0c620d251d..a42a8e24d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ members = [ "client/cli", "client/consensus/aura", "client/consensus/babe", + "client/consensus/babe/rpc", "client/consensus/manual-seal", "client/consensus/pow", "client/consensus/uncles", diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index ff53b9aa3a..a882483a44 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -95,8 +95,21 @@ macro_rules! new_full_start { import_setup = Some((block_import, grandpa_link, babe_link)); Ok(import_queue) })? - .with_rpc_extensions(|client, pool, _backend, fetcher, _remote_blockchain| -> Result { - Ok(node_rpc::create(client, pool, node_rpc::LightDeps::none(fetcher))) + .with_rpc_extensions(|builder| -> Result { + let babe_link = import_setup.as_ref().map(|s| &s.2) + .expect("BabeLink is present for full services or set up failed; qed."); + let deps = node_rpc::FullDeps { + client: builder.client().clone(), + pool: builder.pool(), + select_chain: builder.select_chain().cloned() + .expect("SelectChain is present for full services or set up failed; qed."), + babe: node_rpc::BabeDeps { + keystore: builder.keystore(), + babe_config: sc_consensus_babe::BabeLink::config(babe_link).clone(), + shared_epoch_changes: sc_consensus_babe::BabeLink::epoch_changes(babe_link).clone() + } + }; + Ok(node_rpc::create_full(deps)) })?; (builder, import_setup, inherent_data_providers) @@ -352,14 +365,21 @@ 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, fetcher, remote_blockchain| -> Result { - let fetcher = fetcher + .with_rpc_extensions(|builder,| -> + Result + { + let fetcher = builder.fetcher() .ok_or_else(|| "Trying to start node RPC without active fetcher")?; - let remote_blockchain = remote_blockchain + let remote_blockchain = builder.remote_backend() .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))) + let light_deps = node_rpc::LightDeps { + remote_blockchain, + fetcher, + client: builder.client().clone(), + pool: builder.pool(), + }; + Ok(node_rpc::create_light(light_deps)) })? .build()?; diff --git a/bin/node/rpc/Cargo.toml b/bin/node/rpc/Cargo.toml index 289d20ea01..aefc9222f7 100644 --- a/bin/node/rpc/Cargo.toml +++ b/bin/node/rpc/Cargo.toml @@ -12,7 +12,14 @@ 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" } sp-api = { version = "2.0.0", path = "../../../primitives/api" } -pallet-contracts-rpc = { version = "0.8.0", path = "../../../frame/contracts/rpc/" } +pallet-contracts-rpc = { version = "0.8", 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" } +sc-consensus-babe = { version = "0.8", path = "../../../client/consensus/babe" } +sc-consensus-babe-rpc = { version = "0.8", path = "../../../client/consensus/babe/rpc" } +sp-consensus-babe = { version = "0.8", path = "../../../primitives/consensus/babe" } +sc-keystore = { version = "2.0.0", path = "../../../client/keystore" } +sc-consensus-epochs = { version = "0.8", path = "../../../client/consensus/epochs" } +sp-consensus = { version = "0.8", path = "../../../primitives/consensus/common" } +sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" } diff --git a/bin/node/rpc/src/lib.rs b/bin/node/rpc/src/lib.rs index 4bf0338088..16e5446bb1 100644 --- a/bin/node/rpc/src/lib.rs +++ b/bin/node/rpc/src/lib.rs @@ -29,73 +29,130 @@ #![warn(missing_docs)] -use std::sync::Arc; +use std::{sync::Arc, fmt}; use node_primitives::{Block, BlockNumber, AccountId, Index, Balance}; use node_runtime::UncheckedExtrinsic; use sp_api::ProvideRuntimeApi; use sp_transaction_pool::TransactionPool; +use sp_blockchain::{Error as BlockChainError, HeaderMetadata, HeaderBackend}; +use sp_consensus::SelectChain; +use sc_keystore::KeyStorePtr; +use sp_consensus_babe::BabeApi; +use sc_consensus_epochs::SharedEpochChanges; +use sc_consensus_babe::{Config, Epoch}; +use sc_consensus_babe_rpc::BabeRPCHandler; /// Light client extra dependencies. -pub struct LightDeps { +pub struct LightDeps { + /// The client instance to use. + pub client: Arc, + /// Transaction pool instance. + pub pool: Arc

, /// 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 - } +/// Extra dependencies for BABE. +pub struct BabeDeps { + /// BABE protocol config. + pub babe_config: Config, + /// BABE pending epoch changes. + pub shared_epoch_changes: SharedEpochChanges, + /// The keystore that manages the keys of the node. + pub keystore: KeyStorePtr, } -/// Instantiate all RPC extensions. -/// -/// If you provide `LightDeps`, the system is configured for light client. -pub fn create( - client: Arc, - pool: Arc

, - light_deps: Option>, +/// Full client dependencies. +pub struct FullDeps { + /// The client instance to use. + pub client: Arc, + /// Transaction pool instance. + pub pool: Arc

, + /// The SelectChain Strategy + pub select_chain: SC, + /// BABE specific dependencies. + pub babe: BabeDeps, +} + +/// Instantiate all Full RPC extensions. +pub fn create_full( + deps: FullDeps, ) -> jsonrpc_core::IoHandler where C: ProvideRuntimeApi, - C: sc_client::blockchain::HeaderBackend, + C: HeaderBackend + HeaderMetadata + 'static, C: Send + Sync + 'static, C::Api: substrate_frame_rpc_system::AccountNonceApi, C::Api: pallet_contracts_rpc::ContractsRuntimeApi, C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, - F: sc_client::light::fetcher::Fetcher + 'static, + C::Api: BabeApi, + ::Error: fmt::Debug, P: TransactionPool + 'static, M: jsonrpc_core::Metadata + Default, + SC: SelectChain +'static, { - use substrate_frame_rpc_system::{FullSystem, LightSystem, SystemApi}; + use substrate_frame_rpc_system::{FullSystem, SystemApi}; use pallet_contracts_rpc::{Contracts, ContractsApi}; use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi}; let mut io = jsonrpc_core::IoHandler::default(); + let FullDeps { + client, + pool, + select_chain, + babe + } = deps; + let BabeDeps { + keystore, + babe_config, + shared_epoch_changes, + } = babe; + + 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.clone())) + ); + io.extend_with( + sc_consensus_babe_rpc::BabeApi::to_delegate( + BabeRPCHandler::new(client, shared_epoch_changes, keystore, babe_config, select_chain) + ) + ); + + io +} + +/// Instantiate all Light RPC extensions. +pub fn create_light( + deps: LightDeps, +) -> jsonrpc_core::IoHandler where + C: sc_client::blockchain::HeaderBackend, + C: Send + Sync + 'static, + F: sc_client::light::fetcher::Fetcher + 'static, + P: TransactionPool + 'static, + M: jsonrpc_core::Metadata + Default, +{ + use substrate_frame_rpc_system::{LightSystem, SystemApi}; + + let LightDeps { + client, + pool, + remote_blockchain, + fetcher + } = deps; + let mut io = jsonrpc_core::IoHandler::default(); + io.extend_with( + SystemApi::::to_delegate(LightSystem::new(client, remote_blockchain, fetcher, pool)) + ); - 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/src/lib.rs b/bin/node/runtime/src/lib.rs index 1807952af6..1d460762e4 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 220, - impl_version: 0, + impl_version: 1, apis: RUNTIME_API_VERSIONS, }; @@ -737,6 +737,10 @@ impl_runtime_apis! { secondary_slots: true, } } + + fn current_epoch_start() -> sp_consensus_babe::SlotNumber { + Babe::current_epoch_start() + } } impl sp_authority_discovery::AuthorityDiscoveryApi for Runtime { diff --git a/client/consensus/babe/Cargo.toml b/client/consensus/babe/Cargo.toml index c36b5216c2..3f5487885f 100644 --- a/client/consensus/babe/Cargo.toml +++ b/client/consensus/babe/Cargo.toml @@ -14,6 +14,7 @@ sp-application-crypto = { version = "2.0.0", path = "../../../primitives/applica num-bigint = "0.2.3" num-rational = "0.2.2" num-traits = "0.2.8" +serde = { version = "1.0.104", features = ["derive"] } 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" } diff --git a/client/consensus/babe/rpc/Cargo.toml b/client/consensus/babe/rpc/Cargo.toml new file mode 100644 index 0000000000..3fd0e924af --- /dev/null +++ b/client/consensus/babe/rpc/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "sc-consensus-babe-rpc" +version = "0.8.0" +authors = ["Parity Technologies "] +description = "RPC extensions for the BABE consensus algorithm" +edition = "2018" +license = "GPL-3.0" + +[dependencies] +sc-consensus-babe = { version = "0.8.0", path = "../" } +jsonrpc-core = "14.0.3" +jsonrpc-core-client = "14.0.3" +jsonrpc-derive = "14.0.3" +sp-consensus-babe = { version = "0.8", path = "../../../../primitives/consensus/babe" } +serde = { version = "1.0.104", features=["derive"] } +sp-blockchain = { version = "2.0.0", path = "../../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0", path = "../../../../primitives/runtime" } +sc-consensus-epochs = { version = "0.8", path = "../../epochs" } +futures = "0.3.1" +derive_more = "0.99.2" +sp-api = { version = "2.0.0", path = "../../../../primitives/api" } +sp-consensus = { version = "0.8", path = "../../../../primitives/consensus/common" } +sp-core = { version = "2.0.0", path = "../../../../primitives/core" } +sc-keystore = { version = "2.0.0", path = "../../../keystore" } + +[dev-dependencies] +substrate-test-runtime-client = { version = "2.0.0", path = "../../../../test-utils/runtime/client" } +sp-application-crypto = { version = "2.0.0", path = "../../../../primitives/application-crypto" } +sp-keyring = { version = "2.0.0", path = "../../../../primitives/keyring" } +tempfile = "3.1.0" diff --git a/client/consensus/babe/rpc/src/lib.rs b/client/consensus/babe/rpc/src/lib.rs new file mode 100644 index 0000000000..033a7d6b98 --- /dev/null +++ b/client/consensus/babe/rpc/src/lib.rs @@ -0,0 +1,248 @@ +// Copyright 2020 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 api for babe. + +use sc_consensus_babe::{Epoch, authorship, Config}; +use futures::{FutureExt as _, TryFutureExt as _}; +use jsonrpc_core::{ + Error as RpcError, + futures::future as rpc_future, +}; +use jsonrpc_derive::rpc; +use sc_consensus_epochs::{descendent_query, Epoch as EpochT, SharedEpochChanges}; +use sp_consensus_babe::{ + AuthorityId, + BabeApi as BabeRuntimeApi, + digests::PreDigest, +}; +use serde::{Deserialize, Serialize}; +use sc_keystore::KeyStorePtr; +use sp_api::{ProvideRuntimeApi, BlockId}; +use sp_core::crypto::Pair; +use sp_runtime::traits::{Block as BlockT, Header as _}; +use sp_consensus::{SelectChain, Error as ConsensusError}; +use sp_blockchain::{HeaderBackend, HeaderMetadata, Error as BlockChainError}; +use std::{collections::HashMap, fmt, sync::Arc}; + +type FutureResult = Box + Send>; + +/// Provides rpc methods for interacting with Babe. +#[rpc] +pub trait BabeApi { + /// Returns data about which slots (primary or secondary) can be claimed in the current epoch + /// with the keys in the keystore. + #[rpc(name = "babe_epochAuthorship")] + fn epoch_authorship(&self) -> FutureResult>; +} + +/// Implements the BabeRPC trait for interacting with Babe. +/// +/// Uses a background thread to calculate epoch_authorship data. +pub struct BabeRPCHandler { + /// shared reference to the client. + client: Arc, + /// shared reference to EpochChanges + shared_epoch_changes: SharedEpochChanges, + /// shared reference to the Keystore + keystore: KeyStorePtr, + /// config (actually holds the slot duration) + babe_config: Config, + /// The SelectChain strategy + select_chain: SC, +} + +impl BabeRPCHandler { + /// Creates a new instance of the BabeRpc handler. + pub fn new( + client: Arc, + shared_epoch_changes: SharedEpochChanges, + keystore: KeyStorePtr, + babe_config: Config, + select_chain: SC, + ) -> Self { + + Self { + client, + shared_epoch_changes, + keystore, + babe_config, + select_chain, + } + } +} + +impl BabeApi for BabeRPCHandler + where + B: BlockT, + C: ProvideRuntimeApi + HeaderBackend + HeaderMetadata + 'static, + C::Api: BabeRuntimeApi, + ::Error: fmt::Debug, + SC: SelectChain + Clone + 'static, +{ + fn epoch_authorship(&self) -> FutureResult> { + let ( + babe_config, + keystore, + shared_epoch, + client, + select_chain, + ) = ( + self.babe_config.clone(), + self.keystore.clone(), + self.shared_epoch_changes.clone(), + self.client.clone(), + self.select_chain.clone(), + ); + let future = async move { + let header = select_chain.best_chain().map_err(Error::Consensus)?; + let epoch_start = client.runtime_api() + .current_epoch_start(&BlockId::Hash(header.hash())) + .map_err(|err| { + Error::StringError(format!("{:?}", err)) + })?; + let epoch = epoch_data(&shared_epoch, &client, &babe_config, epoch_start, &select_chain)?; + let (epoch_start, epoch_end) = (epoch.start_slot(), epoch.end_slot()); + + let mut claims: HashMap = HashMap::new(); + + for slot_number in epoch_start..epoch_end { + let epoch = epoch_data(&shared_epoch, &client, &babe_config, slot_number, &select_chain)?; + if let Some((claim, key)) = authorship::claim_slot(slot_number, &epoch, &babe_config, &keystore) { + match claim { + PreDigest::Primary { .. } => { + claims.entry(key.public()).or_default().primary.push(slot_number); + } + PreDigest::Secondary { .. } => { + claims.entry(key.public()).or_default().secondary.push(slot_number); + } + }; + } + } + + Ok(claims) + }.boxed(); + + Box::new(future.compat()) + } +} + +/// Holds information about the `slot_number`'s that can be claimed by a given key. +#[derive(Default, Debug, Deserialize, Serialize)] +pub struct EpochAuthorship { + /// the array of primary slots that can be claimed + primary: Vec, + /// the array of secondary slots that can be claimed + secondary: Vec, +} + +/// Errors encountered by the RPC +#[derive(Debug, derive_more::Display, derive_more::From)] +pub enum Error { + /// Consensus error + Consensus(ConsensusError), + /// Errors that can be formatted as a String + StringError(String) +} + +impl From for jsonrpc_core::Error { + fn from(error: Error) -> Self { + jsonrpc_core::Error { + message: format!("{}", error).into(), + code: jsonrpc_core::ErrorCode::ServerError(1234), + data: None, + } + } +} + +/// fetches the epoch data for a given slot_number. +fn epoch_data( + epoch_changes: &SharedEpochChanges, + client: &Arc, + babe_config: &Config, + slot_number: u64, + select_chain: &SC, +) -> Result + where + B: BlockT, + C: HeaderBackend + HeaderMetadata + 'static, + SC: SelectChain, +{ + let parent = select_chain.best_chain()?; + epoch_changes.lock().epoch_for_child_of( + descendent_query(&**client), + &parent.hash(), + parent.number().clone(), + slot_number, + |slot| babe_config.genesis_epoch(slot), + ) + .map_err(|e| Error::Consensus(ConsensusError::ChainLookup(format!("{:?}", e))))? + .map(|e| e.into_inner()) + .ok_or(Error::Consensus(ConsensusError::InvalidAuthoritiesSet)) +} + +#[cfg(test)] +mod tests { + use super::*; + use substrate_test_runtime_client::{ + DefaultTestClientBuilderExt, + TestClientBuilderExt, + TestClientBuilder, + }; + use sp_application_crypto::AppPair; + use sp_keyring::Ed25519Keyring; + use sc_keystore::Store; + + use std::sync::Arc; + use sc_consensus_babe::{Config, block_import, AuthorityPair}; + use jsonrpc_core::IoHandler; + + /// creates keystore backed by a temp file + fn create_temp_keystore(authority: Ed25519Keyring) -> (KeyStorePtr, tempfile::TempDir) { + let keystore_path = tempfile::tempdir().expect("Creates keystore path"); + let keystore = Store::open(keystore_path.path(), None).expect("Creates keystore"); + keystore.write().insert_ephemeral_from_seed::

(&authority.to_seed()) + .expect("Creates authority key"); + + (keystore, keystore_path) + } + + #[test] + fn rpc() { + let builder = TestClientBuilder::new(); + let (client, longest_chain) = builder.build_with_longest_chain(); + let client = Arc::new(client); + let config = Config::get_or_compute(&*client).expect("config available"); + let (_, link) = block_import( + config.clone(), + client.clone(), + client.clone(), + client.clone(), + ).expect("can initialize block-import"); + + let epoch_changes = link.epoch_changes().clone(); + let select_chain = longest_chain; + let keystore = create_temp_keystore::(Ed25519Keyring::Alice).0; + let handler = BabeRPCHandler::new(client.clone(), epoch_changes, keystore, config, select_chain); + let mut io = IoHandler::new(); + + io.extend_with(BabeApi::to_delegate(handler)); + let request = r#"{"jsonrpc":"2.0","method":"babe_epochAuthorship","params": [],"id":1}"#; + let response = r#"{"jsonrpc":"2.0","result":{"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY":{"primary":[0],"secondary":[1,2,4]}},"id":1}"#; + + assert_eq!(Some(response.into()), io.handle_request_sync(request)); + } +} diff --git a/client/consensus/babe/src/authorship.rs b/client/consensus/babe/src/authorship.rs index 8b28aefa2f..4654f91b89 100644 --- a/client/consensus/babe/src/authorship.rs +++ b/client/consensus/babe/src/authorship.rs @@ -144,7 +144,7 @@ fn claim_secondary_slot( /// a primary VRF based slot. If we are not able to claim it, then if we have /// secondary slots enabled for the given epoch, we will fallback to trying to /// claim a secondary slot. -pub(super) fn claim_slot( +pub fn claim_slot( slot_number: SlotNumber, epoch: &Epoch, config: &BabeConfiguration, diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index 51ea37f6d5..b93619b29c 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -119,7 +119,7 @@ use sp_api::ApiExt; mod aux_schema; mod verification; -mod authorship; +pub mod authorship; #[cfg(test)] mod tests; diff --git a/client/keystore/src/lib.rs b/client/keystore/src/lib.rs index 92c8f4f9a5..087ddf326d 100644 --- a/client/keystore/src/lib.rs +++ b/client/keystore/src/lib.rs @@ -19,13 +19,10 @@ #![warn(missing_docs)] use std::{collections::HashMap, path::PathBuf, fs::{self, File}, io::{self, Write}, sync::Arc}; - use sp_core::{ crypto::{KeyTypeId, Pair as PairT, Public, IsWrappedBy, Protected}, traits::BareCryptoStore, }; - use sp_application_crypto::{AppKey, AppPublic, AppPair, ed25519, sr25519}; - use parking_lot::RwLock; /// Keystore pointer diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 2ab212646a..c67551afa3 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -379,6 +379,30 @@ impl Arc> { + self.keystore.clone() + } + + /// Returns a reference to the transaction pool stored in this builder + pub fn pool(&self) -> Arc { + self.transaction_pool.clone() + } + + /// Returns a reference to the fetcher, only available if builder + /// was created with `new_light`. + pub fn fetcher(&self) -> Option + where TFchr: Clone + { + self.fetcher.clone() + } + + /// Returns a reference to the remote_backend, only available if builder + /// was created with `new_light`. + pub fn remote_backend(&self) -> Option>> { + self.remote_backend.clone() + } + /// Defines which head-of-chain strategy to use. pub fn with_opt_select_chain( self, @@ -647,23 +671,11 @@ impl( self, - rpc_ext_builder: impl FnOnce( - Arc, - Arc, - Arc, - Option, - Option>>, - ) -> Result, + rpc_ext_builder: impl FnOnce(&Self) -> Result, ) -> Result, 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(), - )?; + let rpc_extensions = rpc_ext_builder(&self)?; Ok(ServiceBuilder { config: self.config, diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index 5921b1ba20..e4e37a4b7a 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -365,7 +365,7 @@ impl Module { // finds the start slot of the current epoch. only guaranteed to // give correct results after `do_initialize` of the first block // in the chain (as its result is based off of `GenesisSlot`). - fn current_epoch_start() -> SlotNumber { + pub fn current_epoch_start() -> SlotNumber { (EpochIndex::get() * T::EpochDuration::get()) + GenesisSlot::get() } diff --git a/primitives/consensus/babe/src/lib.rs b/primitives/consensus/babe/src/lib.rs index 78c63e5022..392dcb560b 100644 --- a/primitives/consensus/babe/src/lib.rs +++ b/primitives/consensus/babe/src/lib.rs @@ -139,5 +139,8 @@ sp_api::decl_runtime_apis! { /// /// Dynamic configuration may be supported in the future. fn configuration() -> BabeConfiguration; + + /// Returns the slot number that started the current epoch. + fn current_epoch_start() -> SlotNumber; } } diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index ed32cbef9c..2505bdde22 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -52,7 +52,7 @@ 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 sp_consensus_babe::AuthorityId; +pub use sp_consensus_babe::{AuthorityId, SlotNumber}; pub type AuraId = sp_consensus_aura::sr25519::AuthorityId; // Include the WASM binary @@ -606,6 +606,10 @@ cfg_if! { secondary_slots: true, } } + + fn current_epoch_start() -> SlotNumber { + >::current_epoch_start() + } } impl sp_offchain::OffchainWorkerApi for Runtime { @@ -793,6 +797,10 @@ cfg_if! { secondary_slots: true, } } + + fn current_epoch_start() -> SlotNumber { + >::current_epoch_start() + } } impl sp_offchain::OffchainWorkerApi for Runtime { -- GitLab From 349b54c0c821ec6d90675c233be391127dff5dcb Mon Sep 17 00:00:00 2001 From: h4x3rotab Date: Tue, 18 Feb 2020 02:31:25 +0800 Subject: [PATCH 166/180] nit: remove a bad comment line by merging mistake (#4942) --- primitives/trie/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/primitives/trie/src/lib.rs b/primitives/trie/src/lib.rs index 0cf268856b..f6131c8ed5 100644 --- a/primitives/trie/src/lib.rs +++ b/primitives/trie/src/lib.rs @@ -91,7 +91,6 @@ pub type PlainDB<'a, K> = dyn hash_db::PlainDB + 'a; /// key conflict for non random keys). pub type PrefixedMemoryDB = memory_db::MemoryDB, trie_db::DBValue>; /// Reexport from `hash_db`, with genericity set for `Hasher` trait. -/// This uses the `KeyFunction` for prefixing keys internally (avoiding /// This uses a noops `KeyFunction` (key addressing must be hashed or using /// an encoding scheme that avoid key conflict). pub type MemoryDB = memory_db::MemoryDB, trie_db::DBValue>; -- GitLab From 6e7c5433a9927dad2d993838823000e4da0d111b Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 18 Feb 2020 00:29:37 +0100 Subject: [PATCH 167/180] Fix potential panics related to time (#4951) * Fix potential peerset panic at initialization * Also fix legacy_proto/behaviour.rs --- client/network/src/protocol/legacy_proto/behaviour.rs | 10 ++++++---- client/peerset/src/lib.rs | 6 ++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/client/network/src/protocol/legacy_proto/behaviour.rs b/client/network/src/protocol/legacy_proto/behaviour.rs index 704b4947ed..69c89be9a3 100644 --- a/client/network/src/protocol/legacy_proto/behaviour.rs +++ b/client/network/src/protocol/legacy_proto/behaviour.rs @@ -379,12 +379,14 @@ impl LegacyProto { } }; + let now = Instant::now(); + match mem::replace(occ_entry.get_mut(), PeerState::Poisoned) { - PeerState::Banned { ref until } if *until > Instant::now() => { + PeerState::Banned { ref until } if *until > now => { debug!(target: "sub-libp2p", "PSM => Connect({:?}): Will start to connect at \ until {:?}", occ_entry.key(), until); *occ_entry.into_mut() = PeerState::PendingRequest { - timer: futures_timer::Delay::new(until.clone() - Instant::now()), + timer: futures_timer::Delay::new(until.clone() - now), timer_deadline: until.clone(), }; }, @@ -397,13 +399,13 @@ impl LegacyProto { }, PeerState::Disabled { open, ref connected_point, banned_until: Some(ref banned) } - if *banned > Instant::now() => { + if *banned > now => { debug!(target: "sub-libp2p", "PSM => Connect({:?}): Has idle connection through \ {:?} but node is banned until {:?}", occ_entry.key(), connected_point, banned); *occ_entry.into_mut() = PeerState::DisabledPendingEnable { connected_point: connected_point.clone(), open, - timer: futures_timer::Delay::new(banned.clone() - Instant::now()), + timer: futures_timer::Delay::new(banned.clone() - now), timer_deadline: banned.clone(), }; }, diff --git a/client/peerset/src/lib.rs b/client/peerset/src/lib.rs index bd2b6bb110..fb91f1fcf6 100644 --- a/client/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -199,14 +199,16 @@ impl Peerset { tx: tx.clone(), }; + let now = Instant::now(); + let mut peerset = Peerset { data: peersstate::PeersState::new(config.in_peers, config.out_peers, config.reserved_only), tx, rx, reserved_only: config.reserved_only, message_queue: VecDeque::new(), - created: Instant::now(), - latest_time_update: Instant::now(), + created: now, + latest_time_update: now, }; peerset.data.set_priority_group(RESERVED_NODES, config.reserved_nodes.into_iter().collect()); -- GitLab From 419e5fd0026cfd528cd3b327789bb0a3a8215703 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Tue, 18 Feb 2020 00:59:08 +0100 Subject: [PATCH 168/180] Utility/Recovery passthrough always pays a fee. (#4953) * Utility passthrough always pays a fee. * Use `FunctionOf` instead of Passthrough * Update recovery passthrough --- bin/node/runtime/src/lib.rs | 4 +- frame/recovery/src/lib.rs | 35 ++----- frame/utility/src/lib.rs | 179 ++++++++++-------------------------- 3 files changed, 59 insertions(+), 159 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 1d460762e4..a98b1700fe 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -82,8 +82,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 220, - impl_version: 1, + spec_version: 221, + impl_version: 0, apis: RUNTIME_API_VERSIONS, }; diff --git a/frame/recovery/src/lib.rs b/frame/recovery/src/lib.rs index b456d17c68..6fa00af751 100644 --- a/frame/recovery/src/lib.rs +++ b/frame/recovery/src/lib.rs @@ -160,10 +160,7 @@ use codec::{Encode, Decode}; use frame_support::{ decl_module, decl_event, decl_storage, decl_error, ensure, Parameter, RuntimeDebug, - weights::{ - GetDispatchInfo, PaysFee, DispatchClass, ClassifyDispatch, Weight, WeighData, - SimpleDispatchInfo, - }, + weights::{GetDispatchInfo, SimpleDispatchInfo, FunctionOf}, traits::{Currency, ReservableCurrency, Get, OnReapAccount, BalanceStatus}, }; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -331,10 +328,14 @@ decl_module! { /// - `call`: The call you want to make with the recovered account. /// /// # - /// - The weight of the `call`. + /// - The weight of the `call` + 10,000. /// - One storage lookup to check account is recovered by `who`. O(1) /// # - #[weight = ::Call>>::new()] + #[weight = FunctionOf( + |args: (&T::AccountId, &Box<::Call>)| args.1.get_dispatch_info().weight + 10_000, + |args: (&T::AccountId, &Box<::Call>)| args.1.get_dispatch_info().class, + true + )] fn as_recovered(origin, account: T::AccountId, call: Box<::Call> @@ -646,25 +647,3 @@ impl OnReapAccount for Module { >::remove(who); } } - -/// Simple pass through for the weight functions. -struct Passthrough(sp_std::marker::PhantomData<(AccountId, Call)>); - -impl Passthrough { - fn new() -> Self { Self(Default::default()) } -} -impl WeighData<(&AccountId, &Box)> for Passthrough { - fn weigh_data(&self, (_, call): (&AccountId, &Box)) -> Weight { - call.get_dispatch_info().weight + 10_000 - } -} -impl ClassifyDispatch<(&AccountId, &Box)> for Passthrough { - fn classify_dispatch(&self, (_, call): (&AccountId, &Box)) -> DispatchClass { - call.get_dispatch_info().class - } -} -impl PaysFee<(&AccountId, &Box)> for Passthrough { - fn pays_fee(&self, (_, call): (&AccountId, &Box)) -> bool { - call.get_dispatch_info().pays_fee - } -} diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index c19b044ad7..501e04ad55 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -66,9 +66,9 @@ use codec::{Encode, Decode}; use sp_core::TypeId; use sp_io::hashing::blake2_256; use frame_support::{decl_module, decl_event, decl_error, decl_storage, Parameter, ensure, RuntimeDebug}; -use frame_support::{traits::{Get, ReservableCurrency, Currency}, weights::{ - GetDispatchInfo, ClassifyDispatch, WeighData, Weight, DispatchClass, PaysFee -}}; +use frame_support::{traits::{Get, ReservableCurrency, Currency}, + weights::{GetDispatchInfo, DispatchClass,FunctionOf}, +}; use frame_system::{self as system, ensure_signed}; use sp_runtime::{DispatchError, DispatchResult, traits::Dispatchable}; @@ -188,126 +188,6 @@ decl_event! { } } -/// Simple index-based pass through for the weight functions. -struct Passthrough(sp_std::marker::PhantomData); - -impl Passthrough { - fn new() -> Self { Self(Default::default()) } -} -impl WeighData<(&u16, &Box)> for Passthrough { - fn weigh_data(&self, (_, call): (&u16, &Box)) -> Weight { - call.get_dispatch_info().weight + 10_000 - } -} -impl ClassifyDispatch<(&u16, &Box)> for Passthrough { - fn classify_dispatch(&self, (_, call): (&u16, &Box)) -> DispatchClass { - call.get_dispatch_info().class - } -} -impl PaysFee<(&u16, &Box)> for Passthrough { - fn pays_fee(&self, (_, call): (&u16, &Box)) -> bool { - call.get_dispatch_info().pays_fee - } -} - -/// Summation pass-through for the weight function of the batch call. -/// -/// This just adds all of the weights together of all of the calls. -struct BatchPassthrough(sp_std::marker::PhantomData); - -impl BatchPassthrough { - fn new() -> Self { Self(Default::default()) } -} -impl WeighData<(&Vec,)> for BatchPassthrough { - fn weigh_data(&self, (calls,): (&Vec,)) -> Weight { - calls.iter() - .map(|call| call.get_dispatch_info().weight) - .fold(10_000, |a, n| a + n) - } -} -impl ClassifyDispatch<(&Vec,)> for BatchPassthrough { - fn classify_dispatch(&self, (calls,): (&Vec,)) -> DispatchClass { - let all_operational = calls.iter() - .map(|call| call.get_dispatch_info().class) - .all(|class| class == DispatchClass::Operational); - if all_operational { - DispatchClass::Operational - } else { - DispatchClass::Normal - } - } -} -impl PaysFee<(&Vec,)> for BatchPassthrough { - fn pays_fee(&self, (calls,): (&Vec,)) -> bool { - calls.iter() - .any(|call| call.get_dispatch_info().pays_fee) - } -} - -/// Simple index-based pass through for the weight functions. -struct MultiPassthrough( - sp_std::marker::PhantomData<(Call, AccountId, Timepoint)> -); - -impl MultiPassthrough { - fn new() -> Self { Self(Default::default()) } -} -impl WeighData<(&u16, &Vec, &Timepoint, &Box)> -for MultiPassthrough -{ - fn weigh_data(&self, (_, sigs, _, call): (&u16, &Vec, &Timepoint, &Box)) -> Weight { - call.get_dispatch_info().weight + 10_000 * (sigs.len() as u32 + 1) - } -} -impl ClassifyDispatch<(&u16, &Vec, &Timepoint, &Box)> -for MultiPassthrough -{ - fn classify_dispatch(&self, (_, _, _, call): (&u16, &Vec, &Timepoint, &Box)) - -> DispatchClass - { - call.get_dispatch_info().class - } -} -impl PaysFee<(&u16, &Vec, &Timepoint, &Box)> -for MultiPassthrough -{ - fn pays_fee(&self, _: (&u16, &Vec, &Timepoint, &Box)) -> bool { - true - } -} - -/// Simple index-based pass through for the weight functions. -struct SigsLen( - sp_std::marker::PhantomData<(AccountId, Timepoint)> -); - -impl SigsLen { - fn new() -> Self { Self(Default::default()) } -} -impl WeighData<(&u16, &Vec, &Timepoint, &[u8; 32])> -for SigsLen -{ - fn weigh_data(&self, (_, sigs, _, _): (&u16, &Vec, &Timepoint, &[u8; 32])) -> Weight { - 10_000 * (sigs.len() as u32 + 1) - } -} -impl ClassifyDispatch<(&u16, &Vec, &Timepoint, &[u8; 32])> -for SigsLen -{ - fn classify_dispatch(&self, _: (&u16, &Vec, &Timepoint, &[u8; 32])) - -> DispatchClass - { - DispatchClass::Normal - } -} -impl PaysFee<(&u16, &Vec, &Timepoint, &[u8; 32])> -for SigsLen -{ - fn pays_fee(&self, _: (&u16, &Vec, &Timepoint, &[u8; 32])) -> bool { - true - } -} - /// A module identifier. These are per module and should be stored in a registry somewhere. #[derive(Clone, Copy, Eq, PartialEq, Encode, Decode)] struct IndexedUtilityModuleId(u16); @@ -341,7 +221,24 @@ decl_module! { /// `BatchInterrupted` event is deposited, along with the number of successful calls made /// and the error of the failed call. If all were successful, then the `BatchCompleted` /// event is deposited. - #[weight = ::Call>>::new()] + #[weight = FunctionOf( + |args: (&Vec<::Call>,)| { + args.0.iter() + .map(|call| call.get_dispatch_info().weight) + .fold(10_000, |a, n| a + n) + }, + |args: (&Vec<::Call>,)| { + let all_operational = args.0.iter() + .map(|call| call.get_dispatch_info().class) + .all(|class| class == DispatchClass::Operational); + if all_operational { + DispatchClass::Operational + } else { + DispatchClass::Normal + } + }, + true + )] fn batch(origin, calls: Vec<::Call>) { for (index, call) in calls.into_iter().enumerate() { let result = call.dispatch(origin.clone()); @@ -358,9 +255,13 @@ decl_module! { /// The dispatch origin for this call must be _Signed_. /// /// # - /// - The weight of the `call`. + /// - The weight of the `call` + 10,000. /// # - #[weight = ::Call>>::new()] + #[weight = FunctionOf( + |args: (&u16, &Box<::Call>)| args.1.get_dispatch_info().weight + 10_000, + |args: (&u16, &Box<::Call>)| args.1.get_dispatch_info().class, + true + )] fn as_sub(origin, index: u16, call: Box<::Call>) -> DispatchResult { let who = ensure_signed(origin)?; let pseudonym = Self::sub_account_id(who, index); @@ -408,7 +309,15 @@ decl_module! { /// deposit taken for its lifetime of /// `MultisigDepositBase + threshold * MultisigDepositFactor`. /// # - #[weight = ::Call, T::AccountId, Option>>>::new()] + #[weight = FunctionOf( + |args: (&u16, &Vec, &Option>, &Box<::Call>)| { + args.3.get_dispatch_info().weight + 10_000 * (args.1.len() as u32 + 1) + }, + |args: (&u16, &Vec, &Option>, &Box<::Call>)| { + args.3.get_dispatch_info().class + }, + true + )] fn as_multi(origin, threshold: u16, other_signatories: Vec, @@ -498,7 +407,13 @@ decl_module! { /// deposit taken for its lifetime of /// `MultisigDepositBase + threshold * MultisigDepositFactor`. /// # - #[weight = >>>::new()] + #[weight = FunctionOf( + |args: (&u16, &Vec, &Option>, &[u8; 32])| { + 10_000 * (args.1.len() as u32 + 1) + }, + DispatchClass::Normal, + true + )] fn approve_as_multi(origin, threshold: u16, other_signatories: Vec, @@ -567,7 +482,13 @@ decl_module! { /// - I/O: 1 read `O(S)`, one remove. /// - Storage: removes one item. /// # - #[weight = >>::new()] + #[weight = FunctionOf( + |args: (&u16, &Vec, &Timepoint, &[u8; 32])| { + 10_000 * (args.1.len() as u32 + 1) + }, + DispatchClass::Normal, + true + )] fn cancel_as_multi(origin, threshold: u16, other_signatories: Vec, -- GitLab From 0c8e05928d9d50e20df4388b9294fadc21058dce Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Tue, 18 Feb 2020 10:54:00 +0100 Subject: [PATCH 169/180] offchain: Upgrade hyper to 0.13, which uses tokio 0.2 (#4860) * service: Don't depend on tokio-executor Seems to be a leftover dependency that's not used anymore. * offchain: Upgrade hyper to 0.13, which uses tokio 0.2 * offchain: Adapt HTTP tests to Tokio 0.2 * network: Don't transitively include tokio 0.2 in WASM 1) We don't specifically depend on Tokio codec impls 2) Conflating features in Cargo means that enabling Tokio runtime in the native environment will also do so in WASM, where it's obviously not implemented and causes a compilation error. * grafana-data-source: Pull hyper/tokio only in native environment --- Cargo.lock | 48 ++++++++++------- client/network/Cargo.toml | 2 +- client/offchain/Cargo.toml | 9 ++-- client/offchain/src/api/http.rs | 71 +++++++++++++------------ client/service/Cargo.toml | 1 - utils/grafana-data-source/Cargo.toml | 4 +- utils/grafana-data-source/src/lib.rs | 10 ++-- utils/grafana-data-source/src/server.rs | 6 ++- 8 files changed, 84 insertions(+), 67 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e9b9ca337c..305b609708 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2221,6 +2221,7 @@ dependencies = [ "httparse", "itoa", "log 0.4.8", + "net2", "pin-project", "time", "tokio 0.2.11", @@ -2230,19 +2231,19 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.17.1" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719d85c7df4a7f309a77d145340a063ea929dcb2e025bae46a80345cffec2952" +checksum = "f6ea6215c7314d450ee45970ab8b3851ab447a0e6bafdd19e31b20a42dbb7faf" dependencies = [ - "bytes 0.4.12", + "bytes 0.5.4", "ct-logs", - "futures 0.1.29", - "hyper 0.12.35", + "futures-util", + "hyper 0.13.2", "rustls", - "tokio-io", + "rustls-native-certs", + "tokio 0.2.11", "tokio-rustls", "webpki", - "webpki-roots 0.17.0", ] [[package]] @@ -5475,6 +5476,18 @@ dependencies = [ "webpki", ] +[[package]] +name = "rustls-native-certs" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51ffebdbb48c14f84eba0b715197d673aff1dd22cc1007ca647e28483bbcc307" +dependencies = [ + "openssl-probe", + "rustls", + "schannel", + "security-framework", +] + [[package]] name = "rustversion" version = "1.0.2" @@ -6243,13 +6256,12 @@ dependencies = [ name = "sc-offchain" version = "2.0.0" dependencies = [ - "bytes 0.4.12", + "bytes 0.5.4", "env_logger 0.7.1", "fnv", - "futures 0.1.29", "futures 0.3.4", "futures-timer 3.0.1", - "hyper 0.12.35", + "hyper 0.13.2", "hyper-rustls", "log 0.4.8", "num_cpus", @@ -6268,7 +6280,7 @@ dependencies = [ "sp-transaction-pool", "substrate-test-runtime-client", "threadpool", - "tokio 0.1.22", + "tokio 0.2.11", ] [[package]] @@ -6418,7 +6430,6 @@ dependencies = [ "sysinfo", "target_info", "tokio 0.2.11", - "tokio-executor 0.1.10", "tracing", "wasm-timer", ] @@ -8011,6 +8022,7 @@ checksum = "8fdd17989496f49cdc57978c96f0c9fe5e4a58a8bddc6813c449a4624f6a030b" dependencies = [ "bytes 0.5.4", "fnv", + "iovec", "lazy_static", "libc", "memchr", @@ -8019,6 +8031,7 @@ dependencies = [ "num_cpus", "pin-project-lite", "signal-hook-registry", + "slab", "tokio-macros", "winapi 0.3.8", ] @@ -8130,15 +8143,13 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.10.3" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d7cf08f990090abd6c6a73cab46fed62f85e8aef8b99e4b918a9f4a637f0676" +checksum = "141afec0978abae6573065a48882c6bae44c5cc61db9b511ac4abf6a09bfd9cc" dependencies = [ - "bytes 0.4.12", - "futures 0.1.29", - "iovec", + "futures-core", "rustls", - "tokio-io", + "tokio 0.2.11", "webpki", ] @@ -8501,7 +8512,6 @@ checksum = "c689459fbaeb50e56c6749275f084decfd02194ac5852e6617d95d0d3cf02eaf" dependencies = [ "bytes 0.5.4", "futures_codec", - "tokio-util", ] [[package]] diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index d16f3d81c1..f2d50b988a 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -51,7 +51,7 @@ sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" } 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" } thiserror = "1" -unsigned-varint = { version = "0.3.0", features = ["codec"] } +unsigned-varint = { version = "0.3.0", features = ["futures-codec"] } void = "1.0.2" zeroize = "1.0.0" yamux = "0.4.2" diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index ed5db3f2c7..29e6dca2a7 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -7,11 +7,10 @@ authors = ["Parity Technologies "] edition = "2018" [dependencies] -bytes = "0.4.12" +bytes = "0.5" 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" futures-timer = "3.0.1" log = "0.4.8" @@ -27,14 +26,14 @@ 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" +hyper = "0.13.2" +hyper-rustls = "0.19" [dev-dependencies] sc-client-db = { version = "0.8", default-features = true, path = "../db/" } env_logger = "0.7.0" substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" } -tokio = "0.1.22" +tokio = "0.2" sc-transaction-pool = { version = "2.0.0", path = "../../client/transaction-pool" } sp-transaction-pool = { version = "2.0.0", path = "../../primitives/transaction-pool" } diff --git a/client/offchain/src/api/http.rs b/client/offchain/src/api/http.rs index 7aa0963fcf..0483f84e2f 100644 --- a/client/offchain/src/api/http.rs +++ b/client/offchain/src/api/http.rs @@ -26,9 +26,9 @@ //! actively calling any function. use crate::api::timestamp; -use bytes::Buf as _; +use bytes::buf::ext::{Reader, BufExt}; use fnv::FnvHashMap; -use futures::{prelude::*, channel::mpsc, compat::Compat01As03}; +use futures::{prelude::*, future, channel::mpsc}; use log::error; use sp_core::offchain::{HttpRequestId, Timestamp, HttpRequestStatus, HttpError}; use std::{fmt, io::Read as _, mem, pin::Pin, task::Context, task::Poll}; @@ -50,7 +50,7 @@ pub fn http() -> (HttpApi, HttpWorker) { let engine = HttpWorker { to_api, from_api, - http_client: hyper::Client::builder().build(hyper_rustls::HttpsConnector::new(1)), + http_client: hyper::Client::builder().build(hyper_rustls::HttpsConnector::new()), requests: Vec::new(), }; @@ -103,10 +103,10 @@ struct HttpApiRequestRp { /// Elements extracted from the channel are first put into `current_read_chunk`. /// If the channel produces an error, then that is translated into an `IoError` and the request /// is removed from the list. - body: stream::Fuse>>, + body: stream::Fuse>>, /// Chunk that has been extracted from the channel and that is currently being read. /// Reading data from the response should read from this field in priority. - current_read_chunk: Option>, + current_read_chunk: Option>, } impl HttpApi { @@ -122,7 +122,7 @@ impl HttpApi { let (body_sender, body) = hyper::Body::channel(); let mut request = hyper::Request::new(body); *request.method_mut() = hyper::Method::from_bytes(method.as_bytes()).map_err(|_| ())?; - *request.uri_mut() = hyper::Uri::from_shared(From::from(uri)).map_err(|_| ())?; + *request.uri_mut() = hyper::Uri::from_maybe_shared(uri.to_owned()).map_err(|_| ())?; let new_id = self.next_id; debug_assert!(!self.requests.contains_key(&new_id)); @@ -177,9 +177,7 @@ impl HttpApi { // (if the body has been written), or `DeadlineReached`, or `IoError`. // If `IoError` is returned, don't forget to remove the request from the list. let mut poll_sender = move |sender: &mut hyper::body::Sender| -> Result<(), HttpError> { - let mut when_ready = future::maybe_done(Compat01As03::new( - futures01::future::poll_fn(|| sender.poll_ready()) - )); + let mut when_ready = future::maybe_done(future::poll_fn(|cx| sender.poll_ready(cx))); futures::executor::block_on(future::select(&mut when_ready, &mut deadline)); match when_ready { future::MaybeDone::Done(Ok(())) => {} @@ -191,13 +189,11 @@ impl HttpApi { } }; - match sender.send_data(hyper::Chunk::from(chunk.to_owned())) { - Ok(()) => Ok(()), - Err(_chunk) => { + futures::executor::block_on(sender.send_data(hyper::body::Bytes::from(chunk.to_owned()))) + .map_err(|_| { error!("HTTP sender refused data despite being ready"); - Err(HttpError::IoError) - }, - } + HttpError::IoError + }) }; loop { @@ -538,7 +534,7 @@ enum WorkerToApi { /// the next item. /// Can also be used to send an error, in case an error happend on the HTTP socket. After /// an error is sent, the channel will close. - body: mpsc::Receiver>, + body: mpsc::Receiver>, }, /// A request has failed because of an error. The request is then no longer valid. Fail { @@ -564,13 +560,13 @@ pub struct HttpWorker { /// HTTP request being processed by the worker. enum HttpWorkerRequest { /// Request has been dispatched and is waiting for a response from the Internet. - Dispatched(Compat01As03), + Dispatched(hyper::client::ResponseFuture), /// Progressively reading the body of the response and sending it to the channel. ReadBody { /// Body to read `Chunk`s from. Only used if the channel is ready to accept data. - body: Compat01As03, + body: hyper::Body, /// Channel to the [`HttpApi`] where we send the chunks to. - tx: mpsc::Sender>, + tx: mpsc::Sender>, }, } @@ -608,7 +604,7 @@ impl Future for HttpWorker { // We received a response! Decompose it into its parts. let status_code = response.status(); let headers = mem::replace(response.headers_mut(), hyper::HeaderMap::new()); - let body = Compat01As03::new(response.into_body()); + let body = response.into_body(); let (body_tx, body_rx) = mpsc::channel(3); let _ = me.to_api.unbounded_send(WorkerToApi::Response { @@ -660,7 +656,7 @@ impl Future for HttpWorker { Poll::Pending => {}, Poll::Ready(None) => return Poll::Ready(()), // stops the worker Poll::Ready(Some(ApiToWorker::Dispatch { id, request })) => { - let future = Compat01As03::new(me.http_client.request(request)); + let future = me.http_client.request(request); debug_assert!(me.requests.iter().all(|(i, _)| *i != id)); me.requests.push((id, HttpWorkerRequest::Dispatched(future))); cx.waker().wake_by_ref(); // reschedule the task to poll the request @@ -692,31 +688,36 @@ impl fmt::Debug for HttpWorkerRequest { #[cfg(test)] mod tests { + use core::convert::Infallible; use crate::api::timestamp; use super::http; - use futures::prelude::*; - use futures01::Future as _; 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. macro_rules! build_api_server { () => {{ + fn tokio_run(future: impl std::future::Future) { + let _ = tokio::runtime::Runtime::new().unwrap().block_on(future); + } + let (api, worker) = http(); - // Note: we have to use tokio because hyper still uses old futures. - std::thread::spawn(move || { - tokio::run(futures::compat::Compat::new(worker.map(|()| Ok::<(), ()>(())))) - }); + std::thread::spawn(move || tokio_run(worker)); + let (addr_tx, addr_rx) = std::sync::mpsc::channel(); std::thread::spawn(move || { - let server = hyper::Server::bind(&"127.0.0.1:0".parse().unwrap()) - .serve(|| { - hyper::service::service_fn_ok(move |_: hyper::Request| { - hyper::Response::new(hyper::Body::from("Hello World!")) - }) - }); - let _ = addr_tx.send(server.local_addr()); - hyper::rt::run(server.map_err(|e| panic!("{:?}", e))); + tokio_run(async move { + let server = hyper::Server::bind(&"127.0.0.1:0".parse().unwrap()) + .serve(hyper::service::make_service_fn(|_| { async move { + Ok::<_, Infallible>(hyper::service::service_fn(move |_req| async move { + Ok::<_, Infallible>( + hyper::Response::new(hyper::Body::from("Hello World!")) + ) + })) + }})); + let _ = addr_tx.send(server.local_addr()); + server.await + }); }); (api, addr_rx.recv().unwrap()) }}; diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 7f7ef80b16..1e781aa695 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -23,7 +23,6 @@ parking_lot = "0.10.0" lazy_static = "1.4.0" log = "0.4.8" slog = { version = "2.5.2", features = ["nested-values"] } -tokio-executor = "0.1.8" futures-timer = "3.0.1" wasm-timer = "0.2" exit-future = "0.2.0" diff --git a/utils/grafana-data-source/Cargo.toml b/utils/grafana-data-source/Cargo.toml index e1bd037009..c49ee963f0 100644 --- a/utils/grafana-data-source/Cargo.toml +++ b/utils/grafana-data-source/Cargo.toml @@ -8,8 +8,6 @@ edition = "2018" [dependencies] 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"] } serde_json = "1" serde = { version = "1", features = ["derive"] } @@ -21,3 +19,5 @@ derive_more = "0.99" [target.'cfg(not(target_os = "unknown"))'.dependencies] async-std = { version = "1.0.1", features = ["unstable"] } +hyper = { version = "0.13.1", default-features = false, features = ["stream"] } +tokio = "0.2" diff --git a/utils/grafana-data-source/src/lib.rs b/utils/grafana-data-source/src/lib.rs index fbba064706..bc40fc39bb 100644 --- a/utils/grafana-data-source/src/lib.rs +++ b/utils/grafana-data-source/src/lib.rs @@ -72,11 +72,13 @@ pub fn record_metrics_slice(metrics: &[(&str, f32)]) -> Result<(), Error> { #[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { /// Hyper internal error. + #[cfg(not(target_os = "unknown"))] Hyper(hyper::Error), - /// Serialization/deserialization error. - Serde(serde_json::Error), /// Http request error. + #[cfg(not(target_os = "unknown"))] Http(hyper::http::Error), + /// Serialization/deserialization error. + Serde(serde_json::Error), /// Timestamp error. Timestamp(TryFromIntError), /// i/o error. @@ -86,9 +88,11 @@ pub enum Error { impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { + #[cfg(not(target_os = "unknown"))] Error::Hyper(error) => Some(error), - Error::Serde(error) => Some(error), + #[cfg(not(target_os = "unknown"))] Error::Http(error) => Some(error), + Error::Serde(error) => Some(error), Error::Timestamp(error) => Some(error), Error::Io(error) => Some(error) } diff --git a/utils/grafana-data-source/src/server.rs b/utils/grafana-data-source/src/server.rs index 8ef5e03784..f2f06f7688 100644 --- a/utils/grafana-data-source/src/server.rs +++ b/utils/grafana-data-source/src/server.rs @@ -15,12 +15,15 @@ // along with Substrate. If not, see . 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, TryStreamExt, future::{Future, select, Either}}; use futures_timer::Delay; use crate::{DATABASE, Error, types::{Target, Query, TimeseriesData, Range}}; +#[cfg(not(target_os = "unknown"))] +use hyper::{Body, Request, Response, header, service::{service_fn, make_service_fn}, Server}; + +#[cfg(not(target_os = "unknown"))] async fn api_response(req: Request) -> Result, Error> { match req.uri().path() { "/search" => { @@ -57,6 +60,7 @@ async fn api_response(req: Request) -> Result, Error> { } } +#[cfg(not(target_os = "unknown"))] async fn map_request_to_response(req: Request, transformation: T) -> Result, Error> where Req: DeserializeOwned, -- GitLab From dececc3fce5181feb56d981bd25217c454b2e239 Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Tue, 18 Feb 2020 12:57:58 +0300 Subject: [PATCH 170/180] Reusable bench-db & bench-keyring (#4955) * move to node-testing/bench * to tabs --- Cargo.lock | 1 - bin/node/testing/Cargo.toml | 5 +- bin/node/testing/benches/import.rs | 382 +------------------------- bin/node/testing/src/bench.rs | 424 +++++++++++++++++++++++++++++ bin/node/testing/src/lib.rs | 2 +- 5 files changed, 435 insertions(+), 379 deletions(-) create mode 100644 bin/node/testing/src/bench.rs diff --git a/Cargo.lock b/Cargo.lock index 305b609708..144cc495e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3658,7 +3658,6 @@ dependencies = [ "frame-support", "frame-system", "fs_extra", - "hex-literal", "log 0.4.8", "node-executor", "node-primitives", diff --git a/bin/node/testing/Cargo.toml b/bin/node/testing/Cargo.toml index 558c8f2f0b..840b2d0fef 100644 --- a/bin/node/testing/Cargo.toml +++ b/bin/node/testing/Cargo.toml @@ -41,12 +41,11 @@ sp-block-builder = { version = "2.0.0", path = "../../../primitives/block-builde sp-inherents = { version = "2.0.0", path = "../../../primitives/inherents" } sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" } log = "0.4.8" +tempdir = "0.3" +fs_extra = "1" [dev-dependencies] criterion = "0.3.0" -tempdir = "0.3" -fs_extra = "1" -hex-literal = "0.2.1" sc-cli = { version = "0.8.0", path = "../../../client/cli" } sc-service = { version = "0.8.0", path = "../../../client/service", features = ["rocksdb"] } diff --git a/bin/node/testing/benches/import.rs b/bin/node/testing/benches/import.rs index b294ae3604..f8cbbec79d 100644 --- a/bin/node/testing/benches/import.rs +++ b/bin/node/testing/benches/import.rs @@ -28,44 +28,10 @@ //! to much configuring - just block full of randomized transactions. //! It is not supposed to measure runtime modules weight correctness -use std::{sync::Arc, path::Path, collections::BTreeMap}; - -use node_primitives::Block; -use node_testing::client::{Client, Backend}; -use node_testing::keyring::*; -use sc_client_db::PruningMode; -use sc_executor::{NativeExecutor, WasmExecutionMethod}; -use sp_consensus::{ - BlockOrigin, BlockImport, BlockImportParams, - ForkChoiceStrategy, ImportResult, ImportedAux -}; -use sp_runtime::{ - generic::BlockId, - OpaqueExtrinsic, - traits::{Block as BlockT, Verify, Zero, IdentifyAccount}, -}; -use codec::{Decode, Encode}; -use node_runtime::{ - Call, - CheckedExtrinsic, - constants::currency::DOLLARS, - UncheckedExtrinsic, - MinimumPeriod, - BalancesCall, - AccountId, - Signature, -}; -use sp_core::ExecutionContext; -use sp_api::ProvideRuntimeApi; -use sp_block_builder::BlockBuilder; -use sp_inherents::InherentData; -use sc_client_api::{ - Backend as _, ExecutionStrategy, - execution_extensions::{ExecutionExtensions, ExecutionStrategies}, -}; -use sp_core::{Pair, Public, sr25519}; - +use node_testing::bench::{BenchDb, Profile}; +use sp_runtime::generic::BlockId; use criterion::{Criterion, criterion_group, criterion_main}; +use sc_client_api::backend::Backend; criterion_group!( name = benches; @@ -79,344 +45,13 @@ criterion_group!( ); criterion_main!(benches, profile); -fn genesis(keyring: &BenchKeyring) -> node_runtime::GenesisConfig { - node_testing::genesis::config_endowed( - false, - Some(node_runtime::WASM_BINARY), - keyring.collect_account_ids(), - ) -} - -// this is deterministic keyring of ordered accounts -// //endowed-user//00 -// //endowed-user//01 -// ... -// //endowed-user//N -#[derive(Clone)] -struct BenchKeyring { - accounts: BTreeMap, -} - -// This is prepared database with genesis and keyring -// that can be cloned and then used for any benchmarking. -struct BenchDb { - keyring: BenchKeyring, - directory_guard: Guard, -} - -impl Clone for BenchDb { - fn clone(&self) -> Self { - let keyring = self.keyring.clone(); - let dir = tempdir::TempDir::new("sub-bench").expect("temp dir creation failed"); - - let seed_dir = self.directory_guard.0.path(); - - log::trace!( - target: "bench-logistics", - "Copying seed db from {} to {}", - seed_dir.to_string_lossy(), - dir.path().to_string_lossy(), - ); - let seed_db_files = std::fs::read_dir(seed_dir) - .expect("failed to list file in seed dir") - .map(|f_result| - f_result.expect("failed to read file in seed db") - .path() - .clone() - ).collect(); - fs_extra::copy_items( - &seed_db_files, - dir.path(), - &fs_extra::dir::CopyOptions::new(), - ).expect("Copy of seed database is ok"); - - BenchDb { keyring, directory_guard: Guard(dir) } - } -} - -impl BenchDb { - fn new(keyring_length: usize) -> Self { - let keyring = BenchKeyring::new(keyring_length); - - let dir = tempdir::TempDir::new("sub-bench").expect("temp dir creation failed"); - log::trace!( - target: "bench-logistics", - "Created seed db at {}", - dir.path().to_string_lossy(), - ); - let (_client, _backend) = bench_client(dir.path(), Profile::Native, &keyring); - let directory_guard = Guard(dir); - - BenchDb { keyring, directory_guard } - } - - fn generate_block(&mut self) -> Block { - let (client, _backend) = bench_client( - self.directory_guard.path(), - Profile::Wasm, - &self.keyring, - ); - - let version = client.runtime_version_at(&BlockId::number(0)) - .expect("There should be runtime version at 0") - .spec_version; - - let genesis_hash = client.block_hash(Zero::zero()) - .expect("Database error?") - .expect("Genesis block always exists; qed") - .into(); - - let mut block = client - .new_block(Default::default()) - .expect("Block creation failed"); - - let timestamp = 1 * MinimumPeriod::get(); - - let mut inherent_data = InherentData::new(); - inherent_data.put_data(sp_timestamp::INHERENT_IDENTIFIER, ×tamp) - .expect("Put timestamp failed"); - inherent_data.put_data(sp_finality_tracker::INHERENT_IDENTIFIER, &0) - .expect("Put finality tracker failed"); - - for extrinsic in client.runtime_api() - .inherent_extrinsics_with_context( - &BlockId::number(0), - ExecutionContext::BlockConstruction, - inherent_data, - ).expect("Get inherents failed") - { - block.push(extrinsic).expect("Push inherent failed"); - } - - let mut iteration = 0; - let start = std::time::Instant::now(); - for _ in 0..100 { - - let sender = self.keyring.at(iteration); - let receiver = get_account_id_from_seed::( - &format!("random-user//{}", iteration) - ); - - let signed = self.keyring.sign( - CheckedExtrinsic { - signed: Some((sender, signed_extra(0, 1*DOLLARS))), - function: Call::Balances( - BalancesCall::transfer( - pallet_indices::address::Address::Id(receiver), - 1*DOLLARS - ) - ), - }, - version, - genesis_hash, - ); - - let encoded = Encode::encode(&signed); - - let opaque = OpaqueExtrinsic::decode(&mut &encoded[..]) - .expect("Failed to decode opaque"); - - match block.push(opaque) { - Err(sp_blockchain::Error::ApplyExtrinsicFailed( - sp_blockchain::ApplyExtrinsicFailed::Validity(e) - )) if e.exhausted_resources() => { - break; - }, - Err(err) => panic!("Error pushing transaction: {:?}", err), - Ok(_) => {}, - } - iteration += 1; - } - let block = block.build().expect("Block build failed").block; - - log::info!( - target: "bench-logistics", - "Block construction: {:#?} ({} tx)", - start.elapsed(), block.extrinsics.len() - ); - - block - } - - fn path(&self) -> &Path { - self.directory_guard.path() - } - - fn create_context(&self, profile: Profile) -> BenchContext { - let BenchDb { directory_guard, keyring } = self.clone(); - let (client, backend) = bench_client(directory_guard.path(), profile, &keyring); - - BenchContext { - client, backend, db_guard: directory_guard, - } - } -} - -impl BenchKeyring { - // `length` is the number of random accounts generated. - fn new(length: usize) -> Self { - let mut accounts = BTreeMap::new(); - - for n in 0..length { - let seed = format!("//endowed-user/{}", n); - let pair = sr25519::Pair::from_string(&seed, None).expect("failed to generate pair"); - let account_id = AccountPublic::from(pair.public()).into_account(); - accounts.insert(account_id, pair); - } - - Self { accounts } - } - - fn collect_account_ids(&self) -> Vec { - self.accounts.keys().cloned().collect() - } - - fn at(&self, index: usize) -> AccountId { - self.accounts.keys().nth(index).expect("Failed to get account").clone() - } - - fn sign(&self, xt: CheckedExtrinsic, version: u32, genesis_hash: [u8; 32]) -> UncheckedExtrinsic { - match xt.signed { - Some((signed, extra)) => { - let payload = (xt.function, extra.clone(), version, genesis_hash, genesis_hash); - let key = self.accounts.get(&signed).expect("Account id not found in keyring"); - let signature = payload.using_encoded(|b| { - if b.len() > 256 { - key.sign(&sp_io::hashing::blake2_256(b)) - } else { - key.sign(b) - } - }).into(); - UncheckedExtrinsic { - signature: Some((pallet_indices::address::Address::Id(signed), signature, extra)), - function: payload.0, - } - } - None => UncheckedExtrinsic { - signature: None, - function: xt.function, - }, - } - } -} - -#[derive(Clone, Copy, Debug)] -enum Profile { - Native, - Wasm, -} - -impl Profile { - fn into_execution_strategies(self) -> ExecutionStrategies { - match self { - Profile::Wasm => ExecutionStrategies { - syncing: ExecutionStrategy::AlwaysWasm, - importing: ExecutionStrategy::AlwaysWasm, - block_construction: ExecutionStrategy::AlwaysWasm, - offchain_worker: ExecutionStrategy::AlwaysWasm, - other: ExecutionStrategy::AlwaysWasm, - }, - Profile::Native => ExecutionStrategies { - syncing: ExecutionStrategy::NativeElseWasm, - importing: ExecutionStrategy::NativeElseWasm, - block_construction: ExecutionStrategy::NativeElseWasm, - offchain_worker: ExecutionStrategy::NativeElseWasm, - other: ExecutionStrategy::NativeElseWasm, - } - } - } -} - -// This should return client that is doing everything that full node -// is doing. -// -// - This client should use best wasm execution method. -// - This client should work with real database only. -fn bench_client(dir: &std::path::Path, profile: Profile, keyring: &BenchKeyring) -> (Client, std::sync::Arc) { - let db_config = sc_client_db::DatabaseSettings { - state_cache_size: 16*1024*1024, - state_cache_child_ratio: Some((0, 100)), - pruning: PruningMode::ArchiveAll, - source: sc_client_db::DatabaseSettingsSrc::Path { - path: dir.into(), - cache_size: None, - }, - }; - - let (client, backend) = sc_client_db::new_client( - db_config, - NativeExecutor::new(WasmExecutionMethod::Compiled, None), - &genesis(keyring), - None, - None, - ExecutionExtensions::new(profile.into_execution_strategies(), None), - ).expect("Should not fail"); - - (client, backend) -} - -struct Guard(tempdir::TempDir); - -impl Guard { - fn path(&self) -> &Path { - self.0.path() - } -} - -struct BenchContext { - client: Client, - backend: Arc, - db_guard: Guard, -} - -type AccountPublic = ::Signer; - -pub fn get_from_seed(seed: &str) -> ::Public { - TPublic::Pair::from_string(&format!("//{}", seed), None) - .expect("static values are valid; qed") - .public() -} - -pub fn get_account_id_from_seed(seed: &str) -> AccountId -where - AccountPublic: From<::Public> -{ - AccountPublic::from(get_from_seed::(seed)).into_account() -} - -// Import generated block. -fn import_block(client: &mut Client, block: Block) { - let mut import_params = BlockImportParams::new(BlockOrigin::NetworkBroadcast, block.header.clone()); - import_params.body = Some(block.extrinsics().to_vec()); - import_params.fork_choice = Some(ForkChoiceStrategy::LongestChain); - - assert_eq!(client.chain_info().best_number, 0); - - assert_eq!( - client.import_block(import_params, Default::default()) - .expect("Failed to import block"), - ImportResult::Imported( - ImportedAux { - header_only: false, - clear_justification_requests: false, - needs_justification: false, - bad_justification: false, - needs_finality_proof: false, - is_new_best: true, - } - ) - ); - - assert_eq!(client.chain_info().best_number, 1); -} - fn bench_block_import(c: &mut Criterion) { sc_cli::init_logger(""); // for future uses, uncomment if something wrong. // sc_cli::init_logger("sc_client=debug"); let mut bench_db = BenchDb::new(128); - let block = bench_db.generate_block(); + let block = bench_db.generate_block(100); log::trace!( target: "bench-logistics", @@ -438,14 +73,14 @@ fn bench_block_import(c: &mut Criterion) { log::trace!( target: "bench-logistics", "Next iteration database directory: {}, runtime version: {}", - context.db_guard.0.path().to_string_lossy(), version, + context.path().display(), version, ); context }, |mut context| { let start = std::time::Instant::now(); - import_block(&mut context.client, block.clone()); + context.import_block(block.clone()); let elapsed = start.elapsed(); log::info!( @@ -469,7 +104,6 @@ fn bench_block_import(c: &mut Criterion) { ); } - // This is not an actual benchmark, so don't use it to measure anything. // It just produces special pattern of cpu load that allows easy picking // the part of block import for the profiling in the tool of choice. @@ -477,7 +111,7 @@ fn profile_block_import(c: &mut Criterion) { sc_cli::init_logger(""); let mut bench_db = BenchDb::new(128); - let block = bench_db.generate_block(); + let block = bench_db.generate_block(100); c.bench_function("profile block", move |bencher| { @@ -490,7 +124,7 @@ fn profile_block_import(c: &mut Criterion) { // in rust, we just pause everything completely to help choosing // actual profiling interval std::thread::park_timeout(std::time::Duration::from_secs(2)); - import_block(&mut context.client, block.clone()); + context.import_block(block.clone()); // and here as well std::thread::park_timeout(std::time::Duration::from_secs(2)); log::info!( diff --git a/bin/node/testing/src/bench.rs b/bin/node/testing/src/bench.rs new file mode 100644 index 0000000000..5653ba7701 --- /dev/null +++ b/bin/node/testing/src/bench.rs @@ -0,0 +1,424 @@ +// Copyright 2019-2020 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 . + +//! Benchmarking module. +//! +//! Utilities to do full-scale benchmarks involving database. With `BenchDb` you +//! can pregenerate seed database and `clone` it for every iteration of your benchmarks +//! or tests to get consistent, smooth benchmark experience! + +use std::{sync::Arc, path::Path, collections::BTreeMap}; + +use node_primitives::Block; +use crate::client::{Client, Backend}; +use crate::keyring::*; +use sc_client_db::PruningMode; +use sc_executor::{NativeExecutor, WasmExecutionMethod}; +use sp_consensus::{ + BlockOrigin, BlockImport, BlockImportParams, + ForkChoiceStrategy, ImportResult, ImportedAux +}; +use sp_runtime::{ + generic::BlockId, + OpaqueExtrinsic, + traits::{Block as BlockT, Verify, Zero, IdentifyAccount}, +}; +use codec::{Decode, Encode}; +use node_runtime::{ + Call, + CheckedExtrinsic, + constants::currency::DOLLARS, + UncheckedExtrinsic, + MinimumPeriod, + BalancesCall, + AccountId, + Signature, +}; +use sp_core::ExecutionContext; +use sp_api::ProvideRuntimeApi; +use sp_block_builder::BlockBuilder; +use sp_inherents::InherentData; +use sc_client_api::{ + ExecutionStrategy, + execution_extensions::{ExecutionExtensions, ExecutionStrategies}, +}; +use sp_core::{Pair, Public, sr25519}; + +/// Keyring full of accounts for benching. +/// +/// Accounts are ordered: +/// //endowed-user//00 +/// //endowed-user//01 +/// ... +/// //endowed-user//N +#[derive(Clone)] +pub struct BenchKeyring { + accounts: BTreeMap, +} + +/// Pre-initialized benchmarking database. +/// +/// This is prepared database with genesis and keyring +/// that can be cloned and then used for any benchmarking. +pub struct BenchDb { + keyring: BenchKeyring, + directory_guard: Guard, +} + +impl Clone for BenchDb { + fn clone(&self) -> Self { + let keyring = self.keyring.clone(); + let dir = tempdir::TempDir::new("sub-bench").expect("temp dir creation failed"); + + let seed_dir = self.directory_guard.0.path(); + + log::trace!( + target: "bench-logistics", + "Copying seed db from {} to {}", + seed_dir.to_string_lossy(), + dir.path().to_string_lossy(), + ); + let seed_db_files = std::fs::read_dir(seed_dir) + .expect("failed to list file in seed dir") + .map(|f_result| + f_result.expect("failed to read file in seed db") + .path() + .clone() + ).collect(); + fs_extra::copy_items( + &seed_db_files, + dir.path(), + &fs_extra::dir::CopyOptions::new(), + ).expect("Copy of seed database is ok"); + + BenchDb { keyring, directory_guard: Guard(dir) } + } +} + +impl BenchDb { + /// New immutable benchmarking database. + /// + /// This will generate database files in random temporary directory + /// and keep it there until struct is dropped. + /// + /// You can `clone` this database or you can `create_context` from it + /// (which also do `clone`) to run actual operation against new database + /// which will be identical to this. + pub fn new(keyring_length: usize) -> Self { + let keyring = BenchKeyring::new(keyring_length); + + let dir = tempdir::TempDir::new("sub-bench").expect("temp dir creation failed"); + log::trace!( + target: "bench-logistics", + "Created seed db at {}", + dir.path().to_string_lossy(), + ); + let (_client, _backend) = Self::bench_client(dir.path(), Profile::Native, &keyring); + let directory_guard = Guard(dir); + + BenchDb { keyring, directory_guard } + } + + // This should return client that is doing everything that full node + // is doing. + // + // - This client should use best wasm execution method. + // - This client should work with real database only. + fn bench_client(dir: &std::path::Path, profile: Profile, keyring: &BenchKeyring) -> (Client, std::sync::Arc) { + let db_config = sc_client_db::DatabaseSettings { + state_cache_size: 16*1024*1024, + state_cache_child_ratio: Some((0, 100)), + pruning: PruningMode::ArchiveAll, + source: sc_client_db::DatabaseSettingsSrc::Path { + path: dir.into(), + cache_size: None, + }, + }; + + let (client, backend) = sc_client_db::new_client( + db_config, + NativeExecutor::new(WasmExecutionMethod::Compiled, None), + &keyring.generate_genesis(), + None, + None, + ExecutionExtensions::new(profile.into_execution_strategies(), None), + ).expect("Should not fail"); + + (client, backend) + } + + /// Generate new block using this database. + pub fn generate_block(&mut self, transactions: usize) -> Block { + let (client, _backend) = Self::bench_client( + self.directory_guard.path(), + Profile::Wasm, + &self.keyring, + ); + + let version = client.runtime_version_at(&BlockId::number(0)) + .expect("There should be runtime version at 0") + .spec_version; + + let genesis_hash = client.block_hash(Zero::zero()) + .expect("Database error?") + .expect("Genesis block always exists; qed") + .into(); + + let mut block = client + .new_block(Default::default()) + .expect("Block creation failed"); + + let timestamp = 1 * MinimumPeriod::get(); + + let mut inherent_data = InherentData::new(); + inherent_data.put_data(sp_timestamp::INHERENT_IDENTIFIER, ×tamp) + .expect("Put timestamp failed"); + inherent_data.put_data(sp_finality_tracker::INHERENT_IDENTIFIER, &0) + .expect("Put finality tracker failed"); + + for extrinsic in client.runtime_api() + .inherent_extrinsics_with_context( + &BlockId::number(0), + ExecutionContext::BlockConstruction, + inherent_data, + ).expect("Get inherents failed") + { + block.push(extrinsic).expect("Push inherent failed"); + } + + let mut iteration = 0; + let start = std::time::Instant::now(); + for _ in 0..transactions { + + let sender = self.keyring.at(iteration); + let receiver = get_account_id_from_seed::( + &format!("random-user//{}", iteration) + ); + + let signed = self.keyring.sign( + CheckedExtrinsic { + signed: Some((sender, signed_extra(0, 1*DOLLARS))), + function: Call::Balances( + BalancesCall::transfer( + pallet_indices::address::Address::Id(receiver), + 1*DOLLARS + ) + ), + }, + version, + genesis_hash, + ); + + let encoded = Encode::encode(&signed); + + let opaque = OpaqueExtrinsic::decode(&mut &encoded[..]) + .expect("Failed to decode opaque"); + + match block.push(opaque) { + Err(sp_blockchain::Error::ApplyExtrinsicFailed( + sp_blockchain::ApplyExtrinsicFailed::Validity(e) + )) if e.exhausted_resources() => { + break; + }, + Err(err) => panic!("Error pushing transaction: {:?}", err), + Ok(_) => {}, + } + iteration += 1; + } + let block = block.build().expect("Block build failed").block; + + log::info!( + target: "bench-logistics", + "Block construction: {:#?} ({} tx)", + start.elapsed(), block.extrinsics.len() + ); + + block + } + + /// Database path. + pub fn path(&self) -> &Path { + self.directory_guard.path() + } + + /// Clone this database and create context for testing/benchmarking. + pub fn create_context(&self, profile: Profile) -> BenchContext { + let BenchDb { directory_guard, keyring } = self.clone(); + let (client, backend) = Self::bench_client(directory_guard.path(), profile, &keyring); + + BenchContext { + client, backend, db_guard: directory_guard, + } + } +} + +impl BenchKeyring { + /// New keyring. + /// + /// `length` is the number of accounts generated. + pub fn new(length: usize) -> Self { + let mut accounts = BTreeMap::new(); + + for n in 0..length { + let seed = format!("//endowed-user/{}", n); + let pair = sr25519::Pair::from_string(&seed, None).expect("failed to generate pair"); + let account_id = AccountPublic::from(pair.public()).into_account(); + accounts.insert(account_id, pair); + } + + Self { accounts } + } + + /// Generated account id-s from keyring keypairs. + pub fn collect_account_ids(&self) -> Vec { + self.accounts.keys().cloned().collect() + } + + /// Get account id at position `index` + pub fn at(&self, index: usize) -> AccountId { + self.accounts.keys().nth(index).expect("Failed to get account").clone() + } + + /// Sign transaction with keypair from this keyring. + pub fn sign(&self, xt: CheckedExtrinsic, version: u32, genesis_hash: [u8; 32]) -> UncheckedExtrinsic { + match xt.signed { + Some((signed, extra)) => { + let payload = (xt.function, extra.clone(), version, genesis_hash, genesis_hash); + let key = self.accounts.get(&signed).expect("Account id not found in keyring"); + let signature = payload.using_encoded(|b| { + if b.len() > 256 { + key.sign(&sp_io::hashing::blake2_256(b)) + } else { + key.sign(b) + } + }).into(); + UncheckedExtrinsic { + signature: Some((pallet_indices::address::Address::Id(signed), signature, extra)), + function: payload.0, + } + } + None => UncheckedExtrinsic { + signature: None, + function: xt.function, + }, + } + } + + /// Generate genesis with accounts from this keyring endowed with some balance. + pub fn generate_genesis(&self) -> node_runtime::GenesisConfig { + crate::genesis::config_endowed( + false, + Some(node_runtime::WASM_BINARY), + self.collect_account_ids(), + ) + } +} + +/// Profile for exetion strategies. +#[derive(Clone, Copy, Debug)] +pub enum Profile { + /// As native as possible. + Native, + /// As wasm as possible. + Wasm, +} + +impl Profile { + fn into_execution_strategies(self) -> ExecutionStrategies { + match self { + Profile::Wasm => ExecutionStrategies { + syncing: ExecutionStrategy::AlwaysWasm, + importing: ExecutionStrategy::AlwaysWasm, + block_construction: ExecutionStrategy::AlwaysWasm, + offchain_worker: ExecutionStrategy::AlwaysWasm, + other: ExecutionStrategy::AlwaysWasm, + }, + Profile::Native => ExecutionStrategies { + syncing: ExecutionStrategy::NativeElseWasm, + importing: ExecutionStrategy::NativeElseWasm, + block_construction: ExecutionStrategy::NativeElseWasm, + offchain_worker: ExecutionStrategy::NativeElseWasm, + other: ExecutionStrategy::NativeElseWasm, + } + } + } +} + +struct Guard(tempdir::TempDir); + +impl Guard { + fn path(&self) -> &Path { + self.0.path() + } +} + +/// Benchmarking/test context holding instantiated client and backend references. +pub struct BenchContext { + /// Node client. + pub client: Client, + /// Node backend. + pub backend: Arc, + + db_guard: Guard, +} + +type AccountPublic = ::Signer; + +fn get_from_seed(seed: &str) -> ::Public { + TPublic::Pair::from_string(&format!("//{}", seed), None) + .expect("static values are valid; qed") + .public() +} + +fn get_account_id_from_seed(seed: &str) -> AccountId +where + AccountPublic: From<::Public> +{ + AccountPublic::from(get_from_seed::(seed)).into_account() +} + +impl BenchContext { + /// Import some block. + pub fn import_block(&mut self, block: Block) { + let mut import_params = BlockImportParams::new(BlockOrigin::NetworkBroadcast, block.header.clone()); + import_params.body = Some(block.extrinsics().to_vec()); + import_params.fork_choice = Some(ForkChoiceStrategy::LongestChain); + + assert_eq!(self.client.chain_info().best_number, 0); + + assert_eq!( + self.client.import_block(import_params, Default::default()) + .expect("Failed to import block"), + ImportResult::Imported( + ImportedAux { + header_only: false, + clear_justification_requests: false, + needs_justification: false, + bad_justification: false, + needs_finality_proof: false, + is_new_best: true, + } + ) + ); + + assert_eq!(self.client.chain_info().best_number, 1); + } + + /// Database path for the current context. + pub fn path(&self) -> &Path { + self.db_guard.path() + } +} diff --git a/bin/node/testing/src/lib.rs b/bin/node/testing/src/lib.rs index f4a5e75e49..6a06d31801 100644 --- a/bin/node/testing/src/lib.rs +++ b/bin/node/testing/src/lib.rs @@ -21,4 +21,4 @@ pub mod client; pub mod genesis; pub mod keyring; - +pub mod bench; -- GitLab From 7242c7e14e2f20e31a37032cf1066a5fb2f9f1c4 Mon Sep 17 00:00:00 2001 From: Cecile Tonglet Date: Tue, 18 Feb 2020 11:11:16 +0100 Subject: [PATCH 171/180] Make GenesisSource thread-safe (#4960) This change makes service's Configuration and GenesisSource thread-safe. Related to: https://github.com/paritytech/cumulus/issues/44 Forked at: 099cd0f2ba2a041f087978ef9d53473d0a6d0aee Parent branch: origin/master --- client/chain-spec/src/chain_spec.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/chain-spec/src/chain_spec.rs b/client/chain-spec/src/chain_spec.rs index 696fef5664..ab9c851bdd 100644 --- a/client/chain-spec/src/chain_spec.rs +++ b/client/chain-spec/src/chain_spec.rs @@ -20,7 +20,7 @@ use std::borrow::Cow; use std::collections::HashMap; use std::fs::File; use std::path::PathBuf; -use std::rc::Rc; +use std::sync::Arc; use serde::{Serialize, Deserialize}; use sp_core::storage::{StorageKey, StorageData, ChildInfo, Storage, StorageChild}; use sp_runtime::BuildStorage; @@ -32,7 +32,7 @@ use sc_telemetry::TelemetryEndpoints; enum GenesisSource { File(PathBuf), Binary(Cow<'static, [u8]>), - Factory(Rc G>), + Factory(Arc G + Send + Sync>), } impl Clone for GenesisSource { @@ -215,7 +215,7 @@ impl ChainSpec { } /// Create hardcoded spec. - pub fn from_genesis G + 'static>( + pub fn from_genesis G + 'static + Send + Sync>( name: &str, id: &str, constructor: F, @@ -239,7 +239,7 @@ impl ChainSpec { ChainSpec { client_spec, - genesis: GenesisSource::Factory(Rc::new(constructor)), + genesis: GenesisSource::Factory(Arc::new(constructor)), } } } -- GitLab From 9b33c4715bedc143e22fb0a5819d0d1810302472 Mon Sep 17 00:00:00 2001 From: Toralf Wittner Date: Tue, 18 Feb 2020 15:08:25 +0100 Subject: [PATCH 172/180] Remove direct yamux dependency. (#4968) libp2p-0.16 allows configuring yamux through libp2p-yamux, so the direct dependency is no longer needed. While at it we also update to the latest versions of yamux and nohash-hasher, though the code changes do not depend on it. --- Cargo.lock | 9 ++++----- client/network/Cargo.toml | 3 +-- client/network/src/transport.rs | 19 ++++++++----------- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 144cc495e5..2e8e4d59f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3721,9 +3721,9 @@ checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" [[package]] name = "nohash-hasher" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721a2bf1c26159ebf17e0a980bc4ce61f4b2fec5ec3b42d42fddd7a84a9e538f" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" [[package]] name = "nom" @@ -6204,7 +6204,6 @@ dependencies = [ "unsigned-varint", "void", "wasm-timer", - "yamux", "zeroize 1.1.0", ] @@ -9127,9 +9126,9 @@ checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" [[package]] name = "yamux" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "902f4cee32c401c211b6b69f4a3f6f4cf3515644db5bd822cf685a7dbd6201f9" +checksum = "d73295bc9d9acf89dd9336b3b5f5b57731ee72b587857dd4312721a0196b48e5" dependencies = [ "bytes 0.5.4", "futures 0.3.4", diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index f2d50b988a..e53ba13c8d 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -27,7 +27,7 @@ linked-hash-map = "0.5.2" linked_hash_set = "0.1.3" log = "0.4.8" lru = "0.4.0" -nohash-hasher = "0.1.3" +nohash-hasher = "0.2.0" parking_lot = "0.10.0" prost = "0.6.1" rand = "0.7.2" @@ -54,7 +54,6 @@ thiserror = "1" unsigned-varint = { version = "0.3.0", features = ["futures-codec"] } void = "1.0.2" zeroize = "1.0.0" -yamux = "0.4.2" [dev-dependencies] async-std = "1.5" diff --git a/client/network/src/transport.rs b/client/network/src/transport.rs index e2c95824f8..ba0face137 100644 --- a/client/network/src/transport.rs +++ b/client/network/src/transport.rs @@ -57,17 +57,14 @@ pub fn build_transport( mplex_config.max_buffer_len_behaviour(mplex::MaxBufferBehaviour::Block); mplex_config.max_buffer_len(usize::MAX); - let yamux_config = { - let mut c = yamux::Config::default(); - // Only set SYN flag on first data frame sent to the remote. - c.set_lazy_open(true); - if use_yamux_flow_control { - // Enable proper flow-control: window updates are only sent when - // buffered data has been consumed. - c.set_window_update_mode(yamux::WindowUpdateMode::OnRead); - } - libp2p::yamux::Config::new(c) - }; + let mut yamux_config = libp2p::yamux::Config::default(); + yamux_config.set_lazy_open(true); // Only set SYN flag on first data frame sent to the remote. + + if use_yamux_flow_control { + // Enable proper flow-control: window updates are only sent when + // buffered data has been consumed. + yamux_config.set_window_update_mode(libp2p::yamux::WindowUpdateMode::OnRead); + } // Build the base layer of the transport. let transport = if let Some(t) = wasm_external_transport { -- GitLab From e312eba8b96d99146f0890cab67005aac6e51123 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= Date: Tue, 18 Feb 2020 14:11:44 +0000 Subject: [PATCH 173/180] sync: process empty response for justification requests (#4957) * sync: process empty response for justification request * sync: add test for justification request empty response * network: remove deprecated comment --- client/network/src/protocol.rs | 2 - client/network/src/protocol/sync.rs | 113 ++++++++++++++++-- .../src/protocol/sync/extra_requests.rs | 12 ++ 3 files changed, 118 insertions(+), 9 deletions(-) diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 9e098c27e9..d5e7ae6252 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -864,8 +864,6 @@ impl, H: ExHashT> Protocol { blocks_range ); - // TODO [andre]: move this logic to the import queue so that - // justifications are imported asynchronously (#1482) if request.fields == message::BlockAttributes::JUSTIFICATION { match self.sync.on_block_justification(peer, response) { Ok(sync::OnBlockJustification::Nothing) => CustomMessageOutcome::None, diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index 3b909b3303..88e663c904 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -813,7 +813,7 @@ impl ChainSync { peer.state = PeerSyncState::Available; // We only request one justification at a time - if let Some(block) = response.blocks.into_iter().next() { + let justification = if let Some(block) = response.blocks.into_iter().next() { if hash != block.hash { info!( target: "sync", @@ -821,13 +821,22 @@ impl ChainSync { ); 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 }) - } + + block.justification } else { - // we might have asked the peer for a justification on a block that we thought it had - // (regardless of whether it had a justification for it or not). - trace!(target: "sync", "Peer {:?} provided empty response for justification request {:?}", who, hash) + // we might have asked the peer for a justification on a block that we assumed it + // had but didn't (regardless of whether it had a justification for it or not). + trace!(target: "sync", + "Peer {:?} provided empty response for justification request {:?}", + who, + hash, + ); + + None + }; + + if let Some((peer, hash, number, j)) = self.extra_justifications.on_response(who, justification) { + return Ok(OnBlockJustification::Import { peer, hash, number, justification: j }) } } @@ -1353,3 +1362,93 @@ fn fork_sync_request( } None } + +#[cfg(test)] +mod test { + use super::*; + use super::message::FromBlock; + use substrate_test_runtime_client::{ + runtime::Block, + DefaultTestClientBuilderExt, TestClientBuilder, TestClientBuilderExt, + }; + use sp_blockchain::HeaderBackend; + use sp_consensus::block_validation::DefaultBlockAnnounceValidator; + + #[test] + fn processes_empty_response_on_justification_request_for_unknown_block() { + // if we ask for a justification for a given block to a peer that doesn't know that block + // (different from not having a justification), the peer will reply with an empty response. + // internally we should process the response as the justification not being available. + + let client = Arc::new(TestClientBuilder::new().build()); + let info = client.info(); + let block_announce_validator = Box::new(DefaultBlockAnnounceValidator::new(client.clone())); + let peer_id = PeerId::random(); + + let mut sync = ChainSync::new( + Roles::AUTHORITY, + client.clone(), + &info, + None, + block_announce_validator, + 1, + ); + + let (a1_hash, a1_number) = { + let a1 = client.new_block(Default::default()).unwrap().build().unwrap().block; + (a1.hash(), *a1.header.number()) + }; + + // add a new peer with the same best block + sync.new_peer(peer_id.clone(), a1_hash, a1_number).unwrap(); + + // and request a justification for the block + sync.request_justification(&a1_hash, a1_number); + + // the justification request should be scheduled to that peer + assert!( + sync.justification_requests().any(|(who, request)| { + who == peer_id && request.from == FromBlock::Hash(a1_hash) + }) + ); + + // there are no extra pending requests + assert_eq!( + sync.extra_justifications.pending_requests().count(), + 0, + ); + + // there's one in-flight extra request to the expected peer + assert!( + sync.extra_justifications.active_requests().any(|(who, (hash, number))| { + *who == peer_id && *hash == a1_hash && *number == a1_number + }) + ); + + // if the peer replies with an empty response (i.e. it doesn't know the block), + // the active request should be cleared. + assert_eq!( + sync.on_block_justification( + peer_id.clone(), + BlockResponse:: { + id: 0, + blocks: vec![], + } + ), + Ok(OnBlockJustification::Nothing), + ); + + // there should be no in-flight requests + assert_eq!( + sync.extra_justifications.active_requests().count(), + 0, + ); + + // and the request should now be pending again, waiting for reschedule + assert!( + sync.extra_justifications.pending_requests().any(|(hash, number)| { + *hash == a1_hash && *number == a1_number + }) + ); + } +} diff --git a/client/network/src/protocol/sync/extra_requests.rs b/client/network/src/protocol/sync/extra_requests.rs index 19c6b50743..38c250cddf 100644 --- a/client/network/src/protocol/sync/extra_requests.rs +++ b/client/network/src/protocol/sync/extra_requests.rs @@ -228,6 +228,18 @@ impl ExtraRequests { true } + + /// Returns an iterator over all active (in-flight) requests and associated peer id. + #[cfg(test)] + pub(crate) fn active_requests(&self) -> impl Iterator)> { + self.active_requests.iter() + } + + /// Returns an iterator over all scheduled pending requests. + #[cfg(test)] + pub(crate) fn pending_requests(&self) -> impl Iterator> { + self.pending_requests.iter() + } } /// Matches peers with pending extra requests. -- GitLab From 6f05ef203ade29ac8b909cb4584c22f75ea9b54a Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Tue, 18 Feb 2020 17:19:59 +0300 Subject: [PATCH 174/180] Fix flaky finalisation test (#4967) --- client/transaction-pool/src/testing/pool.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/client/transaction-pool/src/testing/pool.rs b/client/transaction-pool/src/testing/pool.rs index c194a8615b..37b80df9e1 100644 --- a/client/transaction-pool/src/testing/pool.rs +++ b/client/transaction-pool/src/testing/pool.rs @@ -515,8 +515,15 @@ fn fork_aware_finalization() { assert_eq!(stream.next(), Some(TransactionStatus::Ready)); assert_eq!(stream.next(), Some(TransactionStatus::InBlock(c2.clone()))); assert_eq!(stream.next(), Some(TransactionStatus::Retracted(c2))); - assert_eq!(stream.next(), Some(TransactionStatus::Ready)); - assert_eq!(stream.next(), Some(TransactionStatus::InBlock(e1))); + + // can be either Ready, or InBlock, depending on which event comes first + assert_eq!( + match stream.next() { + Some(TransactionStatus::Ready) => stream.next(), + val @ _ => val, + }, + Some(TransactionStatus::InBlock(e1)), + ); assert_eq!(stream.next(), Some(TransactionStatus::Finalized(e1.clone()))); assert_eq!(stream.next(), None); } -- GitLab From 297e649549c5017633c0a6aaf9572d508f0a2fc2 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Tue, 18 Feb 2020 15:27:17 +0100 Subject: [PATCH 175/180] Use a single version of once_cell (#4966) --- Cargo.lock | 94 ++++++++----------------------------- bin/utils/subkey/Cargo.toml | 2 +- frame/support/Cargo.toml | 2 +- primitives/core/Cargo.toml | 2 +- 4 files changed, 23 insertions(+), 77 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e8e4d59f8..eca9c8f1fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -189,7 +189,7 @@ dependencies = [ "mio", "mio-uds", "num_cpus", - "once_cell 1.3.1", + "once_cell", "pin-project-lite", "pin-utils", "slab", @@ -933,7 +933,7 @@ dependencies = [ "crossbeam-utils", "lazy_static", "memoffset", - "scopeguard 1.0.0", + "scopeguard", ] [[package]] @@ -1479,7 +1479,7 @@ dependencies = [ "frame-system", "impl-trait-for-tuples", "log 0.4.8", - "once_cell 0.2.4", + "once_cell", "parity-scale-codec", "paste", "pretty_assertions", @@ -2007,16 +2007,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "hashbrown" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" -dependencies = [ - "byteorder 1.3.4", - "scopeguard 0.3.3", -] - [[package]] name = "hashbrown" version = "0.5.0" @@ -3110,22 +3100,13 @@ dependencies = [ "linked-hash-map", ] -[[package]] -name = "lock_api" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" -dependencies = [ - "scopeguard 0.3.3", -] - [[package]] name = "lock_api" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b" dependencies = [ - "scopeguard 1.0.0", + "scopeguard", ] [[package]] @@ -3797,26 +3778,14 @@ dependencies = [ "winapi-build", ] -[[package]] -name = "once_cell" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37" -dependencies = [ - "parking_lot 0.7.1", -] - -[[package]] -name = "once_cell" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d584f08c2d717d5c23a6414fc2822b71c651560713e54fa7eace675f758a355e" - [[package]] name = "once_cell" version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b" +dependencies = [ + "parking_lot 0.9.0", +] [[package]] name = "oorandom" @@ -4664,23 +4633,13 @@ version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" -[[package]] -name = "parking_lot" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" -dependencies = [ - "lock_api 0.1.5", - "parking_lot_core 0.4.0", -] - [[package]] name = "parking_lot" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" dependencies = [ - "lock_api 0.3.3", + "lock_api", "parking_lot_core 0.6.2", "rustc_version", ] @@ -4691,23 +4650,10 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" dependencies = [ - "lock_api 0.3.3", + "lock_api", "parking_lot_core 0.7.0", ] -[[package]] -name = "parking_lot_core" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" -dependencies = [ - "libc", - "rand 0.6.5", - "rustc_version", - "smallvec 0.6.13", - "winapi 0.3.8", -] - [[package]] name = "parking_lot_core" version = "0.6.2" @@ -5447,6 +5393,12 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc-hex" version = "2.1.0" @@ -6574,12 +6526,6 @@ dependencies = [ "zeroize 0.9.3", ] -[[package]] -name = "scopeguard" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" - [[package]] name = "scopeguard" version = "1.0.0" @@ -7947,16 +7893,16 @@ dependencies = [ [[package]] name = "tiny-bip39" -version = "0.6.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1c5676413eaeb1ea35300a0224416f57abc3bd251657e0fafc12c47ff98c060" +checksum = "1cd1fb03fe8e07d17cd851a624a9fff74642a997b67fbd1ccd77533241640d92" dependencies = [ "failure", - "hashbrown 0.1.8", "hmac", - "once_cell 0.1.8", + "once_cell", "pbkdf2", - "rand 0.6.5", + "rand 0.7.3", + "rustc-hash", "sha2", ] diff --git a/bin/utils/subkey/Cargo.toml b/bin/utils/subkey/Cargo.toml index ce3303c946..8267366d7f 100644 --- a/bin/utils/subkey/Cargo.toml +++ b/bin/utils/subkey/Cargo.toml @@ -13,7 +13,7 @@ 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" +tiny-bip39 = "0.7" rustc-hex = "2.0.1" substrate-bip39 = "0.3.1" hex = "0.4.0" diff --git a/frame/support/Cargo.toml b/frame/support/Cargo.toml index f0e9b53bf2..b20f5c73bf 100644 --- a/frame/support/Cargo.toml +++ b/frame/support/Cargo.toml @@ -18,7 +18,7 @@ sp-arithmetic = { version = "2.0.0", default-features = false, path = "../../pri 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 } +once_cell = { version = "1", default-features = false, optional = true } sp-state-machine = { version = "0.8", optional = true, path = "../../primitives/state-machine" } bitmask = { version = "0.5.0", default-features = false } impl-trait-for-tuples = "0.1.3" diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 574b9aa9cb..3293769023 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -20,7 +20,7 @@ hash256-std-hasher = { version = "0.15.2", default-features = false } base58 = { version = "0.1.0", optional = true } rand = { version = "0.7.2", optional = true } substrate-bip39 = { version = "0.3.1", optional = true } -tiny-bip39 = { version = "0.6.2", optional = true } +tiny-bip39 = { version = "0.7", 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 } -- GitLab From c1a03a60f5c259ff5793809c4d43452cd409319c Mon Sep 17 00:00:00 2001 From: Ashley Date: Tue, 18 Feb 2020 16:18:32 +0100 Subject: [PATCH 176/180] Re-enable networking on wasm (#4880) * Use noise and timeouts on wasm * Don't use wasm-opt when compiling to wasm * Forgot lockfile * Add node about disabling wasm-opt * Enable timeouts in telemetry on wasm --- bin/node/cli/Cargo.toml | 5 ++++ .../src/protocol/light_client_handler.rs | 3 ++- client/network/src/transport.rs | 27 +++---------------- client/telemetry/src/worker.rs | 4 +-- 4 files changed, 13 insertions(+), 26 deletions(-) diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index dad76ae4bf..528d7e5faa 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -8,6 +8,11 @@ edition = "2018" license = "GPL-3.0" default-run = "substrate" +[package.metadata.wasm-pack.profile.release] +# `wasm-opt` has some problems on linux, see +# https://github.com/rustwasm/wasm-pack/issues/781 etc. +wasm-opt = false + [badges] travis-ci = { repository = "paritytech/substrate", branch = "master" } maintenance = { status = "actively-developed" } diff --git a/client/network/src/protocol/light_client_handler.rs b/client/network/src/protocol/light_client_handler.rs index b31877d928..77cf71408d 100644 --- a/client/network/src/protocol/light_client_handler.rs +++ b/client/network/src/protocol/light_client_handler.rs @@ -63,10 +63,11 @@ use std::{ iter, io, sync::Arc, - time::{Duration, Instant}, + time::Duration, task::{Context, Poll} }; use void::Void; +use wasm_timer::Instant; /// Configuration options for `LightClientHandler` behaviour. #[derive(Debug, Clone)] diff --git a/client/network/src/transport.rs b/client/network/src/transport.rs index ba0face137..75ee2d5db8 100644 --- a/client/network/src/transport.rs +++ b/client/network/src/transport.rs @@ -17,10 +17,10 @@ use futures::prelude::*; use libp2p::{ InboundUpgradeExt, OutboundUpgradeExt, PeerId, Transport, - mplex, identity, bandwidth, wasm_ext + mplex, identity, bandwidth, wasm_ext, noise }; #[cfg(not(target_os = "unknown"))] -use libp2p::{tcp, dns, websocket, noise}; +use libp2p::{tcp, dns, websocket}; use libp2p::core::{self, upgrade, transport::boxed::Boxed, transport::OptionalTransport, muxing::StreamMuxerBox}; use std::{io, sync::Arc, time::Duration, usize}; @@ -40,7 +40,6 @@ pub fn build_transport( use_yamux_flow_control: bool ) -> (Boxed<(PeerId, StreamMuxerBox), io::Error>, Arc) { // Build configuration objects for encryption mechanisms. - #[cfg(not(target_os = "unknown"))] let noise_config = { let noise_keypair = noise::Keypair::new().into_authentic(&keypair) // For more information about this panic, see in "On the Importance of Checking @@ -95,9 +94,6 @@ pub fn build_transport( let (transport, sinks) = bandwidth::BandwidthLogging::new(transport, Duration::from_secs(5)); // Encryption - - // For non-WASM, we support both secio and noise. - #[cfg(not(target_os = "unknown"))] let transport = transport.and_then(move |stream, endpoint| { core::upgrade::apply(stream, noise_config, endpoint, upgrade::Version::V1) .and_then(|(remote_id, out)| async move { @@ -109,15 +105,6 @@ pub fn build_transport( }) }); - // We refuse all WASM connections for now. It is intended that we negotiate noise in the - // future. See https://github.com/libp2p/rust-libp2p/issues/1414 - #[cfg(target_os = "unknown")] - let transport = transport.and_then(move |_, _| async move { - let r: Result<(wasm_ext::Connection, PeerId), _> = - Err(io::Error::new(io::ErrorKind::Other, format!("No encryption protocol supported"))); - r - }); - // Multiplexing let transport = transport.and_then(move |(stream, peer_id), endpoint| { let peer_id2 = peer_id.clone(); @@ -129,16 +116,10 @@ pub fn build_transport( .map_ok(|(id, muxer)| (id, core::muxing::StreamMuxerBox::new(muxer))) }); - let transport = if cfg!(not(target_os = "unknown")) { - transport + let transport = transport .timeout(Duration::from_secs(20)) .map_err(|err| io::Error::new(io::ErrorKind::Other, err)) - .boxed() - } else { - transport - .map_err(|err| io::Error::new(io::ErrorKind::Other, err)) - .boxed() - }; + .boxed(); (transport, sinks) } diff --git a/client/telemetry/src/worker.rs b/client/telemetry/src/worker.rs index ef1f9fa067..8f43bb612a 100644 --- a/client/telemetry/src/worker.rs +++ b/client/telemetry/src/worker.rs @@ -98,10 +98,10 @@ impl TelemetryWorker { .map_ok(|data| BytesMut::from(data.as_ref())); future::ready(Ok::<_, io::Error>(connec)) }) - }) - .timeout(CONNECT_TIMEOUT); + }); let transport = transport + .timeout(CONNECT_TIMEOUT) .map_err(|err| io::Error::new(io::ErrorKind::Other, err)) .map(|out, _| { let out = out -- GitLab From d9952dd5e23aceb3aa4dd181fcd3eb51031875af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Tue, 18 Feb 2020 17:56:52 +0100 Subject: [PATCH 177/180] Inspection extension to node CLI (#4697) * Initial inspect. * WiP * Add parsing tests. * Finalize CLI. * Update to latest substrate. * Remove unused imports. * Support ImportParams as well, to get the right pruning setting. * Mention in docs that hash is no 0x. * Move bytes above extrinsics. * Switch to fill helper from sc_cli. * Remove overwrite. * Fix error. * Fix error message. * Remove extra allow. * init_config --- Cargo.lock | 19 ++- bin/node/cli/Cargo.toml | 9 +- bin/node/cli/src/cli.rs | 15 ++- bin/node/cli/src/command.rs | 10 ++ bin/node/cli/src/lib.rs | 1 - bin/node/inspect/Cargo.toml | 17 +++ bin/node/inspect/src/cli.rs | 240 +++++++++++++++++++++++++++++++++++ bin/node/inspect/src/lib.rs | 204 +++++++++++++++++++++++++++++ client/service/src/config.rs | 2 +- primitives/core/Cargo.toml | 2 +- primitives/core/src/lib.rs | 9 ++ 11 files changed, 517 insertions(+), 11 deletions(-) create mode 100644 bin/node/inspect/Cargo.toml create mode 100644 bin/node/inspect/src/cli.rs create mode 100644 bin/node/inspect/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index eca9c8f1fd..b557048f9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3377,6 +3377,7 @@ dependencies = [ "log 0.4.8", "nix", "node-executor", + "node-inspect", "node-primitives", "node-rpc", "node-runtime", @@ -3463,6 +3464,22 @@ dependencies = [ "wabt", ] +[[package]] +name = "node-inspect" +version = "0.8.0" +dependencies = [ + "derive_more", + "log 0.4.8", + "parity-scale-codec", + "sc-cli", + "sc-client-api", + "sc-service", + "sp-blockchain", + "sp-core", + "sp-runtime", + "structopt", +] + [[package]] name = "node-primitives" version = "2.0.0" @@ -7047,7 +7064,7 @@ dependencies = [ "hash256-std-hasher", "hex", "hex-literal", - "impl-serde 0.2.3", + "impl-serde 0.3.0", "lazy_static", "libsecp256k1", "log 0.4.8", diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index 528d7e5faa..079e8d13e2 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -90,6 +90,7 @@ node-executor = { version = "2.0.0", path = "../executor" } # CLI-specific dependencies sc-cli = { version = "0.8.0", optional = true, path = "../../../client/cli" } node-transaction-factory = { version = "0.8.0", optional = true, path = "../transaction-factory" } +node-inspect = { version = "0.8.0", optional = true, path = "../inspect" } # WASM-specific dependencies wasm-bindgen = { version = "0.2.57", optional = true } @@ -110,6 +111,7 @@ nix = "0.17" build-script-utils = { version = "2.0.0", package = "substrate-build-script-utils", path = "../../../utils/build-script-utils" } structopt = { version = "0.3.8", optional = true } node-transaction-factory = { version = "0.8.0", optional = true, path = "../transaction-factory" } +node-inspect = { version = "0.8.0", optional = true, path = "../inspect" } [build-dependencies.sc-cli] version = "0.8.0" @@ -129,12 +131,13 @@ browser = [ "wasm-bindgen-futures", ] cli = [ - "sc-cli", + "node-executor/wasmi-errno", + "node-inspect", "node-transaction-factory", + "sc-cli", "sc-service/rocksdb", - "node-executor/wasmi-errno", - "vergen", "structopt", + "vergen", ] wasmtime = [ "cli", diff --git a/bin/node/cli/src/cli.rs b/bin/node/cli/src/cli.rs index 7844c2c0a5..7dcd02699d 100644 --- a/bin/node/cli/src/cli.rs +++ b/bin/node/cli/src/cli.rs @@ -17,7 +17,7 @@ use sc_cli::{SharedParams, ImportParams, RunCmd}; use structopt::StructOpt; -#[allow(missing_docs)] +/// An overarching CLI command definition. #[derive(Clone, Debug, StructOpt)] #[structopt(settings = &[ structopt::clap::AppSettings::GlobalVersion, @@ -25,7 +25,7 @@ use structopt::StructOpt; structopt::clap::AppSettings::SubcommandsNegateReqs, ])] pub struct Cli { - #[allow(missing_docs)] + /// Possible subcommand with parameters. #[structopt(subcommand)] pub subcommand: Option, #[allow(missing_docs)] @@ -33,10 +33,10 @@ pub struct Cli { pub run: RunCmd, } -#[allow(missing_docs)] +/// Possible subcommands of the main binary. #[derive(Clone, Debug, StructOpt)] pub enum Subcommand { - #[allow(missing_docs)] + /// A set of base subcommands handled by `sc_cli`. #[structopt(flatten)] Base(sc_cli::Subcommand), /// The custom factory subcommmand for manufacturing transactions. @@ -46,6 +46,13 @@ pub enum Subcommand { Only supported for development or local testnet." )] Factory(FactoryCmd), + + /// The custom inspect subcommmand for decoding blocks and extrinsics. + #[structopt( + name = "inspect", + about = "Decode given block or extrinsic using current native runtime." + )] + Inspect(node_inspect::cli::InspectCmd), } /// The `factory` command used to generate transactions. diff --git a/bin/node/cli/src/command.rs b/bin/node/cli/src/command.rs index 61d1051796..ba0f2785c1 100644 --- a/bin/node/cli/src/command.rs +++ b/bin/node/cli/src/command.rs @@ -39,6 +39,16 @@ where load_spec, &version, ), + Some(Subcommand::Inspect(cmd)) => { + cmd.init(&mut config, load_spec, &version)?; + + let client = sc_service::new_full_client::< + node_runtime::Block,node_runtime::RuntimeApi, node_executor::Executor, _, _, + >(&config)?; + let inspect = node_inspect::Inspector::::new(client); + + cmd.run(inspect) + }, Some(Subcommand::Factory(cli_args)) => { sc_cli::init(&cli_args.shared_params, &version)?; sc_cli::init_config(&mut config, &cli_args.shared_params, &version, load_spec)?; diff --git a/bin/node/cli/src/lib.rs b/bin/node/cli/src/lib.rs index f5b915a2be..789d6a6913 100644 --- a/bin/node/cli/src/lib.rs +++ b/bin/node/cli/src/lib.rs @@ -27,7 +27,6 @@ //! hasn't been tested. #![warn(missing_docs)] -#![warn(unused_extern_crates)] pub mod chain_spec; diff --git a/bin/node/inspect/Cargo.toml b/bin/node/inspect/Cargo.toml new file mode 100644 index 0000000000..cbce7e4589 --- /dev/null +++ b/bin/node/inspect/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "node-inspect" +version = "0.8.0" +authors = ["Parity Technologies "] +edition = "2018" + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.0.0" } +derive_more = "0.99" +log = "0.4.8" +sc-cli = { version = "0.8.0", path = "../../../client/cli" } +sc-client-api = { version = "2.0.0", path = "../../../client/api" } +sc-service = { version = "0.8", default-features = false, path = "../../../client/service" } +sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" } +sp-core = { version = "2.0.0", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0", path = "../../../primitives/runtime" } +structopt = "0.3.8" diff --git a/bin/node/inspect/src/cli.rs b/bin/node/inspect/src/cli.rs new file mode 100644 index 0000000000..27afcfff91 --- /dev/null +++ b/bin/node/inspect/src/cli.rs @@ -0,0 +1,240 @@ +// Copyright 2020 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 . + +//! Structs to easily compose inspect sub-command for CLI. + +use std::{ + fmt::Debug, + str::FromStr, +}; +use crate::{Inspector, PrettyPrinter}; +use sc_cli::{ImportParams, SharedParams, error}; +use structopt::StructOpt; + +/// The `inspect` command used to print decoded chain data. +#[derive(Debug, StructOpt, Clone)] +pub struct InspectCmd { + #[allow(missing_docs)] + #[structopt(flatten)] + pub command: InspectSubCmd, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub shared_params: SharedParams, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub import_params: ImportParams, +} + +/// A possible inspect sub-commands. +#[derive(Debug, StructOpt, Clone)] +pub enum InspectSubCmd { + /// Decode block with native version of runtime and print out the details. + Block { + /// Address of the block to print out. + /// + /// Can be either a block hash (no 0x prefix) or a number to retrieve existing block, + /// or a 0x-prefixed bytes hex string, representing SCALE encoding of + /// a block. + #[structopt(value_name = "HASH or NUMBER or BYTES")] + input: String, + }, + /// Decode extrinsic with native version of runtime and print out the details. + Extrinsic { + /// Address of an extrinsic to print out. + /// + /// Can be either a block hash (no 0x prefix) or number and the index, in the form + /// of `{block}:{index}` or a 0x-prefixed bytes hex string, + /// representing SCALE encoding of an extrinsic. + #[structopt(value_name = "BLOCK:INDEX or BYTES")] + input: String, + }, +} + +impl InspectCmd { + /// Parse CLI arguments and initialize given config. + pub fn init( + &self, + config: &mut sc_service::config::Configuration, + spec_factory: impl FnOnce(&str) -> Result>, String>, + version: &sc_cli::VersionInfo, + ) -> error::Result<()> where + G: sc_service::RuntimeGenesis, + E: sc_service::ChainSpecExtension, + { + sc_cli::init_config(config, &self.shared_params, version, spec_factory)?; + // make sure to configure keystore + sc_cli::fill_config_keystore_in_memory(config)?; + // and all import params (especially pruning that has to match db meta) + sc_cli::fill_import_params( + config, + &self.import_params, + sc_service::Roles::FULL, + self.shared_params.dev, + )?; + Ok(()) + } + + /// Run the inspect command, passing the inspector. + pub fn run( + self, + inspect: Inspector, + ) -> error::Result<()> where + B: sp_runtime::traits::Block, + B::Hash: FromStr, + P: PrettyPrinter, + { + match self.command { + InspectSubCmd::Block { input } => { + let input = input.parse()?; + let res = inspect.block(input) + .map_err(|e| format!("{}", e))?; + println!("{}", res); + Ok(()) + }, + InspectSubCmd::Extrinsic { input } => { + let input = input.parse()?; + let res = inspect.extrinsic(input) + .map_err(|e| format!("{}", e))?; + println!("{}", res); + Ok(()) + }, + } + } +} + + +/// A block to retrieve. +#[derive(Debug, Clone, PartialEq)] +pub enum BlockAddress { + /// Get block by hash. + Hash(Hash), + /// Get block by number. + Number(Number), + /// Raw SCALE-encoded bytes. + Bytes(Vec), +} + +impl FromStr for BlockAddress { + type Err = String; + + fn from_str(s: &str) -> Result { + // try to parse hash first + if let Ok(hash) = s.parse() { + return Ok(Self::Hash(hash)) + } + + // then number + if let Ok(number) = s.parse() { + return Ok(Self::Number(number)) + } + + // then assume it's bytes (hex-encoded) + sp_core::bytes::from_hex(s) + .map(Self::Bytes) + .map_err(|e| format!( + "Given string does not look like hash or number. It could not be parsed as bytes either: {}", + e + )) + } +} + +/// An extrinsic address to decode and print out. +#[derive(Debug, Clone, PartialEq)] +pub enum ExtrinsicAddress { + /// Extrinsic as part of existing block. + Block(BlockAddress, usize), + /// Raw SCALE-encoded extrinsic bytes. + Bytes(Vec), +} + +impl FromStr for ExtrinsicAddress { + type Err = String; + + fn from_str(s: &str) -> Result { + // first try raw bytes + if let Ok(bytes) = sp_core::bytes::from_hex(s).map(Self::Bytes) { + return Ok(bytes) + } + + // split by a bunch of different characters + let mut it = s.split(|c| c == '.' || c == ':' || c == ' '); + let block = it.next() + .expect("First element of split iterator is never empty; qed") + .parse()?; + + let index = it.next() + .ok_or_else(|| format!("Extrinsic index missing: example \"5:0\""))? + .parse() + .map_err(|e| format!("Invalid index format: {}", e))?; + + Ok(Self::Block(block, index)) + } +} + + +#[cfg(test)] +mod tests { + use super::*; + use sp_core::hash::H160 as Hash; + + #[test] + fn should_parse_block_strings() { + type BlockAddress = super::BlockAddress; + + let b0 = BlockAddress::from_str("3BfC20f0B9aFcAcE800D73D2191166FF16540258"); + let b1 = BlockAddress::from_str("1234"); + let b2 = BlockAddress::from_str("0"); + let b3 = BlockAddress::from_str("0x0012345f"); + + + assert_eq!(b0, Ok(BlockAddress::Hash( + "3BfC20f0B9aFcAcE800D73D2191166FF16540258".parse().unwrap() + ))); + assert_eq!(b1, Ok(BlockAddress::Number(1234))); + assert_eq!(b2, Ok(BlockAddress::Number(0))); + assert_eq!(b3, Ok(BlockAddress::Bytes(vec![0, 0x12, 0x34, 0x5f]))); + } + + #[test] + fn should_parse_extrinsic_address() { + type BlockAddress = super::BlockAddress; + type ExtrinsicAddress = super::ExtrinsicAddress; + + let e0 = ExtrinsicAddress::from_str("1234"); + let b0 = ExtrinsicAddress::from_str("3BfC20f0B9aFcAcE800D73D2191166FF16540258:5"); + let b1 = ExtrinsicAddress::from_str("1234:0"); + let b2 = ExtrinsicAddress::from_str("0 0"); + let b3 = ExtrinsicAddress::from_str("0x0012345f"); + + + assert_eq!(e0, Err("Extrinsic index missing: example \"5:0\"".into())); + assert_eq!(b0, Ok(ExtrinsicAddress::Block( + BlockAddress::Hash("3BfC20f0B9aFcAcE800D73D2191166FF16540258".parse().unwrap()), + 5 + ))); + assert_eq!(b1, Ok(ExtrinsicAddress::Block( + BlockAddress::Number(1234), + 0 + ))); + assert_eq!(b2, Ok(ExtrinsicAddress::Block( + BlockAddress::Number(0), + 0 + ))); + assert_eq!(b3, Ok(ExtrinsicAddress::Bytes(vec![0, 0x12, 0x34, 0x5f]))); + } +} diff --git a/bin/node/inspect/src/lib.rs b/bin/node/inspect/src/lib.rs new file mode 100644 index 0000000000..5c4e18c0a7 --- /dev/null +++ b/bin/node/inspect/src/lib.rs @@ -0,0 +1,204 @@ +// Copyright 2020 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 CLI extension for substrate node, adding sub-command to pretty print debug info +//! about blocks and extrinsics. +//! +//! The blocks and extrinsics can either be retrieved from the database (on-chain), +//! or a raw SCALE-encoding can be provided. + +#![warn(missing_docs)] + +pub mod cli; + +use std::{ + fmt, + marker::PhantomData +}; +use codec::{Encode, Decode}; +use sc_client_api::BlockBody; +use sp_blockchain::HeaderBackend; +use sp_core::hexdisplay::HexDisplay; +use sp_runtime::{ + generic::BlockId, + traits::{Block, HashFor, NumberFor, Hash} +}; + +/// A helper type for a generic block input. +pub type BlockAddressFor = cli::BlockAddress< + as Hash>::Output, + NumberFor +>; + +/// A Pretty formatter implementation. +pub trait PrettyPrinter { + /// Nicely format block. + fn fmt_block(&self, fmt: &mut fmt::Formatter, block: &TBlock) -> fmt::Result; + /// Nicely format extrinsic. + fn fmt_extrinsic(&self, fmt: &mut fmt::Formatter, extrinsic: &TBlock::Extrinsic) -> fmt::Result; +} + +/// Default dummy debug printer. +#[derive(Default)] +pub struct DebugPrinter; +impl PrettyPrinter for DebugPrinter { + fn fmt_block(&self, fmt: &mut fmt::Formatter, block: &TBlock) -> fmt::Result { + writeln!(fmt, "Header:")?; + writeln!(fmt, "{:?}", block.header())?; + writeln!(fmt, "Block bytes: {:?}", HexDisplay::from(&block.encode()))?; + writeln!(fmt, "Extrinsics ({})", block.extrinsics().len())?; + for (idx, ex) in block.extrinsics().iter().enumerate() { + writeln!(fmt, "- {}:", idx)?; + >::fmt_extrinsic(self, fmt, ex)?; + } + Ok(()) + } + + fn fmt_extrinsic(&self, fmt: &mut fmt::Formatter, extrinsic: &TBlock::Extrinsic) -> fmt::Result { + writeln!(fmt, " {:?}", extrinsic)?; + writeln!(fmt, " Bytes: {:?}", HexDisplay::from(&extrinsic.encode()))?; + Ok(()) + } +} + +/// Aggregated error for `Inspector` operations. +#[derive(Debug, derive_more::From, derive_more::Display)] +pub enum Error { + /// Could not decode Block or Extrinsic. + Codec(codec::Error), + /// Error accessing blockchain DB. + Blockchain(sp_blockchain::Error), + /// Given block has not been found. + NotFound(String), +} + +impl std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match *self { + Self::Codec(ref e) => Some(e), + Self::Blockchain(ref e) => Some(e), + Self::NotFound(_) => None, + } + } +} + +/// A helper trait to access block headers and bodies. +pub trait ChainAccess: + HeaderBackend + + BlockBody +{} + +impl ChainAccess for T where + TBlock: Block, + T: sp_blockchain::HeaderBackend + sc_client_api::BlockBody, +{} + +/// Blockchain inspector. +pub struct Inspector = DebugPrinter> { + printer: TPrinter, + chain: Box>, + _block: PhantomData, +} + +impl> Inspector { + /// Create new instance of the inspector with default printer. + pub fn new( + chain: impl ChainAccess + 'static, + ) -> Self where TPrinter: Default { + Self::with_printer(chain, Default::default()) + } + + /// Customize pretty-printing of the data. + pub fn with_printer( + chain: impl ChainAccess + 'static, + printer: TPrinter, + ) -> Self { + Inspector { + chain: Box::new(chain) as _, + printer, + _block: Default::default(), + } + } + + /// Get a pretty-printed block. + pub fn block(&self, input: BlockAddressFor) -> Result { + struct BlockPrinter<'a, A, B>(A, &'a B); + impl<'a, A: Block, B: PrettyPrinter> fmt::Display for BlockPrinter<'a, A, B> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + self.1.fmt_block(fmt, &self.0) + } + } + + let block = self.get_block(input)?; + Ok(format!("{}", BlockPrinter(block, &self.printer))) + } + + fn get_block(&self, input: BlockAddressFor) -> Result { + Ok(match input { + cli::BlockAddress::Bytes(bytes) => { + TBlock::decode(&mut &*bytes)? + }, + cli::BlockAddress::Number(number) => { + let id = BlockId::number(number); + let not_found = format!("Could not find block {:?}", id); + let body = self.chain.block_body(&id)? + .ok_or_else(|| Error::NotFound(not_found.clone()))?; + let header = self.chain.header(id)? + .ok_or_else(|| Error::NotFound(not_found.clone()))?; + TBlock::new(header, body) + }, + cli::BlockAddress::Hash(hash) => { + let id = BlockId::hash(hash); + let not_found = format!("Could not find block {:?}", id); + let body = self.chain.block_body(&id)? + .ok_or_else(|| Error::NotFound(not_found.clone()))?; + let header = self.chain.header(id)? + .ok_or_else(|| Error::NotFound(not_found.clone()))?; + TBlock::new(header, body) + }, + }) + } + + /// Get a pretty-printed extrinsic. + pub fn extrinsic( + &self, + input: cli::ExtrinsicAddress< as Hash>::Output, NumberFor>, + ) -> Result { + struct ExtrinsicPrinter<'a, A: Block, B>(A::Extrinsic, &'a B); + impl<'a, A: Block, B: PrettyPrinter> fmt::Display for ExtrinsicPrinter<'a, A, B> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + self.1.fmt_extrinsic(fmt, &self.0) + } + } + + let ext = match input { + cli::ExtrinsicAddress::Block(block, index) => { + let block = self.get_block(block)?; + block.extrinsics() + .get(index) + .cloned() + .ok_or_else(|| Error::NotFound(format!( + "Could not find extrinsic {} in block {:?}", index, block + )))? + }, + cli::ExtrinsicAddress::Bytes(bytes) => { + TBlock::Extrinsic::decode(&mut &*bytes)? + } + }; + + Ok(format!("{}", ExtrinsicPrinter(ext, &self.printer))) + } +} diff --git a/client/service/src/config.rs b/client/service/src/config.rs index f4043d533e..2099c600df 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -137,7 +137,7 @@ pub enum KeystoreConfig { password: Option> }, /// In-memory keystore. Recommended for in-browser nodes. - InMemory + InMemory, } impl KeystoreConfig { diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 3293769023..0d28fe139a 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -13,7 +13,7 @@ log = { version = "0.4.8", default-features = false } serde = { version = "1.0.101", optional = true, features = ["derive"] } byteorder = { version = "1.3.2", default-features = false } primitive-types = { version = "0.6.2", default-features = false, features = ["codec"] } -impl-serde = { version = "0.2.3", optional = true } +impl-serde = { version = "0.3.0", 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 } diff --git a/primitives/core/src/lib.rs b/primitives/core/src/lib.rs index f8c48ee970..01a96d8853 100644 --- a/primitives/core/src/lib.rs +++ b/primitives/core/src/lib.rs @@ -133,6 +133,15 @@ impl Deref for Bytes { fn deref(&self) -> &[u8] { &self.0[..] } } +#[cfg(feature = "std")] +impl sp_std::str::FromStr for Bytes { + type Err = bytes::FromHexError; + + fn from_str(s: &str) -> Result { + bytes::from_hex(s).map(Bytes) + } +} + /// Stores the encoded `RuntimeMetadata` for the native side as opaque type. #[derive(Encode, Decode, PartialEq)] pub struct OpaqueMetadata(Vec); -- GitLab From 646e7fb3809d2efc6f0cace5e34755ab958dd9b4 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Tue, 18 Feb 2020 20:44:43 +0100 Subject: [PATCH 178/180] Fix description of --no-private-ipv4 (#4950) --- client/cli/src/params.rs | 2 +- client/network/src/config.rs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/client/cli/src/params.rs b/client/cli/src/params.rs index 9ae7bd7748..d6c437f668 100644 --- a/client/cli/src/params.rs +++ b/client/cli/src/params.rs @@ -207,7 +207,7 @@ pub struct NetworkConfigurationParams { #[structopt(long = "port", value_name = "PORT")] pub port: Option, - /// Allow connecting to private IPv4 addresses (as specified in + /// Forbid connecting to private IPv4 addresses (as specified in /// [RFC1918](https://tools.ietf.org/html/rfc1918)), unless the address was passed with /// `--reserved-nodes` or `--bootnodes`. #[structopt(long = "no-private-ipv4")] diff --git a/client/network/src/config.rs b/client/network/src/config.rs index 87c77fee9f..2f920c6663 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -338,8 +338,9 @@ pub enum TransportConfig { enable_mdns: bool, /// If true, allow connecting to private IPv4 addresses (as defined in - /// [RFC1918](https://tools.ietf.org/html/rfc1918)), unless the address has been passed in - /// [`NetworkConfiguration::reserved_nodes`] or [`NetworkConfiguration::boot_nodes`]. + /// [RFC1918](https://tools.ietf.org/html/rfc1918)). Irrelevant for addresses that have + /// been passed in [`NetworkConfiguration::reserved_nodes`] or + /// [`NetworkConfiguration::boot_nodes`]. allow_private_ipv4: bool, /// Optional external implementation of a libp2p transport. Used in WASM contexts where we -- GitLab From f92b44cce3c0fb31ad96fefec3e3feb4253e7751 Mon Sep 17 00:00:00 2001 From: Stanislav Tkach Date: Wed, 19 Feb 2020 00:25:56 +0200 Subject: [PATCH 179/180] [In Progress] Remove deprecated api (#4973) * Remove deprecated api * Revert changes to wasm-build-runner --- client/finality-grandpa/src/lib.rs | 19 ------------------- client/finality-grandpa/src/observer.rs | 2 +- client/network/src/protocol/specialization.rs | 19 ------------------- 3 files changed, 1 insertion(+), 39 deletions(-) diff --git a/client/finality-grandpa/src/lib.rs b/client/finality-grandpa/src/lib.rs index 45a2400226..e931271df9 100644 --- a/client/finality-grandpa/src/lib.rs +++ b/client/finality-grandpa/src/lib.rs @@ -857,25 +857,6 @@ where } } -#[deprecated(since = "1.1.0", note = "Please switch to run_grandpa_voter.")] -pub fn run_grandpa( - grandpa_params: GrandpaParams, -) -> sp_blockchain::Result + Send + 'static> where - Block::Hash: Ord, - B: Backend + 'static, - E: CallExecutor + Send + Sync + 'static, - N: NetworkT + Send + Sync + Clone + 'static, - SC: SelectChain + 'static, - NumberFor: BlockNumberOps, - DigestFor: Encode, - RA: Send + Sync + 'static, - VR: VotingRule> + Clone + 'static, - X: futures::Future + Clone + Send + Unpin + 'static, - Client: AuxStore, -{ - run_grandpa_voter(grandpa_params) -} - /// When GRANDPA is not initialized we still need to register the finality /// tracker inherent provider which might be expected by the runtime for block /// authoring. Additionally, we register a gossip message validator that diff --git a/client/finality-grandpa/src/observer.rs b/client/finality-grandpa/src/observer.rs index ffe71d573a..77227909dc 100644 --- a/client/finality-grandpa/src/observer.rs +++ b/client/finality-grandpa/src/observer.rs @@ -377,7 +377,7 @@ mod tests { use substrate_test_runtime_client::{TestClientBuilder, TestClientBuilderExt}; use sc_network::PeerId; - use futures::executor::{self, ThreadPool}; + use futures::executor; /// Ensure `Future` implementation of `ObserverWork` is polling its `NetworkBridge`. Regression /// test for bug introduced in d4fbb897c and fixed in b7af8b339. diff --git a/client/network/src/protocol/specialization.rs b/client/network/src/protocol/specialization.rs index af6d5f7a23..6ffa335c8c 100644 --- a/client/network/src/protocol/specialization.rs +++ b/client/network/src/protocol/specialization.rs @@ -41,14 +41,6 @@ pub trait NetworkSpecialization: Send + Sync + 'static { message: Vec ); - /// Called when a network-specific event arrives. - #[deprecated(note = "This method is never called; please use `with_dht_event_tx` when building the service")] - fn on_event(&mut self, _event: Event) {} - - /// Called on abort. - #[deprecated(note = "This method is never called; aborting corresponds to dropping the object")] - fn on_abort(&mut self) { } - /// Called periodically to maintain peers and handle timeouts. fn maintain_peers(&mut self, _ctx: &mut dyn Context) { } @@ -162,17 +154,6 @@ macro_rules! construct_simple_protocol { $( self.$sub_protocol_name.on_message(_ctx, _who, _message); )* } - fn on_event( - &mut self, - _event: $crate::specialization::Event - ) { - $( self.$sub_protocol_name.on_event(_event); )* - } - - fn on_abort(&mut self) { - $( self.$sub_protocol_name.on_abort(); )* - } - fn maintain_peers(&mut self, _ctx: &mut $crate::Context<$block>) { $( self.$sub_protocol_name.maintain_peers(_ctx); )* } -- GitLab From dc92587bea4032e0a0fc96785bfd9aa17c95459e Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Wed, 19 Feb 2020 01:34:31 +0300 Subject: [PATCH 180/180] Build block without checking signatures (#4916) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * in executive * in other places * to UnsafeResult * move doc comment * apply suggestions * allow validity mocking for TestXt * add test * augment checkable instead of another trait * fix im online test * blockbuilder dihotomy * review suggestions * update test * Update client/block-builder/src/lib.rs * updae spec_version Co-authored-by: Bastian Köcher --- bin/node-template/runtime/src/lib.rs | 4 + bin/node/runtime/src/lib.rs | 6 +- .../basic-authorship/src/basic_authorship.rs | 4 +- client/block-builder/src/lib.rs | 43 +++++-- client/rpc/src/state/tests.rs | 2 +- client/service/src/lib.rs | 3 +- frame/executive/src/lib.rs | 69 +++++++++--- frame/im-online/src/tests.rs | 4 +- primitives/block-builder/src/lib.rs | 6 +- primitives/runtime/src/generic/mod.rs | 9 ++ .../src/generic/unchecked_extrinsic.rs | 34 ++++-- primitives/runtime/src/testing.rs | 105 +++++++++++++++--- primitives/runtime/src/traits.rs | 10 +- test-utils/runtime/src/lib.rs | 11 +- test-utils/runtime/src/system.rs | 3 +- 15 files changed, 246 insertions(+), 67 deletions(-) diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index a9944199b8..a1bcd157ad 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -315,6 +315,10 @@ impl_runtime_apis! { Executive::apply_extrinsic(extrinsic) } + fn apply_trusted_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + Executive::apply_trusted_extrinsic(extrinsic) + } + fn finalize_block() -> ::Header { Executive::finalize_block() } diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index a98b1700fe..956fc0bb0e 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -82,7 +82,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 221, + spec_version: 222, impl_version: 0, apis: RUNTIME_API_VERSIONS, }; @@ -686,6 +686,10 @@ impl_runtime_apis! { Executive::apply_extrinsic(extrinsic) } + fn apply_trusted_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + Executive::apply_trusted_extrinsic(extrinsic) + } + fn finalize_block() -> ::Header { Executive::finalize_block() } diff --git a/client/basic-authorship/src/basic_authorship.rs b/client/basic-authorship/src/basic_authorship.rs index cab1231e87..a99453544e 100644 --- a/client/basic-authorship/src/basic_authorship.rs +++ b/client/basic-authorship/src/basic_authorship.rs @@ -195,7 +195,7 @@ impl ProposerInner, inherent_data )? { - block_builder.push(extrinsic)?; + block_builder.push_trusted(extrinsic)?; } // proceed with transactions @@ -218,7 +218,7 @@ impl ProposerInner, 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) { + match sc_block_builder::BlockBuilder::push_trusted(&mut block_builder, pending_tx_data) { Ok(()) => { debug!("[{:?}] Pushed to the block.", pending_tx_hash); } diff --git a/client/block-builder/src/lib.rs b/client/block-builder/src/lib.rs index d0eb8b2892..26bc9ecea8 100644 --- a/client/block-builder/src/lib.rs +++ b/client/block-builder/src/lib.rs @@ -121,11 +121,23 @@ where backend, }) } - + /// Push onto the block's list of extrinsics. /// - /// This will ensure the extrinsic can be validly executed (by executing it); + /// This will ensure the extrinsic can be validly executed (by executing it). pub fn push(&mut self, xt: ::Extrinsic) -> Result<(), ApiErrorFor> { + self.push_internal(xt, false) + } + + /// Push onto the block's list of extrinsics. + /// + /// This will treat incoming extrinsic `xt` as untrusted and perform additional checks + /// (currenty checking signature). + pub fn push_trusted(&mut self, xt: ::Extrinsic) -> Result<(), ApiErrorFor> { + self.push_internal(xt, true) + } + + fn push_internal(&mut self, xt: ::Extrinsic, skip_signature: bool) -> Result<(), ApiErrorFor> { let block_id = &self.block_id; let extrinsics = &mut self.extrinsics; @@ -152,12 +164,29 @@ where } }) } else { - self.api.map_api_result(|api| { - match api.apply_extrinsic_with_context( + let use_trusted = skip_signature && self + .api + .has_api_with::>, _>( block_id, - ExecutionContext::BlockConstruction, - xt.clone(), - )? { + |version| version >= 5, + )?; + + self.api.map_api_result(|api| { + let apply_result = if use_trusted { + api.apply_trusted_extrinsic_with_context( + block_id, + ExecutionContext::BlockConstruction, + xt.clone(), + )? + } else { + api.apply_extrinsic_with_context( + block_id, + ExecutionContext::BlockConstruction, + xt.clone(), + )? + }; + + match apply_result { Ok(_) => { extrinsics.push(xt); Ok(()) diff --git a/client/rpc/src/state/tests.rs b/client/rpc/src/state/tests.rs index a0ab11e977..6508d46ddd 100644 --- a/client/rpc/src/state/tests.rs +++ b/client/rpc/src/state/tests.rs @@ -402,7 +402,7 @@ fn should_return_runtime_version() { let result = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":1,\ \"specVersion\":1,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",2],\ - [\"0x37e397fc7c91f5e4\",1],[\"0xd2bc9897eed08f15\",1],[\"0x40fe3ad401f8959a\",4],\ + [\"0x37e397fc7c91f5e4\",1],[\"0xd2bc9897eed08f15\",1],[\"0x40fe3ad401f8959a\",5],\ [\"0xc6e9a76309f39b09\",1],[\"0xdd718d5cc53262d4\",1],[\"0xcbca25e39f142387\",1],\ [\"0xf78b278be53f454c\",2],[\"0xab3c0572291feb8b\",1],[\"0xbc9d89904f5b923f\",1]]}"; diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index c358e5993e..a2e53616ab 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -705,6 +705,7 @@ mod tests { use futures::executor::block_on; use sp_consensus::SelectChain; use sp_runtime::traits::BlindCheckable; + use sp_runtime::generic::CheckSignature; use substrate_test_runtime_client::{prelude::*, runtime::{Extrinsic, Transfer}}; use sc_transaction_pool::{BasicPool, FullChainApi}; @@ -733,7 +734,7 @@ mod tests { // then assert_eq!(transactions.len(), 1); - assert!(transactions[0].1.clone().check().is_ok()); + assert!(transactions[0].1.clone().check(CheckSignature::Yes).is_ok()); // this should not panic let _ = transactions[0].1.transfer(); } diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 2d1b306531..c112298051 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -79,13 +79,15 @@ use sp_std::{prelude::*, marker::PhantomData}; use frame_support::weights::{GetDispatchInfo, WeighBlock, DispatchInfo}; use sp_runtime::{ - generic::Digest, ApplyExtrinsicResult, + generic::Digest, + ApplyExtrinsicResult, traits::{ self, Header, Zero, One, Checkable, Applyable, CheckEqual, OnFinalize, OnInitialize, NumberFor, Block as BlockT, OffchainWorker, Dispatchable, Saturating, }, transaction_validity::TransactionValidity, }; +use sp_runtime::generic::CheckSignature; #[allow(deprecated)] use sp_runtime::traits::ValidateUnsigned; use codec::{Codec, Encode}; @@ -255,13 +257,22 @@ where pub fn apply_extrinsic(uxt: Block::Extrinsic) -> ApplyExtrinsicResult { let encoded = uxt.encode(); let encoded_len = encoded.len(); - Self::apply_extrinsic_with_len(uxt, encoded_len, Some(encoded)) + Self::apply_extrinsic_with_len(uxt, encoded_len, Some(encoded), CheckSignature::Yes) + } + + /// Apply extrinsic outside of the block execution function. + /// + /// Same as `apply_extrinsic`, but skips signature checks. + pub fn apply_trusted_extrinsic(uxt: Block::Extrinsic) -> ApplyExtrinsicResult { + let encoded = uxt.encode(); + let encoded_len = encoded.len(); + Self::apply_extrinsic_with_len(uxt, encoded_len, Some(encoded), CheckSignature::No) } /// Apply an extrinsic inside the block execution function. fn apply_extrinsic_no_note(uxt: Block::Extrinsic) { let l = uxt.encode().len(); - match Self::apply_extrinsic_with_len(uxt, l, None) { + match Self::apply_extrinsic_with_len(uxt, l, None, CheckSignature::Yes) { Ok(_) => (), Err(e) => { let err: &'static str = e.into(); panic!(err) }, } @@ -272,9 +283,13 @@ where uxt: Block::Extrinsic, encoded_len: usize, to_note: Option>, + check_signature: CheckSignature, ) -> ApplyExtrinsicResult { // Verify that the signature is good. - let xt = uxt.check(&Default::default())?; + let xt = uxt.check( + check_signature, + &Default::default(), + )?; // We don't need to make sure to `note_extrinsic` only after we know it's going to be // executed to prevent it from leaking in storage since at this point, it will either @@ -322,7 +337,7 @@ where /// Changes made to storage should be discarded. pub fn validate_transaction(uxt: Block::Extrinsic) -> TransactionValidity { let encoded_len = uxt.using_encoded(|d| d.len()); - let xt = uxt.check(&Default::default())?; + let xt = uxt.check(CheckSignature::Yes, &Default::default())?; let dispatch_info = xt.get_dispatch_info(); xt.validate::(dispatch_info, encoded_len) @@ -516,8 +531,8 @@ mod tests { ) } - fn sign_extra(who: u64, nonce: u64, fee: u64) -> Option<(u64, SignedExtra)> { - Some((who, extra(nonce, fee))) + fn sign_extra(who: u64, nonce: u64, fee: u64) -> (u64, SignedExtra) { + (who, extra(nonce, fee)) } #[test] @@ -526,7 +541,7 @@ mod tests { pallet_balances::GenesisConfig:: { balances: vec![(1, 211)], }.assimilate_storage(&mut t).unwrap(); - let xt = sp_runtime::testing::TestXt(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(2, 69))); + let xt = sp_runtime::testing::TestXt::new_signed(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(2, 69))); let weight = xt.get_dispatch_info().weight as u64; let mut t = sp_io::TestExternalities::new(t); t.execute_with(|| { @@ -606,7 +621,7 @@ mod tests { fn bad_extrinsic_not_inserted() { let mut t = new_test_ext(1); // bad nonce check! - let xt = sp_runtime::testing::TestXt(sign_extra(1, 30, 0), Call::Balances(BalancesCall::transfer(33, 69))); + let xt = sp_runtime::testing::TestXt::new_signed(sign_extra(1, 30, 0), Call::Balances(BalancesCall::transfer(33, 69))); t.execute_with(|| { Executive::initialize_block(&Header::new( 1, @@ -624,7 +639,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 = sp_runtime::testing::TestXt(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(33, 0))); + let xt = sp_runtime::testing::TestXt::new_signed(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; @@ -641,7 +656,7 @@ mod tests { assert_eq!(>::all_extrinsics_weight(), 175); for nonce in 0..=num_to_exhaust_block { - let xt = sp_runtime::testing::TestXt( + let xt = sp_runtime::testing::TestXt::new_signed( sign_extra(1, nonce.into(), 0), Call::Balances(BalancesCall::transfer(33, 0)), ); let res = Executive::apply_extrinsic(xt); @@ -661,9 +676,9 @@ mod tests { #[test] fn block_weight_and_size_is_stored_per_tx() { - 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 xt = sp_runtime::testing::TestXt::new_signed(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(33, 0))); + let x1 = sp_runtime::testing::TestXt::new_signed(sign_extra(1, 1, 0), Call::Balances(BalancesCall::transfer(33, 0))); + let x2 = sp_runtime::testing::TestXt::new_signed(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(|| { @@ -687,7 +702,7 @@ mod tests { #[test] fn validate_unsigned() { - let xt = sp_runtime::testing::TestXt(None, Call::Balances(BalancesCall::set_balance(33, 69, 69))); + let xt = sp_runtime::testing::TestXt::new_unsigned(Call::Balances(BalancesCall::set_balance(33, 69, 69))); let mut t = new_test_ext(1); t.execute_with(|| { @@ -696,6 +711,28 @@ mod tests { }); } + #[test] + fn apply_trusted_skips_signature_check_but_not_others() { + let xt1 = sp_runtime::testing::TestXt::new_signed(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(33, 0))) + .badly_signed(); + + let mut t = new_test_ext(1); + + t.execute_with(|| { + assert_eq!(Executive::apply_trusted_extrinsic(xt1), Ok(Ok(()))); + }); + + let xt2 = sp_runtime::testing::TestXt::new_signed(sign_extra(1, 0, 0), Call::Balances(BalancesCall::transfer(33, 0))) + .invalid(TransactionValidityError::Invalid(InvalidTransaction::Call)); + + t.execute_with(|| { + assert_eq!( + Executive::apply_trusted_extrinsic(xt2), + Err(TransactionValidityError::Invalid(InvalidTransaction::Call)) + ); + }); + } + #[test] fn can_pay_for_tx_fee_on_full_lock() { let id: LockIdentifier = *b"0 "; @@ -708,7 +745,7 @@ mod tests { 110, lock, ); - let xt = sp_runtime::testing::TestXt( + let xt = sp_runtime::testing::TestXt::new_signed( sign_extra(1, 0, 0), Call::System(SystemCall::remark(vec![1u8])), ); diff --git a/frame/im-online/src/tests.rs b/frame/im-online/src/tests.rs index 808978d403..80056023e5 100644 --- a/frame/im-online/src/tests.rs +++ b/frame/im-online/src/tests.rs @@ -222,7 +222,7 @@ fn should_generate_heartbeats() { assert_eq!(state.read().transactions.len(), 2); // check stuff about the transaction. let ex: Extrinsic = Decode::decode(&mut &*transaction).unwrap(); - let heartbeat = match ex.1 { + let heartbeat = match ex.call { crate::mock::Call::ImOnline(crate::Call::heartbeat(h, _)) => h, e => panic!("Unexpected call: {:?}", e), }; @@ -332,7 +332,7 @@ fn should_not_send_a_report_if_already_online() { assert_eq!(pool_state.read().transactions.len(), 0); // check stuff about the transaction. let ex: Extrinsic = Decode::decode(&mut &*transaction).unwrap(); - let heartbeat = match ex.1 { + let heartbeat = match ex.call { crate::mock::Call::ImOnline(crate::Call::heartbeat(h, _)) => h, e => panic!("Unexpected call: {:?}", e), }; diff --git a/primitives/block-builder/src/lib.rs b/primitives/block-builder/src/lib.rs index f050979bd8..e4e98e1f40 100644 --- a/primitives/block-builder/src/lib.rs +++ b/primitives/block-builder/src/lib.rs @@ -43,7 +43,7 @@ pub mod compatibility_v3 { sp_api::decl_runtime_apis! { /// The `BlockBuilder` api trait that provides the required functionality for building a block. - #[api_version(4)] + #[api_version(5)] pub trait BlockBuilder { /// Compatibility version of `apply_extrinsic` for v3. /// @@ -58,6 +58,10 @@ sp_api::decl_runtime_apis! { /// Returns an inclusion outcome which specifies if this extrinsic is included in /// this block or not. fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult; + /// Apply the given extrinsic. + /// + /// Same as `apply_extrinsic`, but skips signature verification. + fn apply_trusted_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult; /// Finish the current block. #[renamed("finalise_block", 3)] fn finalize_block() -> ::Header; diff --git a/primitives/runtime/src/generic/mod.rs b/primitives/runtime/src/generic/mod.rs index 5e9928ba19..f6399fff13 100644 --- a/primitives/runtime/src/generic/mod.rs +++ b/primitives/runtime/src/generic/mod.rs @@ -39,6 +39,15 @@ pub use self::digest::{ use crate::codec::Encode; use sp_std::prelude::*; +/// Perform singature check. +#[derive(PartialEq, Eq, Clone, Copy)] +pub enum CheckSignature { + /// Perform. + Yes, + /// Don't perform. + No, +} + fn encode_with_vec_prefix)>(encoder: F) -> Vec { let size = ::sp_std::mem::size_of::(); let reserve = match size { diff --git a/primitives/runtime/src/generic/unchecked_extrinsic.rs b/primitives/runtime/src/generic/unchecked_extrinsic.rs index a516bc1f7f..0db60e32a6 100644 --- a/primitives/runtime/src/generic/unchecked_extrinsic.rs +++ b/primitives/runtime/src/generic/unchecked_extrinsic.rs @@ -24,7 +24,8 @@ use crate::{ self, Member, MaybeDisplay, SignedExtension, Checkable, Extrinsic, ExtrinsicMetadata, IdentifyAccount, }, - generic::CheckedExtrinsic, transaction_validity::{TransactionValidityError, InvalidTransaction}, + generic::{CheckSignature, CheckedExtrinsic}, + transaction_validity::{TransactionValidityError, InvalidTransaction}, }; const TRANSACTION_VERSION: u8 = 4; @@ -120,18 +121,26 @@ where { type Checked = CheckedExtrinsic; - fn check(self, lookup: &Lookup) -> Result { + fn check(self, check_signature: CheckSignature, lookup: &Lookup) -> Result { Ok(match self.signature { Some((signed, signature, extra)) => { let signed = lookup.lookup(signed)?; - let raw_payload = SignedPayload::new(self.function, extra)?; - if !raw_payload.using_encoded(|payload| { - signature.verify(payload, &signed) - }) { - return Err(InvalidTransaction::BadProof.into()) - } - let (function, extra, _) = raw_payload.deconstruct(); + let (function, extra) = if let CheckSignature::No = check_signature { + (self.function, extra) + } else { + let raw_payload = SignedPayload::new(self.function, extra)?; + + if !raw_payload.using_encoded(|payload| { + signature.verify(payload, &signed) + }) { + return Err(InvalidTransaction::BadProof.into()) + } + let (function, extra, _) = raw_payload.deconstruct(); + + (function, extra) + }; + CheckedExtrinsic { signed: Some((signed, extra)), function, @@ -322,6 +331,7 @@ mod tests { use sp_io::hashing::blake2_256; use crate::codec::{Encode, Decode}; use crate::traits::{SignedExtension, IdentifyAccount, IdentityLookup}; + use crate::generic::CheckSignature; use serde::{Serialize, Deserialize}; type TestContext = IdentityLookup; @@ -402,7 +412,7 @@ mod tests { fn unsigned_check_should_work() { let ux = Ex::new_unsigned(vec![0u8; 0]); assert!(!ux.is_signed().unwrap_or(false)); - assert!(>::check(ux, &Default::default()).is_ok()); + assert!(>::check(ux, CheckSignature::Yes, &Default::default()).is_ok()); } #[test] @@ -415,7 +425,7 @@ mod tests { ); assert!(ux.is_signed().unwrap_or(false)); assert_eq!( - >::check(ux, &Default::default()), + >::check(ux, CheckSignature::Yes, &Default::default()), Err(InvalidTransaction::BadProof.into()), ); } @@ -430,7 +440,7 @@ mod tests { ); assert!(ux.is_signed().unwrap_or(false)); assert_eq!( - >::check(ux, &Default::default()), + >::check(ux, CheckSignature::Yes, &Default::default()), Ok(CEx { signed: Some((TEST_ACCOUNT, TestExtra)), function: vec![0u8; 0] }), ); } diff --git a/primitives/runtime/src/testing.rs b/primitives/runtime/src/testing.rs index e3e94c3c9f..be0e36b2d1 100644 --- a/primitives/runtime/src/testing.rs +++ b/primitives/runtime/src/testing.rs @@ -25,11 +25,10 @@ use crate::traits::{ }; #[allow(deprecated)] use crate::traits::ValidateUnsigned; -use crate::{generic, KeyTypeId, ApplyExtrinsicResult}; +use crate::{generic::{self, CheckSignature}, KeyTypeId, ApplyExtrinsicResult}; pub use sp_core::{H256, sr25519}; use sp_core::{crypto::{CryptoType, Dummy, key_types, Public}, U256}; -use crate::transaction_validity::{TransactionValidity, TransactionValidityError}; - +use crate::transaction_validity::{TransactionValidity, TransactionValidityError, InvalidTransaction}; /// Authority Id #[derive(Default, PartialEq, Eq, Clone, Encode, Decode, Debug, Hash, Serialize, Deserialize, PartialOrd, Ord)] pub struct UintAuthorityId(pub u64); @@ -295,12 +294,69 @@ impl<'a, Xt> Deserialize<'a> for Block where Block: Decode { } } -/// Test transaction, tuple of (sender, call, signed_extra) -/// with index only used if sender is some. +/// Test validity. +#[derive(PartialEq, Eq, Clone, Encode, Decode)] +pub enum TestValidity { + /// Valid variant that will pass all checks. + Valid, + /// Variant with invalid signature. + /// + /// Will fail signature check. + SignatureInvalid(TransactionValidityError), + /// Variant with invalid logic. + /// + /// Will fail all checks. + OtherInvalid(TransactionValidityError), +} + +/// Test transaction. /// -/// If sender is some then the transaction is signed otherwise it is unsigned. +/// Used to mock actual transaction. #[derive(PartialEq, Eq, Clone, Encode, Decode)] -pub struct TestXt(pub Option<(u64, Extra)>, pub Call); +pub struct TestXt { + /// Signature with extra. + /// + /// if some, then the transaction is signed. Transaction is unsigned otherwise. + pub signature: Option<(u64, Extra)>, + /// Validity. + /// + /// Instantiate invalid variant and transaction will fail correpsonding checks. + pub validity: TestValidity, + /// Call. + pub call: Call, +} + +impl TestXt { + /// New signed test `TextXt`. + pub fn new_signed(signature: (u64, Extra), call: Call) -> Self { + TestXt { + signature: Some(signature), + validity: TestValidity::Valid, + call, + } + } + + /// New unsigned test `TextXt`. + pub fn new_unsigned(call: Call) -> Self { + TestXt { + signature: None, + validity: TestValidity::Valid, + call, + } + } + + /// Build invalid variant of `TestXt`. + pub fn invalid(mut self, err: TransactionValidityError) -> Self { + self.validity = TestValidity::OtherInvalid(err); + self + } + + /// Build badly signed variant of `TestXt`. + pub fn badly_signed(mut self) -> Self { + self.validity = TestValidity::SignatureInvalid(TransactionValidityError::Invalid(InvalidTransaction::BadProof)); + self + } + } // Non-opaque extrinsics always 0. parity_util_mem::malloc_size_of_is_0!(any: TestXt); @@ -313,24 +369,39 @@ impl Serialize for TestXt where TestXt: E impl Debug for TestXt { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "TestXt({:?}, ...)", self.0.as_ref().map(|x| &x.0)) + write!(f, "TestXt({:?}, {}, ...)", + self.signature.as_ref().map(|x| &x.0), + if let TestValidity::Valid = self.validity { "valid" } else { "invalid" } + ) } } impl Checkable for TestXt { type Checked = Self; - fn check(self, _: &Context) -> Result { Ok(self) } + fn check(self, signature: CheckSignature, _: &Context) -> Result { + match self.validity { + TestValidity::Valid => Ok(self), + TestValidity::SignatureInvalid(e) => + if let CheckSignature::No = signature { + Ok(self) + } else { + Err(e) + }, + TestValidity::OtherInvalid(e) => Err(e), + } + } } + impl traits::Extrinsic for TestXt { type Call = Call; type SignaturePayload = (u64, Extra); fn is_signed(&self) -> Option { - Some(self.0.is_some()) + Some(self.signature.is_some()) } - fn new(c: Call, sig: Option) -> Option { - Some(TestXt(sig, c)) + fn new(call: Call, signature: Option) -> Option { + Some(TestXt { signature, call, validity: TestValidity::Valid }) } } @@ -344,7 +415,7 @@ impl Applyable for TestXt where type Call = Call; type DispatchInfo = Info; - fn sender(&self) -> Option<&Self::AccountId> { self.0.as_ref().map(|x| &x.0) } + fn sender(&self) -> Option<&Self::AccountId> { self.signature.as_ref().map(|x| &x.0) } /// Checks to see if this is a valid *transaction*. It returns information on it if so. #[allow(deprecated)] // Allow ValidateUnsigned @@ -364,14 +435,14 @@ impl Applyable for TestXt where info: Self::DispatchInfo, len: usize, ) -> ApplyExtrinsicResult { - let maybe_who = if let Some((who, extra)) = self.0 { - Extra::pre_dispatch(extra, &who, &self.1, info, len)?; + let maybe_who = if let Some((who, extra)) = self.signature { + Extra::pre_dispatch(extra, &who, &self.call, info, len)?; Some(who) } else { - Extra::pre_dispatch_unsigned(&self.1, info, len)?; + Extra::pre_dispatch_unsigned(&self.call, info, len)?; None }; - Ok(self.1.dispatch(maybe_who.into()).map_err(Into::into)) + Ok(self.call.dispatch(maybe_who.into()).map_err(Into::into)) } } diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 1b9b9eec70..183df08ab8 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -31,7 +31,7 @@ use crate::codec::{Codec, Encode, Decode}; use crate::transaction_validity::{ ValidTransaction, TransactionValidity, TransactionValidityError, UnknownTransaction, }; -use crate::generic::{Digest, DigestItem}; +use crate::generic::{Digest, DigestItem, CheckSignature}; pub use sp_arithmetic::traits::{ AtLeast32Bit, UniqueSaturatedInto, UniqueSaturatedFrom, Saturating, SaturatedConversion, Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, @@ -637,7 +637,7 @@ pub trait Checkable: Sized { type Checked; /// Check self, given an instance of Context. - fn check(self, c: &Context) -> Result; + fn check(self, signature: CheckSignature, c: &Context) -> Result; } /// A "checkable" piece of information, used by the standard Substrate Executive in order to @@ -649,15 +649,15 @@ pub trait BlindCheckable: Sized { type Checked; /// Check self. - fn check(self) -> Result; + fn check(self, signature: CheckSignature) -> Result; } // Every `BlindCheckable` is also a `StaticCheckable` for arbitrary `Context`. impl Checkable for T { type Checked = ::Checked; - fn check(self, _c: &Context) -> Result { - BlindCheckable::check(self) + fn check(self, signature: CheckSignature, _c: &Context) -> Result { + BlindCheckable::check(self, signature) } } diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index 2505bdde22..138e79cdd5 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -41,6 +41,7 @@ use sp_runtime::{ BlindCheckable, BlakeTwo256, Block as BlockT, Extrinsic as ExtrinsicT, GetNodeBlockType, GetRuntimeBlockType, Verify, IdentityLookup, }, + generic::CheckSignature, }; use sp_version::RuntimeVersion; pub use sp_core::{hash::H256}; @@ -126,7 +127,7 @@ impl serde::Serialize for Extrinsic { impl BlindCheckable for Extrinsic { type Checked = Self; - fn check(self) -> Result { + fn check(self, _signature: CheckSignature) -> Result { match self { Extrinsic::AuthoritiesChange(new_auth) => Ok(Extrinsic::AuthoritiesChange(new_auth)), Extrinsic::Transfer(transfer, signature) => { @@ -493,6 +494,10 @@ cfg_if! { system::execute_transaction(extrinsic) } + fn apply_trusted_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + system::execute_transaction(extrinsic) + } + fn finalize_block() -> ::Header { system::finalize_block() } @@ -680,6 +685,10 @@ cfg_if! { system::execute_transaction(extrinsic) } + fn apply_trusted_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + system::execute_transaction(extrinsic) + } + fn finalize_block() -> ::Header { system::finalize_block() } diff --git a/test-utils/runtime/src/system.rs b/test-utils/runtime/src/system.rs index d0a38c7c77..b410d317a1 100644 --- a/test-utils/runtime/src/system.rs +++ b/test-utils/runtime/src/system.rs @@ -29,6 +29,7 @@ use sp_runtime::{ transaction_validity::{ TransactionValidity, ValidTransaction, InvalidTransaction, TransactionValidityError, }, + generic::CheckSignature, }; use codec::{KeyedVec, Encode, Decode}; use frame_system::Trait; @@ -243,7 +244,7 @@ pub fn finalize_block() -> Header { #[inline(always)] fn check_signature(utx: &Extrinsic) -> Result<(), TransactionValidityError> { use sp_runtime::traits::BlindCheckable; - utx.clone().check().map_err(|_| InvalidTransaction::BadProof.into()).map(|_| ()) + utx.clone().check(CheckSignature::Yes).map_err(|_| InvalidTransaction::BadProof.into()).map(|_| ()) } fn execute_transaction_backend(utx: &Extrinsic) -> ApplyExtrinsicResult { -- GitLab