From c908c1ca3963f3d32dbb17b9554bd4f15d6967cd Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Sat, 1 Aug 2020 16:16:22 +0800 Subject: [PATCH 01/50] new node permission pallet --- Cargo.lock | 21 ++++++++++ Cargo.toml | 2 + frame/node-permission/Cargo.toml | 27 ++++++++++++ frame/node-permission/src/lib.rs | 59 +++++++++++++++++++++++++++ primitives/core/src/crypto.rs | 2 + primitives/node-permission/Cargo.toml | 29 +++++++++++++ primitives/node-permission/src/lib.rs | 50 +++++++++++++++++++++++ 7 files changed, 190 insertions(+) create mode 100644 frame/node-permission/Cargo.toml create mode 100644 frame/node-permission/src/lib.rs create mode 100644 primitives/node-permission/Cargo.toml create mode 100644 primitives/node-permission/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index d98b3bb9d9504..302462d52c59b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4554,6 +4554,16 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-node-permission" +version = "2.0.0-rc5" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "sp-node-permission", +] + [[package]] name = "pallet-offences" version = "2.0.0-rc5" @@ -7934,6 +7944,17 @@ dependencies = [ "strum", ] +[[package]] +name = "sp-node-permission" +version = "2.0.0-rc5" +dependencies = [ + "parity-scale-codec", + "sp-api", + "sp-application-crypto", + "sp-runtime", + "sp-std", +] + [[package]] name = "sp-npos-elections" version = "2.0.0-rc5" diff --git a/Cargo.toml b/Cargo.toml index ba146e55bca3f..767d82d66bcb5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,6 +88,7 @@ members = [ "frame/metadata", "frame/multisig", "frame/nicks", + "frame/node-permission", "frame/offences", "frame/proxy", "frame/randomness-collective-flip", @@ -138,6 +139,7 @@ members = [ "primitives/finality-grandpa", "primitives/inherents", "primitives/keyring", + "primitives/node-permission", "primitives/offchain", "primitives/panic-handler", "primitives/npos-elections", diff --git a/frame/node-permission/Cargo.toml b/frame/node-permission/Cargo.toml new file mode 100644 index 0000000000000..0df5b09e72a72 --- /dev/null +++ b/frame/node-permission/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "pallet-node-permission" +version = "2.0.0-rc5" +authors = ["Parity Technologies "] +edition = "2018" +license = "Apache-2.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "FRAME pallet for permissioned node" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } +frame-support = { version = "2.0.0-rc5", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc5", default-features = false, path = "../system" } +sp-node-permission = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/node-permission" } + +[features] +default = ["std"] +std = [ + "codec/std", + "frame-support/std", + "frame-system/std", + "sp-node-permission/std", +] diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs new file mode 100644 index 0000000000000..19fe186737d05 --- /dev/null +++ b/frame/node-permission/src/lib.rs @@ -0,0 +1,59 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! # Node permission moudule + +//! +//! This module is used by the `client/peerset` to retrieve the current +//! permissioned nodes. + +// Ensure we're `no_std` when compiling for Wasm. +#![cfg_attr(not(feature = "std"), no_std)] + +use frame_support::{decl_module, decl_storage, dispatch::DispatchResult}; +use frame_system::ensure_signed; +use sp_node_permission::NodeId; + +/// The module's config trait. +pub trait Trait: frame_system::Trait {} + +decl_storage! { + trait Store for Module as NodePermission { + /// Public keys of the permissioned nodes. + // TODO add genesis config + NodePublicKeys get(fn node_public_keys): Vec; + } +} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + // type Error = Error; + + // fn deposit_event() = default; + + /// Add a node to the allowlist. + #[weight = 0] + pub fn add_node(origin, node_public_key: NodeId) -> DispatchResult { + // TODO ensure to be coucil/root + let _who = ensure_signed(origin)?; + + NodePublicKeys::mutate(|old| old.push(node_public_key)); + + Ok(()) + } + } +} diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index efacf0b2e76a6..f47243cc94215 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -1023,6 +1023,8 @@ pub mod key_types { pub const STAKING: KeyTypeId = KeyTypeId(*b"stak"); /// Key type for equivocation reporting, built-in. Identified as `fish`. pub const REPORTING: KeyTypeId = KeyTypeId(*b"fish"); + /// Key type for node permission module, build-in. Identified as `node`. + pub const NODE_PERMISSION: KeyTypeId = KeyTypeId(*b"node"); /// A key type ID useful for tests. pub const DUMMY: KeyTypeId = KeyTypeId(*b"dumy"); } diff --git a/primitives/node-permission/Cargo.toml b/primitives/node-permission/Cargo.toml new file mode 100644 index 0000000000000..60f0e9c718e16 --- /dev/null +++ b/primitives/node-permission/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "sp-node-permission" +version = "2.0.0-rc5" +authors = ["Parity Technologies "] +description = "Node permission primitives" +edition = "2018" +license = "Apache-2.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", default-features = false, version = "1.3.1" } +sp-api = { version = "2.0.0-rc5", default-features = false, path = "../api" } +sp-application-crypto = { version = "2.0.0-rc5", default-features = false, path = "../application-crypto" } +sp-runtime = { version = "2.0.0-rc5", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-rc5", default-features = false, path = "../std" } + +[features] +default = ["std"] +std = [ + "codec/std", + "sp-api/std", + "sp-application-crypto/std", + "sp-runtime/std", + "sp-std/std", +] diff --git a/primitives/node-permission/src/lib.rs b/primitives/node-permission/src/lib.rs new file mode 100644 index 0000000000000..2a4852ec6b999 --- /dev/null +++ b/primitives/node-permission/src/lib.rs @@ -0,0 +1,50 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Runtime Api to get permissioned nodes + +#![cfg_attr(not(feature = "std"), no_std)] + +use sp_std::vec::Vec; + +mod app { + use sp_application_crypto::{ + key_types::NODE_PERMISSION, + app_crypto, + ed25519, + }; + app_crypto!(ed25519, NODE_PERMISSION); +} + +// sp_application_crypto::with_pair! { +// /// A node keypair. +// pub type NodePair = app::Pair; +// } + +/// A node identifier. +pub type NodeId = app::Public; + +sp_api::decl_runtime_apis! { + /// The node permission api + /// + /// This api is used by the `client/peerset` to retrieve identifiers + /// of the current permissioned nodes. + pub trait NodePermissionApi { + /// Retrieve node identifiers of the current permissioned nodes. + fn nodes() -> Vec; + } +} From f44a9701ff8d1e24e3f26eccecc78289aed66a95 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Sat, 1 Aug 2020 16:45:45 +0800 Subject: [PATCH 02/50] runtime api for node ides. --- Cargo.lock | 3 +++ bin/node/runtime/Cargo.toml | 4 ++++ bin/node/runtime/src/lib.rs | 11 +++++++++++ frame/node-permission/Cargo.toml | 2 ++ frame/node-permission/src/lib.rs | 8 ++++++++ 5 files changed, 28 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 302462d52c59b..c8aeddcafd00f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3756,6 +3756,7 @@ dependencies = [ "pallet-indices", "pallet-membership", "pallet-multisig", + "pallet-node-permission", "pallet-offences", "pallet-offences-benchmarking", "pallet-proxy", @@ -3784,6 +3785,7 @@ dependencies = [ "sp-inherents", "sp-io", "sp-keyring", + "sp-node-permission", "sp-offchain", "sp-runtime", "sp-session", @@ -4562,6 +4564,7 @@ dependencies = [ "frame-system", "parity-scale-codec", "sp-node-permission", + "sp-std", ] [[package]] diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 35ed7400459f2..8486408803678 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -25,6 +25,7 @@ sp-authority-discovery = { version = "2.0.0-rc5", default-features = false, path sp-consensus-babe = { version = "0.8.0-rc5", default-features = false, path = "../../../primitives/consensus/babe" } sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-rc5"} sp-inherents = { version = "2.0.0-rc5", default-features = false, path = "../../../primitives/inherents" } +sp-node-permission = { version = "2.0.0-rc5", default-features = false, path = "../../../primitives/node-permission" } node-primitives = { version = "2.0.0-rc5", default-features = false, path = "../primitives" } sp-offchain = { version = "2.0.0-rc5", default-features = false, path = "../../../primitives/offchain" } sp-core = { version = "2.0.0-rc5", default-features = false, path = "../../../primitives/core" } @@ -61,6 +62,7 @@ pallet-indices = { version = "2.0.0-rc5", default-features = false, path = "../. pallet-identity = { version = "2.0.0-rc5", default-features = false, path = "../../../frame/identity" } pallet-membership = { version = "2.0.0-rc5", default-features = false, path = "../../../frame/membership" } pallet-multisig = { version = "2.0.0-rc5", default-features = false, path = "../../../frame/multisig" } +pallet-node-permission = { version = "2.0.0-rc5", default-features = false, path = "../../../frame/node-permission" } pallet-offences = { version = "2.0.0-rc5", default-features = false, path = "../../../frame/offences" } pallet-offences-benchmarking = { version = "2.0.0-rc5", path = "../../../frame/offences/benchmarking", default-features = false, optional = true } pallet-proxy = { version = "2.0.0-rc5", default-features = false, path = "../../../frame/proxy" } @@ -111,6 +113,8 @@ std = [ "sp-inherents/std", "pallet-membership/std", "pallet-multisig/std", + "sp-node-permission/std", + "pallet-node-permission/std", "pallet-identity/std", "pallet-scheduler/std", "node-primitives/std", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index acc1b07281834..f28729b540925 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -60,6 +60,7 @@ use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthority use pallet_grandpa::fg_primitives; use pallet_im_online::sr25519::AuthorityId as ImOnlineId; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; +use sp_node_permission::NodeId; use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; pub use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment}; use pallet_contracts_rpc_runtime_api::ContractExecResult; @@ -841,6 +842,9 @@ impl pallet_vesting::Trait for Runtime { type WeightInfo = (); } +impl pallet_node_permission::Trait for Runtime { +} + construct_runtime!( pub enum Runtime where Block = Block, @@ -879,6 +883,7 @@ construct_runtime!( Scheduler: pallet_scheduler::{Module, Call, Storage, Event}, Proxy: pallet_proxy::{Module, Call, Storage, Event}, Multisig: pallet_multisig::{Module, Call, Storage, Event}, + NodePermission: pallet_node_permission::{Module, Call, Storage}, } ); @@ -1107,6 +1112,12 @@ impl_runtime_apis! { } } + impl sp_node_permission::NodePermissionApi for Runtime { + fn nodes() -> Vec { + NodePermission::nodes() + } + } + impl sp_session::SessionKeys for Runtime { fn generate_session_keys(seed: Option>) -> Vec { SessionKeys::generate(seed) diff --git a/frame/node-permission/Cargo.toml b/frame/node-permission/Cargo.toml index 0df5b09e72a72..903ecbad1382d 100644 --- a/frame/node-permission/Cargo.toml +++ b/frame/node-permission/Cargo.toml @@ -16,6 +16,7 @@ codec = { package = "parity-scale-codec", version = "1.3.1", default-features = frame-support = { version = "2.0.0-rc5", default-features = false, path = "../support" } frame-system = { version = "2.0.0-rc5", default-features = false, path = "../system" } sp-node-permission = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/node-permission" } +sp-std = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/std" } [features] default = ["std"] @@ -24,4 +25,5 @@ std = [ "frame-support/std", "frame-system/std", "sp-node-permission/std", + "sp-std/std", ] diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs index 19fe186737d05..6cbd986f0f567 100644 --- a/frame/node-permission/src/lib.rs +++ b/frame/node-permission/src/lib.rs @@ -24,6 +24,7 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] +use sp_std::prelude::*; use frame_support::{decl_module, decl_storage, dispatch::DispatchResult}; use frame_system::ensure_signed; use sp_node_permission::NodeId; @@ -57,3 +58,10 @@ decl_module! { } } } + +impl Module { + /// Retrieve all the permissioned nodes. + pub fn nodes() -> Vec { + NodePublicKeys::get() + } +} \ No newline at end of file From 1c06b8ee94fc7deba658cbe02d41c145ad1bf151 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Tue, 4 Aug 2020 17:15:06 +0800 Subject: [PATCH 03/50] refresh node allowlist when import block --- client/network/src/service.rs | 5 +++++ client/peerset/src/lib.rs | 16 ++++++++++++++++ client/service/src/builder.rs | 1 + client/service/src/config.rs | 2 ++ client/service/src/lib.rs | 5 +++++ 5 files changed, 29 insertions(+) diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 11fdfc0beec3f..acf2f52586e6f 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -951,6 +951,11 @@ impl NetworkService { .to_worker .unbounded_send(ServiceToWorkerMsg::OwnBlockImported(hash, number)); } + + /// Inform the network service about refresh node allowlist. + pub fn refresh_node_allowlist(&self, peer_ids: Vec) { + self.peerset.set_node_allowlist(peer_ids); + } } impl sp_consensus::SyncOracle diff --git a/client/peerset/src/lib.rs b/client/peerset/src/lib.rs index 6f28dd036a3cc..ce9753682124c 100644 --- a/client/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -50,6 +50,7 @@ enum Action { SetPriorityGroup(String, HashSet), AddToPriorityGroup(String, PeerId), RemoveFromPriorityGroup(String, PeerId), + SetNodeAllowList(Vec), } /// Description of a reputation adjustment for a node. @@ -122,6 +123,11 @@ impl PeersetHandle { pub fn remove_from_priority_group(&self, group_id: String, peer_id: PeerId) { let _ = self.tx.unbounded_send(Action::RemoveFromPriorityGroup(group_id, peer_id)); } + + /// Refresh node allowlist + pub fn set_node_allowlist(&self, peer_ids: Vec) { + let _ = self.tx.unbounded_send(Action::SetNodeAllowList(peer_ids)); + } } /// Message that can be sent by the peer set manager (PSM). @@ -199,6 +205,8 @@ pub struct Peerset { created: Instant, /// Last time when we updated the reputations of connected nodes. latest_time_update: Instant, + /// List of nodes that are permissioned to connect. + node_allowlist: Option>, } impl Peerset { @@ -221,6 +229,7 @@ impl Peerset { message_queue: VecDeque::new(), created: now, latest_time_update: now, + None, }; for node in config.priority_groups.into_iter().flat_map(|(_, l)| l) { @@ -352,6 +361,11 @@ impl Peerset { } } + fn on_set_node_allowlist(&mut self, peer_ids: Vec) { + self.node_allowlist = Some(peer_ids); + self.alloc_slots(); // TODO only disconnect if it's not empty + } + /// Updates the value of `self.latest_time_update` and performs all the updates that happen /// over time, such as reputation increases for staying connected. fn update_time(&mut self) { @@ -665,6 +679,8 @@ impl Stream for Peerset { self.on_add_to_priority_group(&group_id, peer_id), Action::RemoveFromPriorityGroup(group_id, peer_id) => self.on_remove_from_priority_group(&group_id, peer_id), + Action::SetNodeAllowList(peers_ids) => + self.on_set_node_allowlist(peer_ids), } } } diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index eedc4582299d3..f79e5796453d2 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -899,6 +899,7 @@ pub fn build_network( system_rpc_rx, has_bootnodes, config.announce_block, + config.refresh_node_allowlist, ); // TODO: Normally, one is supposed to pass a list of notifications protocols supported by the diff --git a/client/service/src/config.rs b/client/service/src/config.rs index 15783a87f9917..e781c045924ab 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -111,6 +111,8 @@ pub struct Configuration { pub base_path: Option, /// Configuration of the output format that the informant uses. pub informant_output_format: sc_informant::OutputFormat, + /// Refresh nodes allowlist after block imported + pub refresh_node_allowlist: bool, } /// Type for tasks spawned by the executor. diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 415a5de4f930d..b70efd65b3337 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -190,6 +190,7 @@ async fn build_network_future< mut rpc_rx: TracingUnboundedReceiver>, should_have_peers: bool, announce_imported_blocks: bool, + refresh_node_allowlist: bool, ) { let mut imported_blocks_stream = client.import_notification_stream().fuse(); @@ -233,6 +234,10 @@ async fn build_network_future< notification.header.number().clone(), ); } + if refresh_node_allowlist { + let peer_ids = Vec![]; + ntework.service().refresh_node_allowlist(peer_ids); + } } // List of blocks that the client has finalized. From 686dd0bc21a71cea5e453a12ab276250b8c3da60 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Tue, 4 Aug 2020 18:28:19 +0800 Subject: [PATCH 04/50] fix more --- Cargo.lock | 1 + client/peerset/src/lib.rs | 4 ++-- client/service/Cargo.toml | 1 + client/service/src/lib.rs | 20 ++++++++++++++++---- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c8aeddcafd00f..e5da08c02aaf6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7011,6 +7011,7 @@ dependencies = [ "sp-finality-grandpa", "sp-inherents", "sp-io", + "sp-node-permission", "sp-runtime", "sp-session", "sp-state-machine", diff --git a/client/peerset/src/lib.rs b/client/peerset/src/lib.rs index ce9753682124c..d565518743048 100644 --- a/client/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -229,7 +229,7 @@ impl Peerset { message_queue: VecDeque::new(), created: now, latest_time_update: now, - None, + node_allowlist: None, }; for node in config.priority_groups.into_iter().flat_map(|(_, l)| l) { @@ -679,7 +679,7 @@ impl Stream for Peerset { self.on_add_to_priority_group(&group_id, peer_id), Action::RemoveFromPriorityGroup(group_id, peer_id) => self.on_remove_from_priority_group(&group_id, peer_id), - Action::SetNodeAllowList(peers_ids) => + Action::SetNodeAllowList(peer_ids) => self.on_set_node_allowlist(peer_ids), } } diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 3ad91dc3ea39b..7acd0bccf2ca1 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -63,6 +63,7 @@ codec = { package = "parity-scale-codec", version = "1.3.4" } sc-executor = { version = "0.8.0-rc5", path = "../executor" } sc-transaction-pool = { version = "2.0.0-rc5", path = "../transaction-pool" } sp-transaction-pool = { version = "2.0.0-rc5", path = "../../primitives/transaction-pool" } +sp-node-permission = { version = "2.0.0-rc5", path = "../../primitives/node-permission" } sc-rpc-server = { version = "2.0.0-rc5", path = "../rpc-servers" } sc-rpc = { version = "2.0.0-rc5", path = "../rpc" } sc-block-builder = { version = "0.8.0-rc5", path = "../block-builder" } diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index b70efd65b3337..923898e3f35b7 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -45,6 +45,9 @@ use futures::{Future, FutureExt, Stream, StreamExt, stream, compat::*}; use sc_network::{NetworkStatus, network_state::NetworkState, PeerId}; use log::{warn, debug, error}; use codec::{Encode, Decode}; +use sc_client_api::blockchain::HeaderBackend; +use sp_api::ProvideRuntimeApi; +use sp_node_permission::NodePermissionApi; use sp_runtime::generic::BlockId; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use parity_util_mem::MallocSizeOf; @@ -180,7 +183,7 @@ pub struct PartialComponents, + C: BlockchainEvents + ProvideRuntimeApi + HeaderBackend, H: sc_network::ExHashT > ( role: Role, @@ -191,7 +194,10 @@ async fn build_network_future< should_have_peers: bool, announce_imported_blocks: bool, refresh_node_allowlist: bool, -) { +) +where + >::Api: NodePermissionApi +{ let mut imported_blocks_stream = client.import_notification_stream().fuse(); // Stream of finalized blocks reported by the client. @@ -235,8 +241,14 @@ async fn build_network_future< ); } if refresh_node_allowlist { - let peer_ids = Vec![]; - ntework.service().refresh_node_allowlist(peer_ids); + let id = BlockId::hash(client.info().best_hash); + let node_allowlist = match client.runtime_api().nodes(&id) { + Ok(r) => r, + Err(_) => return, // TODO log error + }; + // Transform to PeerId + let peer_ids = node_allowlist.iter().map(|pubkey| pubkey.into_peer_id()); + network.service().refresh_node_allowlist(peer_ids); } } From e12784b89c55f695124d8b4be2572bbca44ca1c3 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Wed, 5 Aug 2020 21:10:07 +0800 Subject: [PATCH 05/50] more --- Cargo.lock | 4 ++++ bin/node/runtime/src/lib.rs | 2 +- client/cli/src/config.rs | 1 + client/service/Cargo.toml | 2 ++ client/service/src/builder.rs | 2 ++ client/service/src/lib.rs | 13 ++++++++++++- frame/node-permission/Cargo.toml | 2 ++ frame/node-permission/src/lib.rs | 4 +++- primitives/node-permission/Cargo.toml | 2 ++ primitives/node-permission/src/lib.rs | 4 +++- utils/browser/src/lib.rs | 1 + 11 files changed, 33 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e5da08c02aaf6..17340f4c29ee2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4563,6 +4563,7 @@ dependencies = [ "frame-support", "frame-system", "parity-scale-codec", + "sp-core", "sp-node-permission", "sp-std", ] @@ -6968,6 +6969,7 @@ dependencies = [ "async-std", "derive_more", "directories", + "ed25519-dalek", "exit-future", "futures 0.1.29", "futures 0.3.5", @@ -6975,6 +6977,7 @@ dependencies = [ "hash-db", "jsonrpc-pubsub", "lazy_static", + "libp2p", "log", "parity-scale-codec", "parity-util-mem 0.7.0", @@ -7955,6 +7958,7 @@ dependencies = [ "parity-scale-codec", "sp-api", "sp-application-crypto", + "sp-core", "sp-runtime", "sp-std", ] diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index f28729b540925..624894de5cc45 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -60,7 +60,7 @@ use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthority use pallet_grandpa::fg_primitives; use pallet_im_online::sr25519::AuthorityId as ImOnlineId; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; -use sp_node_permission::NodeId; +use sp_core::ed25519::Public as NodeId; use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; pub use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment}; use pallet_contracts_rpc_runtime_api::ContractExecResult; diff --git a/client/cli/src/config.rs b/client/cli/src/config.rs index efda45a0eca9a..e1a21d34c9add 100644 --- a/client/cli/src/config.rs +++ b/client/cli/src/config.rs @@ -475,6 +475,7 @@ pub trait CliConfiguration: Sized { role, base_path: Some(base_path), informant_output_format: Default::default(), + refresh_node_allowlist: true, }) } diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 7acd0bccf2ca1..4e85e44969300 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -75,6 +75,8 @@ prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../.. sc-tracing = { version = "2.0.0-rc5", path = "../tracing" } tracing = "0.1.18" parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] } +ed25519-dalek = { version = "1.0.0-pre.4", default-features = false, features = ["u64_backend", "alloc"] } +libp2p = { version = "0.22.0", default-features = false } [target.'cfg(not(target_os = "unknown"))'.dependencies] tempfile = "3.1.0" diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index f79e5796453d2..af6930e615a5f 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -61,6 +61,7 @@ use sc_client_api::{ execution_extensions::ExecutionExtensions }; use sp_blockchain::{HeaderMetadata, HeaderBackend}; +use sp_node_permission::NodePermissionApi; /// A utility trait for building an RPC extension given a `DenyUnsafe` instance. /// This is useful since at service definition time we don't know whether the @@ -831,6 +832,7 @@ pub fn build_network( TCl: ProvideRuntimeApi + HeaderMetadata + Chain + BlockBackend + BlockIdTo + ProofProvider + HeaderBackend + BlockchainEvents + 'static, + >::Api: NodePermissionApi, TExPool: MaintainedTransactionPool::Hash> + 'static, TImpQu: ImportQueue + 'static, { diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 923898e3f35b7..960d928fedef0 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -39,6 +39,8 @@ use std::net::SocketAddr; use std::collections::HashMap; use std::time::Duration; use std::task::Poll; +use libp2p::identity::PublicKey; +use libp2p::identity::ed25519::PublicKey as Ed25519PublicKey; use parking_lot::Mutex; use futures::{Future, FutureExt, Stream, StreamExt, stream, compat::*}; @@ -240,6 +242,7 @@ where notification.header.number().clone(), ); } + if refresh_node_allowlist { let id = BlockId::hash(client.info().best_hash); let node_allowlist = match client.runtime_api().nodes(&id) { @@ -247,7 +250,15 @@ where Err(_) => return, // TODO log error }; // Transform to PeerId - let peer_ids = node_allowlist.iter().map(|pubkey| pubkey.into_peer_id()); + let peer_ids = node_allowlist.iter() + .map(|pubkey| { + PublicKey::Ed25519( + Ed25519PublicKey::decode(&pubkey.0) + .unwrap() + ) // TODO error handling + .into_peer_id() + }) + .collect(); network.service().refresh_node_allowlist(peer_ids); } } diff --git a/frame/node-permission/Cargo.toml b/frame/node-permission/Cargo.toml index 903ecbad1382d..6897a998185ad 100644 --- a/frame/node-permission/Cargo.toml +++ b/frame/node-permission/Cargo.toml @@ -15,6 +15,7 @@ targets = ["x86_64-unknown-linux-gnu"] codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } frame-support = { version = "2.0.0-rc5", default-features = false, path = "../support" } frame-system = { version = "2.0.0-rc5", default-features = false, path = "../system" } +sp-core = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/core" } sp-node-permission = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/node-permission" } sp-std = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/std" } @@ -24,6 +25,7 @@ std = [ "codec/std", "frame-support/std", "frame-system/std", + "sp-core/std", "sp-node-permission/std", "sp-std/std", ] diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs index 6cbd986f0f567..145e981363961 100644 --- a/frame/node-permission/src/lib.rs +++ b/frame/node-permission/src/lib.rs @@ -27,7 +27,9 @@ use sp_std::prelude::*; use frame_support::{decl_module, decl_storage, dispatch::DispatchResult}; use frame_system::ensure_signed; -use sp_node_permission::NodeId; +use sp_core::ed25519::Public; + +type NodeId = Public; /// The module's config trait. pub trait Trait: frame_system::Trait {} diff --git a/primitives/node-permission/Cargo.toml b/primitives/node-permission/Cargo.toml index 60f0e9c718e16..b75d4b0b44d69 100644 --- a/primitives/node-permission/Cargo.toml +++ b/primitives/node-permission/Cargo.toml @@ -15,6 +15,7 @@ targets = ["x86_64-unknown-linux-gnu"] codec = { package = "parity-scale-codec", default-features = false, version = "1.3.1" } sp-api = { version = "2.0.0-rc5", default-features = false, path = "../api" } sp-application-crypto = { version = "2.0.0-rc5", default-features = false, path = "../application-crypto" } +sp-core = { version = "2.0.0-rc5", default-features = false, path = "../core" } sp-runtime = { version = "2.0.0-rc5", default-features = false, path = "../runtime" } sp-std = { version = "2.0.0-rc5", default-features = false, path = "../std" } @@ -24,6 +25,7 @@ std = [ "codec/std", "sp-api/std", "sp-application-crypto/std", + "sp-core/std", "sp-runtime/std", "sp-std/std", ] diff --git a/primitives/node-permission/src/lib.rs b/primitives/node-permission/src/lib.rs index 2a4852ec6b999..76c101be7b753 100644 --- a/primitives/node-permission/src/lib.rs +++ b/primitives/node-permission/src/lib.rs @@ -19,6 +19,7 @@ #![cfg_attr(not(feature = "std"), no_std)] +use sp_core::ed25519::Public; use sp_std::vec::Vec; mod app { @@ -36,7 +37,8 @@ mod app { // } /// A node identifier. -pub type NodeId = app::Public; +// pub type NodeId = app::Public; +pub type NodeId = Public; sp_api::decl_runtime_apis! { /// The node permission api diff --git a/utils/browser/src/lib.rs b/utils/browser/src/lib.rs index 718a9b9751154..bc7522d14e4a2 100644 --- a/utils/browser/src/lib.rs +++ b/utils/browser/src/lib.rs @@ -106,6 +106,7 @@ where enable_color: false, prefix: String::new(), }, + refresh_node_allowlist: true, }; Ok(config) From 06207c5b51e47e4009c48d6cef7c81adbcd08bbb Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Wed, 5 Aug 2020 22:23:13 +0800 Subject: [PATCH 06/50] use well known keys --- client/service/src/builder.rs | 9 ++++----- client/service/src/lib.rs | 15 +++++++-------- client/service/test/src/lib.rs | 1 + frame/node-permission/src/lib.rs | 11 ++++++++--- primitives/storage/src/lib.rs | 3 +++ 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index af6930e615a5f..f3527ce75881a 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -56,12 +56,11 @@ use sp_core::traits::{CodeExecutor, SpawnNamed}; use sp_runtime::BuildStorage; use sc_client_api::{ BlockBackend, BlockchainEvents, - backend::StorageProvider, + backend::{StorageProvider, Backend as BackendT}, proof_provider::ProofProvider, execution_extensions::ExecutionExtensions }; use sp_blockchain::{HeaderMetadata, HeaderBackend}; -use sp_node_permission::NodePermissionApi; /// A utility trait for building an RPC extension given a `DenyUnsafe` instance. /// This is useful since at service definition time we don't know whether the @@ -816,7 +815,7 @@ pub struct BuildNetworkParams<'a, TBl: BlockT, TExPool, TImpQu, TCl> { } /// Build the network service, the network status sinks and an RPC sender. -pub fn build_network( +pub fn build_network( params: BuildNetworkParams ) -> Result< ( @@ -829,10 +828,10 @@ pub fn build_network( > where TBl: BlockT, + TBE: BackendT + 'static, TCl: ProvideRuntimeApi + HeaderMetadata + Chain + BlockBackend + BlockIdTo + ProofProvider + - HeaderBackend + BlockchainEvents + 'static, - >::Api: NodePermissionApi, + HeaderBackend + BlockchainEvents + StorageProvider + 'static, TExPool: MaintainedTransactionPool::Hash> + 'static, TImpQu: ImportQueue + 'static, { diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 960d928fedef0..db7775a1e34c8 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -48,12 +48,13 @@ use sc_network::{NetworkStatus, network_state::NetworkState, PeerId}; use log::{warn, debug, error}; use codec::{Encode, Decode}; use sc_client_api::blockchain::HeaderBackend; -use sp_api::ProvideRuntimeApi; -use sp_node_permission::NodePermissionApi; use sp_runtime::generic::BlockId; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use parity_util_mem::MallocSizeOf; use sp_utils::{status_sinks, mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}}; +use sp_core::storage::well_known_keys; +use sp_core::storage::StorageKey; +use sc_client_api::backend::{Backend as BackendT, StorageProvider}; pub use self::error::Error; pub use self::builder::{ @@ -185,7 +186,8 @@ pub struct PartialComponents + ProvideRuntimeApi + HeaderBackend, + BE: BackendT, + C: BlockchainEvents + StorageProvider + HeaderBackend, H: sc_network::ExHashT > ( role: Role, @@ -196,10 +198,7 @@ async fn build_network_future< should_have_peers: bool, announce_imported_blocks: bool, refresh_node_allowlist: bool, -) -where - >::Api: NodePermissionApi -{ +) { let mut imported_blocks_stream = client.import_notification_stream().fuse(); // Stream of finalized blocks reported by the client. @@ -245,7 +244,7 @@ where if refresh_node_allowlist { let id = BlockId::hash(client.info().best_hash); - let node_allowlist = match client.runtime_api().nodes(&id) { + let node_allowlist = match client.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())) { Ok(r) => r, Err(_) => return, // TODO log error }; diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 0d589cee7e12d..722c98434e937 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -269,6 +269,7 @@ fn node_config = storage::unhashed::get(well_known_keys::NODE_ALLOWLIST).unwrap(); + nodes.push(node_public_key); + storage::unhashed::put(well_known_keys::NODE_ALLOWLIST, &nodes); Ok(()) } } diff --git a/primitives/storage/src/lib.rs b/primitives/storage/src/lib.rs index 073d80291c13e..70add1ca9cfdf 100644 --- a/primitives/storage/src/lib.rs +++ b/primitives/storage/src/lib.rs @@ -151,6 +151,9 @@ pub mod well_known_keys { /// Prefix of the default child storage keys in the top trie. pub const DEFAULT_CHILD_STORAGE_KEY_PREFIX: &'static [u8] = b":child_storage:default:"; + /// Permissioned node list. + pub const NODE_ALLOWLIST: &'static [u8] = b":node_allowlist"; + /// Whether a key is a child storage key. /// /// This is convenience function which basically checks if the given `key` starts From 18639a5281513b2b4ecb1fde855754367419e220 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Wed, 5 Aug 2020 22:33:38 +0800 Subject: [PATCH 07/50] rm runtime api --- Cargo.lock | 15 -------- Cargo.toml | 1 - bin/node/runtime/Cargo.toml | 2 -- bin/node/runtime/src/lib.rs | 6 ---- client/service/Cargo.toml | 1 - frame/node-permission/Cargo.toml | 2 -- primitives/node-permission/Cargo.toml | 31 ---------------- primitives/node-permission/src/lib.rs | 52 --------------------------- 8 files changed, 110 deletions(-) delete mode 100644 primitives/node-permission/Cargo.toml delete mode 100644 primitives/node-permission/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 17340f4c29ee2..daeca0660d689 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3785,7 +3785,6 @@ dependencies = [ "sp-inherents", "sp-io", "sp-keyring", - "sp-node-permission", "sp-offchain", "sp-runtime", "sp-session", @@ -4564,7 +4563,6 @@ dependencies = [ "frame-system", "parity-scale-codec", "sp-core", - "sp-node-permission", "sp-std", ] @@ -7014,7 +7012,6 @@ dependencies = [ "sp-finality-grandpa", "sp-inherents", "sp-io", - "sp-node-permission", "sp-runtime", "sp-session", "sp-state-machine", @@ -7951,18 +7948,6 @@ dependencies = [ "strum", ] -[[package]] -name = "sp-node-permission" -version = "2.0.0-rc5" -dependencies = [ - "parity-scale-codec", - "sp-api", - "sp-application-crypto", - "sp-core", - "sp-runtime", - "sp-std", -] - [[package]] name = "sp-npos-elections" version = "2.0.0-rc5" diff --git a/Cargo.toml b/Cargo.toml index 767d82d66bcb5..e56b08e1f99ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -139,7 +139,6 @@ members = [ "primitives/finality-grandpa", "primitives/inherents", "primitives/keyring", - "primitives/node-permission", "primitives/offchain", "primitives/panic-handler", "primitives/npos-elections", diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 8486408803678..55ff5730cbe06 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -25,7 +25,6 @@ sp-authority-discovery = { version = "2.0.0-rc5", default-features = false, path sp-consensus-babe = { version = "0.8.0-rc5", default-features = false, path = "../../../primitives/consensus/babe" } sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-rc5"} sp-inherents = { version = "2.0.0-rc5", default-features = false, path = "../../../primitives/inherents" } -sp-node-permission = { version = "2.0.0-rc5", default-features = false, path = "../../../primitives/node-permission" } node-primitives = { version = "2.0.0-rc5", default-features = false, path = "../primitives" } sp-offchain = { version = "2.0.0-rc5", default-features = false, path = "../../../primitives/offchain" } sp-core = { version = "2.0.0-rc5", default-features = false, path = "../../../primitives/core" } @@ -113,7 +112,6 @@ std = [ "sp-inherents/std", "pallet-membership/std", "pallet-multisig/std", - "sp-node-permission/std", "pallet-node-permission/std", "pallet-identity/std", "pallet-scheduler/std", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 624894de5cc45..bc7ca118bc64c 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1112,12 +1112,6 @@ impl_runtime_apis! { } } - impl sp_node_permission::NodePermissionApi for Runtime { - fn nodes() -> Vec { - NodePermission::nodes() - } - } - impl sp_session::SessionKeys for Runtime { fn generate_session_keys(seed: Option>) -> Vec { SessionKeys::generate(seed) diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 4e85e44969300..8cc73418032d8 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -63,7 +63,6 @@ codec = { package = "parity-scale-codec", version = "1.3.4" } sc-executor = { version = "0.8.0-rc5", path = "../executor" } sc-transaction-pool = { version = "2.0.0-rc5", path = "../transaction-pool" } sp-transaction-pool = { version = "2.0.0-rc5", path = "../../primitives/transaction-pool" } -sp-node-permission = { version = "2.0.0-rc5", path = "../../primitives/node-permission" } sc-rpc-server = { version = "2.0.0-rc5", path = "../rpc-servers" } sc-rpc = { version = "2.0.0-rc5", path = "../rpc" } sc-block-builder = { version = "0.8.0-rc5", path = "../block-builder" } diff --git a/frame/node-permission/Cargo.toml b/frame/node-permission/Cargo.toml index 6897a998185ad..f23f05e3cda75 100644 --- a/frame/node-permission/Cargo.toml +++ b/frame/node-permission/Cargo.toml @@ -16,7 +16,6 @@ codec = { package = "parity-scale-codec", version = "1.3.1", default-features = frame-support = { version = "2.0.0-rc5", default-features = false, path = "../support" } frame-system = { version = "2.0.0-rc5", default-features = false, path = "../system" } sp-core = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/core" } -sp-node-permission = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/node-permission" } sp-std = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/std" } [features] @@ -26,6 +25,5 @@ std = [ "frame-support/std", "frame-system/std", "sp-core/std", - "sp-node-permission/std", "sp-std/std", ] diff --git a/primitives/node-permission/Cargo.toml b/primitives/node-permission/Cargo.toml deleted file mode 100644 index b75d4b0b44d69..0000000000000 --- a/primitives/node-permission/Cargo.toml +++ /dev/null @@ -1,31 +0,0 @@ -[package] -name = "sp-node-permission" -version = "2.0.0-rc5" -authors = ["Parity Technologies "] -description = "Node permission primitives" -edition = "2018" -license = "Apache-2.0" -homepage = "https://substrate.dev" -repository = "https://github.com/paritytech/substrate/" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -codec = { package = "parity-scale-codec", default-features = false, version = "1.3.1" } -sp-api = { version = "2.0.0-rc5", default-features = false, path = "../api" } -sp-application-crypto = { version = "2.0.0-rc5", default-features = false, path = "../application-crypto" } -sp-core = { version = "2.0.0-rc5", default-features = false, path = "../core" } -sp-runtime = { version = "2.0.0-rc5", default-features = false, path = "../runtime" } -sp-std = { version = "2.0.0-rc5", default-features = false, path = "../std" } - -[features] -default = ["std"] -std = [ - "codec/std", - "sp-api/std", - "sp-application-crypto/std", - "sp-core/std", - "sp-runtime/std", - "sp-std/std", -] diff --git a/primitives/node-permission/src/lib.rs b/primitives/node-permission/src/lib.rs deleted file mode 100644 index 76c101be7b753..0000000000000 --- a/primitives/node-permission/src/lib.rs +++ /dev/null @@ -1,52 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Runtime Api to get permissioned nodes - -#![cfg_attr(not(feature = "std"), no_std)] - -use sp_core::ed25519::Public; -use sp_std::vec::Vec; - -mod app { - use sp_application_crypto::{ - key_types::NODE_PERMISSION, - app_crypto, - ed25519, - }; - app_crypto!(ed25519, NODE_PERMISSION); -} - -// sp_application_crypto::with_pair! { -// /// A node keypair. -// pub type NodePair = app::Pair; -// } - -/// A node identifier. -// pub type NodeId = app::Public; -pub type NodeId = Public; - -sp_api::decl_runtime_apis! { - /// The node permission api - /// - /// This api is used by the `client/peerset` to retrieve identifiers - /// of the current permissioned nodes. - pub trait NodePermissionApi { - /// Retrieve node identifiers of the current permissioned nodes. - fn nodes() -> Vec; - } -} From 24a61a28b885795729e8cde7f05e3c9066b30bb8 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Wed, 5 Aug 2020 22:48:28 +0800 Subject: [PATCH 08/50] refactor --- bin/node/runtime/src/lib.rs | 1 - client/cli/src/config.rs | 2 +- client/network/src/service.rs | 4 ++-- client/peerset/src/lib.rs | 12 ++++++------ client/service/src/builder.rs | 2 +- client/service/src/config.rs | 4 ++-- client/service/src/lib.rs | 6 +++--- client/service/test/src/lib.rs | 2 +- utils/browser/src/lib.rs | 2 +- 9 files changed, 17 insertions(+), 18 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index bc7ca118bc64c..5d4eefae4c081 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -60,7 +60,6 @@ use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthority use pallet_grandpa::fg_primitives; use pallet_im_online::sr25519::AuthorityId as ImOnlineId; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; -use sp_core::ed25519::Public as NodeId; use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; pub use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment}; use pallet_contracts_rpc_runtime_api::ContractExecResult; diff --git a/client/cli/src/config.rs b/client/cli/src/config.rs index e1a21d34c9add..c5b43eee7171d 100644 --- a/client/cli/src/config.rs +++ b/client/cli/src/config.rs @@ -475,7 +475,7 @@ pub trait CliConfiguration: Sized { role, base_path: Some(base_path), informant_output_format: Default::default(), - refresh_node_allowlist: true, + update_allowlist: true, }) } diff --git a/client/network/src/service.rs b/client/network/src/service.rs index acf2f52586e6f..b6096f4dc4264 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -953,8 +953,8 @@ impl NetworkService { } /// Inform the network service about refresh node allowlist. - pub fn refresh_node_allowlist(&self, peer_ids: Vec) { - self.peerset.set_node_allowlist(peer_ids); + pub fn set_peer_allowlist(&self, peer_ids: Vec) { + self.peerset.set_allowlist(peer_ids); } } diff --git a/client/peerset/src/lib.rs b/client/peerset/src/lib.rs index d565518743048..4cc6d4ab202fd 100644 --- a/client/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -50,7 +50,7 @@ enum Action { SetPriorityGroup(String, HashSet), AddToPriorityGroup(String, PeerId), RemoveFromPriorityGroup(String, PeerId), - SetNodeAllowList(Vec), + SetAllowList(Vec), } /// Description of a reputation adjustment for a node. @@ -125,8 +125,8 @@ impl PeersetHandle { } /// Refresh node allowlist - pub fn set_node_allowlist(&self, peer_ids: Vec) { - let _ = self.tx.unbounded_send(Action::SetNodeAllowList(peer_ids)); + pub fn set_allowlist(&self, peer_ids: Vec) { + let _ = self.tx.unbounded_send(Action::SetAllowList(peer_ids)); } } @@ -361,7 +361,7 @@ impl Peerset { } } - fn on_set_node_allowlist(&mut self, peer_ids: Vec) { + fn on_set_allowlist(&mut self, peer_ids: Vec) { self.node_allowlist = Some(peer_ids); self.alloc_slots(); // TODO only disconnect if it's not empty } @@ -679,8 +679,8 @@ impl Stream for Peerset { self.on_add_to_priority_group(&group_id, peer_id), Action::RemoveFromPriorityGroup(group_id, peer_id) => self.on_remove_from_priority_group(&group_id, peer_id), - Action::SetNodeAllowList(peer_ids) => - self.on_set_node_allowlist(peer_ids), + Action::SetAllowList(peer_ids) => + self.on_set_allowlist(peer_ids), } } } diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index f3527ce75881a..29b16bebbc4d5 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -900,7 +900,7 @@ pub fn build_network( system_rpc_rx, has_bootnodes, config.announce_block, - config.refresh_node_allowlist, + config.update_allowlist, ); // TODO: Normally, one is supposed to pass a list of notifications protocols supported by the diff --git a/client/service/src/config.rs b/client/service/src/config.rs index e781c045924ab..321c9a8b11440 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -111,8 +111,8 @@ pub struct Configuration { pub base_path: Option, /// Configuration of the output format that the informant uses. pub informant_output_format: sc_informant::OutputFormat, - /// Refresh nodes allowlist after block imported - pub refresh_node_allowlist: bool, + /// Refresh nodes allowlist after block imported TODO do i need this? + pub update_allowlist: bool, } /// Type for tasks spawned by the executor. diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index db7775a1e34c8..6c2e7b234b280 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -197,7 +197,7 @@ async fn build_network_future< mut rpc_rx: TracingUnboundedReceiver>, should_have_peers: bool, announce_imported_blocks: bool, - refresh_node_allowlist: bool, + update_allowlist: bool, ) { let mut imported_blocks_stream = client.import_notification_stream().fuse(); @@ -242,7 +242,7 @@ async fn build_network_future< ); } - if refresh_node_allowlist { + if update_allowlist { let id = BlockId::hash(client.info().best_hash); let node_allowlist = match client.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())) { Ok(r) => r, @@ -258,7 +258,7 @@ async fn build_network_future< .into_peer_id() }) .collect(); - network.service().refresh_node_allowlist(peer_ids); + network.service().set_peer_allowlist(peer_ids); } } diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 722c98434e937..2486e2495edc4 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -269,7 +269,7 @@ fn node_config Date: Thu, 6 Aug 2020 10:55:08 +0800 Subject: [PATCH 09/50] improve node permission module --- bin/node/runtime/src/lib.rs | 9 +++- client/peerset/src/lib.rs | 8 ++-- frame/node-permission/src/lib.rs | 71 ++++++++++++++++++++++---------- 3 files changed, 61 insertions(+), 27 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 5d4eefae4c081..ccb2fbcd65d10 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -841,7 +841,14 @@ impl pallet_vesting::Trait for Runtime { type WeightInfo = (); } +parameter_types! { + pub const MaxPermissionedNodes: u32 = 8; +} impl pallet_node_permission::Trait for Runtime { + type Event = Event; + type MaxPermissionedNodes = MaxPermissionedNodes; + type AddNodeOrigin = EnsureRootOrHalfCouncil; + type ResetNodesOrigin = EnsureRootOrHalfCouncil; } construct_runtime!( @@ -882,7 +889,7 @@ construct_runtime!( Scheduler: pallet_scheduler::{Module, Call, Storage, Event}, Proxy: pallet_proxy::{Module, Call, Storage, Event}, Multisig: pallet_multisig::{Module, Call, Storage, Event}, - NodePermission: pallet_node_permission::{Module, Call, Storage}, + NodePermission: pallet_node_permission::{Module, Call, Storage, Event}, } ); diff --git a/client/peerset/src/lib.rs b/client/peerset/src/lib.rs index 4cc6d4ab202fd..96bc77abc6c8f 100644 --- a/client/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -205,8 +205,8 @@ pub struct Peerset { created: Instant, /// Last time when we updated the reputations of connected nodes. latest_time_update: Instant, - /// List of nodes that are permissioned to connect. - node_allowlist: Option>, + /// List of nodes that are allowed to connect. + allowlist: Option>, } impl Peerset { @@ -229,7 +229,7 @@ impl Peerset { message_queue: VecDeque::new(), created: now, latest_time_update: now, - node_allowlist: None, + allowlist: None, }; for node in config.priority_groups.into_iter().flat_map(|(_, l)| l) { @@ -362,7 +362,7 @@ impl Peerset { } fn on_set_allowlist(&mut self, peer_ids: Vec) { - self.node_allowlist = Some(peer_ids); + self.allowlist = Some(peer_ids); self.alloc_slots(); // TODO only disconnect if it's not empty } diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs index 47c3386288f02..5769fbca3bfea 100644 --- a/frame/node-permission/src/lib.rs +++ b/frame/node-permission/src/lib.rs @@ -24,51 +24,78 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] +use sp_core::{ed25519::Public, storage::well_known_keys}; use sp_std::prelude::*; use frame_support::{ - decl_module, decl_storage, dispatch::DispatchResult, - storage, + decl_module, decl_storage, decl_event, decl_error, + dispatch::DispatchResult, storage, ensure, + traits::{Get, EnsureOrigin}, }; -use frame_system::ensure_signed; -use sp_core::ed25519::Public; -use sp_core::storage::well_known_keys; type NodeId = Public; /// The module's config trait. -pub trait Trait: frame_system::Trait {} +pub trait Trait: frame_system::Trait { + /// The event type of this module. + type Event: From + Into<::Event>; + + /// The maximum number of permissioned nodes that are allowed to set + type MaxPermissionedNodes: Get; + + /// The origin which can add a permissioned node. + type AddNodeOrigin: EnsureOrigin; + + /// The origin which can reset the permissioned nodes. + type ResetNodesOrigin: EnsureOrigin; +} decl_storage! { trait Store for Module as NodePermission { - /// Public keys of the permissioned nodes. - // TODO add genesis config - NodePublicKeys get(fn node_public_keys): Vec; + } +} + +decl_event! { + pub enum Event { + /// The given node was added. + NodeAdded, + } +} + +decl_error! { + /// Error for the node permission module. + pub enum Error for Module { + /// Too many permissioned nodes. + TooManyNodes, + AlreadyJoined, } } decl_module! { pub struct Module for enum Call where origin: T::Origin { - // type Error = Error; + /// The maximum number of permissioned nodes + const MaxPermissionedNodes: u32 = T::MaxPermissionedNodes::get(); - // fn deposit_event() = default; + type Error = Error; + + fn deposit_event() = default; /// Add a node to the allowlist. + /// + /// Can only be called from `T::AddNodeOrigin`. #[weight = 0] pub fn add_node(origin, node_public_key: NodeId) -> DispatchResult { - // TODO ensure to be coucil/root - let _who = ensure_signed(origin)?; + T::AddNodeOrigin::ensure_origin(origin)?; + + let mut nodes: Vec = storage::unhashed::get_or_default(well_known_keys::NODE_ALLOWLIST); + ensure!(nodes.len() < T::MaxPermissionedNodes::get() as usize, Error::::TooManyNodes); - let mut nodes: Vec = storage::unhashed::get(well_known_keys::NODE_ALLOWLIST).unwrap(); - nodes.push(node_public_key); + let location = nodes.binary_search(&node_public_key).err().ok_or(Error::::AlreadyJoined)?; + nodes.insert(location, node_public_key); storage::unhashed::put(well_known_keys::NODE_ALLOWLIST, &nodes); + + Self::deposit_event(Event::NodeAdded); + Ok(()) } } } - -impl Module { - /// Retrieve all the permissioned nodes. - pub fn nodes() -> Vec { - NodePublicKeys::get() - } -} \ No newline at end of file From eb67330af19e74f6b5d01ac8c59188f244ccb223 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Thu, 6 Aug 2020 17:40:19 +0800 Subject: [PATCH 10/50] more --- client/peerset/src/lib.rs | 35 +++++++++++++++++++++++++++++++++++ client/service/src/lib.rs | 9 ++------- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/client/peerset/src/lib.rs b/client/peerset/src/lib.rs index 96bc77abc6c8f..1b67283425a2c 100644 --- a/client/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -426,6 +426,41 @@ impl Peerset { fn alloc_slots(&mut self) { self.update_time(); + // Try to connnect to permissioned nodes + if let Some(peer_ids) = &self.allowlist { + loop { + let next = { + let data = &mut self.data; + peer_ids.iter() + .filter(move |n| { + data.peer(n).into_connected().is_none() + }) + .next() + .cloned() + }; + + let next = match next { + Some(n) => n, + None => break, + }; + + let next = match self.data.peer(&next) { + peersstate::Peer::Unknown(n) => n.discover(), + peersstate::Peer::NotConnected(n) => n, + peersstate::Peer::Connected(_) => { + debug_assert!(false, "State inconsistency: not connected state"); + break; + } + }; + + match next.try_outgoing() { + Ok(conn) => self.message_queue.push_back(Message::Connect(conn.into_peer_id())), + Err(_) => break, // No more slots available. + } + } + return; + } + // Try to connect to all the reserved nodes that we are not connected to. loop { let next = { diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 6c2e7b234b280..00556395aec06 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -250,13 +250,8 @@ async fn build_network_future< }; // Transform to PeerId let peer_ids = node_allowlist.iter() - .map(|pubkey| { - PublicKey::Ed25519( - Ed25519PublicKey::decode(&pubkey.0) - .unwrap() - ) // TODO error handling - .into_peer_id() - }) + .filter_map(|pubkey| Ed25519PublicKey::decode(&pubkey.0).ok()) + .map(|pubkey| PublicKey::Ed25519(pubkey).into_peer_id()) .collect(); network.service().set_peer_allowlist(peer_ids); } From c652e07a40453f76420eed661311970d7d2fcb65 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Sun, 9 Aug 2020 10:38:52 +0800 Subject: [PATCH 11/50] fix build --- client/peerset/src/lib.rs | 14 +++++++++++- client/service/src/lib.rs | 47 +++++++++++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/client/peerset/src/lib.rs b/client/peerset/src/lib.rs index 1b67283425a2c..979df1ad14477 100644 --- a/client/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -23,7 +23,7 @@ mod peersstate; use std::{collections::{HashSet, HashMap}, collections::VecDeque}; use futures::prelude::*; -use log::{debug, error, trace}; +use log::{debug, error, trace, info}; use serde_json::json; use std::{pin::Pin, task::{Context, Poll}, time::Duration}; use wasm_timer::Instant; @@ -428,6 +428,7 @@ impl Peerset { // Try to connnect to permissioned nodes if let Some(peer_ids) = &self.allowlist { + info!(target: "peerset", "alloc_slots peer_ids =========: {:?}", peer_ids); loop { let next = { let data = &mut self.data; @@ -444,6 +445,8 @@ impl Peerset { None => break, }; + info!(target: "peerset", "this peer_id =========: {:?}", next); + let next = match self.data.peer(&next) { peersstate::Peer::Unknown(n) => n.discover(), peersstate::Peer::NotConnected(n) => n, @@ -569,6 +572,15 @@ impl Peerset { trace!(target: "peerset", "Incoming {:?}", peer_id); self.update_time(); + // Only connect to permissioned node + if let Some(peer_ids) = &self.allowlist { + info!(target: "peerset", "-======== allowed incoming peer_ids =========: {:?}, incoming: {:?}", peer_ids, peer_id); + if !peer_ids.contains(&peer_id) { + self.message_queue.push_back(Message::Reject(index)); + return; + } + } + if self.reserved_only { if !self.priority_groups.get(RESERVED_NODES).map_or(false, |n| n.contains(&peer_id)) { self.message_queue.push_back(Message::Reject(index)); diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 00556395aec06..299e040a25902 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -45,7 +45,7 @@ use parking_lot::Mutex; use futures::{Future, FutureExt, Stream, StreamExt, stream, compat::*}; use sc_network::{NetworkStatus, network_state::NetworkState, PeerId}; -use log::{warn, debug, error}; +use log::{warn, debug, error, info}; use codec::{Encode, Decode}; use sc_client_api::blockchain::HeaderBackend; use sp_runtime::generic::BlockId; @@ -53,7 +53,8 @@ use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use parity_util_mem::MallocSizeOf; use sp_utils::{status_sinks, mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}}; use sp_core::storage::well_known_keys; -use sp_core::storage::StorageKey; +use sp_core::storage::{StorageKey, StorageData}; +use sp_core::ed25519::Public as NodePublic; use sc_client_api::backend::{Backend as BackendT, StorageProvider}; pub use self::error::Error; @@ -244,13 +245,45 @@ async fn build_network_future< if update_allowlist { let id = BlockId::hash(client.info().best_hash); - let node_allowlist = match client.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())) { - Ok(r) => r, - Err(_) => return, // TODO log error - }; + let raw_allowlist = match client.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())) { + Ok(Some(r)) => r, + Ok(None) => { + info!( + target: "sub-libp2p", + "🏷 err in get storage -------------" + ); + StorageData(vec![]) + }, + Err(_) => { + info!( + target: "sub-libp2p", + "🏷 err in get storage error result -------------" + ); + return + }, // TODO log error + }; + let node_allowlist: Vec = match Decode::decode(&mut &raw_allowlist.0[..]) { + Ok(r) => r, + Err(_) => { + info!( + target: "sub-libp2p", + "🏷 err in decode------------- {:?}", + raw_allowlist + ); + vec![] + }, // TODO log error + }; // Transform to PeerId let peer_ids = node_allowlist.iter() - .filter_map(|pubkey| Ed25519PublicKey::decode(&pubkey.0).ok()) + .filter_map(|pubkey| { + info!( + target: "sub-libp2p", + "🏷 deocoding node id now: {:?}, {:?}", + Ed25519PublicKey::decode(&pubkey.0), + &pubkey.0 + ); + Ed25519PublicKey::decode(&pubkey.0).ok() + }) .map(|pubkey| PublicKey::Ed25519(pubkey).into_peer_id()) .collect(); network.service().set_peer_allowlist(peer_ids); From 804785899d0711dfeb8728cae51b68696b9bd8db Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Mon, 10 Aug 2020 01:18:15 +0800 Subject: [PATCH 12/50] apply allowlist when init discovery --- client/cli/src/config.rs | 2 +- client/network/src/behaviour.rs | 69 +++++++++++++------ client/network/src/block_requests.rs | 18 +++-- client/network/src/chain.rs | 17 +++-- client/network/src/config.rs | 11 ++- client/network/src/error.rs | 3 + client/network/src/light_client_handler.rs | 22 +++--- client/network/src/protocol.rs | 53 ++++++++++---- client/network/src/protocol/sync.rs | 15 ++-- client/network/src/service.rs | 80 +++++++++++++++++----- client/network/test/src/lib.rs | 7 +- client/peerset/src/lib.rs | 6 +- client/service/src/builder.rs | 6 +- client/service/src/config.rs | 2 +- client/service/src/lib.rs | 28 ++++---- client/service/test/src/lib.rs | 2 +- utils/browser/src/lib.rs | 2 +- 17 files changed, 243 insertions(+), 100 deletions(-) diff --git a/client/cli/src/config.rs b/client/cli/src/config.rs index c5b43eee7171d..b471d6c4ca514 100644 --- a/client/cli/src/config.rs +++ b/client/cli/src/config.rs @@ -475,7 +475,7 @@ pub trait CliConfiguration: Sized { role, base_path: Some(base_path), informant_output_format: Default::default(), - update_allowlist: true, + permissioned_network: true, // TODO make it default to false }) } diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index a43c61054d974..974ecfc49f39b 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -29,6 +29,7 @@ use libp2p::identify::IdentifyInfo; use libp2p::kad::record; use libp2p::swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters}; use log::debug; +use sc_client_api::backend::Backend as BackendT; use sp_consensus::{BlockOrigin, import_queue::{IncomingBlock, Origin}}; use sp_runtime::{traits::{Block as BlockT, NumberFor}, ConsensusEngineId, Justification}; use std::{ @@ -42,20 +43,23 @@ use std::{ /// General behaviour of the network. Combines all protocols together. #[derive(NetworkBehaviour)] #[behaviour(out_event = "BehaviourOut", poll_method = "poll")] -pub struct Behaviour { +pub struct Behaviour + where + BE: BackendT +{ /// All the substrate-specific protocols. - substrate: Protocol, + substrate: Protocol, /// Periodically pings and identifies the nodes we are connected to, and store information in a /// cache. peer_info: peer_info::PeerInfoBehaviour, /// Discovers nodes of the network. discovery: DiscoveryBehaviour, /// Block request handling. - block_requests: block_requests::BlockRequests, + block_requests: block_requests::BlockRequests, /// Finality proof request handling. finality_proof_requests: finality_requests::FinalityProofRequests, /// Light client request handling. - light_client_handler: light_client_handler::LightClientHandler, + light_client_handler: light_client_handler::LightClientHandler, /// Queue of events to produce for the outside. #[behaviour(ignore)] @@ -150,16 +154,19 @@ pub enum BehaviourOut { Dht(DhtEvent, Duration), } -impl Behaviour { +impl Behaviour + where + BE: BackendT +{ /// Builds a new `Behaviour`. pub fn new( - substrate: Protocol, + substrate: Protocol, role: Role, user_agent: String, local_public_key: PublicKey, - block_requests: block_requests::BlockRequests, + block_requests: block_requests::BlockRequests, finality_proof_requests: finality_requests::FinalityProofRequests, - light_client_handler: light_client_handler::LightClientHandler, + light_client_handler: light_client_handler::LightClientHandler, disco_config: DiscoveryConfig, ) -> Self { Behaviour { @@ -237,12 +244,12 @@ impl Behaviour { } /// Returns a shared reference to the user protocol. - pub fn user_protocol(&self) -> &Protocol { + pub fn user_protocol(&self) -> &Protocol { &self.substrate } /// Returns a mutable reference to the user protocol. - pub fn user_protocol_mut(&mut self) -> &mut Protocol { + pub fn user_protocol_mut(&mut self) -> &mut Protocol { &mut self.substrate } @@ -278,15 +285,20 @@ fn reported_roles_to_observed_role(local_role: &Role, remote: &PeerId, roles: Ro } } -impl NetworkBehaviourEventProcess for -Behaviour { +impl NetworkBehaviourEventProcess for +Behaviour + where + BE: BackendT +{ fn inject_event(&mut self, event: void::Void) { void::unreachable(event) } } -impl NetworkBehaviourEventProcess> for -Behaviour { +impl NetworkBehaviourEventProcess> for +Behaviour + where BE: BackendT +{ fn inject_event(&mut self, event: CustomMessageOutcome) { match event { CustomMessageOutcome::BlockImport(origin, blocks) => @@ -358,7 +370,10 @@ Behaviour { } } -impl NetworkBehaviourEventProcess> for Behaviour { +impl NetworkBehaviourEventProcess> for Behaviour + where + BE: BackendT +{ fn inject_event(&mut self, event: block_requests::Event) { match event { block_requests::Event::AnsweredRequest { peer, total_handling_time } => { @@ -392,7 +407,10 @@ impl NetworkBehaviourEventProcess NetworkBehaviourEventProcess> for Behaviour { +impl NetworkBehaviourEventProcess> for Behaviour + where + BE: BackendT +{ fn inject_event(&mut self, event: finality_requests::Event) { match event { finality_requests::Event::Response { peer, block_hash, proof } => { @@ -412,8 +430,11 @@ impl NetworkBehaviourEventProcess NetworkBehaviourEventProcess - for Behaviour { +impl NetworkBehaviourEventProcess + for Behaviour + where + BE: BackendT +{ fn inject_event(&mut self, event: peer_info::PeerInfoEvent) { let peer_info::PeerInfoEvent::Identified { peer_id, @@ -442,8 +463,11 @@ impl NetworkBehaviourEventProcess NetworkBehaviourEventProcess - for Behaviour { +impl NetworkBehaviourEventProcess + for Behaviour + where + BE: BackendT +{ fn inject_event(&mut self, out: DiscoveryOut) { match out { DiscoveryOut::UnroutablePeer(_peer_id) => { @@ -476,7 +500,10 @@ impl NetworkBehaviourEventProcess } } -impl Behaviour { +impl Behaviour + where + BE: BackendT +{ fn poll(&mut self, _: &mut Context, _: &mut impl PollParameters) -> Poll>> { if let Some(event) = self.events.pop_front() { return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event)) diff --git a/client/network/src/block_requests.rs b/client/network/src/block_requests.rs index d7a12816dd4e1..6c2ff40db1de9 100644 --- a/client/network/src/block_requests.rs +++ b/client/network/src/block_requests.rs @@ -54,6 +54,7 @@ use libp2p::{ }; use prost::Message; use sp_runtime::{generic::BlockId, traits::{Block, Header, One, Zero}}; +use sc_client_api::backend::Backend; use std::{ cmp::min, collections::{HashMap, VecDeque}, @@ -194,11 +195,14 @@ impl Config { } /// The block request handling behaviour. -pub struct BlockRequests { +pub struct BlockRequests + where + BE: Backend +{ /// This behaviour's configuration. config: Config, /// Blockchain client. - chain: Arc>, + chain: Arc>, /// List of all active connections and the requests we've sent. peers: HashMap>>, /// Futures sending back the block request response. Returns the `PeerId` we sent back to, and @@ -243,11 +247,12 @@ pub enum SendRequestOutcome { EncodeError(prost::EncodeError), } -impl BlockRequests +impl BlockRequests where B: Block, + BE: Backend { - pub fn new(cfg: Config, chain: Arc>) -> Self { + pub fn new(cfg: Config, chain: Arc>) -> Self { BlockRequests { config: cfg, chain, @@ -462,9 +467,10 @@ where } } -impl NetworkBehaviour for BlockRequests +impl NetworkBehaviour for BlockRequests where - B: Block + B: Block, + BE: Backend + 'static, { type ProtocolsHandler = OneShotHandler, OutboundProtocol, NodeEvent>; type OutEvent = Event; diff --git a/client/network/src/chain.rs b/client/network/src/chain.rs index 20fbe0284397d..19b94ebea0cb3 100644 --- a/client/network/src/chain.rs +++ b/client/network/src/chain.rs @@ -19,18 +19,25 @@ //! Blockchain access trait use sp_blockchain::{Error, HeaderBackend, HeaderMetadata}; -use sc_client_api::{BlockBackend, ProofProvider}; +use sc_client_api::{ + backend::{Backend as BackendT, StorageProvider}, + BlockBackend, ProofProvider +}; use sp_runtime::traits::{Block as BlockT, BlockIdTo}; /// Local client abstraction for the network. -pub trait Client: HeaderBackend + ProofProvider + BlockIdTo - + BlockBackend + HeaderMetadata + Send + Sync +pub trait Client: HeaderBackend + ProofProvider + BlockIdTo + + BlockBackend + HeaderMetadata + StorageProvider + Send + Sync + where + Backend: BackendT {} -impl Client for T +impl Client for T where + Backend: BackendT, T: HeaderBackend + ProofProvider + BlockIdTo - + BlockBackend + HeaderMetadata + Send + Sync + + BlockBackend + HeaderMetadata + StorageProvider + + Send + Sync {} /// Finality proof provider. diff --git a/client/network/src/config.rs b/client/network/src/config.rs index 94b2993b4e6bd..73093221ae3cf 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -38,6 +38,7 @@ use libp2p::identity::{ed25519, Keypair}; use libp2p::wasm_ext; use libp2p::{multiaddr, Multiaddr, PeerId}; use prometheus_endpoint::Registry; +use sc_client_api::backend::Backend as BackendT; use sp_consensus::{block_validation::BlockAnnounceValidator, import_queue::ImportQueue}; use sp_runtime::{traits::Block as BlockT, ConsensusEngineId}; use std::{borrow::Cow, convert::TryFrom, future::Future, pin::Pin, str::FromStr}; @@ -53,7 +54,10 @@ use std::{ use zeroize::Zeroize; /// Network initialization parameters. -pub struct Params { +pub struct Params + where + BE: BackendT +{ /// Assigned role for our node (full, light, ...). pub role: Role, @@ -65,7 +69,7 @@ pub struct Params { pub network_config: NetworkConfiguration, /// Client that contains the blockchain. - pub chain: Arc>, + pub chain: Arc>, /// Finality proof provider. /// @@ -103,6 +107,9 @@ pub struct Params { /// Registry for recording prometheus metrics to. pub metrics_registry: Option, + + /// Whether a node is in a permissioned network or not. + pub permissioned_network: bool, } /// Role of the local node. diff --git a/client/network/src/error.rs b/client/network/src/error.rs index d5a4024ef53d7..796410e389568 100644 --- a/client/network/src/error.rs +++ b/client/network/src/error.rs @@ -61,6 +61,8 @@ pub enum Error { /// The invalid addresses. addresses: Vec, }, + /// Unable to fetch storage error. + InvalidStorage, } // Make `Debug` use the `Display` implementation. @@ -78,6 +80,7 @@ impl std::error::Error for Error { Error::DuplicateBootnode { .. } => None, Error::Prometheus(ref err) => Some(err), Error::AddressesForAnotherTransport { .. } => None, + Error::InvalidStorage => None, // TODO is it correct } } } diff --git a/client/network/src/light_client_handler.rs b/client/network/src/light_client_handler.rs index 678a717a898ff..29660a7b6c29d 100644 --- a/client/network/src/light_client_handler.rs +++ b/client/network/src/light_client_handler.rs @@ -58,6 +58,7 @@ use nohash_hasher::IntMap; use prost::Message; use sc_client_api::{ StorageProof, + backend::Backend, light::{ self, RemoteReadRequest, RemoteBodyRequest, ChangesProof, RemoteCallRequest, RemoteChangesRequest, RemoteHeaderRequest, @@ -284,11 +285,14 @@ enum PeerStatus { } /// The light client handler behaviour. -pub struct LightClientHandler { +pub struct LightClientHandler + where + BE: Backend +{ /// This behaviour's configuration. config: Config, /// Blockchain client. - chain: Arc>, + chain: Arc>, /// Verifies that received responses are correct. checker: Arc>, /// Peer information (addresses, their best block, etc.) @@ -305,14 +309,15 @@ pub struct LightClientHandler { peerset: sc_peerset::PeersetHandle, } -impl LightClientHandler +impl LightClientHandler where B: Block, + BE: Backend, { /// Construct a new light client handler. pub fn new( cfg: Config, - chain: Arc>, + chain: Arc>, checker: Arc>, peerset: sc_peerset::PeersetHandle, ) -> Self { @@ -744,9 +749,10 @@ where } } -impl NetworkBehaviour for LightClientHandler +impl NetworkBehaviour for LightClientHandler where - B: Block + B: Block, + BE: Backend + 'static, { type ProtocolsHandler = OneShotHandler>; type OutEvent = Void; @@ -1499,7 +1505,7 @@ mod tests { ( ok: bool , ps: sc_peerset::PeersetHandle , cf: super::Config - ) -> LightClientHandler + ) -> LightClientHandler { let client = Arc::new(substrate_test_runtime_client::new()); let checker = Arc::new(DummyFetchChecker { ok, _mark: std::marker::PhantomData }); @@ -1510,7 +1516,7 @@ mod tests { ConnectedPoint::Dialer { address: Multiaddr::empty() } } - fn poll(mut b: &mut LightClientHandler) -> Poll> { + 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.rs b/client/network/src/protocol.rs index f1ce6d2b5608e..8106451faf687 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -59,7 +59,10 @@ use std::sync::Arc; use std::fmt::Write; use std::{cmp, io, num::NonZeroUsize, pin::Pin, task::Poll, time}; use log::{log, Level, trace, debug, warn, error}; -use sc_client_api::{ChangesProof, StorageProof}; +use sc_client_api::{ + backend::Backend as BackendT, + ChangesProof, StorageProof +}; use util::LruHashSet; use wasm_timer::Instant; @@ -227,7 +230,10 @@ impl Future for PendingTransaction { } // Lock must always be taken in order declared here. -pub struct Protocol { +pub struct Protocol + where + BE: BackendT +{ /// Interval at which we call `tick`. tick_timeout: Pin + Send>>, /// Interval at which we call `propagate_transactions`. @@ -243,8 +249,8 @@ pub struct Protocol { pending_transactions_peers: HashMap>, config: ProtocolConfig, genesis_hash: B::Hash, - sync: ChainSync, - context_data: ContextData, + sync: ChainSync, + context_data: ContextData, /// List of nodes for which we perform additional logging because they are important for the /// user. important_peers: HashSet, @@ -306,11 +312,14 @@ pub struct PeerInfo { } /// Data necessary to create a context. -struct ContextData { +struct ContextData + where + BE: BackendT +{ // All connected peers peers: HashMap>, stats: HashMap<&'static str, PacketStats>, - pub chain: Arc>, + pub chain: Arc>, } /// Configuration for the Substrate-specific part of the networking layer. @@ -344,8 +353,12 @@ struct BlockAnnouncesHandshake { genesis_hash: B::Hash, } -impl BlockAnnouncesHandshake { - fn build(protocol_config: &ProtocolConfig, chain: &Arc>) -> Self { +impl BlockAnnouncesHandshake +{ + fn build(protocol_config: &ProtocolConfig, chain: &Arc>) -> Self + where + BE: BackendT + { let info = chain.info(); BlockAnnouncesHandshake { genesis_hash: info.genesis_hash, @@ -357,7 +370,10 @@ impl BlockAnnouncesHandshake { } /// Builds a SCALE-encoded "Status" message to send as handshake for the legacy protocol. -fn build_status_message(protocol_config: &ProtocolConfig, chain: &Arc>) -> Vec { +fn build_status_message(protocol_config: &ProtocolConfig, chain: &Arc>) -> Vec + where + BE: BackendT +{ let info = chain.info(); let status = message::generic::Status { version: CURRENT_VERSION, @@ -383,12 +399,15 @@ enum Fallback { BlockAnnounce, } -impl Protocol { +impl Protocol + where + BE: BackendT +{ /// Create a new instance. pub fn new( config: ProtocolConfig, local_peer_id: PeerId, - chain: Arc>, + chain: Arc>, transaction_pool: Arc>, finality_proof_provider: Option>>, finality_proof_request_builder: Option>, @@ -397,7 +416,7 @@ impl Protocol { block_announce_validator: Box + Send>, metrics_registry: Option<&Registry>, boot_node_ids: Arc>, - ) -> error::Result<(Protocol, sc_peerset::PeersetHandle)> { + ) -> error::Result<(Protocol, sc_peerset::PeersetHandle)> { let info = chain.info(); let sync = ChainSync::new( config.roles, @@ -1927,7 +1946,10 @@ fn send_message( } } -impl NetworkBehaviour for Protocol { +impl NetworkBehaviour for Protocol + where + BE: BackendT + 'static +{ type ProtocolsHandler = ::ProtocolsHandler; type OutEvent = CustomMessageOutcome; @@ -2148,7 +2170,10 @@ impl NetworkBehaviour for Protocol { } } -impl Drop for Protocol { +impl Drop for Protocol + where + BE: BackendT +{ fn drop(&mut self) { debug!(target: "sync", "Network stats:\n{}", self.format_stats()); } diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index bfd8c4fe218de..d818d82142a80 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -29,6 +29,7 @@ use codec::Encode; use blocks::BlockCollection; +use sc_client_api::backend::Backend as BackendT; use sp_blockchain::{Error as ClientError, Info as BlockchainInfo, HeaderMetadata}; use sp_consensus::{BlockOrigin, BlockStatus, block_validation::{BlockAnnounceValidator, Validation}, @@ -154,9 +155,12 @@ impl Default for PendingRequests { /// The main data structure which contains all the state for a chains /// active syncing strategy. -pub struct ChainSync { +pub struct ChainSync + where + BE: BackendT +{ /// Chain client. - client: Arc>, + client: Arc>, /// The active peers that we are using to sync and their PeerSync status peers: HashMap>, /// A `BlockCollection` of blocks that are being downloaded from peers @@ -343,11 +347,14 @@ pub enum OnBlockFinalityProof { } } -impl ChainSync { +impl ChainSync + where + BE: BackendT +{ /// Create a new instance. pub fn new( role: Roles, - client: Arc>, + client: Arc>, info: &BlockchainInfo, request_builder: Option>, block_announce_validator: Box + Send>, diff --git a/client/network/src/service.rs b/client/network/src/service.rs index b6096f4dc4264..f253f3b55f58b 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -45,6 +45,10 @@ use crate::{ use futures::prelude::*; use libp2p::{PeerId, multiaddr, Multiaddr}; use libp2p::core::{ConnectedPoint, Executor, connection::{ConnectionError, PendingConnectionError}, either::EitherError}; +use libp2p::identity::{ + ed25519::PublicKey as Ed25519PublicKey, + PublicKey +}; use libp2p::kad::record; use libp2p::ping::handler::PingFailure; use libp2p::swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent, protocols_handler::NodeHandlerWrapperError}; @@ -55,9 +59,12 @@ use prometheus_endpoint::{ PrometheusError, Registry, U64, }; use sc_peerset::PeersetHandle; +use sc_client_api::backend::Backend as BackendT; +use sp_core::storage::{StorageKey, well_known_keys}; use sp_consensus::import_queue::{BlockImportError, BlockImportResult, ImportQueue, Link}; use sp_runtime::{ traits::{Block as BlockT, NumberFor}, + generic::BlockId, ConsensusEngineId, }; use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}; @@ -110,13 +117,16 @@ pub struct NetworkService { _marker: PhantomData, } -impl NetworkWorker { +impl NetworkWorker + where + BE: BackendT +{ /// Creates the network service. /// /// Returns a `NetworkWorker` that implements `Future` and must be regularly polled in order /// for the network processing to advance. From it, you can extract a `NetworkService` using /// `worker.service()`. The `NetworkService` can be shared through the codebase. - pub fn new(params: Params) -> Result, Error> { + pub fn new(params: Params) -> Result, Error> { // Ensure the listen addresses are consistent with the transport. ensure_addresses_consistent_with_transport( params.network_config.listen_addresses.iter(), @@ -220,12 +230,29 @@ impl NetworkWorker { ] }; + // Initialize the permissioned nodes + let mut init_allowlist = None; + if params.permissioned_network { + let id = BlockId::hash(params.chain.info().best_hash); + let node_allowlist = match params.chain.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())) { + Ok(r) => r, + Err(_) => return Err(Error::InvalidStorage), // TODO log error + }; + // Transform to PeerId + let peer_ids = node_allowlist.iter() + .filter_map(|pubkey| Ed25519PublicKey::decode(&pubkey.0).ok()) + .map(|pubkey| PublicKey::Ed25519(pubkey).into_peer_id()) + .collect(); + init_allowlist = Some(peer_ids); + } + let peerset_config = sc_peerset::PeersetConfig { in_peers: params.network_config.in_peers, out_peers: params.network_config.out_peers, bootnodes, reserved_only: params.network_config.non_reserved_mode == NonReservedPeerMode::Deny, priority_groups, + init_allowlist, }; // Private and public keys configuration. @@ -270,7 +297,7 @@ impl NetworkWorker { )?; // Build the swarm. - let (mut swarm, bandwidth): (Swarm, _) = { + let (mut swarm, bandwidth): (Swarm, _) = { let user_agent = format!( "{} ({})", params.network_config.client_version, @@ -355,14 +382,14 @@ impl NetworkWorker { // Listen on multiaddresses. for addr in ¶ms.network_config.listen_addresses { - if let Err(err) = Swarm::::listen_on(&mut swarm, addr.clone()) { + if let Err(err) = Swarm::::listen_on(&mut swarm, addr.clone()) { warn!(target: "sub-libp2p", "Can't listen on {} because: {:?}", addr, err) } } // Add external addresses. for addr in ¶ms.network_config.public_addresses { - Swarm::::add_external_address(&mut swarm, addr.clone()); + Swarm::::add_external_address(&mut swarm, addr.clone()); } let external_addresses = Arc::new(Mutex::new(Vec::new())); @@ -477,14 +504,14 @@ impl NetworkWorker { /// Returns the local `PeerId`. pub fn local_peer_id(&self) -> &PeerId { - Swarm::::local_peer_id(&self.network_service) + Swarm::::local_peer_id(&self.network_service) } /// Returns the list of addresses we are listening on. /// /// Does **NOT** include a trailing `/p2p/` with our `PeerId`. pub fn listen_addresses(&self) -> impl Iterator { - Swarm::::listeners(&self.network_service) + Swarm::::listeners(&self.network_service) } /// Get network state. @@ -538,9 +565,9 @@ impl NetworkWorker { }; NetworkState { - peer_id: Swarm::::local_peer_id(&swarm).to_base58(), - listened_addresses: Swarm::::listeners(&swarm).cloned().collect(), - external_addresses: Swarm::::external_addresses(&swarm).cloned().collect(), + peer_id: Swarm::::local_peer_id(&swarm).to_base58(), + listened_addresses: Swarm::::listeners(&swarm).cloned().collect(), + external_addresses: Swarm::::external_addresses(&swarm).cloned().collect(), average_download_per_sec: self.service.bandwidth.average_download_per_sec(), average_upload_per_sec: self.service.bandwidth.average_upload_per_sec(), connected_peers, @@ -1105,7 +1132,10 @@ enum ServiceToWorkerMsg { /// /// You are encouraged to poll this in a separate background thread or task. #[must_use = "The NetworkWorker must be polled in order for the network to advance"] -pub struct NetworkWorker { +pub struct NetworkWorker + where + BE: BackendT + 'static +{ /// Updated by the `NetworkWorker` and loaded by the `NetworkService`. external_addresses: Arc>>, /// Updated by the `NetworkWorker` and loaded by the `NetworkService`. @@ -1115,7 +1145,7 @@ pub struct NetworkWorker { /// The network service that can be extracted and shared through the codebase. service: Arc>, /// The *actual* network. - network_service: Swarm, + network_service: Swarm, /// The import queue that was passed at initialization. import_queue: Box>, /// Messages from the [`NetworkService`] that must be processed. @@ -1355,7 +1385,10 @@ impl Metrics { } } -impl Future for NetworkWorker { +impl Future for NetworkWorker + where + BE: BackendT +{ type Output = (); fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context) -> Poll { @@ -1712,7 +1745,7 @@ impl Future for NetworkWorker { // Update the variables shared with the `NetworkService`. this.num_connected.store(num_connected_peers, Ordering::Relaxed); { - let external_addresses = Swarm::::external_addresses(&this.network_service).cloned().collect(); + let external_addresses = Swarm::::external_addresses(&this.network_service).cloned().collect(); *this.external_addresses.lock() = external_addresses; } @@ -1749,7 +1782,10 @@ impl Future for NetworkWorker { } } -impl Unpin for NetworkWorker { +impl Unpin for NetworkWorker + where + BE: BackendT +{ } /// Turns bytes that are potentially UTF-8 into a reasonable representable string. @@ -1764,14 +1800,20 @@ fn maybe_utf8_bytes_to_string(id: &[u8]) -> Cow { } /// The libp2p swarm, customized for our needs. -type Swarm = libp2p::swarm::Swarm>; +type Swarm = libp2p::swarm::Swarm>; // Implementation of `import_queue::Link` trait using the available local variables. -struct NetworkLink<'a, B: BlockT, H: ExHashT> { - protocol: &'a mut Swarm, +struct NetworkLink<'a, B: BlockT, BE, H: ExHashT> +where + BE: BackendT + 'static +{ + protocol: &'a mut Swarm, } -impl<'a, B: BlockT, H: ExHashT> Link for NetworkLink<'a, B, H> { +impl<'a, B: BlockT, BE, H: ExHashT> Link for NetworkLink<'a, B, BE, H> + where + BE: BackendT +{ fn blocks_processed( &mut self, imported: usize, diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 35587cbdc08b3..1a983d1f1b730 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -221,7 +221,7 @@ pub struct Peer { block_import: BlockImportAdapter<()>, select_chain: Option>, backend: Option>, - network: NetworkWorker::Hash>, + network: NetworkWorker::Hash>, imported_blocks_stream: Pin> + Send>>, finality_notification_stream: Pin> + Send>>, } @@ -680,6 +680,7 @@ pub trait TestNetFactory: Sized { block_announce_validator: config.block_announce_validator .unwrap_or_else(|| Box::new(DefaultBlockAnnounceValidator)), metrics_registry: None, + permissioned_network: false }).unwrap(); self.mut_peers(|peers| { @@ -704,6 +705,7 @@ pub trait TestNetFactory: Sized { }); } + // TODO this needs fix, Peer need a network with LightBackend /// Add a light peer. fn add_light_peer(&mut self) { let (c, backend) = substrate_test_runtime_client::new_light(); @@ -759,6 +761,7 @@ pub trait TestNetFactory: Sized { import_queue, block_announce_validator: Box::new(DefaultBlockAnnounceValidator), metrics_registry: None, + permissioned_network: false, }).unwrap(); self.mut_peers(|peers| { @@ -769,7 +772,7 @@ pub trait TestNetFactory: Sized { let imported_blocks_stream = Box::pin(client.import_notification_stream().fuse()); let finality_notification_stream = Box::pin(client.finality_notification_stream().fuse()); - peers.push(Peer { + peers.push(LightPeer { data, verifier, select_chain: None, diff --git a/client/peerset/src/lib.rs b/client/peerset/src/lib.rs index 979df1ad14477..2d03f1f790279 100644 --- a/client/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -180,6 +180,9 @@ pub struct PeersetConfig { /// > **Note**: Keep in mind that the networking has to know an address for these nodes, /// > otherwise it will not be able to connect to them. pub priority_groups: Vec<(String, HashSet)>, + + /// Initialization of permissioned nodes + pub init_allowlist: Option> } /// Side of the peer set manager owned by the network. In other words, the "receiving" side. @@ -229,7 +232,7 @@ impl Peerset { message_queue: VecDeque::new(), created: now, latest_time_update: now, - allowlist: None, + allowlist: config.init_allowlist, }; for node in config.priority_groups.into_iter().flat_map(|(_, l)| l) { @@ -573,6 +576,7 @@ impl Peerset { self.update_time(); // Only connect to permissioned node + trace!(target: "peerset", "==== incoming allowlist {:?}", &self.allowlist); if let Some(peer_ids) = &self.allowlist { info!(target: "peerset", "-======== allowed incoming peer_ids =========: {:?}, incoming: {:?}", peer_ids, peer_id); if !peer_ids.contains(&peer_id) { diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 29b16bebbc4d5..0d4b3561592cb 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -844,6 +844,7 @@ pub fn build_network( imports_external_transactions: !matches!(config.role, Role::Light), pool: transaction_pool, client: client.clone(), + _backend: Default::default(), }); let protocol_id = { @@ -882,7 +883,8 @@ pub fn build_network( import_queue: Box::new(import_queue), protocol_id, block_announce_validator, - metrics_registry: config.prometheus_config.as_ref().map(|config| config.registry.clone()) + metrics_registry: config.prometheus_config.as_ref().map(|config| config.registry.clone()), + permissioned_network: config.permissioned_network, }; let has_bootnodes = !network_params.network_config.boot_nodes.is_empty(); @@ -900,7 +902,7 @@ pub fn build_network( system_rpc_rx, has_bootnodes, config.announce_block, - config.update_allowlist, + config.permissioned_network, ); // TODO: Normally, one is supposed to pass a list of notifications protocols supported by the diff --git a/client/service/src/config.rs b/client/service/src/config.rs index 321c9a8b11440..25290c4b94429 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -112,7 +112,7 @@ pub struct Configuration { /// Configuration of the output format that the informant uses. pub informant_output_format: sc_informant::OutputFormat, /// Refresh nodes allowlist after block imported TODO do i need this? - pub update_allowlist: bool, + pub permissioned_network: bool, } /// Type for tasks spawned by the executor. diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 299e040a25902..e6a27ba20b9e5 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -39,8 +39,11 @@ use std::net::SocketAddr; use std::collections::HashMap; use std::time::Duration; use std::task::Poll; -use libp2p::identity::PublicKey; -use libp2p::identity::ed25519::PublicKey as Ed25519PublicKey; +use std::marker::PhantomData; +use libp2p::identity::{ + ed25519::PublicKey as Ed25519PublicKey, + PublicKey +}; use parking_lot::Mutex; use futures::{Future, FutureExt, Stream, StreamExt, stream, compat::*}; @@ -52,8 +55,7 @@ use sp_runtime::generic::BlockId; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use parity_util_mem::MallocSizeOf; use sp_utils::{status_sinks, mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}}; -use sp_core::storage::well_known_keys; -use sp_core::storage::{StorageKey, StorageData}; +use sp_core::storage::{StorageKey, StorageData, well_known_keys}; use sp_core::ed25519::Public as NodePublic; use sc_client_api::backend::{Backend as BackendT, StorageProvider}; @@ -192,13 +194,13 @@ async fn build_network_future< H: sc_network::ExHashT > ( role: Role, - mut network: sc_network::NetworkWorker, + mut network: sc_network::NetworkWorker, client: Arc, status_sinks: NetworkStatusSinks, mut rpc_rx: TracingUnboundedReceiver>, should_have_peers: bool, announce_imported_blocks: bool, - update_allowlist: bool, + permissioned_network: bool, ) { let mut imported_blocks_stream = client.import_notification_stream().fuse(); @@ -243,7 +245,7 @@ async fn build_network_future< ); } - if update_allowlist { + if permissioned_network { let id = BlockId::hash(client.info().best_hash); let raw_allowlist = match client.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())) { Ok(Some(r)) => r, @@ -507,10 +509,11 @@ impl RpcSession { } /// Transaction pool adapter. -pub struct TransactionPoolAdapter { +pub struct TransactionPoolAdapter { imports_external_transactions: bool, pool: Arc

