substrate_relay_helper/cli/
mod.rs1use clap::Parser;
20use rbtag::BuildInfo;
21use sp_runtime::traits::TryConvert;
22use std::str::FromStr;
23
24pub mod bridge;
25pub mod chain_schema;
26pub mod detect_equivocations;
27pub mod init_bridge;
28pub mod relay_headers;
29pub mod relay_headers_and_messages;
30pub mod relay_messages;
31pub mod relay_parachains;
32
33pub const LOG_TARGET: &str = "bridge";
35
36pub type DefaultClient<C> = relay_substrate_client::RpcWithCachingClient<C>;
40
41#[derive(Debug, Clone, PartialEq, Eq)]
43pub struct HexLaneId(Vec<u8>);
44
45impl<T: TryFrom<Vec<u8>>> TryConvert<HexLaneId, T> for HexLaneId {
46 fn try_convert(lane_id: HexLaneId) -> Result<T, HexLaneId> {
47 T::try_from(lane_id.0.clone()).map_err(|_| lane_id)
48 }
49}
50
51impl FromStr for HexLaneId {
52 type Err = hex::FromHexError;
53
54 fn from_str(s: &str) -> Result<Self, Self::Err> {
55 hex::decode(s).map(Self)
56 }
57}
58
59#[derive(Clone, Debug, PartialEq, Parser)]
61pub struct PrometheusParams {
62 #[arg(long)]
64 pub no_prometheus: bool,
65 #[arg(long, default_value = "127.0.0.1")]
67 pub prometheus_host: String,
68 #[arg(long, default_value = "9616")]
70 pub prometheus_port: u16,
71}
72
73#[derive(BuildInfo)]
75struct SubstrateRelayBuildInfo;
76
77impl SubstrateRelayBuildInfo {
78 pub fn get_git_commit() -> String {
80 let maybe_sha_from_ci = option_env!("CI_COMMIT_SHORT_SHA");
84 maybe_sha_from_ci
85 .map(|short_sha| {
86 format!("{short_sha}-clean")
88 })
89 .unwrap_or_else(|| SubstrateRelayBuildInfo.get_build_commit().into())
90 }
91}
92
93impl PrometheusParams {
94 pub fn into_metrics_params(self) -> anyhow::Result<relay_utils::metrics::MetricsParams> {
96 let metrics_address = if !self.no_prometheus {
97 Some(relay_utils::metrics::MetricsAddress {
98 host: self.prometheus_host,
99 port: self.prometheus_port,
100 })
101 } else {
102 None
103 };
104
105 let relay_version = relay_utils::initialize::RELAYER_VERSION
106 .lock()
107 .clone()
108 .unwrap_or_else(|| "unknown".to_string());
109 let relay_commit = SubstrateRelayBuildInfo::get_git_commit();
110 relay_utils::metrics::MetricsParams::new(metrics_address, relay_version, relay_commit)
111 .map_err(|e| anyhow::format_err!("{:?}", e))
112 }
113}
114
115#[derive(Debug, Clone, PartialEq, Eq)]
117pub enum ExplicitOrMaximal<V> {
118 Explicit(V),
120 Maximal,
122}
123
124impl<V: std::str::FromStr> std::str::FromStr for ExplicitOrMaximal<V>
125where
126 V::Err: std::fmt::Debug,
127{
128 type Err = String;
129
130 fn from_str(s: &str) -> Result<Self, Self::Err> {
131 if s.to_lowercase() == "max" {
132 return Ok(ExplicitOrMaximal::Maximal)
133 }
134
135 V::from_str(s)
136 .map(ExplicitOrMaximal::Explicit)
137 .map_err(|e| format!("Failed to parse '{e:?}'. Expected 'max' or explicit value"))
138 }
139}
140
141#[cfg(test)]
142mod tests {
143 use super::*;
144 use bp_messages::{HashedLaneId, LegacyLaneId};
145 use sp_core::H256;
146
147 #[test]
148 fn hex_lane_id_from_str_works() {
149 assert!(HexLaneId::from_str(
151 "101010101010101010101010101010101010101010101010101010101010101"
152 )
153 .is_err());
154 assert!(HexLaneId::from_str(
155 "00101010101010101010101010101010101010101010101010101010101010101"
156 )
157 .is_err());
158 assert_eq!(
159 HexLaneId::try_convert(
160 HexLaneId::from_str(
161 "0101010101010101010101010101010101010101010101010101010101010101"
162 )
163 .unwrap()
164 ),
165 Ok(HashedLaneId::from_inner(H256::from([1u8; 32])))
166 );
167
168 assert!(HexLaneId::from_str("0000001").is_err());
170 assert!(HexLaneId::from_str("000000001").is_err());
171 assert_eq!(
172 HexLaneId::try_convert(HexLaneId::from_str("00000001").unwrap()),
173 Ok(LegacyLaneId([0, 0, 0, 1]))
174 );
175 }
176}