1919use std:: sync:: Arc ;
2020
2121use client:: { self , Client , BlockchainEvents } ;
22- use jsonrpc_macros:: pubsub;
22+ use jsonrpc_macros:: { pubsub, Trailing } ;
2323use jsonrpc_pubsub:: SubscriptionId ;
24- use jsonrpc_macros:: Trailing ;
2524use rpc:: Result as RpcResult ;
2625use rpc:: futures:: { stream, Future , Sink , Stream } ;
2726use runtime_primitives:: generic:: { BlockId , SignedBlock } ;
28- use runtime_primitives:: traits:: Block as BlockT ;
27+ use runtime_primitives:: traits:: { Block as BlockT , Header , NumberFor } ;
2928use runtime_version:: RuntimeVersion ;
3029use tokio:: runtime:: TaskExecutor ;
3130use primitives:: { KeccakHasher , RlpCodec } ;
@@ -40,20 +39,22 @@ use self::error::Result;
4039
4140build_rpc_trait ! {
4241 /// Polkadot blockchain API
43- pub trait ChainApi <Hash , Header , Extrinsic > {
42+ pub trait ChainApi <Hash , Header , Number , Extrinsic > {
4443 type Metadata ;
4544
4645 /// Get header of a relay chain block.
4746 #[ rpc( name = "chain_getHeader" ) ]
48- fn header( & self , Hash ) -> Result <Option <Header >>;
47+ fn header( & self , Trailing < Hash > ) -> Result <Option <Header >>;
4948
5049 /// Get header and body of a relay chain block.
5150 #[ rpc( name = "chain_getBlock" ) ]
52- fn block( & self , Hash ) -> Result <Option <SignedBlock <Header , Extrinsic , Hash >>>;
51+ fn block( & self , Trailing < Hash > ) -> Result <Option <SignedBlock <Header , Extrinsic , Hash >>>;
5352
54- /// Get hash of the head.
55- #[ rpc( name = "chain_getHead" ) ]
56- fn head( & self ) -> Result <Hash >;
53+ /// Get hash of the n-th block in the canon chain.
54+ ///
55+ /// By default returns latest block hash.
56+ #[ rpc( name = "chain_getBlockHash" , alias = [ "chain_getHead" , ] ) ]
57+ fn block_hash( & self , Trailing <Number >) -> Result <Option <Hash >>;
5758
5859 /// Get the runtime version.
5960 #[ rpc( name = "chain_getRuntimeVersion" ) ]
@@ -102,23 +103,28 @@ impl<B, E, Block> Chain<B, E, Block> where
102103 }
103104}
104105
105- impl < B , E , Block > ChainApi < Block :: Hash , Block :: Header , Block :: Extrinsic > for Chain < B , E , Block > where
106+ impl < B , E , Block > ChainApi < Block :: Hash , Block :: Header , NumberFor < Block > , Block :: Extrinsic > for Chain < B , E , Block > where
106107 Block : BlockT + ' static ,
107108 B : client:: backend:: Backend < Block , KeccakHasher , RlpCodec > + Send + Sync + ' static ,
108109 E : client:: CallExecutor < Block , KeccakHasher , RlpCodec > + Send + Sync + ' static ,
109110{
110111 type Metadata = :: metadata:: Metadata ;
111112
112- fn header ( & self , hash : Block :: Hash ) -> Result < Option < Block :: Header > > {
113+ fn header ( & self , hash : Trailing < Block :: Hash > ) -> Result < Option < Block :: Header > > {
114+ let hash = self . unwrap_or_best ( hash) ?;
113115 Ok ( self . client . header ( & BlockId :: Hash ( hash) ) ?)
114116 }
115117
116- fn block ( & self , hash : Block :: Hash ) -> Result < Option < SignedBlock < Block :: Header , Block :: Extrinsic , Block :: Hash > > > {
118+ fn block ( & self , hash : Trailing < Block :: Hash > ) -> Result < Option < SignedBlock < Block :: Header , Block :: Extrinsic , Block :: Hash > > > {
119+ let hash = self . unwrap_or_best ( hash) ?;
117120 Ok ( self . client . block ( & BlockId :: Hash ( hash) ) ?)
118121 }
119122
120- fn head ( & self ) -> Result < Block :: Hash > {
121- Ok ( self . client . info ( ) ?. chain . best_hash )
123+ fn block_hash ( & self , number : Trailing < NumberFor < Block > > ) -> Result < Option < Block :: Hash > > {
124+ Ok ( match number. into ( ) {
125+ None => Some ( self . client . info ( ) ?. chain . best_hash ) ,
126+ Some ( number) => self . client . header ( & BlockId :: number ( number) ) ?. map ( |h| h. hash ( ) ) ,
127+ } )
122128 }
123129
124130 fn runtime_version ( & self , at : Trailing < Block :: Hash > ) -> Result < RuntimeVersion > {
@@ -129,8 +135,8 @@ impl<B, E, Block> ChainApi<Block::Hash, Block::Header, Block::Extrinsic> for Cha
129135 fn subscribe_new_head ( & self , _metadata : Self :: Metadata , subscriber : pubsub:: Subscriber < Block :: Header > ) {
130136 self . subscriptions . add ( subscriber, |sink| {
131137 // send current head right at the start.
132- let header = self . head ( )
133- . and_then ( |hash| self . header ( hash) )
138+ let header = self . block_hash ( None . into ( ) )
139+ . and_then ( |hash| self . header ( hash. into ( ) ) )
134140 . and_then ( |header| {
135141 header. ok_or_else ( || self :: error:: ErrorKind :: Unimplemented . into ( ) )
136142 } )
0 commit comments