1use crate::{CodeInfo, Error};
2use codec::{Compact, Decode};
3use futures::StreamExt;
4use jam_program_blob_common::{ConventionalMetadata as Metadata, CrateInfo};
5use jam_std_common::{Node, NodeError, NodeExt as _, Service, SyncStatus};
6use jam_types::{HeaderHash, ServiceId};
7use std::future::Future;
8
9pub trait NodeExt: Node {
10 fn query_service(
11 &self,
12 head: HeaderHash,
13 id: ServiceId,
14 ) -> impl Future<Output = Result<(Service, CodeInfo<CrateInfo>), anyhow::Error>> + Send {
15 async move {
16 use CodeInfo::*;
17 let info = self.service_data(head, id).await?.ok_or(Error::ServiceNotFound)?;
18 let maybe_code = self.service_preimage(head, id, info.code_hash.0).await?;
19 let meta = match maybe_code {
20 None => CodeNotProvided(info.code_hash.0),
21 Some(code) =>
22 match <(Compact<u32>, Metadata)>::decode(&mut &code[..]).ok().map(|x| x.1) {
23 None => Undefined(info.code_hash.0),
24 Some(Metadata::Info(crate_info)) => Known(crate_info),
25 },
26 };
27 Ok((info, meta))
28 }
29 }
30
31 fn wait_for_sync(&self) -> impl Future<Output = Result<(), anyhow::Error>> + Send {
32 async move {
33 let mut sync_state = self.subscribe_sync_status().await?;
34 loop {
35 let status = sync_state.next().await;
36 match status {
37 Some(Ok(SyncStatus::Completed)) => break,
38 Some(Ok(_)) => continue,
39 Some(Err(e)) => return Err(e.into()),
40 None => break,
41 }
42 }
43 let mut final_block = self.subscribe_finalized_block().await?;
45 loop {
46 let status = final_block.next().await;
47 match status {
48 Some(Ok(block)) if block.slot > 0 => {
49 match self.parent(block.header_hash).await {
50 Ok(parent) => {
51 if parent.slot > 0 {
52 break;
55 }
56 eprintln!("Waiting for two non-genesis blocks to be finalized...");
57 },
58 Err(NodeError::BlockUnavailable(_)) => {
59 eprintln!("Waiting for two non-genesis blocks to be finalized and available...");
61 },
62 Err(err) => return Err(err.into()),
63 }
64 },
65 Some(Ok(_)) => {
66 eprintln!("Waiting for two non-genesis blocks to be finalized...");
67 },
68 Some(Err(e)) => return Err(e.into()),
69 None => break,
70 }
71 }
72 Ok(())
73 }
74 }
75}
76
77impl<T: Node + ?Sized> NodeExt for T {}