pezframe_benchmarking_cli/overhead/
remark_builder.rs1use crate::extrinsic::ExtrinsicBuilder;
19use codec::{Decode, Encode};
20use pezkuwi_subxt::{
21 client::RuntimeVersion as SubxtRuntimeVersion,
22 config::{bizinikiwi::BizinikiwiExtrinsicParamsBuilder as ParamsBuilder, HashFor},
23 BizinikiwConfig, Config, OfflineClient,
24};
25use pezsc_client_api::UsageProvider;
26use pezsp_api::{ApiExt, Core, Metadata, ProvideRuntimeApi};
27use pezsp_runtime::{traits::Block as BlockT, OpaqueExtrinsic};
28use std::sync::Arc;
29
30pub type BizinikiwiConfig = BizinikiwConfig;
32pub type BizinikiwiExtrinsicParamsBuilder = ParamsBuilder<BizinikiwiConfig>;
34
35pub type BizinikiwiRemarkBuilder = DynamicRemarkBuilder<BizinikiwiConfig>;
36
37pub struct DynamicRemarkBuilder<C: Config> {
40 offline_client: OfflineClient<C>,
41}
42
43impl<C: Config> DynamicRemarkBuilder<C> {
44 pub fn new_from_client<Client, Block>(client: Arc<Client>) -> pezsc_cli::Result<Self>
49 where
50 Block: BlockT,
51 Client: UsageProvider<Block> + ProvideRuntimeApi<Block>,
52 Client::Api: Metadata<Block> + Core<Block>,
53 {
54 let genesis = client.usage_info().chain.best_hash;
55 let api = client.runtime_api();
56
57 let Ok(Some(metadata_api_version)) = api.api_version::<dyn Metadata<Block>>(genesis) else {
58 return Err("Unable to fetch metadata runtime API version.".to_string().into());
59 };
60
61 log::debug!("Found metadata API version {}.", metadata_api_version);
62 let opaque_metadata = if metadata_api_version > 1 {
63 let Ok(supported_metadata_versions) = api.metadata_versions(genesis) else {
64 return Err("Unable to fetch metadata versions".to_string().into());
65 };
66
67 let latest = supported_metadata_versions
68 .into_iter()
69 .max()
70 .ok_or("No stable metadata versions supported".to_string())?;
71
72 api.metadata_at_version(genesis, latest)
73 .map_err(|e| format!("Unable to fetch metadata: {:?}", e))?
74 .ok_or("Unable to decode metadata".to_string())?
75 } else {
76 api.metadata(genesis)
78 .map_err(|e| format!("Unable to fetch metadata: {:?}", e))?
79 };
80
81 let version = api.version(genesis).unwrap();
82 let runtime_version = SubxtRuntimeVersion {
83 spec_version: version.spec_version,
84 transaction_version: version.transaction_version,
85 };
86 let metadata = pezkuwi_subxt::Metadata::decode(&mut (*opaque_metadata).as_slice())?;
87 let genesis = HashFor::<C>::decode(&mut &genesis.encode()[..])
88 .map_err(|_| "Incompatible hash types?")?;
89
90 Ok(Self { offline_client: OfflineClient::new(genesis, runtime_version, metadata) })
91 }
92}
93
94impl<C: Config> DynamicRemarkBuilder<C> {
95 pub fn new(
97 metadata: pezkuwi_subxt::Metadata,
98 genesis_hash: HashFor<C>,
99 runtime_version: SubxtRuntimeVersion,
100 ) -> Self {
101 Self { offline_client: OfflineClient::new(genesis_hash, runtime_version, metadata) }
102 }
103}
104
105impl ExtrinsicBuilder for DynamicRemarkBuilder<BizinikiwiConfig> {
106 fn pezpallet(&self) -> &str {
107 "system"
108 }
109
110 fn extrinsic(&self) -> &str {
111 "remark"
112 }
113
114 fn build(&self, nonce: u32) -> std::result::Result<OpaqueExtrinsic, &'static str> {
115 let signer = pezkuwi_subxt_signer::sr25519::dev::alice();
116 let dynamic_tx = pezkuwi_subxt::dynamic::tx("System", "remark", vec![Vec::<u8>::new()]);
117
118 let params = BizinikiwiExtrinsicParamsBuilder::new().nonce(nonce.into()).build();
119
120 let transaction = self
122 .offline_client
123 .tx()
124 .create_partial_offline(&dynamic_tx, params)
125 .unwrap()
126 .sign(&signer);
127 let mut encoded = transaction.into_encoded();
128
129 OpaqueExtrinsic::try_from_encoded_extrinsic(&mut encoded)
130 .map_err(|_| "Unable to construct OpaqueExtrinsic")
131 }
132}