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

Commit c0ccc24

Browse files
octolandresilvaDemi-MarietomusdrwHCastano
authored
Expose GRANDPA round state through RPC (#5375)
* grandpa: wire up basic RPC call * grandpa: make it compile against GRANDPA with expose round state * grandpa: use shared voter state to expose RPC endpoint * grandpa: restructure into nested structs * grandpa: return background rounds too * grandpa: return error when endpoint not ready * grandpa: collect grandpa rpc deps * grandpa: decide to use concrete AuthorityId in finality-grandpa-rpc * grandpa: remove unncessary type annotation * grandpa: move error code to const * grandpa: remove unnecessary WIP comment * grandpa: remove Id type parameter for SharedVoterState * grandpa: update tests to add shared_voter_state in parameters * grandpa: remove old deprecated test * grandpa: fix getting the correct set_id * grandpa: make SharedVoterState a struct * grandpa: wrap shared_voter_state in rpc_setup * grandpa: replace spaces with tabs * grandpa: limit RwLock write attempt to 1 sec * grandpa: add missing doc comments and remove some pub * Apply suggestions from code review Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> Co-Authored-By: Hernando Castano <HCastano@users.noreply.github.com> * grandpa: update function name call after change in finality-grandpa * grandpa: group pub use and only export voter::report * grandpa: add missing docs * grandpa: extract out structs used for json serialization * grandpa: stick to u32 for fields intended for js * grandpa: move Error type to its own file * grandpa: group pub use better * Apply code review suggestion Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * grandpa: use correct version of finality-granpda in rpc crate * grandpa: add back basic rpc unit test * grandpa: replace SharedVoterState::new() with empty() * node: cleanup grandpa::SharedVoterState usage in macro * grandpa: remove VoterState error variant * grandpa: enable missing futures compat feature * grandpa: fix typo in error variant * grandpa: remove test_utils * grandpa: allow mocking rpc handler components * grandpa: rename serialized to report in rpc module * grandpa: add proper test for RPC * grandpa: update to finality-grandpa v0.12.1 Co-authored-by: André Silva <andre.beat@gmail.com> Co-authored-by: Demi Obenour <demi@parity.io> Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com> Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
1 parent af70e66 commit c0ccc24

File tree

15 files changed

+552
-19
lines changed

15 files changed

+552
-19
lines changed

Cargo.lock

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

bin/node-template/node/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ name = "node-template"
1919
futures = "0.3.4"
2020
log = "0.4.8"
2121
structopt = "0.3.8"
22+
parking_lot = "0.10.0"
2223

2324
sc-cli = { version = "0.8.0-dev", path = "../../../client/cli" }
2425
sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" }

bin/node-template/node/src/service.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ use sp_inherents::InherentDataProviders;
1010
use sc_executor::native_executor_instance;
1111
pub use sc_executor::NativeExecutor;
1212
use sp_consensus_aura::sr25519::{AuthorityPair as AuraPair};
13-
use sc_finality_grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider};
13+
use sc_finality_grandpa::{
14+
FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider, SharedVoterState,
15+
};
1416

1517
// Our native executor instance.
1618
native_executor_instance!(
@@ -157,7 +159,8 @@ pub fn new_full(config: Configuration) -> Result<impl AbstractService, ServiceEr
157159
inherent_data_providers: inherent_data_providers.clone(),
158160
telemetry_on_connect: Some(service.telemetry_on_connect_stream()),
159161
voting_rule: sc_finality_grandpa::VotingRulesBuilder::default().build(),
160-
prometheus_registry: service.prometheus_registry()
162+
prometheus_registry: service.prometheus_registry(),
163+
shared_voter_state: SharedVoterState::empty(),
161164
};
162165

163166
// the GRANDPA voter task is considered infallible, i.e.

bin/node/cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ log = "0.4.8"
4343
rand = "0.7.2"
4444
structopt = { version = "0.3.8", optional = true }
4545
tracing = "0.1.10"
46+
parking_lot = "0.10.0"
4647

4748
# primitives
4849
sp-authority-discovery = { version = "2.0.0-dev", path = "../../../primitives/authority-discovery" }

bin/node/cli/src/service.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
use std::sync::Arc;
2222

