Skip to content

Commit 0750ccd

Browse files
lexnvjsdw
andauthored
Add chainHead RPC methods (#766)
* rpc/types: Add chainHead event types Signed-off-by: Alexandru Vasile <[email protected]> * rpc: Add `chainHead` RPC methods Signed-off-by: Alexandru Vasile <[email protected]> * rpc: Fix chainHead doc links Signed-off-by: Alexandru Vasile <[email protected]> * Update subxt/src/rpc/rpc.rs Co-authored-by: James Wilson <[email protected]> * tests: Test the chainHead RPC methods Signed-off-by: Alexandru Vasile <[email protected]> * tests: Fix clippy Signed-off-by: Alexandru Vasile <[email protected]> * rpc: Improve `chainhead_unstable_follow` docs Signed-off-by: Alexandru Vasile <[email protected]> Signed-off-by: Alexandru Vasile <[email protected]> Co-authored-by: James Wilson <[email protected]>
1 parent 977f2a3 commit 0750ccd

File tree

3 files changed

+731
-2
lines changed

3 files changed

+731
-2
lines changed

subxt/src/rpc/rpc.rs

Lines changed: 162 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@
4141
4242
use super::{
4343
rpc_params,
44-
types,
44+
types::{
45+
self,
46+
ChainHeadEvent,
47+
FollowEvent,
48+
},
4549
RpcClient,
4650
RpcClientT,
4751
Subscription,
@@ -465,6 +469,163 @@ impl<T: Config> Rpc<T> {
465469
self.client.request("system_dryRun", params).await?;
466470
Ok(types::decode_dry_run_result(&mut &*result_bytes.0)?)
467471
}
472+
473+
/// Subscribe to `chainHead_unstable_follow` to obtain all reported blocks by the chain.
474+
///
475+
/// The subscription ID can be used to make queries for the
476+
/// block's body ([`chainhead_unstable_body`](Rpc::chainhead_unstable_follow)),
477+
/// block's header ([`chainhead_unstable_header`](Rpc::chainhead_unstable_header)),
478+
/// block's storage ([`chainhead_unstable_storage`](Rpc::chainhead_unstable_storage)) and submitting
479+
/// runtime API calls at this block ([`chainhead_unstable_call`](Rpc::chainhead_unstable_call)).
480+
///
481+
/// # Note
482+
///
483+
/// When the user is no longer interested in a block, the user is responsible
484+
/// for calling the [`chainhead_unstable_unpin`](Rpc::chainhead_unstable_unpin) method.
485+
/// Failure to do so will result in the subscription being stopped by generating the `Stop` event.
486+
pub async fn chainhead_unstable_follow(
487+
&self,
488+
runtime_updates: bool,
489+
) -> Result<Subscription<FollowEvent<T::Hash>>, Error> {
490+
let subscription = self
491+
.client
492+
.subscribe(
493+
"chainHead_unstable_follow",
494+
rpc_params![runtime_updates],
495+
"chainHead_unstable_unfollow",
496+
)
497+
.await?;
498+
499+
Ok(subscription)
500+
}
501+
502+
/// Subscribe to `chainHead_unstable_body` to obtain events regarding the block's body.
503+
///
504+
/// # Note
505+
///
506+
/// The subscription ID is obtained from an open subscription created by
507+
/// [`chainhead_unstable_follow`](Rpc::chainhead_unstable_follow).
508+
pub async fn chainhead_unstable_body(
509+
&self,
510+
subscription_id: String,
511+
hash: T::Hash,
512+
) -> Result<Subscription<ChainHeadEvent<String>>, Error> {
513+
let subscription = self
514+
.client
515+
.subscribe(
516+
"chainHead_unstable_body",
517+
rpc_params![subscription_id, hash],
518+
"chainHead_unstable_stopBody",
519+
)
520+
.await?;
521+
522+
Ok(subscription)
523+
}
524+
525+
/// Get the block's body using the `chainHead_unstable_header` method.
526+
///
527+
/// # Note
528+
///
529+
/// The subscription ID is obtained from an open subscription created by
530+
/// [`chainhead_unstable_follow`](Rpc::chainhead_unstable_follow).
531+
pub async fn chainhead_unstable_header(
532+
&self,
533+
subscription_id: String,
534+
hash: T::Hash,
535+
) -> Result<Option<String>, Error> {
536+
let header = self
537+
.client
538+
.request(
539+
"chainHead_unstable_header",
540+
rpc_params![subscription_id, hash],
541+
)
542+
.await?;
543+
544+
Ok(header)
545+
}
546+
547+
/// Subscribe to `chainHead_storage` to obtain events regarding the
548+
/// block's storage.
549+
///
550+
/// # Note
551+
///
552+
/// The subscription ID is obtained from an open subscription created by
553+
/// [`chainhead_unstable_follow`](Rpc::chainhead_unstable_follow).
554+
pub async fn chainhead_unstable_storage(
555+
&self,
556+
subscription_id: String,
557+
hash: T::Hash,
558+
key: &[u8],
559+
child_key: Option<&[u8]>,
560+
) -> Result<Subscription<ChainHeadEvent<Option<String>>>, Error> {
561+
let subscription = self
562+
.client
563+
.subscribe(
564+
"chainHead_unstable_storage",
565+
rpc_params![subscription_id, hash, to_hex(key), child_key.map(to_hex)],
566+
"chainHead_unstable_stopStorage",
567+
)
568+
.await?;
569+
570+
Ok(subscription)
571+
}
572+
573+
/// Subscribe to `chainHead_call` to obtain events regarding the
574+
/// runtime API call.
575+
///
576+
/// # Note
577+
///
578+
/// The subscription ID is obtained from an open subscription created by
579+
/// [`chainhead_unstable_follow`](Rpc::chainhead_unstable_follow).
580+
pub async fn chainhead_unstable_call(
581+
&self,
582+
subscription_id: String,
583+
hash: T::Hash,
584+
function: String,
585+
call_parameters: &[u8],
586+
) -> Result<Subscription<ChainHeadEvent<String>>, Error> {
587+
let subscription = self
588+
.client
589+
.subscribe(
590+
"chainHead_unstable_call",
591+
rpc_params![subscription_id, hash, function, to_hex(call_parameters)],
592+
"chainHead_unstable_stopCall",
593+
)
594+
.await?;
595+
596+
Ok(subscription)
597+
}
598+
599+
/// Unpin a block reported by the `chainHead_follow` subscription.
600+
///
601+
/// # Note
602+
///
603+
/// The subscription ID is obtained from an open subscription created by
604+
/// [`chainhead_unstable_follow`](Rpc::chainhead_unstable_follow).
605+
pub async fn chainhead_unstable_unpin(
606+
&self,
607+
subscription_id: String,
608+
hash: T::Hash,
609+
) -> Result<(), Error> {
610+
self.client
611+
.request(
612+
"chainHead_unstable_unpin",
613+
rpc_params![subscription_id, hash],
614+
)
615+
.await?;
616+
617+
Ok(())
618+
}
619+
620+
/// Get genesis hash obtained from the `chainHead_genesisHash` method.
621+
pub async fn chainhead_unstable_genesishash(&self) -> Result<T::Hash, Error> {
622+
let hash = self
623+
.client
624+
.request("chainHead_unstable_genesisHash", rpc_params![])
625+
.await?;
626+
627+
Ok(hash)
628+
}
468629
}
469630

470631
fn to_hex(bytes: impl AsRef<[u8]>) -> String {

0 commit comments

Comments
 (0)