, client: Arc, + _backend: PhantomData, } /// Get transactions for propagation. @@ -534,12 +537,13 @@ where .collect() } -impl sc_network::config::TransactionPool for - TransactionPoolAdapter +impl sc_network::config::TransactionPool for + TransactionPoolAdapter where - C: sc_network::config::Client + Send + Sync, - Pool: 'static + TransactionPool, B: BlockT, + BE: BackendT, + C: sc_network::config::Client + Send + Sync, + Pool: 'static + TransactionPool, H: std::hash::Hash + Eq + sp_runtime::traits::Member + sp_runtime::traits::MaybeSerialize, E: 'static + IntoPoolError + From, { diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index 2486e2495edc4..fb54e2b7038a2 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -269,7 +269,7 @@ fn node_config Date: Mon, 10 Aug 2020 10:19:27 +0800 Subject: [PATCH 13/50] fix init peerset --- Cargo.lock | 3 +++ bin/node/cli/Cargo.toml | 1 + bin/node/cli/src/chain_spec.rs | 11 ++++++++-- bin/node/runtime/src/lib.rs | 2 +- bin/node/testing/src/genesis.rs | 7 +++++-- client/network/src/service.rs | 36 ++++++++++++++++++++++++++++---- frame/node-permission/Cargo.toml | 4 ++++ frame/node-permission/src/lib.rs | 7 +++++++ 8 files changed, 62 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index daeca0660d689..f4a93dd2b8cfa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3571,6 +3571,7 @@ dependencies = [ "pallet-grandpa", "pallet-im-online", "pallet-indices", + "pallet-node-permission", "pallet-staking", "pallet-timestamp", "pallet-transaction-payment", @@ -4562,7 +4563,9 @@ dependencies = [ "frame-support", "frame-system", "parity-scale-codec", + "serde", "sp-core", + "sp-io", "sp-std", ] diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index 16ab9bbe80641..f941e6edd41f9 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -89,6 +89,7 @@ pallet-im-online = { version = "2.0.0-rc5", default-features = false, path = ".. pallet-authority-discovery = { version = "2.0.0-rc5", path = "../../../frame/authority-discovery" } pallet-staking = { version = "2.0.0-rc5", path = "../../../frame/staking" } pallet-grandpa = { version = "2.0.0-rc5", path = "../../../frame/grandpa" } +pallet-node-permission = { version = "2.0.0-rc5", path = "../../../frame/node-permission" } # node-specific dependencies node-runtime = { version = "2.0.0-rc5", path = "../runtime" } diff --git a/bin/node/cli/src/chain_spec.rs b/bin/node/cli/src/chain_spec.rs index e323f7956f169..67c5f0a4c1ce3 100644 --- a/bin/node/cli/src/chain_spec.rs +++ b/bin/node/cli/src/chain_spec.rs @@ -19,13 +19,13 @@ //! Substrate chain configurations. use sc_chain_spec::ChainSpecExtension; -use sp_core::{Pair, Public, crypto::UncheckedInto, sr25519}; +use sp_core::{Pair, Public, crypto::UncheckedInto, sr25519, ed25519}; use serde::{Serialize, Deserialize}; use node_runtime::{ AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, DemocracyConfig,GrandpaConfig, ImOnlineConfig, SessionConfig, SessionKeys, StakerStatus, StakingConfig, ElectionsConfig, IndicesConfig, SocietyConfig, SudoConfig, SystemConfig, - TechnicalCommitteeConfig, wasm_binary_unwrap, + TechnicalCommitteeConfig, NodePermissionConfig, wasm_binary_unwrap, }; use node_runtime::Block; use node_runtime::constants::currency::*; @@ -37,6 +37,7 @@ use sp_consensus_babe::{AuthorityId as BabeId}; use pallet_im_online::sr25519::{AuthorityId as ImOnlineId}; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; use sp_runtime::{Perbill, traits::{Verify, IdentifyAccount}}; +use std::str::FromStr; pub use node_primitives::{AccountId, Balance, Signature}; pub use node_runtime::GenesisConfig; @@ -321,6 +322,12 @@ pub fn testnet_genesis( max_members: 999, }), pallet_vesting: Some(Default::default()), + pallet_node_permission: Some(NodePermissionConfig { + nodes: vec![ + ed25519::Public::from_str("5CibWAiYURpoy3o8SsA1hS75ypxCzGrT9mt3ufCerfQYCEC6").unwrap(), + ed25519::Public::from_str("5H1bTmUExYZZfHQ5S6RJ6k1qG4H7e1WHsimKXQc1Rz2j982o").unwrap(), + ], + }), } } diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index ccb2fbcd65d10..19c17f6d00804 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -889,7 +889,7 @@ construct_runtime!( Scheduler: pallet_scheduler::{Module, Call, Storage, Event}, Proxy: pallet_proxy::{Module, Call, Storage, Event}, Multisig: pallet_multisig::{Module, Call, Storage, Event}, - NodePermission: pallet_node_permission::{Module, Call, Storage, Event}, + NodePermission: pallet_node_permission::{Module, Call, Storage, Event, Config}, } ); diff --git a/bin/node/testing/src/genesis.rs b/bin/node/testing/src/genesis.rs index 6fa178ba4bcdd..f9c4cf94f09bb 100644 --- a/bin/node/testing/src/genesis.rs +++ b/bin/node/testing/src/genesis.rs @@ -22,8 +22,8 @@ use crate::keyring::*; use sp_keyring::{Ed25519Keyring, Sr25519Keyring}; use node_runtime::{ GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, SystemConfig, - GrandpaConfig, IndicesConfig, ContractsConfig, SocietyConfig, wasm_binary_unwrap, - AccountId, StakerStatus, + GrandpaConfig, IndicesConfig, ContractsConfig, SocietyConfig, NodePermissionConfig, + wasm_binary_unwrap, AccountId, StakerStatus, }; use node_runtime::constants::currency::*; use sp_core::ChangesTrieConfiguration; @@ -119,5 +119,8 @@ pub fn config_endowed( max_members: 999, }), pallet_vesting: Some(Default::default()), + pallet_node_permission: Some(NodePermissionConfig { + nodes: vec![], + }), } } diff --git a/client/network/src/service.rs b/client/network/src/service.rs index f253f3b55f58b..a68a359a2e2ca 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -60,7 +60,8 @@ use prometheus_endpoint::{ }; use sc_peerset::PeersetHandle; use sc_client_api::backend::Backend as BackendT; -use sp_core::storage::{StorageKey, well_known_keys}; +use sp_core::ed25519::Public as NodePublic; +use sp_core::storage::{StorageKey, StorageData, well_known_keys}; use sp_consensus::import_queue::{BlockImportError, BlockImportResult, ImportQueue, Link}; use sp_runtime::{ traits::{Block as BlockT, NumberFor}, @@ -82,6 +83,7 @@ use std::{ }, task::Poll, }; +use codec::Decode; mod out_events; #[cfg(test)] @@ -234,13 +236,39 @@ impl NetworkWorker let mut init_allowlist = None; if params.permissioned_network { let id = BlockId::hash(params.chain.info().best_hash); - let node_allowlist = match params.chain.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())) { - Ok(r) => r, + let raw_allowlist = match params.chain.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())) { + Ok(Some(r)) => r, + Ok(None) => { + info!( + target: "sub-libp2p", + "🏷 err in get init storage -------------" + ); + StorageData(vec![]) + }, Err(_) => return Err(Error::InvalidStorage), // TODO log error }; + let node_allowlist: Vec = match Decode::decode(&mut &raw_allowlist.0[..]) { + Ok(r) => r, + Err(_) => { + info!( + target: "sub-libp2p", + "🏷 err in init decode------------- {:?}", + raw_allowlist + ); + vec![] + }, // TODO log error + }; // Transform to PeerId let peer_ids = node_allowlist.iter() - .filter_map(|pubkey| Ed25519PublicKey::decode(&pubkey.0).ok()) + .filter_map(|pubkey| { + info!( + target: "sub-libp2p", + "🏷 init deocoding node id now: {:?}, {:?}", + Ed25519PublicKey::decode(&pubkey.0), + &pubkey.0 + ); + Ed25519PublicKey::decode(&pubkey.0).ok() + }) .map(|pubkey| PublicKey::Ed25519(pubkey).into_peer_id()) .collect(); init_allowlist = Some(peer_ids); diff --git a/frame/node-permission/Cargo.toml b/frame/node-permission/Cargo.toml index f23f05e3cda75..96cc35d4ec5b3 100644 --- a/frame/node-permission/Cargo.toml +++ b/frame/node-permission/Cargo.toml @@ -12,18 +12,22 @@ description = "FRAME pallet for permissioned node" targets = ["x86_64-unknown-linux-gnu"] [dependencies] +serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } frame-support = { version = "2.0.0-rc5", default-features = false, path = "../support" } frame-system = { version = "2.0.0-rc5", default-features = false, path = "../system" } sp-core = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/core" } +sp-io = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/io" } sp-std = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/std" } [features] default = ["std"] std = [ + "serde", "codec/std", "frame-support/std", "frame-system/std", "sp-core/std", + "sp-io/std", "sp-std/std", ] diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs index 5769fbca3bfea..11f41d5d38927 100644 --- a/frame/node-permission/src/lib.rs +++ b/frame/node-permission/src/lib.rs @@ -31,6 +31,7 @@ use frame_support::{ dispatch::DispatchResult, storage, ensure, traits::{Get, EnsureOrigin}, }; +use codec::Encode; type NodeId = Public; @@ -52,6 +53,12 @@ pub trait Trait: frame_system::Trait { decl_storage! { trait Store for Module as NodePermission { } + add_extra_genesis { + config(nodes): Vec; + build(|config: &GenesisConfig| { + sp_io::storage::set(well_known_keys::NODE_ALLOWLIST, &config.nodes.encode()); + }); + } } decl_event! { From ad07ce68766b2e65d0ca282a87216633865e16f7 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Mon, 10 Aug 2020 11:09:08 +0800 Subject: [PATCH 14/50] remove node permission key id --- primitives/core/src/crypto.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index f47243cc94215..efacf0b2e76a6 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -1023,8 +1023,6 @@ pub mod key_types { pub const STAKING: KeyTypeId = KeyTypeId(*b"stak"); /// Key type for equivocation reporting, built-in. Identified as `fish`. pub const REPORTING: KeyTypeId = KeyTypeId(*b"fish"); - /// Key type for node permission module, build-in. Identified as `node`. - pub const NODE_PERMISSION: KeyTypeId = KeyTypeId(*b"node"); /// A key type ID useful for tests. pub const DUMMY: KeyTypeId = KeyTypeId(*b"dumy"); } From 6d6944435f816777b33a5ee274be845c2ae24065 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Thu, 13 Aug 2020 15:13:53 +0800 Subject: [PATCH 15/50] more dispatchable calls, clean logs --- bin/node/runtime/src/lib.rs | 6 +- client/cli/src/config.rs | 1 - client/network/src/config.rs | 3 - client/network/src/service.rs | 39 ++---------- client/network/test/src/lib.rs | 1 - client/service/src/builder.rs | 2 - client/service/src/config.rs | 2 - client/service/src/lib.rs | 58 ++++-------------- client/service/test/src/lib.rs | 1 - frame/node-permission/src/lib.rs | 100 ++++++++++++++++++++++++++----- utils/browser/src/lib.rs | 1 - 11 files changed, 108 insertions(+), 106 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 19c17f6d00804..1e0838fc11aa6 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -847,8 +847,10 @@ parameter_types! { impl pallet_node_permission::Trait for Runtime { type Event = Event; type MaxPermissionedNodes = MaxPermissionedNodes; - type AddNodeOrigin = EnsureRootOrHalfCouncil; - type ResetNodesOrigin = EnsureRootOrHalfCouncil; + type AddOrigin = EnsureRootOrHalfCouncil; + type RemoveOrigin = EnsureRootOrHalfCouncil; + type SwapOrigin = EnsureRootOrHalfCouncil; + type ResetOrigin = EnsureRootOrHalfCouncil; } construct_runtime!( diff --git a/client/cli/src/config.rs b/client/cli/src/config.rs index b471d6c4ca514..efda45a0eca9a 100644 --- a/client/cli/src/config.rs +++ b/client/cli/src/config.rs @@ -475,7 +475,6 @@ pub trait CliConfiguration: Sized { role, base_path: Some(base_path), informant_output_format: Default::default(), - permissioned_network: true, // TODO make it default to false }) } diff --git a/client/network/src/config.rs b/client/network/src/config.rs index 73093221ae3cf..2f44674d2ad9c 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -107,9 +107,6 @@ pub struct Params /// Registry for recording prometheus metrics to. pub metrics_registry: Option, - - /// Whether a node is in a permissioned network or not. - pub permissioned_network: bool, } /// Role of the local node. diff --git a/client/network/src/service.rs b/client/network/src/service.rs index a68a359a2e2ca..7c4b8bd092196 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -234,41 +234,14 @@ impl NetworkWorker // Initialize the permissioned nodes let mut init_allowlist = None; - if params.permissioned_network { - let id = BlockId::hash(params.chain.info().best_hash); - let raw_allowlist = match params.chain.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())) { - Ok(Some(r)) => r, - Ok(None) => { - info!( - target: "sub-libp2p", - "🏷 err in get init storage -------------" - ); - StorageData(vec![]) - }, - Err(_) => return Err(Error::InvalidStorage), // TODO log error - }; - let node_allowlist: Vec = match Decode::decode(&mut &raw_allowlist.0[..]) { - Ok(r) => r, - Err(_) => { - info!( - target: "sub-libp2p", - "🏷 err in init decode------------- {:?}", - raw_allowlist - ); - vec![] - }, // TODO log error - }; + let id = BlockId::hash(params.chain.info().best_hash); + let allowlist_storage = params.chain.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())).map_err(|_| Error::InvalidStorage)?; + if let Some(raw_allowlist) = allowlist_storage { + let node_allowlist: Vec = Decode::decode(&mut &raw_allowlist.0[..]).map_err(|_| Error::InvalidStorage)?; // TODO another error type + // Transform to PeerId let peer_ids = node_allowlist.iter() - .filter_map(|pubkey| { - info!( - target: "sub-libp2p", - "🏷 init deocoding node id now: {:?}, {:?}", - Ed25519PublicKey::decode(&pubkey.0), - &pubkey.0 - ); - Ed25519PublicKey::decode(&pubkey.0).ok() - }) + .filter_map(|pubkey| Ed25519PublicKey::decode(&pubkey.0).ok()) // TODO ok or unwrap() .map(|pubkey| PublicKey::Ed25519(pubkey).into_peer_id()) .collect(); init_allowlist = Some(peer_ids); diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 1a983d1f1b730..bea1591578cf1 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -680,7 +680,6 @@ pub trait TestNetFactory: Sized { block_announce_validator: config.block_announce_validator .unwrap_or_else(|| Box::new(DefaultBlockAnnounceValidator)), metrics_registry: None, - permissioned_network: false }).unwrap(); self.mut_peers(|peers| { diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 0d4b3561592cb..c6fa5cad85b90 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -884,7 +884,6 @@ pub fn build_network( protocol_id, block_announce_validator, metrics_registry: config.prometheus_config.as_ref().map(|config| config.registry.clone()), - permissioned_network: config.permissioned_network, }; let has_bootnodes = !network_params.network_config.boot_nodes.is_empty(); @@ -902,7 +901,6 @@ pub fn build_network( system_rpc_rx, has_bootnodes, config.announce_block, - config.permissioned_network, ); // TODO: Normally, one is supposed to pass a list of notifications protocols supported by the diff --git a/client/service/src/config.rs b/client/service/src/config.rs index 25290c4b94429..15783a87f9917 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -111,8 +111,6 @@ pub struct Configuration { pub base_path: Option, /// Configuration of the output format that the informant uses. pub informant_output_format: sc_informant::OutputFormat, - /// Refresh nodes allowlist after block imported TODO do i need this? - pub permissioned_network: bool, } /// Type for tasks spawned by the executor. diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index e6a27ba20b9e5..2cef5d80946f1 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -200,7 +200,6 @@ async fn build_network_future< mut rpc_rx: TracingUnboundedReceiver>, should_have_peers: bool, announce_imported_blocks: bool, - permissioned_network: bool, ) { let mut imported_blocks_stream = client.import_notification_stream().fuse(); @@ -245,50 +244,19 @@ async fn build_network_future< ); } - if permissioned_network { - let id = BlockId::hash(client.info().best_hash); - let raw_allowlist = match client.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())) { - Ok(Some(r)) => r, - Ok(None) => { - info!( - target: "sub-libp2p", - "🏷 err in get storage -------------" - ); - StorageData(vec![]) - }, - Err(_) => { - info!( - target: "sub-libp2p", - "🏷 err in get storage error result -------------" - ); - return - }, // TODO log error - }; - let node_allowlist: Vec = match Decode::decode(&mut &raw_allowlist.0[..]) { - Ok(r) => r, - Err(_) => { - info!( - target: "sub-libp2p", - "🏷 err in decode------------- {:?}", - raw_allowlist - ); - vec![] - }, // TODO log error - }; - // Transform to PeerId - let peer_ids = node_allowlist.iter() - .filter_map(|pubkey| { - info!( - target: "sub-libp2p", - "🏷 deocoding node id now: {:?}, {:?}", - Ed25519PublicKey::decode(&pubkey.0), - &pubkey.0 - ); - Ed25519PublicKey::decode(&pubkey.0).ok() - }) - .map(|pubkey| PublicKey::Ed25519(pubkey).into_peer_id()) - .collect(); - network.service().set_peer_allowlist(peer_ids); + let id = BlockId::hash(client.info().best_hash); + let allowlist_storage = client.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())); + if let Ok(Some(raw_allowlist)) = allowlist_storage { + let node_allowlist: Result, _> = Decode::decode(&mut &raw_allowlist.0[..]); + + if let Ok(node_allowlist) = node_allowlist { + // Transform to PeerId + let peer_ids = node_allowlist.iter() + .filter_map(|pubkey| Ed25519PublicKey::decode(&pubkey.0).ok()) // TODO ok or unwrap() + .map(|pubkey| PublicKey::Ed25519(pubkey).into_peer_id()) + .collect(); + network.service().set_peer_allowlist(peer_ids); + } } } diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index fb54e2b7038a2..0d589cee7e12d 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -269,7 +269,6 @@ fn node_config + Into<::Event>; @@ -44,15 +41,20 @@ pub trait Trait: frame_system::Trait { type MaxPermissionedNodes: Get; /// The origin which can add a permissioned node. - type AddNodeOrigin: EnsureOrigin; + type AddOrigin: EnsureOrigin; + + /// The origin which can remove a permissioned node. + type RemoveOrigin: EnsureOrigin; + + /// The origin which can swap the permissioned nodes. + type SwapOrigin: EnsureOrigin; /// The origin which can reset the permissioned nodes. - type ResetNodesOrigin: EnsureOrigin; + type ResetOrigin: EnsureOrigin; } decl_storage! { - trait Store for Module as NodePermission { - } + trait Store for Module as NodePermission {} add_extra_genesis { config(nodes): Vec; build(|config: &GenesisConfig| { @@ -63,8 +65,14 @@ decl_storage! { decl_event! { pub enum Event { - /// The given node was added. + /// The given node was added; see the transaction for node id. NodeAdded, + /// The given node was removed; see the transaction for node id. + NodeRemoved, + /// Two given nodes were swapped; see the transaction for node id. + NodesSwapped, + /// The given nodes were reset; see the transaction for new set. + NodesReset, } } @@ -73,7 +81,10 @@ decl_error! { pub enum Error for Module { /// Too many permissioned nodes. TooManyNodes, + /// The node is already joined in the list. AlreadyJoined, + /// The node doesn't exist in the list. + NotExist, } } @@ -88,21 +99,80 @@ decl_module! { /// Add a node to the allowlist. /// - /// Can only be called from `T::AddNodeOrigin`. + /// May only be called from `T::AddOrigin`. #[weight = 0] - pub fn add_node(origin, node_public_key: NodeId) -> DispatchResult { - T::AddNodeOrigin::ensure_origin(origin)?; + pub fn add_node(origin, node_public_key: NodeId) { + T::AddOrigin::ensure_origin(origin)?; - let mut nodes: Vec = storage::unhashed::get_or_default(well_known_keys::NODE_ALLOWLIST); + let mut nodes: Vec = Self::get_allowlist(); ensure!(nodes.len() < T::MaxPermissionedNodes::get() as usize, Error::::TooManyNodes); let location = nodes.binary_search(&node_public_key).err().ok_or(Error::::AlreadyJoined)?; nodes.insert(location, node_public_key); - storage::unhashed::put(well_known_keys::NODE_ALLOWLIST, &nodes); + Self::put_allowlist(nodes); Self::deposit_event(Event::NodeAdded); + } + + /// Remove a node from te allowlist. + /// + /// May only be called from `T::RemoveOrigin`. + #[weight = 0] + pub fn remove_node(origin, node_public_key: NodeId) { + T::RemoveOrigin::ensure_origin(origin)?; + + let mut nodes: Vec = Self::get_allowlist(); + + let location = nodes.binary_search(&node_public_key).ok().ok_or(Error::::NotExist)?; + nodes.remove(location); + Self::put_allowlist(nodes); + + Self::deposit_event(Event::NodeRemoved); + } + + /// Swap two nodes; `remove` is the one which will be put out of the list, + /// `add` will be in the list. + /// + /// May only be called from `T::SwapOrigin`. + #[weight = 0] + pub fn swap_node(origin, remove: NodeId, add: NodeId) { + T::SwapOrigin::ensure_origin(origin)?; + + if remove == add { return Ok(()) } + + let mut nodes: Vec = Self::get_allowlist(); + let location = nodes.binary_search(&remove).ok().ok_or(Error::::NotExist)?; + let _ = nodes.binary_search(&add).err().ok_or(Error::::AlreadyJoined)?; + nodes[location] = add; + nodes.sort(); + Self::put_allowlist(nodes); + + Self::deposit_event(Event::NodesSwapped); + } + + /// Reset all the permissioned nodes in the list. + /// + /// May only be called from `T::ResetOrigin`. + #[weight = 0] + pub fn reset_nodes(origin, nodes: Vec) { + T::ResetOrigin::ensure_origin(origin)?; + ensure!(nodes.len() < T::MaxPermissionedNodes::get() as usize, Error::::TooManyNodes); - Ok(()) + let mut nodes = nodes; + nodes.sort(); + Self::put_allowlist(nodes); + + Self::deposit_event(Event::NodesReset); } } } + +impl Module { + fn get_allowlist() -> Vec { + storage::unhashed::get_or_default(well_known_keys::NODE_ALLOWLIST) + } + + fn put_allowlist(nodes: Vec) { + storage::unhashed::put(well_known_keys::NODE_ALLOWLIST, &nodes); + } +} diff --git a/utils/browser/src/lib.rs b/utils/browser/src/lib.rs index e6753238941b7..718a9b9751154 100644 --- a/utils/browser/src/lib.rs +++ b/utils/browser/src/lib.rs @@ -106,7 +106,6 @@ where enable_color: false, prefix: String::new(), }, - permissioned_network: true, }; Ok(config) From 89e7d4c7145fba8b6eaf4cf5b2e2d408c9e040cb Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Thu, 13 Aug 2020 17:27:39 +0800 Subject: [PATCH 16/50] init in client service --- client/network/src/service.rs | 32 ++++++++----- client/network/test/src/lib.rs | 3 +- client/peerset/src/lib.rs | 86 +++++++++++++++++++--------------- client/service/src/lib.rs | 64 ++++++++++++++++++------- 4 files changed, 117 insertions(+), 68 deletions(-) diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 7c4b8bd092196..0b3de47b2b93a 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -61,7 +61,7 @@ use prometheus_endpoint::{ use sc_peerset::PeersetHandle; use sc_client_api::backend::Backend as BackendT; use sp_core::ed25519::Public as NodePublic; -use sp_core::storage::{StorageKey, StorageData, well_known_keys}; +use sp_core::storage::{StorageKey, well_known_keys}; use sp_consensus::import_queue::{BlockImportError, BlockImportResult, ImportQueue, Link}; use sp_runtime::{ traits::{Block as BlockT, NumberFor}, @@ -234,18 +234,18 @@ impl NetworkWorker // Initialize the permissioned nodes let mut init_allowlist = None; - let id = BlockId::hash(params.chain.info().best_hash); - let allowlist_storage = params.chain.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())).map_err(|_| Error::InvalidStorage)?; - if let Some(raw_allowlist) = allowlist_storage { - let node_allowlist: Vec = Decode::decode(&mut &raw_allowlist.0[..]).map_err(|_| Error::InvalidStorage)?; // TODO another error type - - // Transform to PeerId - let peer_ids = node_allowlist.iter() - .filter_map(|pubkey| Ed25519PublicKey::decode(&pubkey.0).ok()) // TODO ok or unwrap() - .map(|pubkey| PublicKey::Ed25519(pubkey).into_peer_id()) - .collect(); - init_allowlist = Some(peer_ids); - } + // let id = BlockId::hash(params.chain.info().best_hash); + // let allowlist_storage = params.chain.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())).map_err(|_| Error::InvalidStorage)?; + // if let Some(raw_allowlist) = allowlist_storage { + // let node_allowlist: Vec = Decode::decode(&mut &raw_allowlist.0[..]).map_err(|_| Error::InvalidStorage)?; // TODO another error type + + // // Transform to PeerId + // let peer_ids = node_allowlist.iter() + // .filter_map(|pubkey| Ed25519PublicKey::decode(&pubkey.0).ok()) // TODO ok or unwrap() + // .map(|pubkey| PublicKey::Ed25519(pubkey).into_peer_id()) + // .collect(); + // init_allowlist = Some(peer_ids); + // } let peerset_config = sc_peerset::PeersetConfig { in_peers: params.network_config.in_peers, @@ -908,6 +908,12 @@ impl NetworkService { Ok(()) } + /// Sets reserved peers to the new peers + pub fn set_reserved_peers(&self, peer_ids: HashSet, reserved_only: bool) { + self.peerset.set_reserved_peers(peer_ids); + self.peerset.set_reserved_only(reserved_only); + } + /// Configure an explicit fork sync request. /// Note that this function should not be used for recent blocks. /// Sync should be able to download all the recent forks normally. diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index bea1591578cf1..153ffc613a322 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -760,7 +760,6 @@ pub trait TestNetFactory: Sized { import_queue, block_announce_validator: Box::new(DefaultBlockAnnounceValidator), metrics_registry: None, - permissioned_network: false, }).unwrap(); self.mut_peers(|peers| { @@ -771,7 +770,7 @@ pub trait TestNetFactory: Sized { let imported_blocks_stream = Box::pin(client.import_notification_stream().fuse()); let finality_notification_stream = Box::pin(client.finality_notification_stream().fuse()); - peers.push(LightPeer { + peers.push(Peer { data, verifier, select_chain: None, diff --git a/client/peerset/src/lib.rs b/client/peerset/src/lib.rs index 2d03f1f790279..33ade655ca267 100644 --- a/client/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -45,6 +45,7 @@ const FORGET_AFTER: Duration = Duration::from_secs(3600); enum Action { AddReservedPeer(PeerId), RemoveReservedPeer(PeerId), + SetReservedPeers(HashSet), SetReservedOnly(bool), ReportPeer(PeerId, ReputationChange), SetPriorityGroup(String, HashSet), @@ -99,6 +100,11 @@ impl PeersetHandle { let _ = self.tx.unbounded_send(Action::RemoveReservedPeer(peer_id)); } + /// Set reserved peers to the new peers. + pub fn set_reserved_peers(&self, peer_ids: HashSet) { + let _ = self.tx.unbounded_send(Action::SetReservedPeers(peer_ids)); + } + /// Sets whether or not the peerset only has connections . pub fn set_reserved_only(&self, reserved: bool) { let _ = self.tx.unbounded_send(Action::SetReservedOnly(reserved)); @@ -259,6 +265,10 @@ impl Peerset { self.on_remove_from_priority_group(RESERVED_NODES, peer_id); } + fn on_set_reserved_peers(&mut self, peer_ids: HashSet) { + self.on_set_priority_group(RESERVED_NODES, peer_ids); + } + fn on_set_reserved_only(&mut self, reserved_only: bool) { self.reserved_only = reserved_only; @@ -429,43 +439,43 @@ impl Peerset { fn alloc_slots(&mut self) { self.update_time(); - // Try to connnect to permissioned nodes - if let Some(peer_ids) = &self.allowlist { - info!(target: "peerset", "alloc_slots peer_ids =========: {:?}", peer_ids); - loop { - let next = { - let data = &mut self.data; - peer_ids.iter() - .filter(move |n| { - data.peer(n).into_connected().is_none() - }) - .next() - .cloned() - }; - - let next = match next { - Some(n) => n, - None => break, - }; - - info!(target: "peerset", "this peer_id =========: {:?}", next); - - let next = match self.data.peer(&next) { - peersstate::Peer::Unknown(n) => n.discover(), - peersstate::Peer::NotConnected(n) => n, - peersstate::Peer::Connected(_) => { - debug_assert!(false, "State inconsistency: not connected state"); - break; - } - }; - - match next.try_outgoing() { - Ok(conn) => self.message_queue.push_back(Message::Connect(conn.into_peer_id())), - Err(_) => break, // No more slots available. - } - } - return; - } + // // Try to connnect to permissioned nodes + // if let Some(peer_ids) = &self.allowlist { + // info!(target: "peerset", "alloc_slots peer_ids =========: {:?}", peer_ids); + // loop { + // let next = { + // let data = &mut self.data; + // peer_ids.iter() + // .filter(move |n| { + // data.peer(n).into_connected().is_none() + // }) + // .next() + // .cloned() + // }; + + // let next = match next { + // Some(n) => n, + // None => break, + // }; + + // info!(target: "peerset", "this peer_id =========: {:?}", next); + + // let next = match self.data.peer(&next) { + // peersstate::Peer::Unknown(n) => n.discover(), + // peersstate::Peer::NotConnected(n) => n, + // peersstate::Peer::Connected(_) => { + // debug_assert!(false, "State inconsistency: not connected state"); + // break; + // } + // }; + + // match next.try_outgoing() { + // Ok(conn) => self.message_queue.push_back(Message::Connect(conn.into_peer_id())), + // Err(_) => break, // No more slots available. + // } + // } + // return; + // } // Try to connect to all the reserved nodes that we are not connected to. loop { @@ -720,6 +730,8 @@ impl Stream for Peerset { self.on_add_reserved_peer(peer_id), Action::RemoveReservedPeer(peer_id) => self.on_remove_reserved_peer(peer_id), + Action::SetReservedPeers(peer_ids) => + self.on_set_reserved_peers(peer_ids), Action::SetReservedOnly(reserved) => self.on_set_reserved_only(reserved), Action::ReportPeer(peer_id, score_diff) => diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 2cef5d80946f1..db4922846867c 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -48,14 +48,14 @@ use parking_lot::Mutex; use futures::{Future, FutureExt, Stream, StreamExt, stream, compat::*}; use sc_network::{NetworkStatus, network_state::NetworkState, PeerId}; -use log::{warn, debug, error, info}; +use log::{warn, debug, error}; use codec::{Encode, Decode}; use sc_client_api::blockchain::HeaderBackend; use sp_runtime::generic::BlockId; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use parity_util_mem::MallocSizeOf; use sp_utils::{status_sinks, mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}}; -use sp_core::storage::{StorageKey, StorageData, well_known_keys}; +use sp_core::storage::{StorageKey, well_known_keys}; use sp_core::ed25519::Public as NodePublic; use sc_client_api::backend::{Backend as BackendT, StorageProvider}; @@ -201,6 +201,8 @@ async fn build_network_future< should_have_peers: bool, announce_imported_blocks: bool, ) { + check_node_allowlist(&network, &client); + let mut imported_blocks_stream = client.import_notification_stream().fuse(); // Stream of finalized blocks reported by the client. @@ -244,20 +246,22 @@ async fn build_network_future< ); } - let id = BlockId::hash(client.info().best_hash); - let allowlist_storage = client.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())); - if let Ok(Some(raw_allowlist)) = allowlist_storage { - let node_allowlist: Result, _> = Decode::decode(&mut &raw_allowlist.0[..]); - - if let Ok(node_allowlist) = node_allowlist { - // Transform to PeerId - let peer_ids = node_allowlist.iter() - .filter_map(|pubkey| Ed25519PublicKey::decode(&pubkey.0).ok()) // TODO ok or unwrap() - .map(|pubkey| PublicKey::Ed25519(pubkey).into_peer_id()) - .collect(); - network.service().set_peer_allowlist(peer_ids); - } - } + check_node_allowlist(&network, &client); + // let id = BlockId::hash(client.info().best_hash); + // let allowlist_storage = client.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())); + // if let Ok(Some(raw_allowlist)) = allowlist_storage { + // let node_allowlist: Result, _> = Decode::decode(&mut &raw_allowlist.0[..]); + + // if let Ok(node_allowlist) = node_allowlist { + // // Transform to PeerId. + // // TODO remove local peer id. + // let peer_ids = node_allowlist.iter() + // .filter_map(|pubkey| Ed25519PublicKey::decode(&pubkey.0).ok()) // TODO ok or unwrap() + // .map(|pubkey| PublicKey::Ed25519(pubkey).into_peer_id()) + // .collect(); + // network.service().set_reserved_peers(peer_ids); + // } + // } } // List of blocks that the client has finalized. @@ -357,6 +361,34 @@ async fn build_network_future< } } +/// Set storage `NODE_ALLOWLIST` means it's a permissioned network, +/// then only connect to these well known peers. +fn check_node_allowlist< + B: BlockT, + BE: BackendT, + C: BlockchainEvents + StorageProvider + HeaderBackend, + H: sc_network::ExHashT +> ( + network: &sc_network::NetworkWorker, + client: &Arc, +) { + let id = BlockId::hash(client.info().best_hash); + let allowlist_storage = client.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())); + if let Ok(Some(raw_allowlist)) = allowlist_storage { + let node_allowlist: Result, _> = Decode::decode(&mut &raw_allowlist.0[..]); + + if let Ok(node_allowlist) = node_allowlist { + // Transform to PeerId. + // TODO remove local peer id. + let peer_ids = node_allowlist.iter() + .filter_map(|pubkey| Ed25519PublicKey::decode(&pubkey.0).ok()) // TODO ok or unwrap() + .map(|pubkey| PublicKey::Ed25519(pubkey).into_peer_id()) + .collect(); + network.service().set_reserved_peers(peer_ids, true); + } + } +} + #[cfg(not(target_os = "unknown"))] // Wrapper for HTTP and WS servers that makes sure they are properly shut down. mod waiting { From f06d2feb935facf032a2772c90666e165ee1ee9c Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Thu, 13 Aug 2020 17:36:39 +0800 Subject: [PATCH 17/50] rm allowlist in peerset --- client/network/src/service.rs | 29 --------------- client/peerset/src/lib.rs | 69 +---------------------------------- 2 files changed, 1 insertion(+), 97 deletions(-) diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 0b3de47b2b93a..8776ac6f6305a 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -45,10 +45,6 @@ use crate::{ use futures::prelude::*; use libp2p::{PeerId, multiaddr, Multiaddr}; use libp2p::core::{ConnectedPoint, Executor, connection::{ConnectionError, PendingConnectionError}, either::EitherError}; -use libp2p::identity::{ - ed25519::PublicKey as Ed25519PublicKey, - PublicKey -}; use libp2p::kad::record; use libp2p::ping::handler::PingFailure; use libp2p::swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent, protocols_handler::NodeHandlerWrapperError}; @@ -60,12 +56,9 @@ use prometheus_endpoint::{ }; use sc_peerset::PeersetHandle; use sc_client_api::backend::Backend as BackendT; -use sp_core::ed25519::Public as NodePublic; -use sp_core::storage::{StorageKey, well_known_keys}; use sp_consensus::import_queue::{BlockImportError, BlockImportResult, ImportQueue, Link}; use sp_runtime::{ traits::{Block as BlockT, NumberFor}, - generic::BlockId, ConsensusEngineId, }; use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}; @@ -83,7 +76,6 @@ use std::{ }, task::Poll, }; -use codec::Decode; mod out_events; #[cfg(test)] @@ -232,28 +224,12 @@ impl NetworkWorker ] }; - // Initialize the permissioned nodes - let mut init_allowlist = None; - // let id = BlockId::hash(params.chain.info().best_hash); - // let allowlist_storage = params.chain.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())).map_err(|_| Error::InvalidStorage)?; - // if let Some(raw_allowlist) = allowlist_storage { - // let node_allowlist: Vec = Decode::decode(&mut &raw_allowlist.0[..]).map_err(|_| Error::InvalidStorage)?; // TODO another error type - - // // Transform to PeerId - // let peer_ids = node_allowlist.iter() - // .filter_map(|pubkey| Ed25519PublicKey::decode(&pubkey.0).ok()) // TODO ok or unwrap() - // .map(|pubkey| PublicKey::Ed25519(pubkey).into_peer_id()) - // .collect(); - // init_allowlist = Some(peer_ids); - // } - let peerset_config = sc_peerset::PeersetConfig { in_peers: params.network_config.in_peers, out_peers: params.network_config.out_peers, bootnodes, reserved_only: params.network_config.non_reserved_mode == NonReservedPeerMode::Deny, priority_groups, - init_allowlist, }; // Private and public keys configuration. @@ -985,11 +961,6 @@ impl NetworkService { .to_worker .unbounded_send(ServiceToWorkerMsg::OwnBlockImported(hash, number)); } - - /// Inform the network service about refresh node allowlist. - pub fn set_peer_allowlist(&self, peer_ids: Vec) { - self.peerset.set_allowlist(peer_ids); - } } impl sp_consensus::SyncOracle diff --git a/client/peerset/src/lib.rs b/client/peerset/src/lib.rs index 33ade655ca267..ff2644396f535 100644 --- a/client/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -23,7 +23,7 @@ mod peersstate; use std::{collections::{HashSet, HashMap}, collections::VecDeque}; use futures::prelude::*; -use log::{debug, error, trace, info}; +use log::{debug, error, trace}; use serde_json::json; use std::{pin::Pin, task::{Context, Poll}, time::Duration}; use wasm_timer::Instant; @@ -51,7 +51,6 @@ enum Action { SetPriorityGroup(String, HashSet), AddToPriorityGroup(String, PeerId), RemoveFromPriorityGroup(String, PeerId), - SetAllowList(Vec), } /// Description of a reputation adjustment for a node. @@ -129,11 +128,6 @@ impl PeersetHandle { pub fn remove_from_priority_group(&self, group_id: String, peer_id: PeerId) { let _ = self.tx.unbounded_send(Action::RemoveFromPriorityGroup(group_id, peer_id)); } - - /// Refresh node allowlist - pub fn set_allowlist(&self, peer_ids: Vec) { - let _ = self.tx.unbounded_send(Action::SetAllowList(peer_ids)); - } } /// Message that can be sent by the peer set manager (PSM). @@ -186,9 +180,6 @@ pub struct PeersetConfig { /// > **Note**: Keep in mind that the networking has to know an address for these nodes, /// > otherwise it will not be able to connect to them. pub priority_groups: Vec<(String, HashSet)>, - - /// Initialization of permissioned nodes - pub init_allowlist: Option> } /// Side of the peer set manager owned by the network. In other words, the "receiving" side. @@ -214,8 +205,6 @@ pub struct Peerset { created: Instant, /// Last time when we updated the reputations of connected nodes. latest_time_update: Instant, - /// List of nodes that are allowed to connect. - allowlist: Option>, } impl Peerset { @@ -238,7 +227,6 @@ impl Peerset { message_queue: VecDeque::new(), created: now, latest_time_update: now, - allowlist: config.init_allowlist, }; for node in config.priority_groups.into_iter().flat_map(|(_, l)| l) { @@ -374,11 +362,6 @@ impl Peerset { } } - fn on_set_allowlist(&mut self, peer_ids: Vec) { - self.allowlist = Some(peer_ids); - self.alloc_slots(); // TODO only disconnect if it's not empty - } - /// Updates the value of `self.latest_time_update` and performs all the updates that happen /// over time, such as reputation increases for staying connected. fn update_time(&mut self) { @@ -439,44 +422,6 @@ impl Peerset { fn alloc_slots(&mut self) { self.update_time(); - // // Try to connnect to permissioned nodes - // if let Some(peer_ids) = &self.allowlist { - // info!(target: "peerset", "alloc_slots peer_ids =========: {:?}", peer_ids); - // loop { - // let next = { - // let data = &mut self.data; - // peer_ids.iter() - // .filter(move |n| { - // data.peer(n).into_connected().is_none() - // }) - // .next() - // .cloned() - // }; - - // let next = match next { - // Some(n) => n, - // None => break, - // }; - - // info!(target: "peerset", "this peer_id =========: {:?}", next); - - // let next = match self.data.peer(&next) { - // peersstate::Peer::Unknown(n) => n.discover(), - // peersstate::Peer::NotConnected(n) => n, - // peersstate::Peer::Connected(_) => { - // debug_assert!(false, "State inconsistency: not connected state"); - // break; - // } - // }; - - // match next.try_outgoing() { - // Ok(conn) => self.message_queue.push_back(Message::Connect(conn.into_peer_id())), - // Err(_) => break, // No more slots available. - // } - // } - // return; - // } - // Try to connect to all the reserved nodes that we are not connected to. loop { let next = { @@ -585,16 +530,6 @@ impl Peerset { trace!(target: "peerset", "Incoming {:?}", peer_id); self.update_time(); - // Only connect to permissioned node - trace!(target: "peerset", "==== incoming allowlist {:?}", &self.allowlist); - if let Some(peer_ids) = &self.allowlist { - info!(target: "peerset", "-======== allowed incoming peer_ids =========: {:?}, incoming: {:?}", peer_ids, peer_id); - if !peer_ids.contains(&peer_id) { - self.message_queue.push_back(Message::Reject(index)); - return; - } - } - if self.reserved_only { if !self.priority_groups.get(RESERVED_NODES).map_or(false, |n| n.contains(&peer_id)) { self.message_queue.push_back(Message::Reject(index)); @@ -742,8 +677,6 @@ impl Stream for Peerset { self.on_add_to_priority_group(&group_id, peer_id), Action::RemoveFromPriorityGroup(group_id, peer_id) => self.on_remove_from_priority_group(&group_id, peer_id), - Action::SetAllowList(peer_ids) => - self.on_set_allowlist(peer_ids), } } } From ec778a965d2895777d525f816348dc6a4a8f08a0 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Thu, 13 Aug 2020 18:13:45 +0800 Subject: [PATCH 18/50] revert backend constraint for client network. --- client/network/src/behaviour.rs | 69 +++++++--------------- client/network/src/block_requests.rs | 16 ++--- client/network/src/chain.rs | 17 ++---- client/network/src/config.rs | 8 +-- client/network/src/error.rs | 3 - client/network/src/light_client_handler.rs | 16 ++--- client/network/src/protocol.rs | 50 ++++------------ client/network/src/protocol/sync.rs | 15 ++--- client/network/src/service.rs | 57 ++++++------------ client/network/test/src/lib.rs | 3 +- client/service/src/builder.rs | 1 - client/service/src/lib.rs | 30 ++-------- 12 files changed, 81 insertions(+), 204 deletions(-) diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index 974ecfc49f39b..a43c61054d974 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -29,7 +29,6 @@ use libp2p::identify::IdentifyInfo; use libp2p::kad::record; use libp2p::swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters}; use log::debug; -use sc_client_api::backend::Backend as BackendT; use sp_consensus::{BlockOrigin, import_queue::{IncomingBlock, Origin}}; use sp_runtime::{traits::{Block as BlockT, NumberFor}, ConsensusEngineId, Justification}; use std::{ @@ -43,23 +42,20 @@ use std::{ /// General behaviour of the network. Combines all protocols together. #[derive(NetworkBehaviour)] #[behaviour(out_event = "BehaviourOut", poll_method = "poll")] -pub struct Behaviour - where - BE: BackendT -{ +pub struct Behaviour { /// All the substrate-specific protocols. - substrate: Protocol, + substrate: Protocol, /// Periodically pings and identifies the nodes we are connected to, and store information in a /// cache. peer_info: peer_info::PeerInfoBehaviour, /// Discovers nodes of the network. discovery: DiscoveryBehaviour, /// Block request handling. - block_requests: block_requests::BlockRequests, + block_requests: block_requests::BlockRequests, /// Finality proof request handling. finality_proof_requests: finality_requests::FinalityProofRequests, /// Light client request handling. - light_client_handler: light_client_handler::LightClientHandler, + light_client_handler: light_client_handler::LightClientHandler, /// Queue of events to produce for the outside. #[behaviour(ignore)] @@ -154,19 +150,16 @@ pub enum BehaviourOut { Dht(DhtEvent, Duration), } -impl Behaviour - where - BE: BackendT -{ +impl Behaviour { /// Builds a new `Behaviour`. pub fn new( - substrate: Protocol, + substrate: Protocol, role: Role, user_agent: String, local_public_key: PublicKey, - block_requests: block_requests::BlockRequests, + block_requests: block_requests::BlockRequests, finality_proof_requests: finality_requests::FinalityProofRequests, - light_client_handler: light_client_handler::LightClientHandler, + light_client_handler: light_client_handler::LightClientHandler, disco_config: DiscoveryConfig, ) -> Self { Behaviour { @@ -244,12 +237,12 @@ impl Behaviour } /// Returns a shared reference to the user protocol. - pub fn user_protocol(&self) -> &Protocol { + pub fn user_protocol(&self) -> &Protocol { &self.substrate } /// Returns a mutable reference to the user protocol. - pub fn user_protocol_mut(&mut self) -> &mut Protocol { + pub fn user_protocol_mut(&mut self) -> &mut Protocol { &mut self.substrate } @@ -285,20 +278,15 @@ fn reported_roles_to_observed_role(local_role: &Role, remote: &PeerId, roles: Ro } } -impl NetworkBehaviourEventProcess for -Behaviour - where - BE: BackendT -{ +impl NetworkBehaviourEventProcess for +Behaviour { fn inject_event(&mut self, event: void::Void) { void::unreachable(event) } } -impl NetworkBehaviourEventProcess> for -Behaviour - where BE: BackendT -{ +impl NetworkBehaviourEventProcess> for +Behaviour { fn inject_event(&mut self, event: CustomMessageOutcome) { match event { CustomMessageOutcome::BlockImport(origin, blocks) => @@ -370,10 +358,7 @@ Behaviour } } -impl NetworkBehaviourEventProcess> for Behaviour - where - BE: BackendT -{ +impl NetworkBehaviourEventProcess> for Behaviour { fn inject_event(&mut self, event: block_requests::Event) { match event { block_requests::Event::AnsweredRequest { peer, total_handling_time } => { @@ -407,10 +392,7 @@ impl NetworkBehaviourEventProcess NetworkBehaviourEventProcess> for Behaviour - where - BE: BackendT -{ +impl NetworkBehaviourEventProcess> for Behaviour { fn inject_event(&mut self, event: finality_requests::Event) { match event { finality_requests::Event::Response { peer, block_hash, proof } => { @@ -430,11 +412,8 @@ impl NetworkBehaviourEventProcess NetworkBehaviourEventProcess - for Behaviour - where - BE: BackendT -{ +impl NetworkBehaviourEventProcess + for Behaviour { fn inject_event(&mut self, event: peer_info::PeerInfoEvent) { let peer_info::PeerInfoEvent::Identified { peer_id, @@ -463,11 +442,8 @@ impl NetworkBehaviourEventProcess NetworkBehaviourEventProcess - for Behaviour - where - BE: BackendT -{ +impl NetworkBehaviourEventProcess + for Behaviour { fn inject_event(&mut self, out: DiscoveryOut) { match out { DiscoveryOut::UnroutablePeer(_peer_id) => { @@ -500,10 +476,7 @@ impl NetworkBehaviourEventProcess } } -impl Behaviour - where - BE: BackendT -{ +impl Behaviour { fn poll(&mut self, _: &mut Context, _: &mut impl PollParameters) -> Poll>> { if let Some(event) = self.events.pop_front() { return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event)) diff --git a/client/network/src/block_requests.rs b/client/network/src/block_requests.rs index 6c2ff40db1de9..8904ca03db21e 100644 --- a/client/network/src/block_requests.rs +++ b/client/network/src/block_requests.rs @@ -54,7 +54,6 @@ use libp2p::{ }; use prost::Message; use sp_runtime::{generic::BlockId, traits::{Block, Header, One, Zero}}; -use sc_client_api::backend::Backend; use std::{ cmp::min, collections::{HashMap, VecDeque}, @@ -195,14 +194,11 @@ impl Config { } /// The block request handling behaviour. -pub struct BlockRequests - where - BE: Backend -{ +pub struct BlockRequests { /// This behaviour's configuration. config: Config, /// Blockchain client. - chain: Arc>, + chain: Arc>, /// List of all active connections and the requests we've sent. peers: HashMap>>, /// Futures sending back the block request response. Returns the `PeerId` we sent back to, and @@ -247,12 +243,11 @@ pub enum SendRequestOutcome { EncodeError(prost::EncodeError), } -impl BlockRequests +impl BlockRequests where B: Block, - BE: Backend { - pub fn new(cfg: Config, chain: Arc>) -> Self { + pub fn new(cfg: Config, chain: Arc>) -> Self { BlockRequests { config: cfg, chain, @@ -467,10 +462,9 @@ where } } -impl NetworkBehaviour for BlockRequests +impl NetworkBehaviour for BlockRequests where B: Block, - BE: Backend + 'static, { type ProtocolsHandler = OneShotHandler, OutboundProtocol, NodeEvent>; type OutEvent = Event; diff --git a/client/network/src/chain.rs b/client/network/src/chain.rs index 19b94ebea0cb3..20fbe0284397d 100644 --- a/client/network/src/chain.rs +++ b/client/network/src/chain.rs @@ -19,25 +19,18 @@ //! Blockchain access trait use sp_blockchain::{Error, HeaderBackend, HeaderMetadata}; -use sc_client_api::{ - backend::{Backend as BackendT, StorageProvider}, - BlockBackend, ProofProvider -}; +use sc_client_api::{BlockBackend, ProofProvider}; use sp_runtime::traits::{Block as BlockT, BlockIdTo}; /// Local client abstraction for the network. -pub trait Client: HeaderBackend + ProofProvider + BlockIdTo - + BlockBackend + HeaderMetadata + StorageProvider + Send + Sync - where - Backend: BackendT +pub trait Client: HeaderBackend + ProofProvider + BlockIdTo + + BlockBackend + HeaderMetadata + Send + Sync {} -impl Client for T +impl Client for T where - Backend: BackendT, T: HeaderBackend + ProofProvider + BlockIdTo - + BlockBackend + HeaderMetadata + StorageProvider - + Send + Sync + + BlockBackend + HeaderMetadata + Send + Sync {} /// Finality proof provider. diff --git a/client/network/src/config.rs b/client/network/src/config.rs index 2f44674d2ad9c..94b2993b4e6bd 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -38,7 +38,6 @@ use libp2p::identity::{ed25519, Keypair}; use libp2p::wasm_ext; use libp2p::{multiaddr, Multiaddr, PeerId}; use prometheus_endpoint::Registry; -use sc_client_api::backend::Backend as BackendT; use sp_consensus::{block_validation::BlockAnnounceValidator, import_queue::ImportQueue}; use sp_runtime::{traits::Block as BlockT, ConsensusEngineId}; use std::{borrow::Cow, convert::TryFrom, future::Future, pin::Pin, str::FromStr}; @@ -54,10 +53,7 @@ use std::{ use zeroize::Zeroize; /// Network initialization parameters. -pub struct Params - where - BE: BackendT -{ +pub struct Params { /// Assigned role for our node (full, light, ...). pub role: Role, @@ -69,7 +65,7 @@ pub struct Params pub network_config: NetworkConfiguration, /// Client that contains the blockchain. - pub chain: Arc>, + pub chain: Arc>, /// Finality proof provider. /// diff --git a/client/network/src/error.rs b/client/network/src/error.rs index 796410e389568..d5a4024ef53d7 100644 --- a/client/network/src/error.rs +++ b/client/network/src/error.rs @@ -61,8 +61,6 @@ pub enum Error { /// The invalid addresses. addresses: Vec, }, - /// Unable to fetch storage error. - InvalidStorage, } // Make `Debug` use the `Display` implementation. @@ -80,7 +78,6 @@ impl std::error::Error for Error { Error::DuplicateBootnode { .. } => None, Error::Prometheus(ref err) => Some(err), Error::AddressesForAnotherTransport { .. } => None, - Error::InvalidStorage => None, // TODO is it correct } } } diff --git a/client/network/src/light_client_handler.rs b/client/network/src/light_client_handler.rs index 29660a7b6c29d..c5395c885cf20 100644 --- a/client/network/src/light_client_handler.rs +++ b/client/network/src/light_client_handler.rs @@ -58,7 +58,6 @@ use nohash_hasher::IntMap; use prost::Message; use sc_client_api::{ StorageProof, - backend::Backend, light::{ self, RemoteReadRequest, RemoteBodyRequest, ChangesProof, RemoteCallRequest, RemoteChangesRequest, RemoteHeaderRequest, @@ -285,14 +284,11 @@ enum PeerStatus { } /// The light client handler behaviour. -pub struct LightClientHandler - where - BE: Backend -{ +pub struct LightClientHandler { /// This behaviour's configuration. config: Config, /// Blockchain client. - chain: Arc>, + chain: Arc>, /// Verifies that received responses are correct. checker: Arc>, /// Peer information (addresses, their best block, etc.) @@ -309,15 +305,14 @@ pub struct LightClientHandler peerset: sc_peerset::PeersetHandle, } -impl LightClientHandler +impl LightClientHandler where B: Block, - BE: Backend, { /// Construct a new light client handler. pub fn new( cfg: Config, - chain: Arc>, + chain: Arc>, checker: Arc>, peerset: sc_peerset::PeersetHandle, ) -> Self { @@ -749,10 +744,9 @@ where } } -impl NetworkBehaviour for LightClientHandler +impl NetworkBehaviour for LightClientHandler where B: Block, - BE: Backend + 'static, { type ProtocolsHandler = OneShotHandler>; type OutEvent = Void; diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index 8106451faf687..0d031d98cb526 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -59,10 +59,7 @@ use std::sync::Arc; use std::fmt::Write; use std::{cmp, io, num::NonZeroUsize, pin::Pin, task::Poll, time}; use log::{log, Level, trace, debug, warn, error}; -use sc_client_api::{ - backend::Backend as BackendT, - ChangesProof, StorageProof -}; +use sc_client_api::{ChangesProof, StorageProof}; use util::LruHashSet; use wasm_timer::Instant; @@ -230,10 +227,7 @@ impl Future for PendingTransaction { } // Lock must always be taken in order declared here. -pub struct Protocol - where - BE: BackendT -{ +pub struct Protocol { /// Interval at which we call `tick`. tick_timeout: Pin + Send>>, /// Interval at which we call `propagate_transactions`. @@ -249,8 +243,8 @@ pub struct Protocol pending_transactions_peers: HashMap>, config: ProtocolConfig, genesis_hash: B::Hash, - sync: ChainSync, - context_data: ContextData, + sync: ChainSync, + context_data: ContextData, /// List of nodes for which we perform additional logging because they are important for the /// user. important_peers: HashSet, @@ -312,14 +306,11 @@ pub struct PeerInfo { } /// Data necessary to create a context. -struct ContextData - where - BE: BackendT -{ +struct ContextData { // All connected peers peers: HashMap>, stats: HashMap<&'static str, PacketStats>, - pub chain: Arc>, + pub chain: Arc>, } /// Configuration for the Substrate-specific part of the networking layer. @@ -355,10 +346,7 @@ struct BlockAnnouncesHandshake { impl BlockAnnouncesHandshake { - fn build(protocol_config: &ProtocolConfig, chain: &Arc>) -> Self - where - BE: BackendT - { + fn build(protocol_config: &ProtocolConfig, chain: &Arc>) -> Self { let info = chain.info(); BlockAnnouncesHandshake { genesis_hash: info.genesis_hash, @@ -370,10 +358,7 @@ impl BlockAnnouncesHandshake } /// Builds a SCALE-encoded "Status" message to send as handshake for the legacy protocol. -fn build_status_message(protocol_config: &ProtocolConfig, chain: &Arc>) -> Vec - where - BE: BackendT -{ +fn build_status_message(protocol_config: &ProtocolConfig, chain: &Arc>) -> Vec { let info = chain.info(); let status = message::generic::Status { version: CURRENT_VERSION, @@ -399,15 +384,12 @@ enum Fallback { BlockAnnounce, } -impl Protocol - where - BE: BackendT -{ +impl Protocol { /// Create a new instance. pub fn new( config: ProtocolConfig, local_peer_id: PeerId, - chain: Arc>, + chain: Arc>, transaction_pool: Arc>, finality_proof_provider: Option>>, finality_proof_request_builder: Option>, @@ -416,7 +398,7 @@ impl Protocol block_announce_validator: Box + Send>, metrics_registry: Option<&Registry>, boot_node_ids: Arc>, - ) -> error::Result<(Protocol, sc_peerset::PeersetHandle)> { + ) -> error::Result<(Protocol, sc_peerset::PeersetHandle)> { let info = chain.info(); let sync = ChainSync::new( config.roles, @@ -1946,10 +1928,7 @@ fn send_message( } } -impl NetworkBehaviour for Protocol - where - BE: BackendT + 'static -{ +impl NetworkBehaviour for Protocol { type ProtocolsHandler = ::ProtocolsHandler; type OutEvent = CustomMessageOutcome; @@ -2170,10 +2149,7 @@ impl NetworkBehaviour for Protocol } } -impl Drop for Protocol - where - BE: BackendT -{ +impl Drop for Protocol { fn drop(&mut self) { debug!(target: "sync", "Network stats:\n{}", self.format_stats()); } diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index d818d82142a80..bfd8c4fe218de 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -29,7 +29,6 @@ use codec::Encode; use blocks::BlockCollection; -use sc_client_api::backend::Backend as BackendT; use sp_blockchain::{Error as ClientError, Info as BlockchainInfo, HeaderMetadata}; use sp_consensus::{BlockOrigin, BlockStatus, block_validation::{BlockAnnounceValidator, Validation}, @@ -155,12 +154,9 @@ impl Default for PendingRequests { /// The main data structure which contains all the state for a chains /// active syncing strategy. -pub struct ChainSync - where - BE: BackendT -{ +pub struct ChainSync { /// Chain client. - client: Arc>, + client: Arc>, /// The active peers that we are using to sync and their PeerSync status peers: HashMap>, /// A `BlockCollection` of blocks that are being downloaded from peers @@ -347,14 +343,11 @@ pub enum OnBlockFinalityProof { } } -impl ChainSync - where - BE: BackendT -{ +impl ChainSync { /// Create a new instance. pub fn new( role: Roles, - client: Arc>, + client: Arc>, info: &BlockchainInfo, request_builder: Option>, block_announce_validator: Box + Send>, diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 8776ac6f6305a..ee08713bff79b 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -55,7 +55,6 @@ use prometheus_endpoint::{ PrometheusError, Registry, U64, }; use sc_peerset::PeersetHandle; -use sc_client_api::backend::Backend as BackendT; use sp_consensus::import_queue::{BlockImportError, BlockImportResult, ImportQueue, Link}; use sp_runtime::{ traits::{Block as BlockT, NumberFor}, @@ -111,16 +110,13 @@ pub struct NetworkService { _marker: PhantomData, } -impl NetworkWorker - where - BE: BackendT -{ +impl NetworkWorker { /// Creates the network service. /// /// Returns a `NetworkWorker` that implements `Future` and must be regularly polled in order /// for the network processing to advance. From it, you can extract a `NetworkService` using /// `worker.service()`. The `NetworkService` can be shared through the codebase. - pub fn new(params: Params) -> Result, Error> { + pub fn new(params: Params) -> Result, Error> { // Ensure the listen addresses are consistent with the transport. ensure_addresses_consistent_with_transport( params.network_config.listen_addresses.iter(), @@ -274,7 +270,7 @@ impl NetworkWorker )?; // Build the swarm. - let (mut swarm, bandwidth): (Swarm, _) = { + let (mut swarm, bandwidth): (Swarm, _) = { let user_agent = format!( "{} ({})", params.network_config.client_version, @@ -359,14 +355,14 @@ impl NetworkWorker // Listen on multiaddresses. for addr in ¶ms.network_config.listen_addresses { - if let Err(err) = Swarm::::listen_on(&mut swarm, addr.clone()) { + if let Err(err) = Swarm::::listen_on(&mut swarm, addr.clone()) { warn!(target: "sub-libp2p", "Can't listen on {} because: {:?}", addr, err) } } // Add external addresses. for addr in ¶ms.network_config.public_addresses { - Swarm::::add_external_address(&mut swarm, addr.clone()); + Swarm::::add_external_address(&mut swarm, addr.clone()); } let external_addresses = Arc::new(Mutex::new(Vec::new())); @@ -481,14 +477,14 @@ impl NetworkWorker /// Returns the local `PeerId`. pub fn local_peer_id(&self) -> &PeerId { - Swarm::::local_peer_id(&self.network_service) + Swarm::::local_peer_id(&self.network_service) } /// Returns the list of addresses we are listening on. /// /// Does **NOT** include a trailing `/p2p/` with our `PeerId`. pub fn listen_addresses(&self) -> impl Iterator { - Swarm::::listeners(&self.network_service) + Swarm::::listeners(&self.network_service) } /// Get network state. @@ -542,9 +538,9 @@ impl NetworkWorker }; NetworkState { - peer_id: Swarm::::local_peer_id(&swarm).to_base58(), - listened_addresses: Swarm::::listeners(&swarm).cloned().collect(), - external_addresses: Swarm::::external_addresses(&swarm).cloned().collect(), + peer_id: Swarm::::local_peer_id(&swarm).to_base58(), + listened_addresses: Swarm::::listeners(&swarm).cloned().collect(), + external_addresses: Swarm::::external_addresses(&swarm).cloned().collect(), average_download_per_sec: self.service.bandwidth.average_download_per_sec(), average_upload_per_sec: self.service.bandwidth.average_upload_per_sec(), connected_peers, @@ -1110,10 +1106,7 @@ enum ServiceToWorkerMsg { /// /// You are encouraged to poll this in a separate background thread or task. #[must_use = "The NetworkWorker must be polled in order for the network to advance"] -pub struct NetworkWorker - where - BE: BackendT + 'static -{ +pub struct NetworkWorker { /// Updated by the `NetworkWorker` and loaded by the `NetworkService`. external_addresses: Arc>>, /// Updated by the `NetworkWorker` and loaded by the `NetworkService`. @@ -1123,7 +1116,7 @@ pub struct NetworkWorker /// The network service that can be extracted and shared through the codebase. service: Arc>, /// The *actual* network. - network_service: Swarm, + network_service: Swarm, /// The import queue that was passed at initialization. import_queue: Box>, /// Messages from the [`NetworkService`] that must be processed. @@ -1363,10 +1356,7 @@ impl Metrics { } } -impl Future for NetworkWorker - where - BE: BackendT -{ +impl Future for NetworkWorker { type Output = (); fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context) -> Poll { @@ -1723,7 +1713,7 @@ impl Future for NetworkWorker // Update the variables shared with the `NetworkService`. this.num_connected.store(num_connected_peers, Ordering::Relaxed); { - let external_addresses = Swarm::::external_addresses(&this.network_service).cloned().collect(); + let external_addresses = Swarm::::external_addresses(&this.network_service).cloned().collect(); *this.external_addresses.lock() = external_addresses; } @@ -1760,10 +1750,7 @@ impl Future for NetworkWorker } } -impl Unpin for NetworkWorker - where - BE: BackendT -{ +impl Unpin for NetworkWorker { } /// Turns bytes that are potentially UTF-8 into a reasonable representable string. @@ -1778,20 +1765,14 @@ fn maybe_utf8_bytes_to_string(id: &[u8]) -> Cow { } /// The libp2p swarm, customized for our needs. -type Swarm = libp2p::swarm::Swarm>; +type Swarm = libp2p::swarm::Swarm>; // Implementation of `import_queue::Link` trait using the available local variables. -struct NetworkLink<'a, B: BlockT, BE, H: ExHashT> -where - BE: BackendT + 'static -{ - protocol: &'a mut Swarm, +struct NetworkLink<'a, B: BlockT, H: ExHashT> { + protocol: &'a mut Swarm, } -impl<'a, B: BlockT, BE, H: ExHashT> Link for NetworkLink<'a, B, BE, H> - where - BE: BackendT -{ +impl<'a, B: BlockT, H: ExHashT> Link for NetworkLink<'a, B, H> { fn blocks_processed( &mut self, imported: usize, diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 153ffc613a322..35587cbdc08b3 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -221,7 +221,7 @@ pub struct Peer { block_import: BlockImportAdapter<()>, select_chain: Option>, backend: Option>, - network: NetworkWorker::Hash>, + network: NetworkWorker::Hash>, imported_blocks_stream: Pin> + Send>>, finality_notification_stream: Pin> + Send>>, } @@ -704,7 +704,6 @@ pub trait TestNetFactory: Sized { }); } - // TODO this needs fix, Peer need a network with LightBackend /// Add a light peer. fn add_light_peer(&mut self) { let (c, backend) = substrate_test_runtime_client::new_light(); diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index c6fa5cad85b90..ba31762b1d542 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -844,7 +844,6 @@ pub fn build_network( imports_external_transactions: !matches!(config.role, Role::Light), pool: transaction_pool, client: client.clone(), - _backend: Default::default(), }); let protocol_id = { diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index db4922846867c..df50c0547bd2f 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -39,7 +39,6 @@ use std::net::SocketAddr; use std::collections::HashMap; use std::time::Duration; use std::task::Poll; -use std::marker::PhantomData; use libp2p::identity::{ ed25519::PublicKey as Ed25519PublicKey, PublicKey @@ -194,7 +193,7 @@ async fn build_network_future< H: sc_network::ExHashT > ( role: Role, - mut network: sc_network::NetworkWorker, + mut network: sc_network::NetworkWorker, client: Arc, status_sinks: NetworkStatusSinks, mut rpc_rx: TracingUnboundedReceiver>, @@ -247,21 +246,6 @@ async fn build_network_future< } check_node_allowlist(&network, &client); - // let id = BlockId::hash(client.info().best_hash); - // let allowlist_storage = client.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())); - // if let Ok(Some(raw_allowlist)) = allowlist_storage { - // let node_allowlist: Result, _> = Decode::decode(&mut &raw_allowlist.0[..]); - - // if let Ok(node_allowlist) = node_allowlist { - // // Transform to PeerId. - // // TODO remove local peer id. - // let peer_ids = node_allowlist.iter() - // .filter_map(|pubkey| Ed25519PublicKey::decode(&pubkey.0).ok()) // TODO ok or unwrap() - // .map(|pubkey| PublicKey::Ed25519(pubkey).into_peer_id()) - // .collect(); - // network.service().set_reserved_peers(peer_ids); - // } - // } } // List of blocks that the client has finalized. @@ -369,7 +353,7 @@ fn check_node_allowlist< C: BlockchainEvents + StorageProvider + HeaderBackend, H: sc_network::ExHashT > ( - network: &sc_network::NetworkWorker, + network: &sc_network::NetworkWorker, client: &Arc, ) { let id = BlockId::hash(client.info().best_hash); @@ -509,11 +493,10 @@ impl RpcSession { } /// Transaction pool adapter. -pub struct TransactionPoolAdapter { +pub struct TransactionPoolAdapter { imports_external_transactions: bool, pool: Arc