2323
use sc_consensus_babe;
24-
use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider};
24+
use grandpa::{
25+
self, FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider,
26+
};
2527
use node_executor;
2628
use node_primitives::Block;
2729
use node_runtime::RuntimeApi;
@@ -38,8 +40,10 @@ use sc_consensus::LongestChain;
3840
macro_rules! new_full_start {
3941
($config:expr) => {{
4042
use std::sync::Arc;
43+
4144
type RpcExtension = jsonrpc_core::IoHandler<sc_rpc::Metadata>;
4245
let mut import_setup = None;
46+
let mut rpc_setup = None;
4347
let inherent_data_providers = sp_inherents::InherentDataProviders::new();
4448

4549
let builder = sc_service::ServiceBuilder::new_full::<
@@ -88,6 +92,10 @@ macro_rules! new_full_start {
8892
.with_rpc_extensions(|builder| -> std::result::Result<RpcExtension, _> {
8993
let babe_link = import_setup.as_ref().map(|s| &s.2)
9094
.expect("BabeLink is present for full services or set up failed; qed.");
95+
let grandpa_link = import_setup.as_ref().map(|s| &s.1)
96+
.expect("GRANDPA LinkHalf is present for full services or set up failed; qed.");
97+
let shared_authority_set = grandpa_link.shared_authority_set();
98+
let shared_voter_state = grandpa::SharedVoterState::empty();
9199
let deps = node_rpc::FullDeps {
92100
client: builder.client().clone(),
93101
pool: builder.pool(),
@@ -97,12 +105,17 @@ macro_rules! new_full_start {
97105
keystore: builder.keystore(),
98106
babe_config: sc_consensus_babe::BabeLink::config(babe_link).clone(),
99107
shared_epoch_changes: sc_consensus_babe::BabeLink::epoch_changes(babe_link).clone()
100-
}
108+
},
109+
grandpa: node_rpc::GrandpaDeps {
110+
shared_voter_state: shared_voter_state.clone(),
111+
shared_authority_set: shared_authority_set.clone(),
112+
},
101113
};
114+
rpc_setup = Some((shared_voter_state));
102115
Ok(node_rpc::create_full(deps))
103116
})?;
104117

105-
(builder, import_setup, inherent_data_providers)
118+
(builder, import_setup, inherent_data_providers, rpc_setup)
106119
}}
107120
}
108121

@@ -128,7 +141,8 @@ macro_rules! new_full {
128141
$config.disable_grandpa,
129142
);
130143

131-
let (builder, mut import_setup, inherent_data_providers) = new_full_start!($config);
144+
let (builder, mut import_setup, inherent_data_providers, mut rpc_setup) =
145+
new_full_start!($config);
132146

