blocks: Fetch chainHead header

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
This commit is contained in:
Alexandru Vasile
2022-11-30 11:04:43 +00:00
parent 6a5cb229af
commit 9ef0a70742
3 changed files with 47 additions and 2 deletions
@@ -34,6 +34,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let body = event.body().await?;
println!("[hash={:?}] body={:?}", event.hash(), body);
let header = event.header().await?;
println!("[hash={:?}] header={:?}", event.hash(), header);
}
// Subscribe to the `chainHead_follow` method.
+26 -1
View File
@@ -64,11 +64,12 @@ where
T: Config,
C: OnlineClientT<T>,
{
/// Fetch the body (vector of extrinsics) of this block.
pub async fn body(&self) -> Result<Vec<Vec<u8>>, Error> {
let mut sub = self
.client
.rpc()
.subscribe_chainhead_body(self.hash, self.subscription_id.clone())
.subscribe_chainhead_body(self.subscription_id.clone(), self.hash)
.await?;
if let Some(event) = sub.next().await {
@@ -90,6 +91,30 @@ where
Err(Error::Other("Failed to fetch the block body".into()))
}
/// Fetch the header of this block.
pub async fn header(&self) -> Result<T::Header, Error> {
let header = self
.client
.rpc()
.get_chainhead_header(self.subscription_id.clone(), self.hash)
.await?;
let header = match header {
Some(header) => header,
None => {
return Err(Error::Other(
"Chain does not contain the header of this block".into(),
))
}
};
let bytes = hex::decode(header.trim_start_matches("0x"))
.map_err(|err| Error::Other(err.to_string()))?;
let header: T::Header = Decode::decode(&mut &bytes[..])?;
Ok(header)
}
}
/// A representation of a block.
+18 -1
View File
@@ -630,8 +630,8 @@ impl<T: Config> Rpc<T> {
/// Subscribe to the chain head body.
pub async fn subscribe_chainhead_body(
&self,
hash: T::Hash,
subscription_id: String,
hash: T::Hash,
) -> Result<Subscription<ChainHeadEvent<String>>, Error> {
let subscription = self
.client
@@ -645,6 +645,23 @@ impl<T: Config> Rpc<T> {
Ok(subscription)
}
/// Get the chain head header.
pub async fn get_chainhead_header(
&self,
subscription_id: String,
hash: T::Hash,
) -> Result<Option<String>, Error> {
let header = self
.client
.request(
"chainHead_unstable_header",
rpc_params![subscription_id, hash],
)
.await?;
Ok(header)
}
/// Subscribe to finalized block headers.
///
/// Note: this may not produce _every_ block in the finalized chain;