Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
Prev Previous commit
Next Next commit
port babe rpc
  • Loading branch information
niklasad1 committed Sep 3, 2021
commit ded670b049b3420eba93b7ca30904d156e592522
7 changes: 3 additions & 4 deletions bin/node/cli/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use jsonrpsee::RpcModule;
use pallet_contracts_rpc::ContractsRpc;
use pallet_mmr_rpc::MmrRpc;
use pallet_transaction_payment_rpc::{TransactionPaymentApiServer, TransactionPaymentRpc};
use sc_consensus_babe_rpc::BabeRpc;
use sc_consensus_babe_rpc::{BabeApiServer, BabeRpc};
use sc_finality_grandpa_rpc::GrandpaRpc;
use sc_sync_state_rpc::SyncStateRpc;
use substrate_frame_rpc_system::{SystemApiServer, SystemRpc, SystemRpcBackendFull};
Expand Down Expand Up @@ -191,8 +191,7 @@ pub fn new_partial(
select_chain2,
deny_unsafe,
)
.into_rpc_module()
.expect("TODO: error handling");
.into_rpc();
let sync_state_rpc = SyncStateRpc::new(
chain_spec,
client2.clone(),
Expand Down Expand Up @@ -758,7 +757,7 @@ mod tests {
sc_consensus_babe::authorship::claim_slot(slot.into(), &epoch, &keystore)
.map(|(digest, _)| digest)
{
break (babe_pre_digest, epoch_descriptor)
break (babe_pre_digest, epoch_descriptor);
}

slot += 1;
Expand Down
159 changes: 80 additions & 79 deletions client/consensus/babe/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@

//! RPC api for babe.

use futures::{FutureExt as _, TryFutureExt as _};
use jsonrpsee::{types::error::Error as JsonRpseeError, RpcModule};
use futures::TryFutureExt;
use jsonrpsee::{
proc_macros::rpc,
types::{async_trait, Error as JsonRpseeError, JsonRpcResult},
};

use sc_consensus_babe::{authorship, Config, Epoch};
use sc_consensus_epochs::{descendent_query, Epoch as EpochT, SharedEpochChanges};
Expand All @@ -35,6 +38,15 @@ use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr};
use sp_runtime::traits::{Block as BlockT, Header as _};
use std::{collections::HashMap, sync::Arc};

/// Provides rpc methods for interacting with Babe.
#[rpc(client, server, namespace = "babe")]
pub trait BabeApi {
/// Returns data about which slots (primary or secondary) can be claimed in the current epoch
/// with the keys in the keystore.
#[method(name = "epochAuthorship")]
async fn epoch_authorship(&self) -> JsonRpcResult<HashMap<AuthorityId, EpochAuthorship>>;
}

/// Provides RPC methods for interacting with Babe.
pub struct BabeRpc<B: BlockT, C, SC> {
/// shared reference to the client.
Expand All @@ -51,16 +63,7 @@ pub struct BabeRpc<B: BlockT, C, SC> {
deny_unsafe: DenyUnsafe,
}

impl<B: BlockT, C, SC> BabeRpc<B, C, SC>
where
B: BlockT,
C: ProvideRuntimeApi<B>
+ HeaderBackend<B>
+ HeaderMetadata<B, Error = BlockChainError>
+ 'static,
C::Api: BabeRuntimeApi<B>,
SC: SelectChain<B> + Clone + 'static,
{
impl<B: BlockT, C, SC> BabeRpc<B, C, SC> {
/// Creates a new instance of the BabeRpc handler.
pub fn new(
client: Arc<C>,
Expand All @@ -72,78 +75,76 @@ where
) -> Self {
Self { client, shared_epoch_changes, keystore, babe_config, select_chain, deny_unsafe }
}
}

/// Convert this [`BabeRpc`] to an [`RpcModule`].
pub fn into_rpc_module(self) -> Result<RpcModule<Self>, JsonRpseeError> {
let mut module = RpcModule::new(self);
// Returns data about which slots (primary or secondary) can be claimed in the current epoch
// with the keys in the keystore.
module.register_async_method("babe_epochAuthorship", |_params, babe| {
async move {
babe.deny_unsafe.check_if_safe()?;
let header = babe.select_chain.best_chain().map_err(Error::Consensus).await?;
let epoch_start = babe
.client
.runtime_api()
.current_epoch_start(&BlockId::Hash(header.hash()))
.map_err(|err| Error::StringError(format!("{:?}", err)))?;

let epoch = epoch_data(
&babe.shared_epoch_changes,
&babe.client,
&babe.babe_config,
*epoch_start,
&babe.select_chain,
)
.await?;
let (epoch_start, epoch_end) = (epoch.start_slot(), epoch.end_slot());
let mut claims: HashMap<AuthorityId, EpochAuthorship> = HashMap::new();

let keys = {
epoch
.authorities
.iter()
.enumerate()
.filter_map(|(i, a)| {
if SyncCryptoStore::has_keys(
&*babe.keystore,
&[(a.0.to_raw_vec(), AuthorityId::ID)],
) {
Some((a.0.clone(), i))
} else {
None
}
})
.collect::<Vec<_>>()
};

for slot in *epoch_start..*epoch_end {
if let Some((claim, key)) = authorship::claim_slot_using_keys(
slot.into(),
&epoch,
&babe.keystore,
&keys,
#[async_trait]
impl<B: BlockT, C, SC> BabeApiServer for BabeRpc<B, C, SC>
where
B: BlockT,
C: ProvideRuntimeApi<B>
+ HeaderBackend<B>
+ HeaderMetadata<B, Error = BlockChainError>
+ 'static,
C::Api: BabeRuntimeApi<B>,
SC: SelectChain<B> + Clone + 'static,
{
async fn epoch_authorship(&self) -> JsonRpcResult<HashMap<AuthorityId, EpochAuthorship>> {
self.deny_unsafe.check_if_safe()?;
let header = self.select_chain.best_chain().map_err(Error::Consensus).await?;
let epoch_start = self
.client
.runtime_api()
.current_epoch_start(&BlockId::Hash(header.hash()))
.map_err(|err| Error::StringError(format!("{:?}", err)))?;

let epoch = epoch_data(
&self.shared_epoch_changes,
&self.client,
&self.babe_config,
*epoch_start,
&self.select_chain,
)
.await?;
let (epoch_start, epoch_end) = (epoch.start_slot(), epoch.end_slot());
let mut claims: HashMap<AuthorityId, EpochAuthorship> = HashMap::new();

let keys = {
epoch
.authorities
.iter()
.enumerate()
.filter_map(|(i, a)| {
if SyncCryptoStore::has_keys(
&*self.keystore,
&[(a.0.to_raw_vec(), AuthorityId::ID)],
) {
match claim {
PreDigest::Primary { .. } => {
claims.entry(key).or_default().primary.push(slot);
},
PreDigest::SecondaryPlain { .. } => {
claims.entry(key).or_default().secondary.push(slot);
},
PreDigest::SecondaryVRF { .. } => {
claims.entry(key).or_default().secondary_vrf.push(slot.into());
},
};
Some((a.0.clone(), i))
} else {
None
}
}

Ok(claims)
})
.collect::<Vec<_>>()
};

for slot in *epoch_start..*epoch_end {
if let Some((claim, key)) =
authorship::claim_slot_using_keys(slot.into(), &epoch, &self.keystore, &keys)
{
match claim {
PreDigest::Primary { .. } => {
claims.entry(key).or_default().primary.push(slot);
}
PreDigest::SecondaryPlain { .. } => {
claims.entry(key).or_default().secondary.push(slot);
}
PreDigest::SecondaryVRF { .. } => {
claims.entry(key).or_default().secondary_vrf.push(slot.into());
}
};
}
.boxed()
})?;
}

Ok(module)
Ok(claims)
}
}

Expand Down