133147
let service = builder
134148
.with_finality_proof_provider(|client, backend| {
@@ -139,7 +153,10 @@ macro_rules! new_full {
139153
.build()?;
140154

141155
let (block_import, grandpa_link, babe_link) = import_setup.take()
142-
.expect("Link Half and Block Import are present for Full Services or setup failed before. qed");
156+
.expect("Link Half and Block Import are present for Full Services or setup failed before. qed");
157+
158+
let shared_voter_state = rpc_setup.take()
159+
.expect("The SharedVoterState is present for Full Services or setup failed before. qed");
143160

144161
($with_startup_data)(&block_import, &babe_link);
145162

@@ -240,6 +257,7 @@ macro_rules! new_full {
240257
telemetry_on_connect: Some(service.telemetry_on_connect_stream()),
241258
voting_rule: grandpa::VotingRulesBuilder::default().build(),
242259
prometheus_registry: service.prometheus_registry(),
260+
shared_voter_state,
243261
};
244262

245263
// the GRANDPA voter task is considered infallible, i.e.

bin/node/rpc/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,5 @@ sc-keystore = { version = "2.0.0-dev", path = "../../../client/keystore" }
2828
sc-consensus-epochs = { version = "0.8.0-dev", path = "../../../client/consensus/epochs" }
2929
sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" }
3030
sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" }
31+
sc-finality-grandpa = { version = "0.8.0-dev", path = "../../../client/finality-grandpa" }
32+
sc-finality-grandpa-rpc = { version = "0.8.0-dev", path = "../../../client/finality-grandpa/rpc" }

bin/node/rpc/src/lib.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
use std::{sync::Arc, fmt};
3333

34-
use node_primitives::{Block, BlockNumber, AccountId, Index, Balance};
34+
use node_primitives::{Block, BlockNumber, AccountId, Index, Balance, Hash};
3535
use node_runtime::UncheckedExtrinsic;
3636
use sp_api::ProvideRuntimeApi;
3737
use sp_transaction_pool::TransactionPool;
@@ -42,6 +42,8 @@ use sp_consensus_babe::BabeApi;
4242
use sc_consensus_epochs::SharedEpochChanges;
4343
use sc_consensus_babe::{Config, Epoch};
4444
use sc_consensus_babe_rpc::BabeRPCHandler;
45+
use sc_finality_grandpa::{SharedVoterState, SharedAuthoritySet};
46+
use sc_finality_grandpa_rpc::GrandpaRpcHandler;
4547

4648
/// Light client extra dependencies.
4749
pub struct LightDeps<C, F, P> {
@@ -65,6 +67,14 @@ pub struct BabeDeps {
6567
pub keystore: KeyStorePtr,
6668
}
6769

70+
/// Extra dependencies for GRANDPA
71+
pub struct GrandpaDeps {
72+
/// Voting round info.
73+
pub shared_voter_state: SharedVoterState,
74+
/// Authority set info.
75+
pub shared_authority_set: SharedAuthoritySet<Hash, BlockNumber>,
76+
}
77+
6878
/// Full client dependencies.
6979
pub struct FullDeps<C, P, SC> {
7080
/// The client instance to use.
@@ -75,6 +85,8 @@ pub struct FullDeps<C, P, SC> {
7585
pub select_chain: SC,
7686
/// BABE specific dependencies.
7787
pub babe: BabeDeps,
88+
/// GRANDPA specific dependencies.
89+
pub grandpa: GrandpaDeps,
7890
}
7991

8092
/// Instantiate all Full RPC extensions.
@@ -102,13 +114,18 @@ pub fn create_full<C, P, M, SC>(
102114
client,
103115
pool,
104116
select_chain,
105-
babe
117+
babe,
118+
grandpa,
106119
} = deps;
107120
let BabeDeps {
108121
keystore,
109122
babe_config,
110123
shared_epoch_changes,
111124
} = babe;
125+
let GrandpaDeps {
126+
shared_voter_state,
127+
shared_authority_set,
128+
} = grandpa;
112129

113130
io.extend_with(
114131
SystemApi::to_delegate(FullSystem::new(client.clone(), pool))
@@ -127,6 +144,11 @@ pub fn create_full<C, P, M, SC>(
127144
BabeRPCHandler::new(client, shared_epoch_changes, keystore, babe_config, select_chain)
128145
)
129146
);
147+
io.extend_with(
148+
sc_finality_grandpa_rpc::GrandpaApi::to_delegate(
149+
GrandpaRpcHandler::new(shared_authority_set, shared_voter_state)
150+
)
151+
);
130152

131153
io
132154
}

client/finality-grandpa/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ sp-finality-tracker = { version = "2.0.0-dev", path = "../../primitives/finality
4242
sp-finality-grandpa = { version = "2.0.0-dev", path = "../../primitives/finality-grandpa" }
4343
prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-dev"}
4444
sc-block-builder = { version = "0.8.0-dev", path = "../block-builder" }
45-
finality-grandpa = { version = "0.12.0", features = ["derive-codec"] }
45+
finality-grandpa = { version = "0.12.1", features = ["derive-codec"] }
4646
pin-project = "0.4.6"
4747

4848
[dev-dependencies]
49-
finality-grandpa = { version = "0.12.0", features = ["derive-codec", "test-helpers"] }
49+
finality-grandpa = { version = "0.12.1", features = ["derive-codec", "test-helpers"] }
5050
sc-network = { version = "0.8.0-dev", path = "../network" }
5151
sc-network-test = { version = "0.8.0-dev", path = "../network/test" }
5252
sp-keyring = { version = "2.0.0-dev", path = "../../primitives/keyring" }
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[package]
2+
name = "sc-finality-grandpa-rpc"
3+
version = "0.8.0-dev"
4+
authors = ["Parity Technologies <admin@parity.io>"]
5+
description = "RPC extensions for the GRANDPA finality gadget"
6+
edition = "2018"
7+
license = "GPL-3.0"
8+
9+
[dependencies]
10+
sc-finality-grandpa = { version = "0.8.0-dev", path = "../" }
11+
finality-grandpa = { version = "0.12.1", features = ["derive-codec"] }
12+
jsonrpc-core = "14.0.3"
13+
jsonrpc-core-client = "14.0.3"
14+
jsonrpc-derive = "14.0.3"
15+
futures = { version = "0.3.4", features = ["compat"] }
16+
serde = { version = "1.0.105", features = ["derive"] }
17+
serde_json = "1.0.50"
18+
log = "0.4.8"
19+
derive_more = "0.99.2"
20+
21+
[dev-dependencies]
22+
sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" }
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2020 Parity Technologies (UK) Ltd.
2+
// This file is part of Substrate.
3+
4+
// Substrate is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
9+
// Substrate is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
14+
// You should have received a copy of the GNU General Public License
15+
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
16+
17+
use crate::NOT_READY_ERROR_CODE;
18+
19+
#[derive(derive_more::Display, derive_more::From)]
20+
/// Top-level error type for the RPC handler
21+
pub enum Error {
22+
/// The GRANDPA RPC endpoint is not ready.
23+
#[display(fmt = "GRANDPA RPC endpoint not ready")]
24+
EndpointNotReady,
25+
/// GRANDPA reports the authority set id to be larger than 32-bits.
26+
#[display(fmt = "GRANDPA reports authority set id unreasonably large")]
27+
AuthoritySetIdReportedAsUnreasonablyLarge,
28+
/// GRANDPA reports voter state with round id or weights larger than 32-bits.
29+
#[display(fmt = "GRANDPA reports voter state as unreasonably large")]
30+
VoterStateReportsUnreasonablyLargeNumbers,
31+
}
32+
33+
impl From<Error> for jsonrpc_core::Error {
34+
fn from(error: Error) -> Self {
35+
jsonrpc_core::Error {
36+
message: format!("{}", error).into(),
37+
code: jsonrpc_core::ErrorCode::ServerError(NOT_READY_ERROR_CODE),
38+
data: None,
39+
}
40+
}
41+
}
42+
43+
impl From<std::num::TryFromIntError> for Error {
44+
fn from(_error: std::num::TryFromIntError) -> Self {
45+
Error::VoterStateReportsUnreasonablyLargeNumbers
46+
}
47+
}

0 commit comments

Comments
 (0)