1616
1717//! rpc api for babe.
1818
19+ use std:: fmt;
1920use futures:: {
2021 prelude:: * ,
2122 executor:: ThreadPool ,
@@ -31,21 +32,24 @@ use std::sync::Arc;
3132use sp_core:: { crypto:: Pair , Bytes } ;
3233use sp_runtime:: traits:: { Block as BlockT , Header as _} ;
3334use sp_consensus:: { SelectChain , Error as ConsensusError } ;
35+ use sp_consensus_babe:: BabeApi ;
3436use sp_blockchain:: { HeaderBackend , HeaderMetadata , Error as BlockChainError } ;
35- use serde:: Deserialize ;
36-
37+ use serde:: { Deserialize , Serialize } ;
38+ use sp_api :: { ProvideRuntimeApi , BlockId } ;
3739
3840/// Provides rpc methods for interacting with Babe
39- #[ rpc]
41+ #[ rpc( server ) ]
4042pub trait Babe {
4143 /// query slot authorship info
42- // #[rpc(name = "babe_epochAuthorship")]
44+ #[ rpc( name = "babe_epochAuthorship" ) ]
4345 fn epoch_authorship ( & self ) -> BoxFuture < Vec < SlotAuthorship > > ;
4446}
4547
4648/// RPC handler for Babe
4749/// provides `babe_epochAuthorship` method for querying slot authorship data.
48- struct BabeRPC < B : BlockT , C > {
50+ ///
51+ /// Uses a background thread to calculate epoch_authorship data.
52+ pub struct BabeRPC < B : BlockT , C > {
4953 /// shared refernce to the client.
5054 client : Arc < C > ,
5155 /// shared reference to EpochChanges
@@ -66,7 +70,11 @@ impl<B: BlockT, C> BabeRPC<B, C> {
6670 keystore : KeyStorePtr ,
6771 babe_config : Config
6872 ) -> Self {
69- let threadpool = ThreadPool :: builder ( ) . pool_size ( 1 ) . create ( ) . unwrap ( ) ;
73+ let threadpool = ThreadPool :: builder ( )
74+ // single thread is fine.
75+ . pool_size ( 1 )
76+ . create ( )
77+ . unwrap ( ) ;
7078 Self {
7179 client,
7280 shared_epoch_changes,
@@ -80,7 +88,10 @@ impl<B: BlockT, C> BabeRPC<B, C> {
8088impl < B , C > Babe for BabeRPC < B , C >
8189 where
8290 B : BlockT ,
83- C : SelectChain < B > + HeaderBackend < B > + HeaderMetadata < B , Error =BlockChainError > + ' static ,
91+ C : ProvideRuntimeApi < B > + SelectChain < B > + HeaderBackend < B >
92+ + HeaderMetadata < B , Error =BlockChainError > + ' static ,
93+ C :: Api : BabeApi < B > ,
94+ <<C as ProvideRuntimeApi < B > >:: Api as sp_api:: ApiErrorExt >:: Error : fmt:: Debug
8495{
8596 fn epoch_authorship ( & self ) -> BoxFuture < Vec < SlotAuthorship > > {
8697 let (
@@ -94,26 +105,27 @@ impl<B, C> Babe for BabeRPC<B, C>
94105 self . shared_epoch_changes . clone ( ) ,
95106 self . client . clone ( ) ,
96107 ) ;
97-
98- // FIXME: get currrent slot_number from runtime.
99- let epoch = epoch_data ( & shared_epoch, & client, & babe_config, slot_number)
100- . map_err ( Error :: Consensus ) ;
101-
102108 let ( tx, rx) = oneshot:: channel ( ) ;
103109
104110 let future = async move {
105- let epoch = epoch?;
111+ let header = client. best_chain ( ) . map_err ( Error :: Consensus ) ?;
112+ // FIXME: no unwraps.
113+ let epoch_start = client. runtime_api ( )
114+ . current_epoch_start ( & BlockId :: Hash ( header. hash ( ) ) )
115+ . map_err ( |err| {
116+ Error :: StringError ( format ! ( "{:?}" , err) )
117+ } ) ?;
118+ let epoch = epoch_data ( & shared_epoch, & client, & babe_config, epoch_start) ?;
106119 let ( epoch_start, epoch_end) = ( epoch. start_slot , epoch. end_slot ( ) ) ;
120+
107121 let mut slots = vec ! [ ] ;
108122
109123 for slot_number in epoch_start..=epoch_end {
110- let epoch = epoch_data ( & shared_epoch, & client, & babe_config, slot_number)
111- . map_err ( Error :: Consensus ) ?;
124+ let epoch = epoch_data ( & shared_epoch, & client, & babe_config, slot_number) ?;
112125 let slot = authorship:: claim_slot ( slot_number, & epoch, & babe_config, & keystore) ;
113126 if let Some ( ( claim, key) ) = slot {
114127 let claim = match claim {
115128 BabePreDigest :: Primary { vrf_output, vrf_proof, threshold, .. } => {
116- let threshold = threshold. expect ( "threshold is set in the call to claim_slot; qed" ) ;
117129 BabeClaim :: Primary {
118130 threshold,
119131 output : Bytes ( vrf_output. as_bytes ( ) . to_vec ( ) ) ,
@@ -150,16 +162,16 @@ impl<B, C> Babe for BabeRPC<B, C>
150162}
151163
152164/// slot authorship information
153- #[ derive( Debug , Deserialize ) ]
154- struct SlotAuthorship {
165+ #[ derive( Debug , Deserialize , Serialize ) ]
166+ pub struct SlotAuthorship {
155167 /// slot number in the epoch
156168 slot_number : u64 ,
157169 /// claim data
158170 claim : BabeClaim ,
159171}
160172
161173/// Babe claim
162- #[ derive( Debug , Deserialize ) ]
174+ #[ derive( Debug , Deserialize , Serialize ) ]
163175enum BabeClaim {
164176 /// a primary claim for a given slot
165177 Primary {
@@ -178,10 +190,15 @@ enum BabeClaim {
178190 } ,
179191}
180192
181- #[ derive( Debug , err_derive:: Error ) ]
193+ /// Errors encountered by the RPC
194+ #[ derive( Debug , err_derive:: Error , derive_more:: From ) ]
182195pub enum Error {
196+ /// Consensus error
183197 #[ error( display = "Consensus Error: {}" , _0) ]
184198 Consensus ( ConsensusError ) ,
199+ /// Errors that can be formatted as a String
200+ #[ error( display = "{}" , _0) ]
201+ StringError ( String )
185202}
186203
187204impl From < Error > for jsonrpc_core:: Error {
@@ -200,7 +217,7 @@ fn epoch_data<B, C>(
200217 client : & Arc < C > ,
201218 babe_config : & Config ,
202219 slot_number : u64 ,
203- ) -> Result < Epoch , ConsensusError >
220+ ) -> Result < Epoch , Error >
204221 where
205222 B : BlockT ,
206223 C : SelectChain < B > + HeaderBackend < B > + HeaderMetadata < B , Error =BlockChainError > + ' static ,
@@ -213,7 +230,7 @@ fn epoch_data<B, C>(
213230 slot_number,
214231 |slot| babe_config. genesis_epoch ( slot) ,
215232 )
216- . map_err ( |e| ConsensusError :: ChainLookup ( format ! ( "{:?}" , e) ) ) ?
233+ . map_err ( |e| Error :: Consensus ( ConsensusError :: ChainLookup ( format ! ( "{:?}" , e) ) ) ) ?
217234 . map ( |e| e. into_inner ( ) )
218- . ok_or ( ConsensusError :: InvalidAuthoritiesSet )
235+ . ok_or ( Error :: Consensus ( ConsensusError :: InvalidAuthoritiesSet ) )
219236}
0 commit comments