Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit bd44423

Browse files
kaichaosuntomusdrwtomaka
authored andcommitted
Set reserved nodes with offchain worker. (#6996)
* add offchain worker api to set reserved nodes. * new offchain api to get node public key. * node public key from converter * refactor set reserved nodes ocw api. * new ndoe authorization pallet * remove unnecessary clone and more. * more * tests for node authorization pallet * remove dependency * fix build * more tests. * refactor * Update primitives/core/src/offchain/testing.rs Co-authored-by: Tomasz Drwięga <[email protected]> * Update frame/node-authorization/src/lib.rs Co-authored-by: Tomasz Drwięga <[email protected]> * Update frame/node-authorization/src/lib.rs Co-authored-by: Tomasz Drwięga <[email protected]> * Update frame/node-authorization/src/lib.rs Co-authored-by: Tomasz Drwięga <[email protected]> * format code * expose NetworkService * remove NetworkStateInfo in offchain * replace NodePublicKey with PeerId. * set max length of peer id. * clear more * use BTreeSet for set of peers. * decode opaque peer id. * extract NetworkProvider for client offchain. * use OpaquePeerId in node authorization pallet. * fix test * better documentation * fix test * doc * more fix * Update primitives/core/src/offchain/mod.rs Co-authored-by: Pierre Krieger <[email protected]> * Update client/offchain/src/api.rs Co-authored-by: Pierre Krieger <[email protected]> * derive serialize and deserialize Co-authored-by: Tomasz Drwięga <[email protected]> Co-authored-by: Pierre Krieger <[email protected]>
1 parent 89e6d66 commit bd44423

File tree

15 files changed

+1080
-44
lines changed

15 files changed

+1080
-44
lines changed

Cargo.lock

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ members = [
8888
"frame/metadata",
8989
"frame/multisig",
9090
"frame/nicks",
91+
"frame/node-authorization",
9192
"frame/offences",
9293
"frame/proxy",
9394
"frame/randomness-collective-flip",

client/network/src/service.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
//!
2121
//! There are two main structs in this module: [`NetworkWorker`] and [`NetworkService`].
2222
//! The [`NetworkWorker`] *is* the network and implements the `Future` trait. It must be polled in
23-
//! order fo the network to advance.
23+
//! order for the network to advance.
2424
//! The [`NetworkService`] is merely a shared version of the [`NetworkWorker`]. You can obtain an
2525
//! `Arc<NetworkService>` by calling [`NetworkWorker::service`].
2626
//!
@@ -605,6 +605,22 @@ impl<B: BlockT + 'static, H: ExHashT> NetworkService<B, H> {
605605
&self.local_peer_id
606606
}
607607

608+
/// Set authorized peers.
609+
///
610+
/// Need a better solution to manage authorized peers, but now just use reserved peers for
611+
/// prototyping.
612+
pub fn set_authorized_peers(&self, peers: HashSet<PeerId>) {
613+
self.peerset.set_reserved_peers(peers)
614+
}
615+
616+
/// Set authorized_only flag.
617+
///
618+
/// Need a better solution to decide authorized_only, but now just use reserved_only flag for
619+
/// prototyping.
620+
pub fn set_authorized_only(&self, reserved_only: bool) {
621+
self.peerset.set_reserved_only(reserved_only)
622+
}
623+
608624
/// Appends a notification to the buffer of pending outgoing notifications with the given peer.
609625
/// Has no effect if the notifications channel with this protocol name is not open.
610626
///

client/offchain/src/api.rs

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,18 @@ use std::{
1919
sync::Arc,
2020
convert::TryFrom,
2121
thread::sleep,
22+
collections::HashSet,
2223
};
2324

24-
use sp_core::offchain::OffchainStorage;
25+
use crate::NetworkProvider;
2526
use futures::Future;
2627
use log::error;
27-
use sc_network::{PeerId, Multiaddr, NetworkStateInfo};
28+
use sc_network::{PeerId, Multiaddr};
2829
use codec::{Encode, Decode};
30+
use sp_core::OpaquePeerId;
2931
use sp_core::offchain::{
3032
Externalities as OffchainExt, HttpRequestId, Timestamp, HttpRequestStatus, HttpError,
31-
OpaqueNetworkState, OpaquePeerId, OpaqueMultiaddr, StorageKind,
33+
OffchainStorage, OpaqueNetworkState, OpaqueMultiaddr, StorageKind,
3234
};
3335
pub use sp_offchain::STORAGE_PREFIX;
3436
pub use http::SharedClient;
@@ -49,8 +51,8 @@ mod timestamp;
4951
pub(crate) struct Api<Storage> {
5052
/// Offchain Workers database.
5153
db: Storage,
52-
/// A NetworkState provider.
53-
network_state: Arc<dyn NetworkStateInfo + Send + Sync>,
54+
/// A provider for substrate networking.
55+
network_provider: Arc<dyn NetworkProvider + Send + Sync>,
5456
/// Is this node a potential validator?
5557
is_validator: bool,
5658
/// Everything HTTP-related is handled by a different struct.
@@ -73,10 +75,10 @@ impl<Storage: OffchainStorage> OffchainExt for Api<Storage> {
7375
}
7476

7577
fn network_state(&self) -> Result<OpaqueNetworkState, ()> {
76-
let external_addresses = self.network_state.external_addresses();
78+
let external_addresses = self.network_provider.external_addresses();
7779

7880
let state = NetworkState::new(
79-
self.network_state.local_peer_id(),
81+
self.network_provider.local_peer_id(),
8082
external_addresses,
8183
);
8284
Ok(OpaqueNetworkState::from(state))
@@ -180,6 +182,15 @@ impl<Storage: OffchainStorage> OffchainExt for Api<Storage> {
180182
) -> Result<usize, HttpError> {
181183
self.http.response_read_body(request_id, buffer, deadline)
182184
}
185+
186+
fn set_authorized_nodes(&mut self, nodes: Vec<OpaquePeerId>, authorized_only: bool) {
187+
let peer_ids: HashSet<PeerId> = nodes.into_iter()
188+
.filter_map(|node| PeerId::from_bytes(node.0).ok())
189+
.collect();
190+
191+
self.network_provider.set_authorized_peers(peer_ids);
192+
self.network_provider.set_authorized_only(authorized_only);
193+
}
183194
}
184195

185196
/// Information about the local node's network state.
@@ -256,18 +267,18 @@ pub(crate) struct AsyncApi {
256267
}
257268

258269
impl AsyncApi {
259-
/// Creates new Offchain extensions API implementation an the asynchronous processing part.
270+
/// Creates new Offchain extensions API implementation an the asynchronous processing part.
260271
pub fn new<S: OffchainStorage>(
261272
db: S,
262-
network_state: Arc<dyn NetworkStateInfo + Send + Sync>,
273+
network_provider: Arc<dyn NetworkProvider + Send + Sync>,
263274
is_validator: bool,
264275
shared_client: SharedClient,
265276
) -> (Api<S>, Self) {
266277
let (http_api, http_worker) = http::http(shared_client);
267278

268279
let api = Api {
269280
db,
270-
network_state,
281+
network_provider,
271282
is_validator,
272283
http: http_api,
273284
};
@@ -292,11 +303,21 @@ mod tests {
292303
use super::*;
293304
use std::{convert::{TryFrom, TryInto}, time::SystemTime};
294305
use sc_client_db::offchain::LocalStorage;
295-
use sc_network::PeerId;
306+
use sc_network::{NetworkStateInfo, PeerId};
296307

297-
struct MockNetworkStateInfo();
308+
struct TestNetwork();
309+
310+
impl NetworkProvider for TestNetwork {
311+
fn set_authorized_peers(&self, _peers: HashSet<PeerId>) {
312+
unimplemented!()
313+
}
298314

299-
impl NetworkStateInfo for MockNetworkStateInfo {
315+
fn set_authorized_only(&self, _reserved_only: bool) {
316+
unimplemented!()
317+
}
318+
}
319+
320+
impl NetworkStateInfo for TestNetwork {
300321
fn external_addresses(&self) -> Vec<Multiaddr> {
301322
Vec::new()
302323
}
@@ -309,10 +330,9 @@ mod tests {
309330
fn offchain_api() -> (Api<LocalStorage>, AsyncApi) {
310331
let _ = env_logger::try_init();
311332
let db = LocalStorage::new_test();
312-
let mock = Arc::new(MockNetworkStateInfo());
333+
let mock = Arc::new(TestNetwork());
313334
let shared_client = SharedClient::new();
314335

315-
316336
AsyncApi::new(
317337
db,
318338
mock,

client/offchain/src/lib.rs

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,17 @@
3333
3434
#![warn(missing_docs)]
3535

36-
use std::{fmt, marker::PhantomData, sync::Arc};
36+
use std::{
37+
fmt, marker::PhantomData, sync::Arc,
38+
collections::HashSet,
39+
};
3740

3841
use parking_lot::Mutex;
3942
use threadpool::ThreadPool;
4043
use sp_api::{ApiExt, ProvideRuntimeApi};
4144
use futures::future::Future;
4245
use log::{debug, warn};
43-
use sc_network::NetworkStateInfo;
46+
use sc_network::{ExHashT, NetworkService, NetworkStateInfo, PeerId};
4447
use sp_core::{offchain::{self, OffchainStorage}, ExecutionContext, traits::SpawnNamed};
4548
use sp_runtime::{generic::BlockId, traits::{self, Header}};
4649
use futures::{prelude::*, future::ready};
@@ -50,6 +53,30 @@ use api::SharedClient;
5053

5154
pub use sp_offchain::{OffchainWorkerApi, STORAGE_PREFIX};
5255

56+
/// NetworkProvider provides [`OffchainWorkers`] with all necessary hooks into the
57+
/// underlying Substrate networking.
58+
pub trait NetworkProvider: NetworkStateInfo {
59+
/// Set the authorized peers.
60+
fn set_authorized_peers(&self, peers: HashSet<PeerId>);
61+
62+
/// Set the authorized only flag.
63+
fn set_authorized_only(&self, reserved_only: bool);
64+
}
65+
66+
impl<B, H> NetworkProvider for NetworkService<B, H>
67+
where
68+
B: traits::Block + 'static,
69+
H: ExHashT,
70+
{
71+
fn set_authorized_peers(&self, peers: HashSet<PeerId>) {
72+
self.set_authorized_peers(peers)
73+
}
74+
75+
fn set_authorized_only(&self, reserved_only: bool) {
76+
self.set_authorized_only(reserved_only)
77+
}
78+
}
79+
5380
/// An offchain workers manager.
5481
pub struct OffchainWorkers<Client, Storage, Block: traits::Block> {
5582
client: Arc<Client>,
@@ -98,7 +125,7 @@ impl<Client, Storage, Block> OffchainWorkers<
98125
pub fn on_block_imported(
99126
&self,
100127
header: &Block::Header,
101-
network_state: Arc<dyn NetworkStateInfo + Send + Sync>,
128+
network_provider: Arc<dyn NetworkProvider + Send + Sync>,
102129
is_validator: bool,
103130
) -> impl Future<Output = ()> {
104131
let runtime = self.client.runtime_api();
@@ -122,7 +149,7 @@ impl<Client, Storage, Block> OffchainWorkers<
122149
if version > 0 {
123150
let (api, runner) = api::AsyncApi::new(
124151
self.db.clone(),
125-
network_state.clone(),
152+
network_provider,
126153
is_validator,
127154
self.shared_client.clone(),
128155
);
@@ -173,7 +200,7 @@ pub async fn notification_future<Client, Storage, Block, Spawner>(
173200
client: Arc<Client>,
174201
offchain: Arc<OffchainWorkers<Client, Storage, Block>>,
175202
spawner: Spawner,
176-
network_state_info: Arc<dyn NetworkStateInfo + Send + Sync>,
203+
network_provider: Arc<dyn NetworkProvider + Send + Sync>,
177204
)
178205
where
179206
Block: traits::Block,
@@ -188,7 +215,7 @@ pub async fn notification_future<Client, Storage, Block, Spawner>(
188215
"offchain-on-block",
189216
offchain.on_block_imported(
190217
&n.header,
191-
network_state_info.clone(),
218+
network_provider.clone(),
192219
is_validator,
193220
).boxed(),
194221
);
@@ -213,9 +240,9 @@ mod tests {
213240
use sc_transaction_pool::{BasicPool, FullChainApi};
214241
use sp_transaction_pool::{TransactionPool, InPoolTransaction};
215242

216-
struct MockNetworkStateInfo();
243+
struct TestNetwork();
217244

218-
impl NetworkStateInfo for MockNetworkStateInfo {
245+
impl NetworkStateInfo for TestNetwork {
219246
fn external_addresses(&self) -> Vec<Multiaddr> {
220247
Vec::new()
221248
}
@@ -225,6 +252,16 @@ mod tests {
225252
}
226253
}
227254

255+
impl NetworkProvider for TestNetwork {
256+
fn set_authorized_peers(&self, _peers: HashSet<PeerId>) {
257+
unimplemented!()
258+
}
259+
260+
fn set_authorized_only(&self, _reserved_only: bool) {
261+
unimplemented!()
262+
}
263+
}
264+
228265
struct TestPool(
229266
Arc<BasicPool<FullChainApi<TestClient, Block>, Block>>
230267
);
@@ -255,12 +292,14 @@ mod tests {
255292
client.clone(),
256293
));
257294
let db = sc_client_db::offchain::LocalStorage::new_test();
258-
let network_state = Arc::new(MockNetworkStateInfo());
295+
let network = Arc::new(TestNetwork());
259296
let header = client.header(&BlockId::number(0)).unwrap().unwrap();
260297

261298
// when
262299
let offchain = OffchainWorkers::new(client, db);
263-
futures::executor::block_on(offchain.on_block_imported(&header, network_state, false));
300+
futures::executor::block_on(
301+
offchain.on_block_imported(&header, network, false)
302+
);
264303

265304
// then
266305
assert_eq!(pool.0.status().ready, 1);

client/peerset/src/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ const FORGET_AFTER: Duration = Duration::from_secs(3600);
4545
enum Action {
4646
AddReservedPeer(PeerId),
4747
RemoveReservedPeer(PeerId),
48+
SetReservedPeers(HashSet<PeerId>),
4849
SetReservedOnly(bool),
4950
ReportPeer(PeerId, ReputationChange),
5051
SetPriorityGroup(String, HashSet<PeerId>),
@@ -102,6 +103,11 @@ impl PeersetHandle {
102103
pub fn set_reserved_only(&self, reserved: bool) {
103104
let _ = self.tx.unbounded_send(Action::SetReservedOnly(reserved));
104105
}
106+
107+
/// Set reserved peers to the new set.
108+
pub fn set_reserved_peers(&self, peer_ids: HashSet<PeerId>) {
109+
let _ = self.tx.unbounded_send(Action::SetReservedPeers(peer_ids));
110+
}
105111

106112
/// Reports an adjustment to the reputation of the given peer.
107113
pub fn report_peer(&self, peer_id: PeerId, score_diff: ReputationChange) {
@@ -246,6 +252,10 @@ impl Peerset {
246252
fn on_remove_reserved_peer(&mut self, peer_id: PeerId) {
247253
self.on_remove_from_priority_group(RESERVED_NODES, peer_id);
248254
}
255+
256+
fn on_set_reserved_peers(&mut self, peer_ids: HashSet<PeerId>) {
257+
self.on_set_priority_group(RESERVED_NODES, peer_ids);
258+
}
249259

250260
fn on_set_reserved_only(&mut self, reserved_only: bool) {
251261
self.reserved_only = reserved_only;
@@ -655,6 +665,8 @@ impl Stream for Peerset {
655665
self.on_add_reserved_peer(peer_id),
656666
Action::RemoveReservedPeer(peer_id) =>
657667
self.on_remove_reserved_peer(peer_id),
668+
Action::SetReservedPeers(peer_ids) =>
669+
self.on_set_reserved_peers(peer_ids),
658670
Action::SetReservedOnly(reserved) =>
659671
self.on_set_reserved_only(reserved),
660672
Action::ReportPeer(peer_id, score_diff) =>

client/service/src/builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ pub fn build_offchain_workers<TBl, TBackend, TCl>(
431431
client.clone(),
432432
offchain,
433433
Clone::clone(&spawn_handle),
434-
network.clone()
434+
network.clone(),
435435
)
436436
);
437437
}

frame/im-online/src/benchmarking.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ use super::*;
2323

2424
use frame_system::RawOrigin;
2525
use frame_benchmarking::benchmarks;
26-
use sp_core::offchain::{OpaquePeerId, OpaqueMultiaddr};
26+
use sp_core::OpaquePeerId;
27+
use sp_core::offchain::OpaqueMultiaddr;
2728
use sp_runtime::traits::{ValidateUnsigned, Zero};
2829
use sp_runtime::transaction_validity::TransactionSource;
2930
use frame_support::traits::UnfilteredDispatchable;

frame/im-online/src/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121

2222
use super::*;
2323
use crate::mock::*;
24+
use sp_core::OpaquePeerId;
2425
use sp_core::offchain::{
25-
OpaquePeerId,
2626
OffchainExt,
2727
TransactionPoolExt,
2828
testing::{TestOffchainExt, TestTransactionPoolExt},

0 commit comments

Comments
 (0)