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

Commit eb0e05e

Browse files
HCastanotomusdrwoctol
authored
Add Subscription RPC for Grandpa Finality (#5732)
* Rough skeleton for what I think the RPC should look like * Create channel for sending justifications Sends finalized header and justification from Grandpa to the client. This lays the groundwork for hooking into the RPC module. * WIP: Add subscribers for justifications to Grandpa Adds the Sender end of a channel into Grandpa, through which notifications about block finality events can be sent. * WIP: Add a struct for managing subscriptions Slightly different approach from the last commit, but same basic idea. Still a rough sketch, very much doesn't compile yet. * Make naming more clear and lock data in Arc * Rough idea of what RPC would look like * Remove code from previous approach * Missed some things * Update client/rpc-api/src/chain/mod.rs Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Update client/rpc-api/src/chain/mod.rs Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Split justification subscription into sender and receiver halves * Replace RwLock with a Mutex * Add sample usage from the Service's point of view * Remove code that referred to "chain_" RPC * Use the Justification sender/receivers from Grandpa LinkHalf * Add some PubSub boilerplate * Add guiding comments * TMP: comment out to fix compilation * Return MetaIoHandler from PubSubHandler in create_full * Uncomment pubsub methods in rpc handler (fails to build) * node/rpc: make Metadata concrete in create_full to fix compilation * node: pass in SubscriptionManger to grandpa rpc handler * grandpa-rpc: use SubscriptionManger to add subscriber * grandpa-rpc: attempt at setting up the justification stream (fails to build) * grandpa-rpc: fix compilation of connecting stream to sink * grandpa-rpc: implement unsubscribe * grandpa-rpc: update older tests * grandpa-rpc: add full prefix to avoid confusing rust-analyzer * grandpa-rpc: add test for pubsub not available * grandpa-rpc: tidy up leftover code * grandpa-rpc: add test for sub and unsub of justifications * grandpa-rpc: minor stylistic changes * grandpa-rpc: split unit test * grandpa-rpc: minor stylistic changes in test * grandpa-rpc: skip returning future when cancelling * grandpa-rpc: reuse testing executor from sc-rpc * grandpa-rpc: don't need to use PubSubHandler in tests * node-rpc: use MetaIoHandler rather than PubSubHandler * grandpa: log if getting header failed * grandpa: move justification channel creation into factory function * grandpa: make the justification sender optional * grandpa: fix compilation warnings * grandpa: move justification notification types to new file * grandpa-rpc: move JustificationNotification to grandpa-rpc * grandpa-rpc: move JustificationNotification to its own file * grandpa: rename justification channel pairs * grandpa: rename notifier types * grandpa: pass justification as GrandpaJustification to the rpc module * Move Metadata to sc-rpc-api * grandpa-rpc: remove unsed error code * grandpa: fix bug for checking if channel is closed before sendind * grandpa-rpc: unit test for sending justifications * grandpa-rpc: update comments for the pubsub test * grandpa-rpc: update pubsub tests with more steps * grandpa-rpc: fix pubsub test * grandpa-rpc: minor indendation * grandpa-rpc: decode instead of encode in test * grandpa: fix review comments * grandpa: remove unused serde dependency Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> Co-authored-by: Jon Häggblad <jon.haggblad@gmail.com> Co-authored-by: Tomasz Drwięga <tomasz@parity.io>
1 parent 6f31766 commit eb0e05e

File tree

28 files changed

+589
-94
lines changed

28 files changed

+589
-94
lines changed

Cargo.lock

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

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ pub fn new_full(config: Configuration) -> Result<TaskManager, ServiceError> {
113113
let client = client.clone();
114114
let pool = transaction_pool.clone();
115115

116-
Box::new(move |deny_unsafe| {
116+
Box::new(move |deny_unsafe, _| {
117117
let deps = crate::rpc::FullDeps {
118118
client: client.clone(),
119119
pool: pool.clone(),
@@ -278,7 +278,7 @@ pub fn new_light(config: Configuration) -> Result<TaskManager, ServiceError> {
278278
transaction_pool,
279279
task_manager: &mut task_manager,
280280
on_demand: Some(on_demand),
281-
rpc_extensions_builder: Box::new(|_| ()),
281+
rpc_extensions_builder: Box::new(|_, _| ()),
282282
telemetry_connection_sinks: sc_service::TelemetryConnectionSinks::default(),
283283
config,
284284
client,

bin/node/cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ serde = { version = "1.0.102", features = ["derive"] }
3939
futures = { version = "0.3.1", features = ["compat"] }
4040
hex-literal = "0.2.1"
4141
jsonrpc-core = "14.2.0"
42+
jsonrpc-pubsub = "14.2.0"
4243
log = "0.4.8"
4344
rand = "0.7.2"
4445
structopt = { version = "0.3.8", optional = true }

bin/node/cli/src/service.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ pub fn new_partial(config: &Configuration) -> Result<sc_service::PartialComponen
4949
sp_consensus::DefaultImportQueue<Block, FullClient>,
5050
sc_transaction_pool::FullPool<Block, FullClient>,
5151
(
52-
impl Fn(node_rpc::DenyUnsafe) -> node_rpc::IoHandler,
52+
impl Fn(
53+
node_rpc::DenyUnsafe,
54+
jsonrpc_pubsub::manager::SubscriptionManager
55+
) -> node_rpc::IoHandler,
5356
(
5457
sc_consensus_babe::BabeBlockImport<Block, FullClient, FullGrandpaBlockImport>,
5558
grandpa::LinkHalf<Block, FullClient, FullSelectChain>,
@@ -101,6 +104,7 @@ pub fn new_partial(config: &Configuration) -> Result<sc_service::PartialComponen
101104
let (rpc_extensions_builder, rpc_setup) = {
102105
let (_, grandpa_link, babe_link) = &import_setup;
103106

107+
let justification_stream = grandpa_link.justification_stream();
104108
let shared_authority_set = grandpa_link.shared_authority_set().clone();
105109
let shared_voter_state = grandpa::SharedVoterState::empty();
106110

@@ -114,7 +118,7 @@ pub fn new_partial(config: &Configuration) -> Result<sc_service::PartialComponen
114118
let select_chain = select_chain.clone();
115119
let keystore = keystore.clone();
116120

117-
let rpc_extensions_builder = move |deny_unsafe| {
121+
let rpc_extensions_builder = move |deny_unsafe, subscriptions| {
118122
let deps = node_rpc::FullDeps {
119123
client: client.clone(),
120124
pool: pool.clone(),
@@ -128,6 +132,8 @@ pub fn new_partial(config: &Configuration) -> Result<sc_service::PartialComponen
128132
grandpa: node_rpc::GrandpaDeps {
129133
shared_voter_state: shared_voter_state.clone(),
130134
shared_authority_set: shared_authority_set.clone(),
135+
justification_stream: justification_stream.clone(),
136+
subscriptions,
131137
},
132138
};
133139

bin/node/rpc/Cargo.toml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,25 @@ repository = "https://github.com/paritytech/substrate/"
1111
targets = ["x86_64-unknown-linux-gnu"]
1212

1313
[dependencies]
14-
sc-client-api = { version = "2.0.0-rc5", path = "../../../client/api" }
15-
sc-rpc = { version = "2.0.0-rc5", path = "../../../client/rpc" }
1614
jsonrpc-core = "14.2.0"
15+
jsonrpc-pubsub = "14.2.0"
1716
node-primitives = { version = "2.0.0-rc5", path = "../primitives" }
1817
node-runtime = { version = "2.0.0-rc5", path = "../runtime" }
19-
sp-runtime = { version = "2.0.0-rc5", path = "../../../primitives/runtime" }
20-
sp-api = { version = "2.0.0-rc5", path = "../../../primitives/api" }
2118
pallet-contracts-rpc = { version = "0.8.0-rc5", path = "../../../frame/contracts/rpc/" }
2219
pallet-transaction-payment-rpc = { version = "2.0.0-rc5", path = "../../../frame/transaction-payment/rpc/" }
23-
substrate-frame-rpc-system = { version = "2.0.0-rc5", path = "../../../utils/frame/rpc/system" }
24-
sp-transaction-pool = { version = "2.0.0-rc5", path = "../../../primitives/transaction-pool" }
20+
sc-client-api = { version = "2.0.0-rc5", path = "../../../client/api" }
2521
sc-consensus-babe = { version = "0.8.0-rc5", path = "../../../client/consensus/babe" }
2622
sc-consensus-babe-rpc = { version = "0.8.0-rc5", path = "../../../client/consensus/babe/rpc" }
27-
sp-consensus-babe = { version = "0.8.0-rc5", path = "../../../primitives/consensus/babe" }
28-
sc-keystore = { version = "2.0.0-rc5", path = "../../../client/keystore" }
2923
sc-consensus-epochs = { version = "0.8.0-rc5", path = "../../../client/consensus/epochs" }
30-
sp-consensus = { version = "0.8.0-rc5", path = "../../../primitives/consensus/common" }
31-
sp-blockchain = { version = "2.0.0-rc5", path = "../../../primitives/blockchain" }
3224
sc-finality-grandpa = { version = "0.8.0-rc5", path = "../../../client/finality-grandpa" }
3325
sc-finality-grandpa-rpc = { version = "0.8.0-rc5", path = "../../../client/finality-grandpa/rpc" }
26+
sc-keystore = { version = "2.0.0-rc5", path = "../../../client/keystore" }
3427
sc-rpc-api = { version = "0.8.0-rc5", path = "../../../client/rpc-api" }
28+
sc-rpc = { version = "2.0.0-rc5", path = "../../../client/rpc" }
29+
sp-api = { version = "2.0.0-rc5", path = "../../../primitives/api" }
3530
sp-block-builder = { version = "2.0.0-rc5", path = "../../../primitives/block-builder" }
31+
sp-blockchain = { version = "2.0.0-rc5", path = "../../../primitives/blockchain" }
32+
sp-consensus = { version = "0.8.0-rc5", path = "../../../primitives/consensus/common" }
33+
sp-consensus-babe = { version = "0.8.0-rc5", path = "../../../primitives/consensus/babe" }
34+
sp-transaction-pool = { version = "2.0.0-rc5", path = "../../../primitives/transaction-pool" }
35+
substrate-frame-rpc-system = { version = "2.0.0-rc5", path = "../../../utils/frame/rpc/system" }

bin/node/rpc/src/lib.rs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,21 @@
3232

3333
use std::sync::Arc;
3434

35+
use jsonrpc_pubsub::manager::SubscriptionManager;
3536
use node_primitives::{Block, BlockNumber, AccountId, Index, Balance, Hash};
36-
use sp_api::ProvideRuntimeApi;
37-
use sp_transaction_pool::TransactionPool;
38-
use sp_blockchain::{Error as BlockChainError, HeaderMetadata, HeaderBackend};
39-
use sp_consensus::SelectChain;
40-
use sc_keystore::KeyStorePtr;
41-
use sp_consensus_babe::BabeApi;
42-
use sc_consensus_epochs::SharedEpochChanges;
4337
use sc_consensus_babe::{Config, Epoch};
4438
use sc_consensus_babe_rpc::BabeRpcHandler;
45-
use sc_finality_grandpa::{SharedVoterState, SharedAuthoritySet};
39+
use sc_consensus_epochs::SharedEpochChanges;
40+
use sc_finality_grandpa::{SharedVoterState, SharedAuthoritySet, GrandpaJustificationStream};
4641
use sc_finality_grandpa_rpc::GrandpaRpcHandler;
47-
use sp_block_builder::BlockBuilder;
42+
use sc_keystore::KeyStorePtr;
4843
pub use sc_rpc_api::DenyUnsafe;
44+
use sp_api::ProvideRuntimeApi;
45+
use sp_block_builder::BlockBuilder;
46+
use sp_blockchain::{Error as BlockChainError, HeaderMetadata, HeaderBackend};
47+
use sp_consensus::SelectChain;
48+
use sp_consensus_babe::BabeApi;
49+
use sp_transaction_pool::TransactionPool;
4950

5051
/// Light client extra dependencies.
5152
pub struct LightDeps<C, F, P> {
@@ -75,6 +76,10 @@ pub struct GrandpaDeps {
7576
pub shared_voter_state: SharedVoterState,
7677
/// Authority set info.
7778
pub shared_authority_set: SharedAuthoritySet<Hash, BlockNumber>,
79+
/// Receives notifications about justification events from Grandpa.
80+
pub justification_stream: GrandpaJustificationStream<Block>,
81+
/// Subscription manager to keep track of pubsub subscribers.
82+
pub subscriptions: SubscriptionManager,
7883
}
7984

8085
/// Full client dependencies.
@@ -97,9 +102,9 @@ pub struct FullDeps<C, P, SC> {
97102
pub type IoHandler = jsonrpc_core::IoHandler<sc_rpc::Metadata>;
98103

99104
/// Instantiate all Full RPC extensions.
100-
pub fn create_full<C, P, M, SC>(
105+
pub fn create_full<C, P, SC>(
101106
deps: FullDeps<C, P, SC>,
102-
) -> jsonrpc_core::IoHandler<M> where
107+
) -> jsonrpc_core::IoHandler<sc_rpc_api::Metadata> where
103108
C: ProvideRuntimeApi<Block>,
104109
C: HeaderBackend<Block> + HeaderMetadata<Block, Error=BlockChainError> + 'static,
105110
C: Send + Sync + 'static,
@@ -109,7 +114,6 @@ pub fn create_full<C, P, M, SC>(
109114
C::Api: BabeApi<Block>,
110115
C::Api: BlockBuilder<Block>,
111116
P: TransactionPool + 'static,
112-
M: jsonrpc_core::Metadata + Default,
113117
SC: SelectChain<Block> +'static,
114118
{
115119
use substrate_frame_rpc_system::{FullSystem, SystemApi};
@@ -125,6 +129,7 @@ pub fn create_full<C, P, M, SC>(
125129
babe,
126130
grandpa,
127131
} = deps;
132+
128133
let BabeDeps {
129134
keystore,
130135
babe_config,
@@ -133,6 +138,8 @@ pub fn create_full<C, P, M, SC>(
133138
let GrandpaDeps {
134139
shared_voter_state,
135140
shared_authority_set,
141+
justification_stream,
142+
subscriptions,
136143
} = grandpa;
137144

138145
io.extend_with(
@@ -161,7 +168,12 @@ pub fn create_full<C, P, M, SC>(
161168
);
162169
io.extend_with(
163170
sc_finality_grandpa_rpc::GrandpaApi::to_delegate(
164-
GrandpaRpcHandler::new(shared_authority_set, shared_voter_state)
171+
GrandpaRpcHandler::new(
172+
shared_authority_set,
173+
shared_voter_state,
174+
justification_stream,
175+
subscriptions,
176+
)
165177
)
166178
);
167179

client/finality-grandpa/rpc/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,29 @@ edition = "2018"
88
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
99

1010
[dependencies]
11+
sc-rpc = { version = "2.0.0-rc5", path = "../../rpc" }
12+
sp-runtime = { version = "2.0.0-rc5", path = "../../../primitives/runtime" }
1113
sc-finality-grandpa = { version = "0.8.0-rc5", path = "../" }
1214
finality-grandpa = { version = "0.12.3", features = ["derive-codec"] }
1315
jsonrpc-core = "14.2.0"
1416
jsonrpc-core-client = "14.2.0"
1517
jsonrpc-derive = "14.2.1"
18+
jsonrpc-pubsub = "14.2.0"
1619
futures = { version = "0.3.4", features = ["compat"] }
1720
serde = { version = "1.0.105", features = ["derive"] }
1821
serde_json = "1.0.50"
1922
log = "0.4.8"
2023
derive_more = "0.99.2"
24+
parity-scale-codec = { version = "1.3.0", features = ["derive"] }
2125

2226
[dev-dependencies]
27+
sc-block-builder = { version = "0.8.0-rc5", path = "../../block-builder" }
28+
sc-network-test = { version = "0.8.0-rc5", path = "../../network/test" }
29+
sc-rpc = { version = "2.0.0-rc5", path = "../../rpc", features = ["test-helpers"] }
30+
sp-blockchain = { version = "2.0.0-rc5", path = "../../../primitives/blockchain" }
31+
sp-consensus = { version = "0.8.0-rc5", path = "../../../primitives/consensus/common" }
2332
sp-core = { version = "2.0.0-rc5", path = "../../../primitives/core" }
33+
sp-finality-grandpa = { version = "2.0.0-rc5", path = "../../../primitives/finality-grandpa" }
34+
sp-keyring = { version = "2.0.0-rc5", path = "../../../primitives/keyring" }
35+
substrate-test-runtime-client = { version = "2.0.0-rc5", path = "../../../test-utils/runtime/client" }
36+
lazy_static = "1.4"

0 commit comments

Comments
 (0)