use rbtag::BuildInfo;
use sp_runtime::traits::TryConvert;
use std::str::FromStr;
use structopt::StructOpt;
pub mod bridge;
pub mod chain_schema;
pub mod detect_equivocations;
pub mod init_bridge;
pub mod relay_headers;
pub mod relay_headers_and_messages;
pub mod relay_messages;
pub mod relay_parachains;
pub const LOG_TARGET: &str = "bridge";
pub type DefaultClient<C> = relay_substrate_client::RpcWithCachingClient<C>;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HexLaneId(Vec<u8>);
impl<T: TryFrom<Vec<u8>>> TryConvert<HexLaneId, T> for HexLaneId {
fn try_convert(lane_id: HexLaneId) -> Result<T, HexLaneId> {
T::try_from(lane_id.0.clone()).map_err(|_| lane_id)
}
}
impl FromStr for HexLaneId {
type Err = hex::FromHexError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
hex::decode(s).map(Self)
}
}
#[derive(Clone, Debug, PartialEq, StructOpt)]
pub struct PrometheusParams {
#[structopt(long)]
pub no_prometheus: bool,
#[structopt(long, default_value = "127.0.0.1")]
pub prometheus_host: String,
#[structopt(long, default_value = "9616")]
pub prometheus_port: u16,
}
#[derive(BuildInfo)]
struct SubstrateRelayBuildInfo;
impl SubstrateRelayBuildInfo {
pub fn get_git_commit() -> String {
let maybe_sha_from_ci = option_env!("CI_COMMIT_SHORT_SHA");
maybe_sha_from_ci
.map(|short_sha| {
format!("{short_sha}-clean")
})
.unwrap_or_else(|| SubstrateRelayBuildInfo.get_build_commit().into())
}
}
impl PrometheusParams {
pub fn into_metrics_params(self) -> anyhow::Result<relay_utils::metrics::MetricsParams> {
let metrics_address = if !self.no_prometheus {
Some(relay_utils::metrics::MetricsAddress {
host: self.prometheus_host,
port: self.prometheus_port,
})
} else {
None
};
let relay_version = relay_utils::initialize::RELAYER_VERSION
.lock()
.clone()
.unwrap_or_else(|| "unknown".to_string());
let relay_commit = SubstrateRelayBuildInfo::get_git_commit();
relay_utils::metrics::MetricsParams::new(metrics_address, relay_version, relay_commit)
.map_err(|e| anyhow::format_err!("{:?}", e))
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ExplicitOrMaximal<V> {
Explicit(V),
Maximal,
}
impl<V: std::str::FromStr> std::str::FromStr for ExplicitOrMaximal<V>
where
V::Err: std::fmt::Debug,
{
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.to_lowercase() == "max" {
return Ok(ExplicitOrMaximal::Maximal)
}
V::from_str(s)
.map(ExplicitOrMaximal::Explicit)
.map_err(|e| format!("Failed to parse '{e:?}'. Expected 'max' or explicit value"))
}
}
#[cfg(test)]
mod tests {
use super::*;
use bp_messages::{HashedLaneId, LegacyLaneId};
use sp_core::H256;
#[test]
fn hex_lane_id_from_str_works() {
assert!(HexLaneId::from_str(
"101010101010101010101010101010101010101010101010101010101010101"
)
.is_err());
assert!(HexLaneId::from_str(
"00101010101010101010101010101010101010101010101010101010101010101"
)
.is_err());
assert_eq!(
HexLaneId::try_convert(
HexLaneId::from_str(
"0101010101010101010101010101010101010101010101010101010101010101"
)
.unwrap()
),
Ok(HashedLaneId::from_inner(H256::from([1u8; 32])))
);
assert!(HexLaneId::from_str("0000001").is_err());
assert!(HexLaneId::from_str("000000001").is_err());
assert_eq!(
HexLaneId::try_convert(HexLaneId::from_str("00000001").unwrap()),
Ok(LegacyLaneId([0, 0, 0, 1]))
);
}
}