| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- #![cfg_attr(
- not(feature = "agave-unstable-api"),
- deprecated(
- since = "3.1.0",
- note = "This crate has been marked for formal inclusion in the Agave Unstable API. From \
- v4.0.0 onward, the `agave-unstable-api` crate feature must be specified to \
- acknowledge use of an interface that may break without warning."
- )
- )]
- #![cfg_attr(feature = "frozen-abi", feature(min_specialization))]
- pub use self::legacy::{LegacyVersion1, LegacyVersion2};
- use {
- rand::{thread_rng, Rng},
- serde::{Deserialize, Serialize},
- solana_sanitize::Sanitize,
- solana_serde_varint as serde_varint,
- std::{convert::TryInto, fmt},
- };
- #[cfg_attr(feature = "frozen-abi", macro_use)]
- #[cfg(feature = "frozen-abi")]
- extern crate solana_frozen_abi_macro;
- mod legacy;
- #[derive(Debug, Eq, PartialEq)]
- pub enum ClientId {
- SolanaLabs,
- JitoLabs,
- Frankendancer,
- Agave,
- AgavePaladin,
- Firedancer,
- AgaveBam,
- Sig,
- // If new variants are added, update From<u16> and TryFrom<ClientId>.
- Unknown(u16),
- }
- #[cfg_attr(feature = "frozen-abi", derive(AbiExample))]
- #[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
- pub struct Version {
- #[serde(with = "serde_varint")]
- pub major: u16,
- #[serde(with = "serde_varint")]
- pub minor: u16,
- #[serde(with = "serde_varint")]
- pub patch: u16,
- pub commit: u32, // first 4 bytes of the sha1 commit hash
- pub feature_set: u32, // first 4 bytes of the FeatureSet identifier
- #[serde(with = "serde_varint")]
- client: u16,
- }
- impl Version {
- pub fn as_semver_version(&self) -> semver::Version {
- semver::Version::new(self.major as u64, self.minor as u64, self.patch as u64)
- }
- pub fn client(&self) -> ClientId {
- ClientId::from(self.client)
- }
- }
- fn compute_commit(sha1: Option<&'static str>) -> Option<u32> {
- u32::from_str_radix(sha1?.get(..8)?, /*radix:*/ 16).ok()
- }
- impl Default for Version {
- fn default() -> Self {
- let feature_set =
- u32::from_le_bytes(agave_feature_set::ID.as_ref()[..4].try_into().unwrap());
- Self {
- major: env!("CARGO_PKG_VERSION_MAJOR").parse().unwrap(),
- minor: env!("CARGO_PKG_VERSION_MINOR").parse().unwrap(),
- patch: env!("CARGO_PKG_VERSION_PATCH").parse().unwrap(),
- commit: compute_commit(option_env!("CI_COMMIT"))
- .or(compute_commit(option_env!("AGAVE_GIT_COMMIT_HASH")))
- .unwrap_or_else(|| thread_rng().gen::<u32>()),
- feature_set,
- // Other client implementations need to modify this line.
- client: u16::try_from(ClientId::Agave).unwrap(),
- }
- }
- }
- impl fmt::Display for Version {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}.{}.{}", self.major, self.minor, self.patch,)
- }
- }
- impl fmt::Debug for Version {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(
- f,
- "{}.{}.{} (src:{:08x}; feat:{}, client:{:?})",
- self.major,
- self.minor,
- self.patch,
- self.commit,
- self.feature_set,
- self.client(),
- )
- }
- }
- impl Sanitize for Version {}
- impl From<u16> for ClientId {
- fn from(client: u16) -> Self {
- match client {
- 0u16 => Self::SolanaLabs,
- 1u16 => Self::JitoLabs,
- 2u16 => Self::Frankendancer,
- 3u16 => Self::Agave,
- 4u16 => Self::AgavePaladin,
- 5u16 => Self::Firedancer,
- 6u16 => Self::AgaveBam,
- 7u16 => Self::Sig,
- _ => Self::Unknown(client),
- }
- }
- }
- impl TryFrom<ClientId> for u16 {
- type Error = String;
- fn try_from(client: ClientId) -> Result<Self, Self::Error> {
- match client {
- ClientId::SolanaLabs => Ok(0u16),
- ClientId::JitoLabs => Ok(1u16),
- ClientId::Frankendancer => Ok(2u16),
- ClientId::Agave => Ok(3u16),
- ClientId::AgavePaladin => Ok(4u16),
- ClientId::Firedancer => Ok(5u16),
- ClientId::AgaveBam => Ok(6u16),
- ClientId::Sig => Ok(7u16),
- ClientId::Unknown(client @ 0u16..=7u16) => Err(format!("Invalid client: {client}")),
- ClientId::Unknown(client) => Ok(client),
- }
- }
- }
- #[macro_export]
- macro_rules! semver {
- () => {
- &*format!("{}", $crate::Version::default())
- };
- }
- #[macro_export]
- macro_rules! version {
- () => {
- &*format!("{:?}", $crate::Version::default())
- };
- }
- #[cfg(test)]
- mod test {
- use super::*;
- #[test]
- fn test_compute_commit() {
- assert_eq!(compute_commit(None), None);
- assert_eq!(compute_commit(Some("1234567890")), Some(0x1234_5678));
- assert_eq!(compute_commit(Some("HEAD")), None);
- assert_eq!(compute_commit(Some("garbagein")), None);
- }
- #[test]
- fn test_client_id() {
- assert_eq!(ClientId::from(0u16), ClientId::SolanaLabs);
- assert_eq!(ClientId::from(1u16), ClientId::JitoLabs);
- assert_eq!(ClientId::from(2u16), ClientId::Frankendancer);
- assert_eq!(ClientId::from(3u16), ClientId::Agave);
- assert_eq!(ClientId::from(4u16), ClientId::AgavePaladin);
- assert_eq!(ClientId::from(5u16), ClientId::Firedancer);
- assert_eq!(ClientId::from(6u16), ClientId::AgaveBam);
- assert_eq!(ClientId::from(7u16), ClientId::Sig);
- for client in 8u16..=u16::MAX {
- assert_eq!(ClientId::from(client), ClientId::Unknown(client));
- }
- assert_eq!(u16::try_from(ClientId::SolanaLabs), Ok(0u16));
- assert_eq!(u16::try_from(ClientId::JitoLabs), Ok(1u16));
- assert_eq!(u16::try_from(ClientId::Frankendancer), Ok(2u16));
- assert_eq!(u16::try_from(ClientId::Agave), Ok(3u16));
- assert_eq!(u16::try_from(ClientId::AgavePaladin), Ok(4u16));
- assert_eq!(u16::try_from(ClientId::Firedancer), Ok(5u16));
- assert_eq!(u16::try_from(ClientId::AgaveBam), Ok(6u16));
- assert_eq!(u16::try_from(ClientId::Sig), Ok(7u16));
- for client in 0..=7u16 {
- assert_eq!(
- u16::try_from(ClientId::Unknown(client)),
- Err(format!("Invalid client: {client}"))
- );
- }
- for client in 8u16..=u16::MAX {
- assert_eq!(u16::try_from(ClientId::Unknown(client)), Ok(client));
- }
- }
- }
|