, client: Arc, - _backend: PhantomData, } /// Get transactions for propagation. @@ -537,12 +520,11 @@ where .collect() } -impl sc_network::config::TransactionPool for - TransactionPoolAdapter +impl sc_network::config::TransactionPool for + TransactionPoolAdapter where B: BlockT, - BE: BackendT, - C: sc_network::config::Client + Send + Sync, + C: sc_network::config::Client + Send + Sync, Pool: 'static + TransactionPool, H: std::hash::Hash + Eq + sp_runtime::traits::Member + sp_runtime::traits::MaybeSerialize, E: 'static + IntoPoolError + From, From 60a2477e11226403963c42da15927f2de80f9aa7 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Thu, 13 Aug 2020 18:27:32 +0800 Subject: [PATCH 19/50] revert more --- client/network/src/block_requests.rs | 2 +- client/network/src/light_client_handler.rs | 6 +++--- client/network/src/protocol.rs | 3 +-- client/service/src/builder.rs | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/client/network/src/block_requests.rs b/client/network/src/block_requests.rs index 8904ca03db21e..d7a12816dd4e1 100644 --- a/client/network/src/block_requests.rs +++ b/client/network/src/block_requests.rs @@ -464,7 +464,7 @@ where impl NetworkBehaviour for BlockRequests where - B: Block, + B: Block { type ProtocolsHandler = OneShotHandler, OutboundProtocol, NodeEvent>; type OutEvent = Event; diff --git a/client/network/src/light_client_handler.rs b/client/network/src/light_client_handler.rs index c5395c885cf20..678a717a898ff 100644 --- a/client/network/src/light_client_handler.rs +++ b/client/network/src/light_client_handler.rs @@ -746,7 +746,7 @@ where impl NetworkBehaviour for LightClientHandler where - B: Block, + B: Block { type ProtocolsHandler = OneShotHandler>; type OutEvent = Void; @@ -1499,7 +1499,7 @@ mod tests { ( ok: bool , ps: sc_peerset::PeersetHandle , cf: super::Config - ) -> LightClientHandler + ) -> LightClientHandler { let client = Arc::new(substrate_test_runtime_client::new()); let checker = Arc::new(DummyFetchChecker { ok, _mark: std::marker::PhantomData }); @@ -1510,7 +1510,7 @@ mod tests { ConnectedPoint::Dialer { address: Multiaddr::empty() } } - fn poll(mut b: &mut LightClientHandler) -> Poll> { + 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.rs b/client/network/src/protocol.rs index 0d031d98cb526..f1ce6d2b5608e 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -344,8 +344,7 @@ struct BlockAnnouncesHandshake { genesis_hash: B::Hash, } -impl BlockAnnouncesHandshake -{ +impl BlockAnnouncesHandshake { fn build(protocol_config: &ProtocolConfig, chain: &Arc>) -> Self { let info = chain.info(); BlockAnnouncesHandshake { diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index ba31762b1d542..a1b66b7cb3cc2 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -882,7 +882,7 @@ pub fn build_network( import_queue: Box::new(import_queue), protocol_id, block_announce_validator, - metrics_registry: config.prometheus_config.as_ref().map(|config| config.registry.clone()), + metrics_registry: config.prometheus_config.as_ref().map(|config| config.registry.clone()) }; let has_bootnodes = !network_params.network_config.boot_nodes.is_empty(); From b32041bb93a9fd6a8f9de8ed3461f1058cb1617b Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Thu, 13 Aug 2020 18:50:28 +0800 Subject: [PATCH 20/50] remove local peer ids from list --- client/service/src/lib.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index df50c0547bd2f..9435dc68832b2 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -36,7 +36,7 @@ mod task_manager; use std::{io, pin::Pin}; use std::net::SocketAddr; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::time::Duration; use std::task::Poll; use libp2p::identity::{ @@ -49,7 +49,6 @@ use futures::{Future, FutureExt, Stream, StreamExt, stream, compat::*}; use sc_network::{NetworkStatus, network_state::NetworkState, PeerId}; use log::{warn, debug, error}; use codec::{Encode, Decode}; -use sc_client_api::blockchain::HeaderBackend; use sp_runtime::generic::BlockId; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use parity_util_mem::MallocSizeOf; @@ -57,6 +56,8 @@ use sp_utils::{status_sinks, mpsc::{tracing_unbounded, TracingUnboundedReceiver, use sp_core::storage::{StorageKey, well_known_keys}; use sp_core::ed25519::Public as NodePublic; use sc_client_api::backend::{Backend as BackendT, StorageProvider}; +use sc_client_api::blockchain::HeaderBackend; +use sc_client_api::BlockchainEvents; pub use self::error::Error; pub use self::builder::{ @@ -88,7 +89,6 @@ pub use sc_tracing::TracingReceiver; pub use task_manager::SpawnTaskHandle; pub use task_manager::TaskManager; pub use sp_consensus::import_queue::ImportQueue; -use sc_client_api::BlockchainEvents; pub use sc_keystore::KeyStorePtr as KeyStore; const DEFAULT_PROTOCOL_ID: &str = "sup"; @@ -362,12 +362,13 @@ fn check_node_allowlist< let node_allowlist: Result, _> = Decode::decode(&mut &raw_allowlist.0[..]); if let Ok(node_allowlist) = node_allowlist { - // Transform to PeerId. - // TODO remove local peer id. - let peer_ids = node_allowlist.iter() - .filter_map(|pubkey| Ed25519PublicKey::decode(&pubkey.0).ok()) // TODO ok or unwrap() + let mut peer_ids: HashSet = node_allowlist.iter() + .filter_map(|pubkey| Ed25519PublicKey::decode(&pubkey.0).ok()) .map(|pubkey| PublicKey::Ed25519(pubkey).into_peer_id()) .collect(); + peer_ids.remove(network.local_peer_id()); + + // Set only reserved peers are allowed to connect. network.service().set_reserved_peers(peer_ids, true); } } From 04609bc3fb3c795ffeb71d88e98ae7f7649a085d Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Thu, 13 Aug 2020 21:26:52 +0800 Subject: [PATCH 21/50] refactor --- Cargo.lock | 1 + bin/node/runtime/src/lib.rs | 4 ++- frame/node-permission/Cargo.toml | 2 ++ frame/node-permission/src/lib.rs | 44 +++++++++++++++++--------------- 4 files changed, 30 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f4a93dd2b8cfa..4c0d0b5c86360 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4566,6 +4566,7 @@ dependencies = [ "serde", "sp-core", "sp-io", + "sp-runtime", "sp-std", ] diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 1e0838fc11aa6..33070090ccc65 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -39,6 +39,7 @@ use sp_core::{ crypto::KeyTypeId, u32_trait::{_1, _2, _3, _4}, OpaqueMetadata, + ed25519::Public as NodePublic, }; pub use node_primitives::{AccountId, Signature}; use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment}; @@ -846,6 +847,7 @@ parameter_types! { } impl pallet_node_permission::Trait for Runtime { type Event = Event; + type NodeId = NodePublic; type MaxPermissionedNodes = MaxPermissionedNodes; type AddOrigin = EnsureRootOrHalfCouncil; type RemoveOrigin = EnsureRootOrHalfCouncil; @@ -891,7 +893,7 @@ construct_runtime!( Scheduler: pallet_scheduler::{Module, Call, Storage, Event}, Proxy: pallet_proxy::{Module, Call, Storage, Event}, Multisig: pallet_multisig::{Module, Call, Storage, Event}, - NodePermission: pallet_node_permission::{Module, Call, Storage, Event, Config}, + NodePermission: pallet_node_permission::{Module, Call, Storage, Event, Config}, } ); diff --git a/frame/node-permission/Cargo.toml b/frame/node-permission/Cargo.toml index 96cc35d4ec5b3..e11cee0cd96fa 100644 --- a/frame/node-permission/Cargo.toml +++ b/frame/node-permission/Cargo.toml @@ -18,6 +18,7 @@ frame-support = { version = "2.0.0-rc5", default-features = false, path = "../su frame-system = { version = "2.0.0-rc5", default-features = false, path = "../system" } sp-core = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/core" } sp-io = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/runtime" } sp-std = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/std" } [features] @@ -29,5 +30,6 @@ std = [ "frame-system/std", "sp-core/std", "sp-io/std", + "sp-runtime/std", "sp-std/std", ] diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs index bfc23051a0d46..83ab8b1e79e0e 100644 --- a/frame/node-permission/src/lib.rs +++ b/frame/node-permission/src/lib.rs @@ -23,16 +23,16 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] -use sp_core::{ed25519::Public, storage::well_known_keys}; use sp_std::prelude::*; +use sp_std::fmt::Debug; +use sp_core::storage::well_known_keys; +use sp_runtime::traits::{Member, MaybeSerializeDeserialize, MaybeDisplay}; use frame_support::{ decl_module, decl_storage, decl_event, decl_error, - storage, ensure, traits::{Get, EnsureOrigin}, + Parameter, storage, ensure, traits::{Get, EnsureOrigin}, }; use codec::Encode; -type NodeId = Public; - pub trait Trait: frame_system::Trait { /// The event type of this module. type Event: From + Into<::Event>; @@ -40,6 +40,10 @@ pub trait Trait: frame_system::Trait { /// The maximum number of permissioned nodes that are allowed to set type MaxPermissionedNodes: Get; + /// The node identifier type for the runtime. + type NodeId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + + Ord + Default; + /// The origin which can add a permissioned node. type AddOrigin: EnsureOrigin; @@ -56,8 +60,8 @@ pub trait Trait: frame_system::Trait { decl_storage! { trait Store for Module as NodePermission {} add_extra_genesis { - config(nodes): Vec; - build(|config: &GenesisConfig| { + config(nodes): Vec; + build(|config: &GenesisConfig| { sp_io::storage::set(well_known_keys::NODE_ALLOWLIST, &config.nodes.encode()); }); } @@ -97,33 +101,33 @@ decl_module! { fn deposit_event() = default; - /// Add a node to the allowlist. + /// Add a node id to the allowlist. It's likely the public key of ed25519 keypair. /// /// May only be called from `T::AddOrigin`. #[weight = 0] - pub fn add_node(origin, node_public_key: NodeId) { + pub fn add_node(origin, node_id: T::NodeId) { T::AddOrigin::ensure_origin(origin)?; - let mut nodes: Vec = Self::get_allowlist(); + let mut nodes = Self::get_allowlist(); ensure!(nodes.len() < T::MaxPermissionedNodes::get() as usize, Error::::TooManyNodes); - let location = nodes.binary_search(&node_public_key).err().ok_or(Error::::AlreadyJoined)?; - nodes.insert(location, node_public_key); + let location = nodes.binary_search(&node_id).err().ok_or(Error::::AlreadyJoined)?; + nodes.insert(location, node_id); Self::put_allowlist(nodes); Self::deposit_event(Event::NodeAdded); } - /// Remove a node from te allowlist. + /// Remove a node from te allowlist. It's likely the public key of ed25519 keypair. /// /// May only be called from `T::RemoveOrigin`. #[weight = 0] - pub fn remove_node(origin, node_public_key: NodeId) { + pub fn remove_node(origin, node_id: T::NodeId) { T::RemoveOrigin::ensure_origin(origin)?; - let mut nodes: Vec = Self::get_allowlist(); + let mut nodes = Self::get_allowlist(); - let location = nodes.binary_search(&node_public_key).ok().ok_or(Error::::NotExist)?; + let location = nodes.binary_search(&node_id).ok().ok_or(Error::::NotExist)?; nodes.remove(location); Self::put_allowlist(nodes); @@ -135,12 +139,12 @@ decl_module! { /// /// May only be called from `T::SwapOrigin`. #[weight = 0] - pub fn swap_node(origin, remove: NodeId, add: NodeId) { + pub fn swap_node(origin, remove: T::NodeId, add: T::NodeId) { T::SwapOrigin::ensure_origin(origin)?; if remove == add { return Ok(()) } - let mut nodes: Vec = Self::get_allowlist(); + let mut nodes = Self::get_allowlist(); let location = nodes.binary_search(&remove).ok().ok_or(Error::::NotExist)?; let _ = nodes.binary_search(&add).err().ok_or(Error::::AlreadyJoined)?; nodes[location] = add; @@ -154,7 +158,7 @@ decl_module! { /// /// May only be called from `T::ResetOrigin`. #[weight = 0] - pub fn reset_nodes(origin, nodes: Vec) { + pub fn reset_nodes(origin, nodes: Vec) { T::ResetOrigin::ensure_origin(origin)?; ensure!(nodes.len() < T::MaxPermissionedNodes::get() as usize, Error::::TooManyNodes); @@ -168,11 +172,11 @@ decl_module! { } impl Module { - fn get_allowlist() -> Vec { + fn get_allowlist() -> Vec { storage::unhashed::get_or_default(well_known_keys::NODE_ALLOWLIST) } - fn put_allowlist(nodes: Vec) { + fn put_allowlist(nodes: Vec) { storage::unhashed::put(well_known_keys::NODE_ALLOWLIST, &nodes); } } From dba317518384115c4ef8ce25e1cca7017709e379 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Thu, 13 Aug 2020 22:46:05 +0800 Subject: [PATCH 22/50] test node permission pallet --- frame/node-permission/src/lib.rs | 134 +++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs index 83ab8b1e79e0e..fce5e6263935d 100644 --- a/frame/node-permission/src/lib.rs +++ b/frame/node-permission/src/lib.rs @@ -180,3 +180,137 @@ impl Module { storage::unhashed::put(well_known_keys::NODE_ALLOWLIST, &nodes); } } + +#[cfg(test)] +mod tests { + use super::*; + + use frame_support::{ + assert_ok, assert_noop, impl_outer_origin, weights::Weight, + parameter_types, ord_parameter_types, + }; + use frame_system::EnsureSignedBy; + use sp_core::H256; + use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup, BadOrigin}, testing::Header}; + + impl_outer_origin! { + pub enum Origin for Test where system = frame_system {} + } + + #[derive(Clone, Eq, PartialEq)] + pub struct Test; + + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + } + impl frame_system::Trait for Test { + type BaseCallFilter = (); + 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 DbWeight = (); + type BlockExecutionWeight = (); + type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + } + + ord_parameter_types! { + pub const One: u64 = 1; + pub const Two: u64 = 2; + pub const Three: u64 = 3; + pub const Four: u64 = 4; + } + parameter_types! { + pub const MaxPermissionedNodes: u32 = 4; + } + impl Trait for Test { + type Event = (); + type MaxPermissionedNodes = MaxPermissionedNodes; + type NodeId = u64; + type AddOrigin = EnsureSignedBy; + type RemoveOrigin = EnsureSignedBy; + type SwapOrigin = EnsureSignedBy; + type ResetOrigin = EnsureSignedBy; + } + + type NodePermission = Module; + + fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + GenesisConfig::{ + nodes: vec![10, 20, 30], + }.assimilate_storage(&mut t).unwrap(); + t.into() + } + + #[test] + fn add_node_works() { + new_test_ext().execute_with(|| { + assert_noop!(NodePermission::add_node(Origin::signed(2), 15), BadOrigin); + assert_noop!(NodePermission::add_node(Origin::signed(1), 20), Error::::AlreadyJoined); + + assert_ok!(NodePermission::add_node(Origin::signed(1), 15)); + assert_eq!(NodePermission::get_allowlist(), vec![10, 15, 20, 30]); + + assert_noop!(NodePermission::add_node(Origin::signed(1), 25), Error::::TooManyNodes); + }); + } + + #[test] + fn remove_node_works() { + new_test_ext().execute_with(|| { + assert_noop!(NodePermission::remove_node(Origin::signed(3), 20), BadOrigin); + assert_noop!(NodePermission::remove_node(Origin::signed(2), 40), Error::::NotExist); + + assert_ok!(NodePermission::remove_node(Origin::signed(2), 20)); + assert_eq!(NodePermission::get_allowlist(), vec![10, 30]); + }); + } + + #[test] + fn swap_node_works() { + new_test_ext().execute_with(|| { + assert_noop!(NodePermission::swap_node(Origin::signed(4), 20, 5), BadOrigin); + + assert_ok!(NodePermission::swap_node(Origin::signed(3), 20, 20)); + assert_eq!(NodePermission::get_allowlist(), vec![10, 20, 30]); + + assert_noop!(NodePermission::swap_node(Origin::signed(3), 15, 5), Error::::NotExist); + assert_noop!(NodePermission::swap_node(Origin::signed(3), 20, 30), Error::::AlreadyJoined); + + assert_ok!(NodePermission::swap_node(Origin::signed(3), 20, 5)); + assert_eq!(NodePermission::get_allowlist(), vec![5, 10, 30]); + }); + } + + #[test] + fn reset_nodes_works() { + new_test_ext().execute_with(|| { + assert_noop!(NodePermission::reset_nodes(Origin::signed(3), vec![15, 5, 20]), BadOrigin); + assert_noop!(NodePermission::reset_nodes(Origin::signed(4), vec![15, 5, 20, 25]), Error::::TooManyNodes); + + assert_ok!(NodePermission::reset_nodes(Origin::signed(4), vec![15, 5, 20])); + assert_eq!(NodePermission::get_allowlist(), vec![5, 15, 20]); + }); + } +} From d48636e37a9f2a52d68176a6bdce39dfe09c437a Mon Sep 17 00:00:00 2001 From: kaichao Date: Thu, 13 Aug 2020 22:51:49 +0800 Subject: [PATCH 23/50] Update client/service/src/lib.rs Co-authored-by: Pierre Krieger --- client/service/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 9435dc68832b2..344b288d7d41b 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -39,7 +39,7 @@ use std::net::SocketAddr; use std::collections::{HashMap, HashSet}; use std::time::Duration; use std::task::Poll; -use libp2p::identity::{ +use sc_network::config::identity::{ ed25519::PublicKey as Ed25519PublicKey, PublicKey }; From 6e71cd926679f876d0da6148bf4acb980e2ac05e Mon Sep 17 00:00:00 2001 From: kaichao Date: Thu, 13 Aug 2020 22:52:04 +0800 Subject: [PATCH 24/50] Update client/service/Cargo.toml Co-authored-by: Pierre Krieger --- client/service/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 8cc73418032d8..9140d4da6b575 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -75,7 +75,6 @@ sc-tracing = { version = "2.0.0-rc5", path = "../tracing" } tracing = "0.1.18" parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] } ed25519-dalek = { version = "1.0.0-pre.4", default-features = false, features = ["u64_backend", "alloc"] } -libp2p = { version = "0.22.0", default-features = false } [target.'cfg(not(target_os = "unknown"))'.dependencies] tempfile = "3.1.0" From b4fb0f302279ba722912269a3d6498520cc3e6f3 Mon Sep 17 00:00:00 2001 From: kaichao Date: Thu, 13 Aug 2020 23:11:25 +0800 Subject: [PATCH 25/50] Update client/service/Cargo.toml Co-authored-by: Pierre Krieger --- client/service/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index 9140d4da6b575..3ad91dc3ea39b 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -74,7 +74,6 @@ prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../.. sc-tracing = { version = "2.0.0-rc5", path = "../tracing" } tracing = "0.1.18" parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] } -ed25519-dalek = { version = "1.0.0-pre.4", default-features = false, features = ["u64_backend", "alloc"] } [target.'cfg(not(target_os = "unknown"))'.dependencies] tempfile = "3.1.0" From a1080e487fc2bcc66bce12bb7aea877f0e410329 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Thu, 13 Aug 2020 23:45:34 +0800 Subject: [PATCH 26/50] use decode_all --- Cargo.lock | 2 -- client/service/src/lib.rs | 4 ++-- frame/node-permission/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4c0d0b5c86360..b91565acf4ab8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6971,7 +6971,6 @@ dependencies = [ "async-std", "derive_more", "directories", - "ed25519-dalek", "exit-future", "futures 0.1.29", "futures 0.3.5", @@ -6979,7 +6978,6 @@ dependencies = [ "hash-db", "jsonrpc-pubsub", "lazy_static", - "libp2p", "log", "parity-scale-codec", "parity-util-mem 0.7.0", diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 344b288d7d41b..d328be2a0afbc 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -48,7 +48,7 @@ use parking_lot::Mutex; use futures::{Future, FutureExt, Stream, StreamExt, stream, compat::*}; use sc_network::{NetworkStatus, network_state::NetworkState, PeerId}; use log::{warn, debug, error}; -use codec::{Encode, Decode}; +use codec::{Encode, Decode, DecodeAll}; use sp_runtime::generic::BlockId; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use parity_util_mem::MallocSizeOf; @@ -359,7 +359,7 @@ fn check_node_allowlist< let id = BlockId::hash(client.info().best_hash); let allowlist_storage = client.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())); if let Ok(Some(raw_allowlist)) = allowlist_storage { - let node_allowlist: Result, _> = Decode::decode(&mut &raw_allowlist.0[..]); + let node_allowlist = Vec::::decode_all(&mut &raw_allowlist.0[..]); if let Ok(node_allowlist) = node_allowlist { let mut peer_ids: HashSet = node_allowlist.iter() diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs index fce5e6263935d..89dfebd6fee00 100644 --- a/frame/node-permission/src/lib.rs +++ b/frame/node-permission/src/lib.rs @@ -17,7 +17,7 @@ //! # Node permission moudule //! -//! This module is used by the `client/peerset` to retrieve the current +//! This module is used by the `client/service` to retrieve the current //! permissioned nodes. // Ensure we're `no_std` when compiling for Wasm. From e7eb421669d25e87b34b767fe1e48fd5125d8a0c Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Fri, 14 Aug 2020 01:26:35 +0800 Subject: [PATCH 27/50] comments and weight --- frame/node-permission/src/lib.rs | 36 +++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs index 89dfebd6fee00..ccec812c05838 100644 --- a/frame/node-permission/src/lib.rs +++ b/frame/node-permission/src/lib.rs @@ -101,10 +101,12 @@ decl_module! { fn deposit_event() = default; - /// Add a node id to the allowlist. It's likely the public key of ed25519 keypair. + /// Add a node to the allowlist. /// /// May only be called from `T::AddOrigin`. - #[weight = 0] + /// + /// - `node_id`: identifier of the node, it's likely the public key of ed25519 keypair. + #[weight = 50_000_000] pub fn add_node(origin, node_id: T::NodeId) { T::AddOrigin::ensure_origin(origin)?; @@ -118,10 +120,12 @@ decl_module! { Self::deposit_event(Event::NodeAdded); } - /// Remove a node from te allowlist. It's likely the public key of ed25519 keypair. + /// Remove a node from the allowlist. /// /// May only be called from `T::RemoveOrigin`. - #[weight = 0] + /// + /// - `node_id`: identifier of the node, it's likely the public key of ed25519 keypair. + #[weight = 50_000_000] pub fn remove_node(origin, node_id: T::NodeId) { T::RemoveOrigin::ensure_origin(origin)?; @@ -134,11 +138,15 @@ decl_module! { Self::deposit_event(Event::NodeRemoved); } - /// Swap two nodes; `remove` is the one which will be put out of the list, - /// `add` will be in the list. + /// Swap two nodes. /// /// May only be called from `T::SwapOrigin`. - #[weight = 0] + /// + /// - `remove`: the node which will be moved out from the list, it's likely the public key + /// of ed25519 keypair. + /// - `add`: the node which will be put in the list, it's likely the public key of ed25519 + /// keypair. + #[weight = 50_000_000] pub fn swap_node(origin, remove: T::NodeId, add: T::NodeId) { T::SwapOrigin::ensure_origin(origin)?; @@ -157,7 +165,9 @@ decl_module! { /// Reset all the permissioned nodes in the list. /// /// May only be called from `T::ResetOrigin`. - #[weight = 0] + /// + /// - `nodes`: the new nodes for the allowlist. + #[weight = 50_000_000] pub fn reset_nodes(origin, nodes: Vec) { T::ResetOrigin::ensure_origin(origin)?; ensure!(nodes.len() < T::MaxPermissionedNodes::get() as usize, Error::::TooManyNodes); @@ -296,7 +306,10 @@ mod tests { assert_eq!(NodePermission::get_allowlist(), vec![10, 20, 30]); assert_noop!(NodePermission::swap_node(Origin::signed(3), 15, 5), Error::::NotExist); - assert_noop!(NodePermission::swap_node(Origin::signed(3), 20, 30), Error::::AlreadyJoined); + assert_noop!( + NodePermission::swap_node(Origin::signed(3), 20, 30), + Error::::AlreadyJoined + ); assert_ok!(NodePermission::swap_node(Origin::signed(3), 20, 5)); assert_eq!(NodePermission::get_allowlist(), vec![5, 10, 30]); @@ -307,7 +320,10 @@ mod tests { fn reset_nodes_works() { new_test_ext().execute_with(|| { assert_noop!(NodePermission::reset_nodes(Origin::signed(3), vec![15, 5, 20]), BadOrigin); - assert_noop!(NodePermission::reset_nodes(Origin::signed(4), vec![15, 5, 20, 25]), Error::::TooManyNodes); + assert_noop!( + NodePermission::reset_nodes(Origin::signed(4), vec![15, 5, 20, 25]), + Error::::TooManyNodes + ); assert_ok!(NodePermission::reset_nodes(Origin::signed(4), vec![15, 5, 20])); assert_eq!(NodePermission::get_allowlist(), vec![5, 15, 20]); From cf86c58ea04e5828569364de11d329d2da81c42d Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Fri, 14 Aug 2020 01:32:42 +0800 Subject: [PATCH 28/50] remove node permission from node runtime. --- Cargo.lock | 2 -- bin/node/cli/Cargo.toml | 1 - bin/node/cli/src/chain_spec.rs | 11 ++--------- bin/node/runtime/Cargo.toml | 2 -- bin/node/runtime/src/lib.rs | 15 --------------- bin/node/testing/src/genesis.rs | 7 ++----- 6 files changed, 4 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b91565acf4ab8..dfa1b5296ea33 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3571,7 +3571,6 @@ dependencies = [ "pallet-grandpa", "pallet-im-online", "pallet-indices", - "pallet-node-permission", "pallet-staking", "pallet-timestamp", "pallet-transaction-payment", @@ -3757,7 +3756,6 @@ dependencies = [ "pallet-indices", "pallet-membership", "pallet-multisig", - "pallet-node-permission", "pallet-offences", "pallet-offences-benchmarking", "pallet-proxy", diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index f941e6edd41f9..16ab9bbe80641 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -89,7 +89,6 @@ pallet-im-online = { version = "2.0.0-rc5", default-features = false, path = ".. pallet-authority-discovery = { version = "2.0.0-rc5", path = "../../../frame/authority-discovery" } pallet-staking = { version = "2.0.0-rc5", path = "../../../frame/staking" } pallet-grandpa = { version = "2.0.0-rc5", path = "../../../frame/grandpa" } -pallet-node-permission = { version = "2.0.0-rc5", path = "../../../frame/node-permission" } # node-specific dependencies node-runtime = { version = "2.0.0-rc5", path = "../runtime" } diff --git a/bin/node/cli/src/chain_spec.rs b/bin/node/cli/src/chain_spec.rs index 67c5f0a4c1ce3..e323f7956f169 100644 --- a/bin/node/cli/src/chain_spec.rs +++ b/bin/node/cli/src/chain_spec.rs @@ -19,13 +19,13 @@ //! Substrate chain configurations. use sc_chain_spec::ChainSpecExtension; -use sp_core::{Pair, Public, crypto::UncheckedInto, sr25519, ed25519}; +use sp_core::{Pair, Public, crypto::UncheckedInto, sr25519}; use serde::{Serialize, Deserialize}; use node_runtime::{ AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, DemocracyConfig,GrandpaConfig, ImOnlineConfig, SessionConfig, SessionKeys, StakerStatus, StakingConfig, ElectionsConfig, IndicesConfig, SocietyConfig, SudoConfig, SystemConfig, - TechnicalCommitteeConfig, NodePermissionConfig, wasm_binary_unwrap, + TechnicalCommitteeConfig, wasm_binary_unwrap, }; use node_runtime::Block; use node_runtime::constants::currency::*; @@ -37,7 +37,6 @@ use sp_consensus_babe::{AuthorityId as BabeId}; use pallet_im_online::sr25519::{AuthorityId as ImOnlineId}; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; use sp_runtime::{Perbill, traits::{Verify, IdentifyAccount}}; -use std::str::FromStr; pub use node_primitives::{AccountId, Balance, Signature}; pub use node_runtime::GenesisConfig; @@ -322,12 +321,6 @@ pub fn testnet_genesis( max_members: 999, }), pallet_vesting: Some(Default::default()), - pallet_node_permission: Some(NodePermissionConfig { - nodes: vec![ - ed25519::Public::from_str("5CibWAiYURpoy3o8SsA1hS75ypxCzGrT9mt3ufCerfQYCEC6").unwrap(), - ed25519::Public::from_str("5H1bTmUExYZZfHQ5S6RJ6k1qG4H7e1WHsimKXQc1Rz2j982o").unwrap(), - ], - }), } } diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 55ff5730cbe06..35ed7400459f2 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -61,7 +61,6 @@ pallet-indices = { version = "2.0.0-rc5", default-features = false, path = "../. pallet-identity = { version = "2.0.0-rc5", default-features = false, path = "../../../frame/identity" } pallet-membership = { version = "2.0.0-rc5", default-features = false, path = "../../../frame/membership" } pallet-multisig = { version = "2.0.0-rc5", default-features = false, path = "../../../frame/multisig" } -pallet-node-permission = { version = "2.0.0-rc5", default-features = false, path = "../../../frame/node-permission" } pallet-offences = { version = "2.0.0-rc5", default-features = false, path = "../../../frame/offences" } pallet-offences-benchmarking = { version = "2.0.0-rc5", path = "../../../frame/offences/benchmarking", default-features = false, optional = true } pallet-proxy = { version = "2.0.0-rc5", default-features = false, path = "../../../frame/proxy" } @@ -112,7 +111,6 @@ std = [ "sp-inherents/std", "pallet-membership/std", "pallet-multisig/std", - "pallet-node-permission/std", "pallet-identity/std", "pallet-scheduler/std", "node-primitives/std", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 33070090ccc65..acc1b07281834 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -39,7 +39,6 @@ use sp_core::{ crypto::KeyTypeId, u32_trait::{_1, _2, _3, _4}, OpaqueMetadata, - ed25519::Public as NodePublic, }; pub use node_primitives::{AccountId, Signature}; use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment}; @@ -842,19 +841,6 @@ impl pallet_vesting::Trait for Runtime { type WeightInfo = (); } -parameter_types! { - pub const MaxPermissionedNodes: u32 = 8; -} -impl pallet_node_permission::Trait for Runtime { - type Event = Event; - type NodeId = NodePublic; - type MaxPermissionedNodes = MaxPermissionedNodes; - type AddOrigin = EnsureRootOrHalfCouncil; - type RemoveOrigin = EnsureRootOrHalfCouncil; - type SwapOrigin = EnsureRootOrHalfCouncil; - type ResetOrigin = EnsureRootOrHalfCouncil; -} - construct_runtime!( pub enum Runtime where Block = Block, @@ -893,7 +879,6 @@ construct_runtime!( Scheduler: pallet_scheduler::{Module, Call, Storage, Event}, Proxy: pallet_proxy::{Module, Call, Storage, Event}, Multisig: pallet_multisig::{Module, Call, Storage, Event}, - NodePermission: pallet_node_permission::{Module, Call, Storage, Event, Config}, } ); diff --git a/bin/node/testing/src/genesis.rs b/bin/node/testing/src/genesis.rs index f9c4cf94f09bb..6fa178ba4bcdd 100644 --- a/bin/node/testing/src/genesis.rs +++ b/bin/node/testing/src/genesis.rs @@ -22,8 +22,8 @@ use crate::keyring::*; use sp_keyring::{Ed25519Keyring, Sr25519Keyring}; use node_runtime::{ GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, SystemConfig, - GrandpaConfig, IndicesConfig, ContractsConfig, SocietyConfig, NodePermissionConfig, - wasm_binary_unwrap, AccountId, StakerStatus, + GrandpaConfig, IndicesConfig, ContractsConfig, SocietyConfig, wasm_binary_unwrap, + AccountId, StakerStatus, }; use node_runtime::constants::currency::*; use sp_core::ChangesTrieConfiguration; @@ -119,8 +119,5 @@ pub fn config_endowed( max_members: 999, }), pallet_vesting: Some(Default::default()), - pallet_node_permission: Some(NodePermissionConfig { - nodes: vec![], - }), } } From 1f57ed2a9180ee4e639a96b593260e2f58f0e9be Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Fri, 14 Aug 2020 18:13:19 +0800 Subject: [PATCH 29/50] WeightInfo --- frame/node-permission/src/lib.rs | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs index ccec812c05838..20da7d7682d05 100644 --- a/frame/node-permission/src/lib.rs +++ b/frame/node-permission/src/lib.rs @@ -29,10 +29,26 @@ use sp_core::storage::well_known_keys; use sp_runtime::traits::{Member, MaybeSerializeDeserialize, MaybeDisplay}; use frame_support::{ decl_module, decl_storage, decl_event, decl_error, - Parameter, storage, ensure, traits::{Get, EnsureOrigin}, + Parameter, storage, ensure, + weights::{DispatchClass, Weight}, + traits::{Get, EnsureOrigin}, }; use codec::Encode; +pub trait WeightInfo { + fn add_node() -> Weight; + fn remove_node() -> Weight; + fn swap_node() -> Weight; + fn reset_nodes() -> Weight; +} + +impl WeightInfo for () { + fn add_node() -> Weight { 50_000_000 } + fn remove_node() -> Weight { 50_000_000 } + fn swap_node() -> Weight { 50_000_000 } + fn reset_nodes() -> Weight { 50_000_000 } +} + pub trait Trait: frame_system::Trait { /// The event type of this module. type Event: From + Into<::Event>; @@ -55,6 +71,9 @@ pub trait Trait: frame_system::Trait { /// The origin which can reset the permissioned nodes. type ResetOrigin: EnsureOrigin; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } decl_storage! { @@ -106,7 +125,7 @@ decl_module! { /// May only be called from `T::AddOrigin`. /// /// - `node_id`: identifier of the node, it's likely the public key of ed25519 keypair. - #[weight = 50_000_000] + #[weight = (T::WeightInfo::add_node(), DispatchClass::Operational)] pub fn add_node(origin, node_id: T::NodeId) { T::AddOrigin::ensure_origin(origin)?; @@ -125,7 +144,7 @@ decl_module! { /// May only be called from `T::RemoveOrigin`. /// /// - `node_id`: identifier of the node, it's likely the public key of ed25519 keypair. - #[weight = 50_000_000] + #[weight = (T::WeightInfo::remove_node(), DispatchClass::Operational)] pub fn remove_node(origin, node_id: T::NodeId) { T::RemoveOrigin::ensure_origin(origin)?; @@ -146,7 +165,7 @@ decl_module! { /// of ed25519 keypair. /// - `add`: the node which will be put in the list, it's likely the public key of ed25519 /// keypair. - #[weight = 50_000_000] + #[weight = (T::WeightInfo::swap_node(), DispatchClass::Operational)] pub fn swap_node(origin, remove: T::NodeId, add: T::NodeId) { T::SwapOrigin::ensure_origin(origin)?; @@ -167,7 +186,7 @@ decl_module! { /// May only be called from `T::ResetOrigin`. /// /// - `nodes`: the new nodes for the allowlist. - #[weight = 50_000_000] + #[weight = (T::WeightInfo::reset_nodes(), DispatchClass::Operational)] pub fn reset_nodes(origin, nodes: Vec) { T::ResetOrigin::ensure_origin(origin)?; ensure!(nodes.len() < T::MaxPermissionedNodes::get() as usize, Error::::TooManyNodes); From 29bbbb4128aba35a978f38da803a56929ec6c867 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Fri, 14 Aug 2020 18:32:34 +0800 Subject: [PATCH 30/50] fix build --- frame/node-permission/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs index 20da7d7682d05..7a108a3bd91c5 100644 --- a/frame/node-permission/src/lib.rs +++ b/frame/node-permission/src/lib.rs @@ -280,6 +280,7 @@ mod tests { type RemoveOrigin = EnsureSignedBy; type SwapOrigin = EnsureSignedBy; type ResetOrigin = EnsureSignedBy; + type WeightInfo = (); } type NodePermission = Module; From 385876bc99c200c80914959725ce9d3a9ea131d6 Mon Sep 17 00:00:00 2001 From: kaichao Date: Fri, 14 Aug 2020 18:47:56 +0800 Subject: [PATCH 31/50] Update client/service/src/lib.rs Co-authored-by: Pierre Krieger --- client/service/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index d328be2a0afbc..8a9d4d576ef15 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -371,6 +371,9 @@ fn check_node_allowlist< // Set only reserved peers are allowed to connect. network.service().set_reserved_peers(peer_ids, true); } + } else { + // Note that the situation where the storage entry previously existed but no longer + // does isn't handled at the moment. } } From 00e2aff3e84931d9d884b0dc5b5953826041fbe1 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Fri, 14 Aug 2020 18:55:43 +0800 Subject: [PATCH 32/50] format --- frame/node-permission/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs index 7a108a3bd91c5..3aaa42a1b959e 100644 --- a/frame/node-permission/src/lib.rs +++ b/frame/node-permission/src/lib.rs @@ -73,7 +73,7 @@ pub trait Trait: frame_system::Trait { type ResetOrigin: EnsureOrigin; /// Weight information for extrinsics in this pallet. - type WeightInfo: WeightInfo; + type WeightInfo: WeightInfo; } decl_storage! { From 6b94f45a15a597f96ff88783a10dc145b08686f8 Mon Sep 17 00:00:00 2001 From: kaichao Date: Sat, 15 Aug 2020 10:03:39 +0800 Subject: [PATCH 33/50] Update frame/node-permission/src/lib.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- frame/node-permission/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs index 3aaa42a1b959e..00799bafa97e8 100644 --- a/frame/node-permission/src/lib.rs +++ b/frame/node-permission/src/lib.rs @@ -15,7 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! # Node permission moudule +//! # Node permission module //! //! This module is used by the `client/service` to retrieve the current //! permissioned nodes. From 0ea0d0599e657c76767eaa38308ab0451a8eb6ca Mon Sep 17 00:00:00 2001 From: kaichao Date: Sat, 15 Aug 2020 10:36:52 +0800 Subject: [PATCH 34/50] Update frame/node-permission/src/lib.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- frame/node-permission/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs index 00799bafa97e8..7ec1948d1ee02 100644 --- a/frame/node-permission/src/lib.rs +++ b/frame/node-permission/src/lib.rs @@ -187,7 +187,7 @@ decl_module! { /// /// - `nodes`: the new nodes for the allowlist. #[weight = (T::WeightInfo::reset_nodes(), DispatchClass::Operational)] - pub fn reset_nodes(origin, nodes: Vec) { + pub fn reset_nodes(origin, mut nodes: Vec) { T::ResetOrigin::ensure_origin(origin)?; ensure!(nodes.len() < T::MaxPermissionedNodes::get() as usize, Error::::TooManyNodes); From 6c8210f8830aecaac2c8efba0c558f44e9059bd2 Mon Sep 17 00:00:00 2001 From: kaichao Date: Sat, 15 Aug 2020 10:37:25 +0800 Subject: [PATCH 35/50] Update frame/node-permission/src/lib.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- frame/node-permission/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs index 7ec1948d1ee02..dd86293e9291e 100644 --- a/frame/node-permission/src/lib.rs +++ b/frame/node-permission/src/lib.rs @@ -191,7 +191,6 @@ decl_module! { T::ResetOrigin::ensure_origin(origin)?; ensure!(nodes.len() < T::MaxPermissionedNodes::get() as usize, Error::::TooManyNodes); - let mut nodes = nodes; nodes.sort(); Self::put_allowlist(nodes); From b2626c3449d8a768f5ba436f166cd7231edc9a42 Mon Sep 17 00:00:00 2001 From: kaichao Date: Sat, 15 Aug 2020 10:39:01 +0800 Subject: [PATCH 36/50] Update frame/node-permission/src/lib.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- frame/node-permission/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs index dd86293e9291e..261f34b12cc1b 100644 --- a/frame/node-permission/src/lib.rs +++ b/frame/node-permission/src/lib.rs @@ -172,7 +172,8 @@ decl_module! { if remove == add { return Ok(()) } let mut nodes = Self::get_allowlist(); - let location = nodes.binary_search(&remove).ok().ok_or(Error::::NotExist)?; + let remove_location = nodes.binary_search(&remove).ok().ok_or(Error::::NotExist)?; + nodes.remove(remove_location); let _ = nodes.binary_search(&add).err().ok_or(Error::::AlreadyJoined)?; nodes[location] = add; nodes.sort(); From 477ca983b4195a1269a16287e5a522eda7ed7cf5 Mon Sep 17 00:00:00 2001 From: kaichao Date: Sat, 15 Aug 2020 10:39:15 +0800 Subject: [PATCH 37/50] Update frame/node-permission/src/lib.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- frame/node-permission/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs index 261f34b12cc1b..51fcafa878711 100644 --- a/frame/node-permission/src/lib.rs +++ b/frame/node-permission/src/lib.rs @@ -174,7 +174,7 @@ decl_module! { let mut nodes = Self::get_allowlist(); let remove_location = nodes.binary_search(&remove).ok().ok_or(Error::::NotExist)?; nodes.remove(remove_location); - let _ = nodes.binary_search(&add).err().ok_or(Error::::AlreadyJoined)?; + let add_location = nodes.binary_search(&add).err().ok_or(Error::::AlreadyJoined)?; nodes[location] = add; nodes.sort(); Self::put_allowlist(nodes); From 5822801c32185ec33ce0d4db51c1cb32bad1d6d9 Mon Sep 17 00:00:00 2001 From: kaichao Date: Sat, 15 Aug 2020 10:39:30 +0800 Subject: [PATCH 38/50] Update frame/node-permission/src/lib.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- frame/node-permission/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs index 51fcafa878711..8e8777da35db3 100644 --- a/frame/node-permission/src/lib.rs +++ b/frame/node-permission/src/lib.rs @@ -175,8 +175,7 @@ decl_module! { let remove_location = nodes.binary_search(&remove).ok().ok_or(Error::::NotExist)?; nodes.remove(remove_location); let add_location = nodes.binary_search(&add).err().ok_or(Error::::AlreadyJoined)?; - nodes[location] = add; - nodes.sort(); + nodes.insert(add_location, node_id); Self::put_allowlist(nodes); Self::deposit_event(Event::NodesSwapped); From d389d491a0725c0a0b2c228bb4215b3db5e26be5 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Sat, 15 Aug 2020 21:40:48 +0800 Subject: [PATCH 39/50] no mut in call param --- client/service/src/lib.rs | 8 ++++---- frame/node-permission/src/lib.rs | 19 ++++++++++--------- primitives/storage/src/lib.rs | 2 +- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 8a9d4d576ef15..767346eaa3956 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -345,7 +345,7 @@ async fn build_network_future< } } -/// Set storage `NODE_ALLOWLIST` means it's a permissioned network, +/// Set storage `NODE_ALLOW_LIST` means it's a permissioned network, /// then only connect to these well known peers. fn check_node_allowlist< B: BlockT, @@ -357,7 +357,7 @@ fn check_node_allowlist< client: &Arc, ) { let id = BlockId::hash(client.info().best_hash); - let allowlist_storage = client.storage(&id, &StorageKey(well_known_keys::NODE_ALLOWLIST.to_vec())); + let allowlist_storage = client.storage(&id, &StorageKey(well_known_keys::NODE_ALLOW_LIST.to_vec())); if let Ok(Some(raw_allowlist)) = allowlist_storage { let node_allowlist = Vec::::decode_all(&mut &raw_allowlist.0[..]); @@ -372,8 +372,8 @@ fn check_node_allowlist< network.service().set_reserved_peers(peer_ids, true); } } else { - // Note that the situation where the storage entry previously existed but no longer - // does isn't handled at the moment. + // Note that the situation where the storage entry previously existed but no longer + // does isn't handled at the moment. } } diff --git a/frame/node-permission/src/lib.rs b/frame/node-permission/src/lib.rs index 8e8777da35db3..745d524b34bb6 100644 --- a/frame/node-permission/src/lib.rs +++ b/frame/node-permission/src/lib.rs @@ -15,10 +15,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! # Node permission module +//! # Node permission pallet //! -//! This module is used by the `client/service` to retrieve the current -//! permissioned nodes. +//! This pallet manages a configurable set of nodes for a permissioned blockchain. +//! The node set is stored under [`well_known_keys::NODE_ALLOW_LIST`]. // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] @@ -81,7 +81,7 @@ decl_storage! { add_extra_genesis { config(nodes): Vec; build(|config: &GenesisConfig| { - sp_io::storage::set(well_known_keys::NODE_ALLOWLIST, &config.nodes.encode()); + sp_io::storage::set(well_known_keys::NODE_ALLOW_LIST, &config.nodes.encode()); }); } } @@ -175,22 +175,23 @@ decl_module! { let remove_location = nodes.binary_search(&remove).ok().ok_or(Error::::NotExist)?; nodes.remove(remove_location); let add_location = nodes.binary_search(&add).err().ok_or(Error::::AlreadyJoined)?; - nodes.insert(add_location, node_id); + nodes.insert(add_location, add); Self::put_allowlist(nodes); Self::deposit_event(Event::NodesSwapped); } - + /// Reset all the permissioned nodes in the list. /// /// May only be called from `T::ResetOrigin`. /// /// - `nodes`: the new nodes for the allowlist. #[weight = (T::WeightInfo::reset_nodes(), DispatchClass::Operational)] - pub fn reset_nodes(origin, mut nodes: Vec) { + pub fn reset_nodes(origin, nodes: Vec) { T::ResetOrigin::ensure_origin(origin)?; ensure!(nodes.len() < T::MaxPermissionedNodes::get() as usize, Error::::TooManyNodes); + let mut nodes = nodes; nodes.sort(); Self::put_allowlist(nodes); @@ -201,11 +202,11 @@ decl_module! { impl Module { fn get_allowlist() -> Vec { - storage::unhashed::get_or_default(well_known_keys::NODE_ALLOWLIST) + storage::unhashed::get_or_default(well_known_keys::NODE_ALLOW_LIST) } fn put_allowlist(nodes: Vec) { - storage::unhashed::put(well_known_keys::NODE_ALLOWLIST, &nodes); + storage::unhashed::put(well_known_keys::NODE_ALLOW_LIST, &nodes); } } diff --git a/primitives/storage/src/lib.rs b/primitives/storage/src/lib.rs index 70add1ca9cfdf..3e1f6a1802348 100644 --- a/primitives/storage/src/lib.rs +++ b/primitives/storage/src/lib.rs @@ -152,7 +152,7 @@ pub mod well_known_keys { pub const DEFAULT_CHILD_STORAGE_KEY_PREFIX: &'static [u8] = b":child_storage:default:"; /// Permissioned node list. - pub const NODE_ALLOWLIST: &'static [u8] = b":node_allowlist"; + pub const NODE_ALLOW_LIST: &'static [u8] = b":node_allow_list"; /// Whether a key is a child storage key. /// From fda845c09406fa05d7c686847d11188683755141 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Sun, 16 Aug 2020 19:02:24 +0800 Subject: [PATCH 40/50] rename to node-authorization --- Cargo.lock | 2 +- Cargo.toml | 2 +- frame/{node-permission => node-authorization}/Cargo.toml | 2 +- frame/{node-permission => node-authorization}/src/lib.rs | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename frame/{node-permission => node-authorization}/Cargo.toml (97%) rename frame/{node-permission => node-authorization}/src/lib.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index a3d2987aefe6a..25e188bdb352b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4568,7 +4568,7 @@ dependencies = [ ] [[package]] -name = "pallet-node-permission" +name = "pallet-node-authorization" version = "2.0.0-rc5" dependencies = [ "frame-support", diff --git a/Cargo.toml b/Cargo.toml index 854e447bf572d..269554d5d16f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,7 +88,7 @@ members = [ "frame/metadata", "frame/multisig", "frame/nicks", - "frame/node-permission", + "frame/node-authorization", "frame/offences", "frame/proxy", "frame/randomness-collective-flip", diff --git a/frame/node-permission/Cargo.toml b/frame/node-authorization/Cargo.toml similarity index 97% rename from frame/node-permission/Cargo.toml rename to frame/node-authorization/Cargo.toml index e11cee0cd96fa..f8ded46f990ea 100644 --- a/frame/node-permission/Cargo.toml +++ b/frame/node-authorization/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "pallet-node-permission" +name = "pallet-node-authorization" version = "2.0.0-rc5" authors = ["Parity Technologies "] edition = "2018" diff --git a/frame/node-permission/src/lib.rs b/frame/node-authorization/src/lib.rs similarity index 100% rename from frame/node-permission/src/lib.rs rename to frame/node-authorization/src/lib.rs From c0912c38a69b831bbc56be9b8688fd9d867a5f51 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Sun, 16 Aug 2020 19:40:44 +0800 Subject: [PATCH 41/50] refactor more --- frame/node-authorization/Cargo.toml | 2 +- frame/node-authorization/src/lib.rs | 76 ++++++++++++++--------------- primitives/storage/src/lib.rs | 2 +- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/frame/node-authorization/Cargo.toml b/frame/node-authorization/Cargo.toml index f8ded46f990ea..dfc58432adf6f 100644 --- a/frame/node-authorization/Cargo.toml +++ b/frame/node-authorization/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" -description = "FRAME pallet for permissioned node" +description = "FRAME pallet for node authorization" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/frame/node-authorization/src/lib.rs b/frame/node-authorization/src/lib.rs index 745d524b34bb6..4f75ea5680177 100644 --- a/frame/node-authorization/src/lib.rs +++ b/frame/node-authorization/src/lib.rs @@ -15,7 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! # Node permission pallet +//! # Node authorization pallet //! //! This pallet manages a configurable set of nodes for a permissioned blockchain. //! The node set is stored under [`well_known_keys::NODE_ALLOW_LIST`]. @@ -53,23 +53,23 @@ pub trait Trait: frame_system::Trait { /// The event type of this module. type Event: From + Into<::Event>; - /// The maximum number of permissioned nodes that are allowed to set - type MaxPermissionedNodes: Get; + /// The maximum number of authorized nodes that are allowed to set + type MaxAuthorizedNodes: Get; /// The node identifier type for the runtime. type NodeId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord + Default; - /// The origin which can add a permissioned node. + /// The origin which can add a authorized node. type AddOrigin: EnsureOrigin; - /// The origin which can remove a permissioned node. + /// The origin which can remove a authorized node. type RemoveOrigin: EnsureOrigin; - /// The origin which can swap the permissioned nodes. + /// The origin which can swap the authorized nodes. type SwapOrigin: EnsureOrigin; - /// The origin which can reset the permissioned nodes. + /// The origin which can reset the authorized nodes. type ResetOrigin: EnsureOrigin; /// Weight information for extrinsics in this pallet. @@ -77,7 +77,7 @@ pub trait Trait: frame_system::Trait { } decl_storage! { - trait Store for Module as NodePermission {} + trait Store for Module as NodeAuthorization {} add_extra_genesis { config(nodes): Vec; build(|config: &GenesisConfig| { @@ -100,9 +100,9 @@ decl_event! { } decl_error! { - /// Error for the node permission module. + /// Error for the node authorization module. pub enum Error for Module { - /// Too many permissioned nodes. + /// Too many authorized nodes. TooManyNodes, /// The node is already joined in the list. AlreadyJoined, @@ -113,8 +113,8 @@ decl_error! { decl_module! { pub struct Module for enum Call where origin: T::Origin { - /// The maximum number of permissioned nodes - const MaxPermissionedNodes: u32 = T::MaxPermissionedNodes::get(); + /// The maximum number of authorized nodes + const MaxAuthorizedNodes: u32 = T::MaxAuthorizedNodes::get(); type Error = Error; @@ -130,7 +130,7 @@ decl_module! { T::AddOrigin::ensure_origin(origin)?; let mut nodes = Self::get_allowlist(); - ensure!(nodes.len() < T::MaxPermissionedNodes::get() as usize, Error::::TooManyNodes); + ensure!(nodes.len() < T::MaxAuthorizedNodes::get() as usize, Error::::TooManyNodes); let location = nodes.binary_search(&node_id).err().ok_or(Error::::AlreadyJoined)?; nodes.insert(location, node_id); @@ -181,7 +181,7 @@ decl_module! { Self::deposit_event(Event::NodesSwapped); } - /// Reset all the permissioned nodes in the list. + /// Reset all the authorized nodes in the list. /// /// May only be called from `T::ResetOrigin`. /// @@ -189,7 +189,7 @@ decl_module! { #[weight = (T::WeightInfo::reset_nodes(), DispatchClass::Operational)] pub fn reset_nodes(origin, nodes: Vec) { T::ResetOrigin::ensure_origin(origin)?; - ensure!(nodes.len() < T::MaxPermissionedNodes::get() as usize, Error::::TooManyNodes); + ensure!(nodes.len() < T::MaxAuthorizedNodes::get() as usize, Error::::TooManyNodes); let mut nodes = nodes; nodes.sort(); @@ -270,11 +270,11 @@ mod tests { pub const Four: u64 = 4; } parameter_types! { - pub const MaxPermissionedNodes: u32 = 4; + pub const MaxAuthorizedNodes: u32 = 4; } impl Trait for Test { type Event = (); - type MaxPermissionedNodes = MaxPermissionedNodes; + type MaxAuthorizedNodes = MaxAuthorizedNodes; type NodeId = u64; type AddOrigin = EnsureSignedBy; type RemoveOrigin = EnsureSignedBy; @@ -283,7 +283,7 @@ mod tests { type WeightInfo = (); } - type NodePermission = Module; + type NodeAuthorization = Module; fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); @@ -296,57 +296,57 @@ mod tests { #[test] fn add_node_works() { new_test_ext().execute_with(|| { - assert_noop!(NodePermission::add_node(Origin::signed(2), 15), BadOrigin); - assert_noop!(NodePermission::add_node(Origin::signed(1), 20), Error::::AlreadyJoined); + assert_noop!(NodeAuthorization::add_node(Origin::signed(2), 15), BadOrigin); + assert_noop!(NodeAuthorization::add_node(Origin::signed(1), 20), Error::::AlreadyJoined); - assert_ok!(NodePermission::add_node(Origin::signed(1), 15)); - assert_eq!(NodePermission::get_allowlist(), vec![10, 15, 20, 30]); + assert_ok!(NodeAuthorization::add_node(Origin::signed(1), 15)); + assert_eq!(NodeAuthorization::get_allowlist(), vec![10, 15, 20, 30]); - assert_noop!(NodePermission::add_node(Origin::signed(1), 25), Error::::TooManyNodes); + assert_noop!(NodeAuthorization::add_node(Origin::signed(1), 25), Error::::TooManyNodes); }); } #[test] fn remove_node_works() { new_test_ext().execute_with(|| { - assert_noop!(NodePermission::remove_node(Origin::signed(3), 20), BadOrigin); - assert_noop!(NodePermission::remove_node(Origin::signed(2), 40), Error::::NotExist); + assert_noop!(NodeAuthorization::remove_node(Origin::signed(3), 20), BadOrigin); + assert_noop!(NodeAuthorization::remove_node(Origin::signed(2), 40), Error::::NotExist); - assert_ok!(NodePermission::remove_node(Origin::signed(2), 20)); - assert_eq!(NodePermission::get_allowlist(), vec![10, 30]); + assert_ok!(NodeAuthorization::remove_node(Origin::signed(2), 20)); + assert_eq!(NodeAuthorization::get_allowlist(), vec![10, 30]); }); } #[test] fn swap_node_works() { new_test_ext().execute_with(|| { - assert_noop!(NodePermission::swap_node(Origin::signed(4), 20, 5), BadOrigin); + assert_noop!(NodeAuthorization::swap_node(Origin::signed(4), 20, 5), BadOrigin); - assert_ok!(NodePermission::swap_node(Origin::signed(3), 20, 20)); - assert_eq!(NodePermission::get_allowlist(), vec![10, 20, 30]); + assert_ok!(NodeAuthorization::swap_node(Origin::signed(3), 20, 20)); + assert_eq!(NodeAuthorization::get_allowlist(), vec![10, 20, 30]); - assert_noop!(NodePermission::swap_node(Origin::signed(3), 15, 5), Error::::NotExist); + assert_noop!(NodeAuthorization::swap_node(Origin::signed(3), 15, 5), Error::::NotExist); assert_noop!( - NodePermission::swap_node(Origin::signed(3), 20, 30), + NodeAuthorization::swap_node(Origin::signed(3), 20, 30), Error::::AlreadyJoined ); - assert_ok!(NodePermission::swap_node(Origin::signed(3), 20, 5)); - assert_eq!(NodePermission::get_allowlist(), vec![5, 10, 30]); + assert_ok!(NodeAuthorization::swap_node(Origin::signed(3), 20, 5)); + assert_eq!(NodeAuthorization::get_allowlist(), vec![5, 10, 30]); }); } #[test] fn reset_nodes_works() { new_test_ext().execute_with(|| { - assert_noop!(NodePermission::reset_nodes(Origin::signed(3), vec![15, 5, 20]), BadOrigin); + assert_noop!(NodeAuthorization::reset_nodes(Origin::signed(3), vec![15, 5, 20]), BadOrigin); assert_noop!( - NodePermission::reset_nodes(Origin::signed(4), vec![15, 5, 20, 25]), + NodeAuthorization::reset_nodes(Origin::signed(4), vec![15, 5, 20, 25]), Error::::TooManyNodes ); - assert_ok!(NodePermission::reset_nodes(Origin::signed(4), vec![15, 5, 20])); - assert_eq!(NodePermission::get_allowlist(), vec![5, 15, 20]); + assert_ok!(NodeAuthorization::reset_nodes(Origin::signed(4), vec![15, 5, 20])); + assert_eq!(NodeAuthorization::get_allowlist(), vec![5, 15, 20]); }); } } diff --git a/primitives/storage/src/lib.rs b/primitives/storage/src/lib.rs index 3e1f6a1802348..8b5e2e2b67e24 100644 --- a/primitives/storage/src/lib.rs +++ b/primitives/storage/src/lib.rs @@ -151,7 +151,7 @@ pub mod well_known_keys { /// Prefix of the default child storage keys in the top trie. pub const DEFAULT_CHILD_STORAGE_KEY_PREFIX: &'static [u8] = b":child_storage:default:"; - /// Permissioned node list. + /// Authorized node list. pub const NODE_ALLOW_LIST: &'static [u8] = b":node_allow_list"; /// Whether a key is a child storage key. From 46cd90107600cec909d54c65d521fd6f47bf6a71 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Tue, 18 Aug 2020 08:04:37 +0800 Subject: [PATCH 42/50] rename to allow list --- client/service/src/lib.rs | 16 +++++++------- frame/node-authorization/src/lib.rs | 34 ++++++++++++++--------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 6ba5d027543be..b3961931db1f5 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -206,7 +206,7 @@ async fn build_network_future< should_have_peers: bool, announce_imported_blocks: bool, ) { - check_node_allowlist(&network, &client); + check_node_allow_list(&network, &client); let mut imported_blocks_stream = client.import_notification_stream().fuse(); @@ -251,7 +251,7 @@ async fn build_network_future< ); } - check_node_allowlist(&network, &client); + check_node_allow_list(&network, &client); } // List of blocks that the client has finalized. @@ -353,7 +353,7 @@ async fn build_network_future< /// Set storage `NODE_ALLOW_LIST` means it's a permissioned network, /// then only connect to these well known peers. -fn check_node_allowlist< +fn check_node_allow_list< B: BlockT, BE: BackendT, C: BlockchainEvents + StorageProvider + HeaderBackend, @@ -363,12 +363,12 @@ fn check_node_allowlist< client: &Arc, ) { let id = BlockId::hash(client.info().best_hash); - let allowlist_storage = client.storage(&id, &StorageKey(well_known_keys::NODE_ALLOW_LIST.to_vec())); - if let Ok(Some(raw_allowlist)) = allowlist_storage { - let node_allowlist = Vec::::decode_all(&mut &raw_allowlist.0[..]); + let allow_list_storage = client.storage(&id, &StorageKey(well_known_keys::NODE_ALLOW_LIST.to_vec())); + if let Ok(Some(raw_allow_list)) = allow_list_storage { + let node_allow_list = Vec::::decode_all(&mut &raw_allow_list.0[..]); - if let Ok(node_allowlist) = node_allowlist { - let mut peer_ids: HashSet = node_allowlist.iter() + if let Ok(node_allow_list) = node_allow_list { + let mut peer_ids: HashSet = node_allow_list.iter() .filter_map(|pubkey| Ed25519PublicKey::decode(&pubkey.0).ok()) .map(|pubkey| PublicKey::Ed25519(pubkey).into_peer_id()) .collect(); diff --git a/frame/node-authorization/src/lib.rs b/frame/node-authorization/src/lib.rs index 4f75ea5680177..9411956a66dc4 100644 --- a/frame/node-authorization/src/lib.rs +++ b/frame/node-authorization/src/lib.rs @@ -120,7 +120,7 @@ decl_module! { fn deposit_event() = default; - /// Add a node to the allowlist. + /// Add a node to the allow list. /// /// May only be called from `T::AddOrigin`. /// @@ -129,17 +129,17 @@ decl_module! { pub fn add_node(origin, node_id: T::NodeId) { T::AddOrigin::ensure_origin(origin)?; - let mut nodes = Self::get_allowlist(); + let mut nodes = Self::get_allow_list(); ensure!(nodes.len() < T::MaxAuthorizedNodes::get() as usize, Error::::TooManyNodes); let location = nodes.binary_search(&node_id).err().ok_or(Error::::AlreadyJoined)?; nodes.insert(location, node_id); - Self::put_allowlist(nodes); + Self::put_allow_list(nodes); Self::deposit_event(Event::NodeAdded); } - /// Remove a node from the allowlist. + /// Remove a node from the allow list. /// /// May only be called from `T::RemoveOrigin`. /// @@ -148,11 +148,11 @@ decl_module! { pub fn remove_node(origin, node_id: T::NodeId) { T::RemoveOrigin::ensure_origin(origin)?; - let mut nodes = Self::get_allowlist(); + let mut nodes = Self::get_allow_list(); let location = nodes.binary_search(&node_id).ok().ok_or(Error::::NotExist)?; nodes.remove(location); - Self::put_allowlist(nodes); + Self::put_allow_list(nodes); Self::deposit_event(Event::NodeRemoved); } @@ -171,12 +171,12 @@ decl_module! { if remove == add { return Ok(()) } - let mut nodes = Self::get_allowlist(); + let mut nodes = Self::get_allow_list(); let remove_location = nodes.binary_search(&remove).ok().ok_or(Error::::NotExist)?; nodes.remove(remove_location); let add_location = nodes.binary_search(&add).err().ok_or(Error::::AlreadyJoined)?; nodes.insert(add_location, add); - Self::put_allowlist(nodes); + Self::put_allow_list(nodes); Self::deposit_event(Event::NodesSwapped); } @@ -185,7 +185,7 @@ decl_module! { /// /// May only be called from `T::ResetOrigin`. /// - /// - `nodes`: the new nodes for the allowlist. + /// - `nodes`: the new nodes for the allow list. #[weight = (T::WeightInfo::reset_nodes(), DispatchClass::Operational)] pub fn reset_nodes(origin, nodes: Vec) { T::ResetOrigin::ensure_origin(origin)?; @@ -193,7 +193,7 @@ decl_module! { let mut nodes = nodes; nodes.sort(); - Self::put_allowlist(nodes); + Self::put_allow_list(nodes); Self::deposit_event(Event::NodesReset); } @@ -201,11 +201,11 @@ decl_module! { } impl Module { - fn get_allowlist() -> Vec { + fn get_allow_list() -> Vec { storage::unhashed::get_or_default(well_known_keys::NODE_ALLOW_LIST) } - fn put_allowlist(nodes: Vec) { + fn put_allow_list(nodes: Vec) { storage::unhashed::put(well_known_keys::NODE_ALLOW_LIST, &nodes); } } @@ -300,7 +300,7 @@ mod tests { assert_noop!(NodeAuthorization::add_node(Origin::signed(1), 20), Error::::AlreadyJoined); assert_ok!(NodeAuthorization::add_node(Origin::signed(1), 15)); - assert_eq!(NodeAuthorization::get_allowlist(), vec![10, 15, 20, 30]); + assert_eq!(NodeAuthorization::get_allow_list(), vec![10, 15, 20, 30]); assert_noop!(NodeAuthorization::add_node(Origin::signed(1), 25), Error::::TooManyNodes); }); @@ -313,7 +313,7 @@ mod tests { assert_noop!(NodeAuthorization::remove_node(Origin::signed(2), 40), Error::::NotExist); assert_ok!(NodeAuthorization::remove_node(Origin::signed(2), 20)); - assert_eq!(NodeAuthorization::get_allowlist(), vec![10, 30]); + assert_eq!(NodeAuthorization::get_allow_list(), vec![10, 30]); }); } @@ -323,7 +323,7 @@ mod tests { assert_noop!(NodeAuthorization::swap_node(Origin::signed(4), 20, 5), BadOrigin); assert_ok!(NodeAuthorization::swap_node(Origin::signed(3), 20, 20)); - assert_eq!(NodeAuthorization::get_allowlist(), vec![10, 20, 30]); + assert_eq!(NodeAuthorization::get_allow_list(), vec![10, 20, 30]); assert_noop!(NodeAuthorization::swap_node(Origin::signed(3), 15, 5), Error::::NotExist); assert_noop!( @@ -332,7 +332,7 @@ mod tests { ); assert_ok!(NodeAuthorization::swap_node(Origin::signed(3), 20, 5)); - assert_eq!(NodeAuthorization::get_allowlist(), vec![5, 10, 30]); + assert_eq!(NodeAuthorization::get_allow_list(), vec![5, 10, 30]); }); } @@ -346,7 +346,7 @@ mod tests { ); assert_ok!(NodeAuthorization::reset_nodes(Origin::signed(4), vec![15, 5, 20])); - assert_eq!(NodeAuthorization::get_allowlist(), vec![5, 15, 20]); + assert_eq!(NodeAuthorization::get_allow_list(), vec![5, 15, 20]); }); } } From 1a81a513710402e7ccdc95bed36e3dffd22380b3 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Tue, 18 Aug 2020 09:05:26 +0800 Subject: [PATCH 43/50] Add node id in events. --- frame/node-authorization/src/lib.rs | 48 ++++++++++++++--------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/frame/node-authorization/src/lib.rs b/frame/node-authorization/src/lib.rs index 9411956a66dc4..375ef158f8f16 100644 --- a/frame/node-authorization/src/lib.rs +++ b/frame/node-authorization/src/lib.rs @@ -51,7 +51,7 @@ impl WeightInfo for () { pub trait Trait: frame_system::Trait { /// The event type of this module. - type Event: From + Into<::Event>; + type Event: From> + Into<::Event>; /// The maximum number of authorized nodes that are allowed to set type MaxAuthorizedNodes: Get; @@ -86,18 +86,18 @@ decl_storage! { } } -decl_event! { - pub enum Event { - /// The given node was added; see the transaction for node id. - NodeAdded, - /// The given node was removed; see the transaction for node id. - NodeRemoved, - /// Two given nodes were swapped; see the transaction for node id. - NodesSwapped, - /// The given nodes were reset; see the transaction for new set. - NodesReset, +decl_event!( + pub enum Event where NodeId = ::NodeId { + /// The given node was added. + NodeAdded(NodeId), + /// The given node was removed. + NodeRemoved(NodeId), + /// Two given nodes were swapped; first item is removed, the latter is added. + NodesSwapped(NodeId, NodeId), + /// The given nodes were reset. + NodesReset(Vec), } -} +); decl_error! { /// Error for the node authorization module. @@ -133,10 +133,10 @@ decl_module! { ensure!(nodes.len() < T::MaxAuthorizedNodes::get() as usize, Error::::TooManyNodes); let location = nodes.binary_search(&node_id).err().ok_or(Error::::AlreadyJoined)?; - nodes.insert(location, node_id); - Self::put_allow_list(nodes); + nodes.insert(location, node_id.clone()); + Self::put_allow_list(&nodes); - Self::deposit_event(Event::NodeAdded); + Self::deposit_event(RawEvent::NodeAdded(node_id)); } /// Remove a node from the allow list. @@ -152,9 +152,9 @@ decl_module! { let location = nodes.binary_search(&node_id).ok().ok_or(Error::::NotExist)?; nodes.remove(location); - Self::put_allow_list(nodes); + Self::put_allow_list(&nodes); - Self::deposit_event(Event::NodeRemoved); + Self::deposit_event(RawEvent::NodeRemoved(node_id)); } /// Swap two nodes. @@ -175,10 +175,10 @@ decl_module! { let remove_location = nodes.binary_search(&remove).ok().ok_or(Error::::NotExist)?; nodes.remove(remove_location); let add_location = nodes.binary_search(&add).err().ok_or(Error::::AlreadyJoined)?; - nodes.insert(add_location, add); - Self::put_allow_list(nodes); + nodes.insert(add_location, add.clone()); + Self::put_allow_list(&nodes); - Self::deposit_event(Event::NodesSwapped); + Self::deposit_event(RawEvent::NodesSwapped(remove, add)); } /// Reset all the authorized nodes in the list. @@ -193,9 +193,9 @@ decl_module! { let mut nodes = nodes; nodes.sort(); - Self::put_allow_list(nodes); + Self::put_allow_list(&nodes); - Self::deposit_event(Event::NodesReset); + Self::deposit_event(RawEvent::NodesReset(nodes)); } } } @@ -205,8 +205,8 @@ impl Module { storage::unhashed::get_or_default(well_known_keys::NODE_ALLOW_LIST) } - fn put_allow_list(nodes: Vec) { - storage::unhashed::put(well_known_keys::NODE_ALLOW_LIST, &nodes); + fn put_allow_list(nodes: &Vec) { + storage::unhashed::put(well_known_keys::NODE_ALLOW_LIST, nodes); } } From 386029e090dd6072ffd7c2a1a8d7b9cb7a3f67c3 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Wed, 19 Aug 2020 23:28:55 +0800 Subject: [PATCH 44/50] rename to NodePublicKey --- frame/node-authorization/src/lib.rs | 42 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/frame/node-authorization/src/lib.rs b/frame/node-authorization/src/lib.rs index 375ef158f8f16..55e5b2fb6ca0d 100644 --- a/frame/node-authorization/src/lib.rs +++ b/frame/node-authorization/src/lib.rs @@ -57,7 +57,7 @@ pub trait Trait: frame_system::Trait { type MaxAuthorizedNodes: Get; /// The node identifier type for the runtime. - type NodeId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + type NodePublicKey: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord + Default; /// The origin which can add a authorized node. @@ -79,7 +79,7 @@ pub trait Trait: frame_system::Trait { decl_storage! { trait Store for Module as NodeAuthorization {} add_extra_genesis { - config(nodes): Vec; + config(nodes): Vec; build(|config: &GenesisConfig| { sp_io::storage::set(well_known_keys::NODE_ALLOW_LIST, &config.nodes.encode()); }); @@ -87,15 +87,15 @@ decl_storage! { } decl_event!( - pub enum Event where NodeId = ::NodeId { + pub enum Event where NodePublicKey = ::NodePublicKey { /// The given node was added. - NodeAdded(NodeId), + NodeAdded(NodePublicKey), /// The given node was removed. - NodeRemoved(NodeId), + NodeRemoved(NodePublicKey), /// Two given nodes were swapped; first item is removed, the latter is added. - NodesSwapped(NodeId, NodeId), + NodesSwapped(NodePublicKey, NodePublicKey), /// The given nodes were reset. - NodesReset(Vec), + NodesReset(Vec), } ); @@ -124,37 +124,37 @@ decl_module! { /// /// May only be called from `T::AddOrigin`. /// - /// - `node_id`: identifier of the node, it's likely the public key of ed25519 keypair. + /// - `node_public_key`: identifier of the node, it's likely the public key of ed25519 keypair. #[weight = (T::WeightInfo::add_node(), DispatchClass::Operational)] - pub fn add_node(origin, node_id: T::NodeId) { + pub fn add_node(origin, node_public_key: T::NodePublicKey) { T::AddOrigin::ensure_origin(origin)?; let mut nodes = Self::get_allow_list(); ensure!(nodes.len() < T::MaxAuthorizedNodes::get() as usize, Error::::TooManyNodes); - let location = nodes.binary_search(&node_id).err().ok_or(Error::::AlreadyJoined)?; - nodes.insert(location, node_id.clone()); + let location = nodes.binary_search(&node_public_key).err().ok_or(Error::::AlreadyJoined)?; + nodes.insert(location, node_public_key.clone()); Self::put_allow_list(&nodes); - Self::deposit_event(RawEvent::NodeAdded(node_id)); + Self::deposit_event(RawEvent::NodeAdded(node_public_key)); } /// Remove a node from the allow list. /// /// May only be called from `T::RemoveOrigin`. /// - /// - `node_id`: identifier of the node, it's likely the public key of ed25519 keypair. + /// - `node_public_key`: identifier of the node, it's likely the public key of ed25519 keypair. #[weight = (T::WeightInfo::remove_node(), DispatchClass::Operational)] - pub fn remove_node(origin, node_id: T::NodeId) { + pub fn remove_node(origin, node_public_key: T::NodePublicKey) { T::RemoveOrigin::ensure_origin(origin)?; let mut nodes = Self::get_allow_list(); - let location = nodes.binary_search(&node_id).ok().ok_or(Error::::NotExist)?; + let location = nodes.binary_search(&node_public_key).ok().ok_or(Error::::NotExist)?; nodes.remove(location); Self::put_allow_list(&nodes); - Self::deposit_event(RawEvent::NodeRemoved(node_id)); + Self::deposit_event(RawEvent::NodeRemoved(node_public_key)); } /// Swap two nodes. @@ -166,7 +166,7 @@ decl_module! { /// - `add`: the node which will be put in the list, it's likely the public key of ed25519 /// keypair. #[weight = (T::WeightInfo::swap_node(), DispatchClass::Operational)] - pub fn swap_node(origin, remove: T::NodeId, add: T::NodeId) { + pub fn swap_node(origin, remove: T::NodePublicKey, add: T::NodePublicKey) { T::SwapOrigin::ensure_origin(origin)?; if remove == add { return Ok(()) } @@ -187,7 +187,7 @@ decl_module! { /// /// - `nodes`: the new nodes for the allow list. #[weight = (T::WeightInfo::reset_nodes(), DispatchClass::Operational)] - pub fn reset_nodes(origin, nodes: Vec) { + pub fn reset_nodes(origin, nodes: Vec) { T::ResetOrigin::ensure_origin(origin)?; ensure!(nodes.len() < T::MaxAuthorizedNodes::get() as usize, Error::::TooManyNodes); @@ -201,11 +201,11 @@ decl_module! { } impl Module { - fn get_allow_list() -> Vec { + fn get_allow_list() -> Vec { storage::unhashed::get_or_default(well_known_keys::NODE_ALLOW_LIST) } - fn put_allow_list(nodes: &Vec) { + fn put_allow_list(nodes: &Vec) { storage::unhashed::put(well_known_keys::NODE_ALLOW_LIST, nodes); } } @@ -275,7 +275,7 @@ mod tests { impl Trait for Test { type Event = (); type MaxAuthorizedNodes = MaxAuthorizedNodes; - type NodeId = u64; + type NodePublicKey = u64; type AddOrigin = EnsureSignedBy; type RemoveOrigin = EnsureSignedBy; type SwapOrigin = EnsureSignedBy; From fdd5afed2a60d384438386917fa1cd93ff51bbf8 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Fri, 21 Aug 2020 12:16:23 +0800 Subject: [PATCH 45/50] primitive type NodePublicKey. --- client/service/src/lib.rs | 10 ++++--- frame/node-authorization/src/lib.rs | 41 ++++++++++++----------------- primitives/core/src/crypto.rs | 8 ++++++ primitives/core/src/lib.rs | 2 +- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index b3961931db1f5..9d41038c7b694 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -54,7 +54,7 @@ use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use parity_util_mem::MallocSizeOf; use sp_utils::{status_sinks, mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}}; use sp_core::storage::{StorageKey, well_known_keys}; -use sp_core::ed25519::Public as NodePublic; +use sp_core::NodePublicKey; use sc_client_api::backend::{Backend as BackendT, StorageProvider}; use sc_client_api::blockchain::HeaderBackend; use sc_client_api::BlockchainEvents; @@ -365,11 +365,15 @@ fn check_node_allow_list< let id = BlockId::hash(client.info().best_hash); let allow_list_storage = client.storage(&id, &StorageKey(well_known_keys::NODE_ALLOW_LIST.to_vec())); if let Ok(Some(raw_allow_list)) = allow_list_storage { - let node_allow_list = Vec::::decode_all(&mut &raw_allow_list.0[..]); + let node_allow_list = Vec::::decode_all(&mut &raw_allow_list.0[..]); if let Ok(node_allow_list) = node_allow_list { let mut peer_ids: HashSet = node_allow_list.iter() - .filter_map(|pubkey| Ed25519PublicKey::decode(&pubkey.0).ok()) + .filter_map(|node_public_key| { + match node_public_key { + NodePublicKey::Ed25519(pubkey) => Ed25519PublicKey::decode(&pubkey.0).ok() + } + }) .map(|pubkey| PublicKey::Ed25519(pubkey).into_peer_id()) .collect(); peer_ids.remove(network.local_peer_id()); diff --git a/frame/node-authorization/src/lib.rs b/frame/node-authorization/src/lib.rs index 55e5b2fb6ca0d..17e9548936e08 100644 --- a/frame/node-authorization/src/lib.rs +++ b/frame/node-authorization/src/lib.rs @@ -24,12 +24,10 @@ #![cfg_attr(not(feature = "std"), no_std)] use sp_std::prelude::*; -use sp_std::fmt::Debug; -use sp_core::storage::well_known_keys; -use sp_runtime::traits::{Member, MaybeSerializeDeserialize, MaybeDisplay}; +use sp_core::{NodePublicKey, storage::well_known_keys}; use frame_support::{ decl_module, decl_storage, decl_event, decl_error, - Parameter, storage, ensure, + storage, ensure, weights::{DispatchClass, Weight}, traits::{Get, EnsureOrigin}, }; @@ -51,15 +49,11 @@ impl WeightInfo for () { pub trait Trait: frame_system::Trait { /// The event type of this module. - type Event: From> + Into<::Event>; + type Event: From + Into<::Event>; /// The maximum number of authorized nodes that are allowed to set type MaxAuthorizedNodes: Get; - /// The node identifier type for the runtime. - type NodePublicKey: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay - + Ord + Default; - /// The origin which can add a authorized node. type AddOrigin: EnsureOrigin; @@ -79,21 +73,21 @@ pub trait Trait: frame_system::Trait { decl_storage! { trait Store for Module as NodeAuthorization {} add_extra_genesis { - config(nodes): Vec; - build(|config: &GenesisConfig| { + config(nodes): Vec; + build(|config: &GenesisConfig| { sp_io::storage::set(well_known_keys::NODE_ALLOW_LIST, &config.nodes.encode()); }); } } decl_event!( - pub enum Event where NodePublicKey = ::NodePublicKey { + pub enum Event { /// The given node was added. NodeAdded(NodePublicKey), /// The given node was removed. NodeRemoved(NodePublicKey), /// Two given nodes were swapped; first item is removed, the latter is added. - NodesSwapped(NodePublicKey, NodePublicKey), + NodeSwapped(NodePublicKey, NodePublicKey), /// The given nodes were reset. NodesReset(Vec), } @@ -126,7 +120,7 @@ decl_module! { /// /// - `node_public_key`: identifier of the node, it's likely the public key of ed25519 keypair. #[weight = (T::WeightInfo::add_node(), DispatchClass::Operational)] - pub fn add_node(origin, node_public_key: T::NodePublicKey) { + pub fn add_node(origin, node_public_key: NodePublicKey) { T::AddOrigin::ensure_origin(origin)?; let mut nodes = Self::get_allow_list(); @@ -136,7 +130,7 @@ decl_module! { nodes.insert(location, node_public_key.clone()); Self::put_allow_list(&nodes); - Self::deposit_event(RawEvent::NodeAdded(node_public_key)); + Self::deposit_event(Event::NodeAdded(node_public_key)); } /// Remove a node from the allow list. @@ -145,7 +139,7 @@ decl_module! { /// /// - `node_public_key`: identifier of the node, it's likely the public key of ed25519 keypair. #[weight = (T::WeightInfo::remove_node(), DispatchClass::Operational)] - pub fn remove_node(origin, node_public_key: T::NodePublicKey) { + pub fn remove_node(origin, node_public_key: NodePublicKey) { T::RemoveOrigin::ensure_origin(origin)?; let mut nodes = Self::get_allow_list(); @@ -154,7 +148,7 @@ decl_module! { nodes.remove(location); Self::put_allow_list(&nodes); - Self::deposit_event(RawEvent::NodeRemoved(node_public_key)); + Self::deposit_event(Event::NodeRemoved(node_public_key)); } /// Swap two nodes. @@ -166,7 +160,7 @@ decl_module! { /// - `add`: the node which will be put in the list, it's likely the public key of ed25519 /// keypair. #[weight = (T::WeightInfo::swap_node(), DispatchClass::Operational)] - pub fn swap_node(origin, remove: T::NodePublicKey, add: T::NodePublicKey) { + pub fn swap_node(origin, remove: NodePublicKey, add: NodePublicKey) { T::SwapOrigin::ensure_origin(origin)?; if remove == add { return Ok(()) } @@ -178,7 +172,7 @@ decl_module! { nodes.insert(add_location, add.clone()); Self::put_allow_list(&nodes); - Self::deposit_event(RawEvent::NodesSwapped(remove, add)); + Self::deposit_event(Event::NodeSwapped(remove, add)); } /// Reset all the authorized nodes in the list. @@ -187,7 +181,7 @@ decl_module! { /// /// - `nodes`: the new nodes for the allow list. #[weight = (T::WeightInfo::reset_nodes(), DispatchClass::Operational)] - pub fn reset_nodes(origin, nodes: Vec) { + pub fn reset_nodes(origin, nodes: Vec) { T::ResetOrigin::ensure_origin(origin)?; ensure!(nodes.len() < T::MaxAuthorizedNodes::get() as usize, Error::::TooManyNodes); @@ -195,17 +189,17 @@ decl_module! { nodes.sort(); Self::put_allow_list(&nodes); - Self::deposit_event(RawEvent::NodesReset(nodes)); + Self::deposit_event(Event::NodesReset(nodes)); } } } impl Module { - fn get_allow_list() -> Vec { + fn get_allow_list() -> Vec { storage::unhashed::get_or_default(well_known_keys::NODE_ALLOW_LIST) } - fn put_allow_list(nodes: &Vec) { + fn put_allow_list(nodes: &Vec) { storage::unhashed::put(well_known_keys::NODE_ALLOW_LIST, nodes); } } @@ -275,7 +269,6 @@ mod tests { impl Trait for Test { type Event = (); type MaxAuthorizedNodes = MaxAuthorizedNodes; - type NodePublicKey = u64; type AddOrigin = EnsureSignedBy; type RemoveOrigin = EnsureSignedBy; type SwapOrigin = EnsureSignedBy; diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index efacf0b2e76a6..0e5ba7ab9249e 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -681,6 +681,14 @@ impl sp_std::str::FromStr for AccountId32 { } } +/// Public key of node which can be used for network connection +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, crate::RuntimeDebug)] +pub enum NodePublicKey { + /// An Ed25519 public key + Ed25519(ed25519::Public), +} + #[cfg(feature = "std")] pub use self::dummy::*; diff --git a/primitives/core/src/lib.rs b/primitives/core/src/lib.rs index c8a289639d4f2..c6945d83f0096 100644 --- a/primitives/core/src/lib.rs +++ b/primitives/core/src/lib.rs @@ -77,7 +77,7 @@ pub use self::hash::{H160, H256, H512, convert_hash}; pub use self::uint::{U256, U512}; pub use changes_trie::{ChangesTrieConfiguration, ChangesTrieConfigurationRange}; #[cfg(feature = "full_crypto")] -pub use crypto::{DeriveJunction, Pair, Public}; +pub use crypto::{DeriveJunction, Pair, Public, NodePublicKey}; pub use hash_db::Hasher; #[cfg(feature = "std")] From 4aa9ef6455331da3974a8f52d0e88cdac17b82d1 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Fri, 21 Aug 2020 13:24:16 +0800 Subject: [PATCH 46/50] fix tests. --- Cargo.lock | 1 + frame/node-authorization/Cargo.toml | 3 + frame/node-authorization/src/lib.rs | 159 ++++++++++++++++++++++++---- 3 files changed, 140 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3ab1e74dfc72c..fdab775b98c4b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4575,6 +4575,7 @@ version = "2.0.0-rc5" dependencies = [ "frame-support", "frame-system", + "hex-literal", "parity-scale-codec", "serde", "sp-core", diff --git a/frame/node-authorization/Cargo.toml b/frame/node-authorization/Cargo.toml index dfc58432adf6f..5140ee6819475 100644 --- a/frame/node-authorization/Cargo.toml +++ b/frame/node-authorization/Cargo.toml @@ -21,6 +21,9 @@ sp-io = { version = "2.0.0-rc5", default-features = false, path = "../../primiti sp-runtime = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/runtime" } sp-std = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/std" } +[dev-dependencies] +hex-literal = "0.2.1" + [features] default = ["std"] std = [ diff --git a/frame/node-authorization/src/lib.rs b/frame/node-authorization/src/lib.rs index 17e9548936e08..f9fc577ae0c49 100644 --- a/frame/node-authorization/src/lib.rs +++ b/frame/node-authorization/src/lib.rs @@ -213,8 +213,9 @@ mod tests { parameter_types, ord_parameter_types, }; use frame_system::EnsureSignedBy; - use sp_core::H256; + use sp_core::{H256, ed25519::Public}; use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup, BadOrigin}, testing::Header}; + use hex_literal::hex; impl_outer_origin! { pub enum Origin for Test where system = frame_system {} @@ -279,9 +280,19 @@ mod tests { type NodeAuthorization = Module; fn new_test_ext() -> sp_io::TestExternalities { + let pub10: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("0000000000000000000000000000000000000000000000000000000000000009") + )); + let pub20: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("0000000000000000000000000000000000000000000000000000000000000013") + )); + let pub30: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("000000000000000000000000000000000000000000000000000000000000001d") + )); + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - GenesisConfig::{ - nodes: vec![10, 20, 30], + GenesisConfig { + nodes: vec![pub10, pub20, pub30], }.assimilate_storage(&mut t).unwrap(); t.into() } @@ -289,57 +300,159 @@ mod tests { #[test] fn add_node_works() { new_test_ext().execute_with(|| { - assert_noop!(NodeAuthorization::add_node(Origin::signed(2), 15), BadOrigin); - assert_noop!(NodeAuthorization::add_node(Origin::signed(1), 20), Error::::AlreadyJoined); + let pub10: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("0000000000000000000000000000000000000000000000000000000000000009") + )); + let pub15: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("000000000000000000000000000000000000000000000000000000000000000e") + )); + let pub20: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("0000000000000000000000000000000000000000000000000000000000000013") + )); + let pub25: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("0000000000000000000000000000000000000000000000000000000000000018") + )); + let pub30: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("000000000000000000000000000000000000000000000000000000000000001d") + )); + + assert_noop!(NodeAuthorization::add_node(Origin::signed(2), pub15.clone()), BadOrigin); + assert_noop!( + NodeAuthorization::add_node(Origin::signed(1), pub20.clone()), + Error::::AlreadyJoined + ); - assert_ok!(NodeAuthorization::add_node(Origin::signed(1), 15)); - assert_eq!(NodeAuthorization::get_allow_list(), vec![10, 15, 20, 30]); + assert_ok!(NodeAuthorization::add_node(Origin::signed(1), pub15.clone())); + assert_eq!( + NodeAuthorization::get_allow_list(), + vec![pub10.clone(), pub15.clone(), pub20.clone(), pub30.clone()] + ); - assert_noop!(NodeAuthorization::add_node(Origin::signed(1), 25), Error::::TooManyNodes); + assert_noop!( + NodeAuthorization::add_node(Origin::signed(1), pub25.clone()), + Error::::TooManyNodes + ); }); } #[test] fn remove_node_works() { new_test_ext().execute_with(|| { - assert_noop!(NodeAuthorization::remove_node(Origin::signed(3), 20), BadOrigin); - assert_noop!(NodeAuthorization::remove_node(Origin::signed(2), 40), Error::::NotExist); + let pub10: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("0000000000000000000000000000000000000000000000000000000000000009") + )); + let pub20: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("0000000000000000000000000000000000000000000000000000000000000013") + )); + let pub30: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("000000000000000000000000000000000000000000000000000000000000001d") + )); + let pub40: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("0000000000000000000000000000000000000000000000000000000000000027") + )); + + assert_noop!( + NodeAuthorization::remove_node(Origin::signed(3), pub20.clone()), + BadOrigin + ); + assert_noop!( + NodeAuthorization::remove_node(Origin::signed(2), pub40.clone()), + Error::::NotExist + ); - assert_ok!(NodeAuthorization::remove_node(Origin::signed(2), 20)); - assert_eq!(NodeAuthorization::get_allow_list(), vec![10, 30]); + assert_ok!(NodeAuthorization::remove_node(Origin::signed(2), pub20.clone())); + assert_eq!(NodeAuthorization::get_allow_list(), vec![pub10.clone(), pub30.clone()]); }); } #[test] fn swap_node_works() { new_test_ext().execute_with(|| { - assert_noop!(NodeAuthorization::swap_node(Origin::signed(4), 20, 5), BadOrigin); + let pub5: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("0000000000000000000000000000000000000000000000000000000000000004") + )); + let pub10: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("0000000000000000000000000000000000000000000000000000000000000009") + )); + let pub15: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("000000000000000000000000000000000000000000000000000000000000000e") + )); + let pub20: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("0000000000000000000000000000000000000000000000000000000000000013") + )); + let pub30: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("000000000000000000000000000000000000000000000000000000000000001d") + )); - assert_ok!(NodeAuthorization::swap_node(Origin::signed(3), 20, 20)); - assert_eq!(NodeAuthorization::get_allow_list(), vec![10, 20, 30]); + assert_noop!( + NodeAuthorization::swap_node(Origin::signed(4), pub20.clone(), pub5.clone()), + BadOrigin + ); + + assert_ok!(NodeAuthorization::swap_node(Origin::signed(3), pub20.clone(), pub20.clone())); + assert_eq!( + NodeAuthorization::get_allow_list(), + vec![pub10.clone(), pub20.clone(), pub30.clone()] + ); - assert_noop!(NodeAuthorization::swap_node(Origin::signed(3), 15, 5), Error::::NotExist); assert_noop!( - NodeAuthorization::swap_node(Origin::signed(3), 20, 30), + NodeAuthorization::swap_node(Origin::signed(3), pub15.clone(), pub5.clone()), + Error::::NotExist + ); + assert_noop!( + NodeAuthorization::swap_node(Origin::signed(3), pub20.clone(), pub30.clone()), Error::::AlreadyJoined ); - assert_ok!(NodeAuthorization::swap_node(Origin::signed(3), 20, 5)); - assert_eq!(NodeAuthorization::get_allow_list(), vec![5, 10, 30]); + assert_ok!(NodeAuthorization::swap_node(Origin::signed(3), pub20.clone(), pub5.clone())); + assert_eq!( + NodeAuthorization::get_allow_list(), + vec![pub5.clone(), pub10.clone(), pub30.clone()] + ); }); } #[test] fn reset_nodes_works() { new_test_ext().execute_with(|| { - assert_noop!(NodeAuthorization::reset_nodes(Origin::signed(3), vec![15, 5, 20]), BadOrigin); + let pub5: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("0000000000000000000000000000000000000000000000000000000000000004") + )); + let pub15: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("000000000000000000000000000000000000000000000000000000000000000e") + )); + let pub20: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("0000000000000000000000000000000000000000000000000000000000000013") + )); + let pub25: NodePublicKey = NodePublicKey::Ed25519(Public::from_raw( + hex!("0000000000000000000000000000000000000000000000000000000000000018") + )); + + assert_noop!( + NodeAuthorization::reset_nodes( + Origin::signed(3), + vec![pub15.clone(), pub5.clone(), pub20.clone()] + ), + BadOrigin + ); assert_noop!( - NodeAuthorization::reset_nodes(Origin::signed(4), vec![15, 5, 20, 25]), + NodeAuthorization::reset_nodes( + Origin::signed(4), + vec![pub15.clone(), pub5.clone(), pub20.clone(), pub25.clone()] + ), Error::::TooManyNodes ); - assert_ok!(NodeAuthorization::reset_nodes(Origin::signed(4), vec![15, 5, 20])); - assert_eq!(NodeAuthorization::get_allow_list(), vec![5, 15, 20]); + assert_ok!( + NodeAuthorization::reset_nodes( + Origin::signed(4), + vec![pub15.clone(), pub5.clone(), pub20.clone()] + ) + ); + assert_eq!( + NodeAuthorization::get_allow_list(), + vec![pub5.clone(), pub15.clone(), pub20.clone()] + ); }); } } From 1072e429915a79a6484cbf3a36ea71b997e623a6 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Fri, 21 Aug 2020 15:08:34 +0800 Subject: [PATCH 47/50] update to rc6 --- Cargo.lock | 2 +- frame/node-authorization/Cargo.toml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b655828cd5f3c..925c428e2362a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4842,7 +4842,7 @@ dependencies = [ [[package]] name = "pallet-node-authorization" -version = "2.0.0-rc5" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", diff --git a/frame/node-authorization/Cargo.toml b/frame/node-authorization/Cargo.toml index 5140ee6819475..620387f9e2bea 100644 --- a/frame/node-authorization/Cargo.toml +++ b/frame/node-authorization/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-node-authorization" -version = "2.0.0-rc5" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" license = "Apache-2.0" @@ -14,12 +14,12 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } -frame-support = { version = "2.0.0-rc5", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-rc5", default-features = false, path = "../system" } -sp-core = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/core" } -sp-io = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-rc5", default-features = false, path = "../../primitives/std" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } [dev-dependencies] hex-literal = "0.2.1" From 847e4c7416781554db23c809f762a02062b9666b Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Fri, 21 Aug 2020 16:28:52 +0800 Subject: [PATCH 48/50] re-export NodePublicKey --- primitives/core/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/primitives/core/src/lib.rs b/primitives/core/src/lib.rs index d45afc18f52bc..1fa8492c6824a 100644 --- a/primitives/core/src/lib.rs +++ b/primitives/core/src/lib.rs @@ -78,8 +78,9 @@ pub use self::hash::{H160, H256, H512, convert_hash}; pub use self::uint::{U256, U512}; pub use changes_trie::{ChangesTrieConfiguration, ChangesTrieConfigurationRange}; #[cfg(feature = "full_crypto")] -pub use crypto::{DeriveJunction, Pair, Public, NodePublicKey}; +pub use crypto::{DeriveJunction, Pair, Public}; +pub use crypto::NodePublicKey; pub use hash_db::Hasher; #[cfg(feature = "std")] pub use self::hasher::blake2::Blake2Hasher; From c8301999bc1b35ee2c84b1e71b12882bf6798c9a Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Fri, 21 Aug 2020 16:36:45 +0800 Subject: [PATCH 49/50] update codec --- frame/node-authorization/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/node-authorization/Cargo.toml b/frame/node-authorization/Cargo.toml index 620387f9e2bea..2e8863c4b9c66 100644 --- a/frame/node-authorization/Cargo.toml +++ b/frame/node-authorization/Cargo.toml @@ -12,8 +12,8 @@ description = "FRAME pallet for node authorization" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } +serde = { version = "1.0.101", optional = true } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } From 14c238982a045df1a7e6fdd127e0d96ef9302478 Mon Sep 17 00:00:00 2001 From: Kaichao Sun Date: Fri, 21 Aug 2020 16:46:27 +0800 Subject: [PATCH 50/50] increase spec version --- bin/node/runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 9595ef424d8c1..19963ef6cc9f1 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -109,7 +109,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: 257, + spec_version: 258, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1,