adds new solana_version::Version with ClientId (#29649)
This commit is contained in:
parent
f24e30e4fe
commit
0941d133a8
|
@ -267,7 +267,7 @@ pub fn make_accounts_hashes_message(
|
||||||
pub(crate) type Ping = ping_pong::Ping<[u8; GOSSIP_PING_TOKEN_SIZE]>;
|
pub(crate) type Ping = ping_pong::Ping<[u8; GOSSIP_PING_TOKEN_SIZE]>;
|
||||||
|
|
||||||
// TODO These messages should go through the gpu pipeline for spam filtering
|
// TODO These messages should go through the gpu pipeline for spam filtering
|
||||||
#[frozen_abi(digest = "Hsj6a2bmzxno1RUcSM1gzHAg2zxgw15E3feb2SimieBA")]
|
#[frozen_abi(digest = "Aui5aMV3SK41tRQN14sgCMK3qp6r9dboLXNAHEBKFzii")]
|
||||||
#[derive(Serialize, Deserialize, Debug, AbiEnumVisitor, AbiExample)]
|
#[derive(Serialize, Deserialize, Debug, AbiEnumVisitor, AbiExample)]
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
pub(crate) enum Protocol {
|
pub(crate) enum Protocol {
|
||||||
|
@ -1240,7 +1240,7 @@ impl ClusterInfo {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_node_version(&self, pubkey: &Pubkey) -> Option<solana_version::Version> {
|
pub fn get_node_version(&self, pubkey: &Pubkey) -> Option<solana_version::LegacyVersion2> {
|
||||||
let gossip_crds = self.gossip.crds.read().unwrap();
|
let gossip_crds = self.gossip.crds.read().unwrap();
|
||||||
if let Some(version) = gossip_crds.get::<&Version>(*pubkey) {
|
if let Some(version) = gossip_crds.get::<&Version>(*pubkey) {
|
||||||
return Some(version.version.clone());
|
return Some(version.version.clone());
|
||||||
|
|
|
@ -359,7 +359,7 @@ impl<'de> Deserialize<'de> for Vote {
|
||||||
pub struct LegacyVersion {
|
pub struct LegacyVersion {
|
||||||
pub from: Pubkey,
|
pub from: Pubkey,
|
||||||
pub wallclock: u64,
|
pub wallclock: u64,
|
||||||
pub version: solana_version::LegacyVersion,
|
pub version: solana_version::LegacyVersion1,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sanitize for LegacyVersion {
|
impl Sanitize for LegacyVersion {
|
||||||
|
@ -374,7 +374,7 @@ impl Sanitize for LegacyVersion {
|
||||||
pub struct Version {
|
pub struct Version {
|
||||||
pub from: Pubkey,
|
pub from: Pubkey,
|
||||||
pub wallclock: u64,
|
pub wallclock: u64,
|
||||||
pub version: solana_version::Version,
|
pub version: solana_version::LegacyVersion2,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sanitize for Version {
|
impl Sanitize for Version {
|
||||||
|
@ -390,7 +390,7 @@ impl Version {
|
||||||
Self {
|
Self {
|
||||||
from,
|
from,
|
||||||
wallclock: timestamp(),
|
wallclock: timestamp(),
|
||||||
version: solana_version::Version::default(),
|
version: solana_version::LegacyVersion2::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,7 +399,7 @@ impl Version {
|
||||||
Self {
|
Self {
|
||||||
from: pubkey.unwrap_or_else(pubkey::new_rand),
|
from: pubkey.unwrap_or_else(pubkey::new_rand),
|
||||||
wallclock: new_rand_timestamp(rng),
|
wallclock: new_rand_timestamp(rng),
|
||||||
version: solana_version::Version {
|
version: solana_version::LegacyVersion2 {
|
||||||
major: rng.gen(),
|
major: rng.gen(),
|
||||||
minor: rng.gen(),
|
minor: rng.gen(),
|
||||||
patch: rng.gen(),
|
patch: rng.gen(),
|
||||||
|
|
|
@ -49,9 +49,9 @@ pub use solana_program::{
|
||||||
decode_error, ed25519_program, epoch_schedule, fee_calculator, impl_sysvar_get, incinerator,
|
decode_error, ed25519_program, epoch_schedule, fee_calculator, impl_sysvar_get, incinerator,
|
||||||
instruction, keccak, lamports, loader_instruction, loader_upgradeable_instruction, message,
|
instruction, keccak, lamports, loader_instruction, loader_upgradeable_instruction, message,
|
||||||
msg, native_token, nonce, program, program_error, program_memory, program_option, program_pack,
|
msg, native_token, nonce, program, program_error, program_memory, program_option, program_pack,
|
||||||
rent, sanitize, sdk_ids, secp256k1_program, secp256k1_recover, serialize_utils, short_vec,
|
rent, sanitize, sdk_ids, secp256k1_program, secp256k1_recover, serde_varint, serialize_utils,
|
||||||
slot_hashes, slot_history, stake, stake_history, syscalls, system_instruction, system_program,
|
short_vec, slot_hashes, slot_history, stake, stake_history, syscalls, system_instruction,
|
||||||
sysvar, unchecked_div_by_const, vote, wasm_bindgen,
|
system_program, sysvar, unchecked_div_by_const, vote, wasm_bindgen,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod account;
|
pub mod account;
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
use {
|
||||||
|
crate::compute_commit,
|
||||||
|
serde_derive::{Deserialize, Serialize},
|
||||||
|
solana_sdk::sanitize::Sanitize,
|
||||||
|
std::{convert::TryInto, fmt},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Older version structure used earlier 1.3.x releases
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, AbiExample)]
|
||||||
|
pub struct LegacyVersion1 {
|
||||||
|
major: u16,
|
||||||
|
minor: u16,
|
||||||
|
patch: u16,
|
||||||
|
commit: Option<u32>, // first 4 bytes of the sha1 commit hash
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sanitize for LegacyVersion1 {}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, AbiExample)]
|
||||||
|
pub struct LegacyVersion2 {
|
||||||
|
pub major: u16,
|
||||||
|
pub minor: u16,
|
||||||
|
pub patch: u16,
|
||||||
|
pub commit: Option<u32>, // first 4 bytes of the sha1 commit hash
|
||||||
|
pub feature_set: u32, // first 4 bytes of the FeatureSet identifier
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<LegacyVersion1> for LegacyVersion2 {
|
||||||
|
fn from(legacy_version: LegacyVersion1) -> Self {
|
||||||
|
Self {
|
||||||
|
major: legacy_version.major,
|
||||||
|
minor: legacy_version.minor,
|
||||||
|
patch: legacy_version.patch,
|
||||||
|
commit: legacy_version.commit,
|
||||||
|
feature_set: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for LegacyVersion2 {
|
||||||
|
fn default() -> Self {
|
||||||
|
let feature_set = u32::from_le_bytes(
|
||||||
|
solana_sdk::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")),
|
||||||
|
feature_set,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for LegacyVersion2 {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "{}.{}.{}", self.major, self.minor, self.patch,)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for LegacyVersion2 {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"{}.{}.{} (src:{}; feat:{})",
|
||||||
|
self.major,
|
||||||
|
self.minor,
|
||||||
|
self.patch,
|
||||||
|
match self.commit {
|
||||||
|
None => "devbuild".to_string(),
|
||||||
|
Some(commit) => format!("{commit:08x}"),
|
||||||
|
},
|
||||||
|
self.feature_set,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sanitize for LegacyVersion2 {}
|
|
@ -1,59 +1,52 @@
|
||||||
#![cfg_attr(RUSTC_WITH_SPECIALIZATION, feature(min_specialization))]
|
#![cfg_attr(RUSTC_WITH_SPECIALIZATION, feature(min_specialization))]
|
||||||
|
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
pub use self::legacy::{LegacyVersion1, LegacyVersion2};
|
||||||
use {
|
use {
|
||||||
serde_derive::{Deserialize, Serialize},
|
serde_derive::{Deserialize, Serialize},
|
||||||
solana_sdk::sanitize::Sanitize,
|
solana_sdk::{sanitize::Sanitize, serde_varint},
|
||||||
std::{convert::TryInto, fmt},
|
std::{convert::TryInto, fmt},
|
||||||
};
|
};
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate solana_frozen_abi_macro;
|
extern crate solana_frozen_abi_macro;
|
||||||
|
|
||||||
// Older version structure used earlier 1.3.x releases
|
mod legacy;
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, AbiExample)]
|
|
||||||
pub struct LegacyVersion {
|
|
||||||
major: u16,
|
|
||||||
minor: u16,
|
|
||||||
patch: u16,
|
|
||||||
commit: Option<u32>, // first 4 bytes of the sha1 commit hash
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Sanitize for LegacyVersion {}
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
enum ClientId {
|
||||||
|
SolanaLabs,
|
||||||
|
JitoLabs,
|
||||||
|
Firedancer,
|
||||||
|
// If new variants are added, update From<u16> and TryFrom<ClientId>.
|
||||||
|
Unknown(u16),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, AbiExample)]
|
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, AbiExample)]
|
||||||
pub struct Version {
|
pub struct Version {
|
||||||
|
#[serde(with = "serde_varint")]
|
||||||
pub major: u16,
|
pub major: u16,
|
||||||
|
#[serde(with = "serde_varint")]
|
||||||
pub minor: u16,
|
pub minor: u16,
|
||||||
|
#[serde(with = "serde_varint")]
|
||||||
pub patch: u16,
|
pub patch: u16,
|
||||||
pub commit: Option<u32>, // first 4 bytes of the sha1 commit hash
|
pub commit: u32, // first 4 bytes of the sha1 commit hash
|
||||||
pub feature_set: u32, // first 4 bytes of the FeatureSet identifier
|
pub feature_set: u32, // first 4 bytes of the FeatureSet identifier
|
||||||
|
#[serde(with = "serde_varint")]
|
||||||
|
client: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Version {
|
impl Version {
|
||||||
pub fn as_semver_version(&self) -> semver::Version {
|
pub fn as_semver_version(&self) -> semver::Version {
|
||||||
semver::Version::new(self.major as u64, self.minor as u64, self.patch as u64)
|
semver::Version::new(self.major as u64, self.minor as u64, self.patch as u64)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl From<LegacyVersion> for Version {
|
fn client(&self) -> ClientId {
|
||||||
fn from(legacy_version: LegacyVersion) -> Self {
|
ClientId::from(self.client)
|
||||||
Self {
|
|
||||||
major: legacy_version.major,
|
|
||||||
minor: legacy_version.minor,
|
|
||||||
patch: legacy_version.patch,
|
|
||||||
commit: legacy_version.commit,
|
|
||||||
feature_set: 0,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_commit(sha1: Option<&'static str>) -> Option<u32> {
|
fn compute_commit(sha1: Option<&'static str>) -> Option<u32> {
|
||||||
let sha1 = sha1?;
|
u32::from_str_radix(sha1?.get(..8)?, /*radix:*/ 16).ok()
|
||||||
if sha1.len() < 8 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
u32::from_str_radix(&sha1[..8], 16).ok()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Version {
|
impl Default for Version {
|
||||||
|
@ -67,8 +60,10 @@ impl Default for Version {
|
||||||
major: env!("CARGO_PKG_VERSION_MAJOR").parse().unwrap(),
|
major: env!("CARGO_PKG_VERSION_MAJOR").parse().unwrap(),
|
||||||
minor: env!("CARGO_PKG_VERSION_MINOR").parse().unwrap(),
|
minor: env!("CARGO_PKG_VERSION_MINOR").parse().unwrap(),
|
||||||
patch: env!("CARGO_PKG_VERSION_PATCH").parse().unwrap(),
|
patch: env!("CARGO_PKG_VERSION_PATCH").parse().unwrap(),
|
||||||
commit: compute_commit(option_env!("CI_COMMIT")),
|
commit: compute_commit(option_env!("CI_COMMIT")).unwrap_or_default(),
|
||||||
feature_set,
|
feature_set,
|
||||||
|
// Other client implementations need to modify this line.
|
||||||
|
client: u16::try_from(ClientId::SolanaLabs).unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,21 +78,44 @@ impl fmt::Debug for Version {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}.{}.{} (src:{}; feat:{})",
|
"{}.{}.{} (src:{:08x}; feat:{}, client:{:?})",
|
||||||
self.major,
|
self.major,
|
||||||
self.minor,
|
self.minor,
|
||||||
self.patch,
|
self.patch,
|
||||||
match self.commit {
|
self.commit,
|
||||||
None => "devbuild".to_string(),
|
|
||||||
Some(commit) => format!("{commit:08x}"),
|
|
||||||
},
|
|
||||||
self.feature_set,
|
self.feature_set,
|
||||||
|
self.client(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sanitize for Version {}
|
impl Sanitize for Version {}
|
||||||
|
|
||||||
|
impl From<u16> for ClientId {
|
||||||
|
fn from(client: u16) -> Self {
|
||||||
|
match client {
|
||||||
|
0u16 => Self::SolanaLabs,
|
||||||
|
1u16 => Self::JitoLabs,
|
||||||
|
2u16 => Self::Firedancer,
|
||||||
|
_ => 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::Firedancer => Ok(2u16),
|
||||||
|
ClientId::Unknown(client @ 0u16..=2u16) => Err(format!("Invalid client: {client}")),
|
||||||
|
ClientId::Unknown(client) => Ok(client),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! semver {
|
macro_rules! semver {
|
||||||
() => {
|
() => {
|
||||||
|
@ -123,4 +141,26 @@ mod test {
|
||||||
assert_eq!(compute_commit(Some("HEAD")), None);
|
assert_eq!(compute_commit(Some("HEAD")), None);
|
||||||
assert_eq!(compute_commit(Some("garbagein")), 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::Firedancer);
|
||||||
|
for client in 3u16..=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::Firedancer), Ok(2u16));
|
||||||
|
for client in 0..=2u16 {
|
||||||
|
assert_eq!(
|
||||||
|
u16::try_from(ClientId::Unknown(client)),
|
||||||
|
Err(format!("Invalid client: {client}"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for client in 3u16..=u16::MAX {
|
||||||
|
assert_eq!(u16::try_from(ClientId::Unknown(client)), Ok(client));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue