Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,14 @@ sc-cli = { path = "vendor/polkadot-sdk/substrate/client/cli", default-features =
sc-client-api = { path = "vendor/polkadot-sdk/substrate/client/api", default-features = false }
sc-consensus = { path = "vendor/polkadot-sdk/substrate/client/consensus/common", default-features = false }
sc-consensus-grandpa = { path = "vendor/polkadot-sdk/substrate/client/consensus/grandpa", default-features = false }
sc-consensus-grandpa-rpc = { path = "vendor/polkadot-sdk/substrate/client/consensus/grandpa/rpc", default-features = false }
sc-consensus-slots = { path = "vendor/polkadot-sdk/substrate/client/consensus/slots", default-features = false }
sc-executor = { path = "vendor/polkadot-sdk/substrate/client/executor", default-features = false }
sc-keystore = { path = "vendor/polkadot-sdk/substrate/client/keystore", default-features = false }
sc-network = { path = "vendor/polkadot-sdk/substrate/client/network", default-features = false }
sc-network-test = { path = "vendor/polkadot-sdk/substrate/client/network/test", default-features = false }
sc-offchain = { path = "vendor/polkadot-sdk/substrate/client/offchain", default-features = false }
sc-rpc = { path = "vendor/polkadot-sdk/substrate/client/rpc", default-features = false }
sc-rpc-api = { path = "vendor/polkadot-sdk/substrate/client/rpc-api", default-features = false }
sc-serde-json = { path = "vendor/polkadot-sdk/substrate/client/serde_json", default-features = false }
sc-service = { path = "vendor/polkadot-sdk/substrate/client/service", default-features = false }
Expand Down
2 changes: 2 additions & 0 deletions node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ sc-chain-spec = { workspace = true, default-features = true }
sc-consensus = { workspace = true, default-features = true }
sc-consensus-grandpa = { workspace = true, default-features = true }
sp-consensus-grandpa = { workspace = true, default-features = true }
sc-consensus-grandpa-rpc = { workspace = true, default-features = true }
sc-client-api = { workspace = true, default-features = true }
sc-rpc = { workspace = true, default-features = true }
sc-rpc-api = { workspace = true, default-features = true }
sc-basic-authorship = { workspace = true, default-features = true }

Expand Down
53 changes: 48 additions & 5 deletions node/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,46 @@
use std::sync::Arc;

use jsonrpsee::RpcModule;
use qf_runtime::{AccountId, Balance, Nonce, opaque::Block};
use qf_runtime::{
AccountId, Balance, BlockNumber, Nonce,
opaque::{Block, Hash},
};
use sc_consensus_grandpa::{
FinalityProofProvider, GrandpaJustificationStream, SharedAuthoritySet, SharedVoterState,
};
pub use sc_rpc::SubscriptionTaskExecutor;
use sc_transaction_pool_api::TransactionPool;
use sp_api::ProvideRuntimeApi;
use sp_block_builder::BlockBuilder;
use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};

/// Extra dependencies for GRANDPA
pub struct GrandpaDeps<B> {
/// Voting round info.
pub shared_voter_state: SharedVoterState,
/// Authority set info.
pub shared_authority_set: SharedAuthoritySet<Hash, BlockNumber>,
/// Receives notifications about justification events from Grandpa.
pub justification_stream: GrandpaJustificationStream<Block>,
/// Executor to drive the subscription manager in the Grandpa RPC handler.
pub subscription_executor: SubscriptionTaskExecutor,
/// Finality proof provider.
pub finality_provider: Arc<FinalityProofProvider<B, Block>>,
}

/// Full client dependencies.
pub struct FullDeps<C, P> {
pub struct FullDeps<C, P, B> {
/// The client instance to use.
pub client: Arc<C>,
/// Transaction pool instance.
pub pool: Arc<P>,
/// GRANDPA specific dependencies.
pub grandpa: GrandpaDeps<B>,
}

/// Instantiate all full RPC extensions.
pub fn create_full<C, P>(
deps: FullDeps<C, P>,
pub fn create_full<C, P, B>(
deps: FullDeps<C, P, B>,
) -> Result<RpcModule<()>, Box<dyn std::error::Error + Send + Sync>>
where
C: ProvideRuntimeApi<Block>,
Expand All @@ -34,15 +57,35 @@ where
C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
C::Api: BlockBuilder<Block>,
P: TransactionPool + 'static,
B: sc_client_api::Backend<Block> + Send + Sync + 'static,
B::State: sc_client_api::backend::StateBackend<sp_runtime::traits::HashingFor<Block>>,
{
use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
use sc_consensus_grandpa_rpc::{Grandpa, GrandpaApiServer};
use substrate_frame_rpc_system::{System, SystemApiServer};

let mut module = RpcModule::new(());
let FullDeps { client, pool } = deps;
let FullDeps { client, pool, grandpa } = deps;
let GrandpaDeps {
shared_voter_state,
shared_authority_set,
justification_stream,
subscription_executor,
finality_provider,
} = grandpa;

module.merge(System::new(client.clone(), pool).into_rpc())?;
module.merge(TransactionPayment::new(client).into_rpc())?;
module.merge(
Grandpa::new(
subscription_executor,
shared_authority_set.clone(),
shared_voter_state,
justification_stream,
finality_provider,
)
.into_rpc(),
)?;

// Extend this RPC with a custom API by using the following syntax.
// `YourRpcStruct` should have a reference to a client, which is needed
Expand Down
35 changes: 28 additions & 7 deletions node/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use qf_runtime::{self, apis::RuntimeApi, opaque::Block};
use qfc_consensus_spin::{ImportQueueParams, SlotProportion, StartSpinParams};
use qfp_consensus_spin::sr25519::AuthorityPair as SpinPair;
use sc_client_api::{Backend, BlockBackend};
use sc_consensus_grandpa::SharedVoterState;
use sc_service::{Configuration, TaskManager, WarpSyncConfig, error::Error as ServiceError};
use sc_telemetry::{Telemetry, TelemetryWorker};
use sc_transaction_pool_api::OffchainTransactionPoolFactory;
Expand Down Expand Up @@ -213,14 +212,36 @@ pub fn new_full<
let enable_grandpa = !config.disable_grandpa;
let prometheus_registry = config.prometheus_registry().cloned();

let rpc_extensions_builder = {
let (rpc_extensions_builder, shared_voter_state) = {
let justification_stream = grandpa_link.justification_stream();
let shared_authority_set = grandpa_link.shared_authority_set().clone();
let shared_voter_state = sc_consensus_grandpa::SharedVoterState::empty();
let shared_voter_state2 = shared_voter_state.clone();

let finality_proof_provider = sc_consensus_grandpa::FinalityProofProvider::new_for_service(
backend.clone(),
Some(shared_authority_set.clone()),
);

let client = client.clone();
let pool = transaction_pool.clone();

Box::new(move |_| {
let deps = crate::rpc::FullDeps { client: client.clone(), pool: pool.clone() };
crate::rpc::create_full(deps).map_err(Into::into)
})
let rpc_extensions_builder =
Box::new(move |subscription_executor: crate::rpc::SubscriptionTaskExecutor| {
let deps = crate::rpc::FullDeps {
client: client.clone(),
pool: pool.clone(),
grandpa: crate::rpc::GrandpaDeps {
shared_voter_state: shared_voter_state.clone(),
shared_authority_set: shared_authority_set.clone(),
justification_stream: justification_stream.clone(),
subscription_executor: subscription_executor.clone(),
finality_provider: finality_proof_provider.clone(),
},
};
crate::rpc::create_full(deps).map_err(Into::into)
});
(rpc_extensions_builder, shared_voter_state2)
};

let _rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams {
Expand Down Expand Up @@ -317,7 +338,7 @@ pub fn new_full<
notification_service: grandpa_notification_service,
voting_rule: sc_consensus_grandpa::VotingRulesBuilder::default().build(),
prometheus_registry,
shared_voter_state: SharedVoterState::empty(),
shared_voter_state,
telemetry: telemetry.as_ref().map(|x| x.handle()),
offchain_tx_pool_factory: OffchainTransactionPoolFactory::new(transaction_pool),
};
Expand Down