-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
adds new contact-info with forward compatible sockets
- Loading branch information
1 parent
3234af4
commit b74c948
Showing
8 changed files
with
165 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
pub use crate::legacy_contact_info::LegacyContactInfo; | ||
use { | ||
crate::crds_value::MAX_WALLCLOCK, | ||
serde::{Deserialize, Deserializer, Serialize, Serializer}, | ||
solana_sdk::{ | ||
pubkey::Pubkey, | ||
sanitize::{Sanitize, SanitizeError}, | ||
serde_varint, short_vec, | ||
}, | ||
std::{ | ||
borrow::Cow, | ||
net::{IpAddr, SocketAddr}, | ||
}, | ||
}; | ||
|
||
const SOCKET_TAG_GOSSIP: u8 = 0u8; | ||
const SOCKET_TAG_REPAIR: u8 = 1u8; | ||
const SOCKET_TAG_RPC: u8 = 2u8; | ||
const SOCKET_TAG_RPC_PUBSUB: u8 = 3u8; | ||
const SOCKET_TAG_SERVE_REPAIR: u8 = 4u8; | ||
const SOCKET_TAG_TPU: u8 = 5u8; | ||
const SOCKET_TAG_TPU_FORWARDS: u8 = 6u8; | ||
const SOCKET_TAG_TPU_VOTE: u8 = 7u8; | ||
const SOCKET_TAG_TVU: u8 = 8u8; | ||
const SOCKET_TAG_TVU_FORWARDS: u8 = 9u8; | ||
|
||
#[derive(Clone, Debug, Default, Eq, PartialEq)] | ||
pub struct ContactInfo { | ||
pubkey: Pubkey, | ||
wallclock: u64, | ||
shred_version: u16, | ||
addrs: Vec<IpAddr>, | ||
// TODO: use port offset with varint? should be sorted! | ||
sockets: Vec<(/*tag:*/ u8, /*addr-idx:*/ u8, /*port:*/ u16)>, | ||
// TODO: should this also include Version? | ||
gossip: Option<SocketAddr>, | ||
repair: Option<SocketAddr>, | ||
rpc: Option<SocketAddr>, | ||
rpc_pubsub: Option<SocketAddr>, | ||
serve_repair: Option<SocketAddr>, | ||
tpu: Option<SocketAddr>, | ||
tpu_forwards: Option<SocketAddr>, | ||
tpu_vote: Option<SocketAddr>, | ||
tvu: Option<SocketAddr>, | ||
tvu_forwards: Option<SocketAddr>, | ||
} | ||
|
||
// Workaround since serde does not have an initializer for skipped fields. | ||
// https://github.com/serde-rs/serde/issues/642 | ||
#[derive(Deserialize, Serialize)] | ||
struct ContactInfoLite<'a> { | ||
pubkey: Cow<'a, Pubkey>, | ||
#[serde(with = "serde_varint")] | ||
wallclock: u64, | ||
shred_version: u16, | ||
#[serde(with = "short_vec")] | ||
addrs: Cow<'a, [IpAddr]>, | ||
#[serde(with = "short_vec")] | ||
sockets: Cow<'a, [(u8, u8, u16)]>, | ||
} | ||
|
||
impl ContactInfo { | ||
#[inline] | ||
pub fn pubkey(&self) -> &Pubkey { | ||
&self.pubkey | ||
} | ||
|
||
#[inline] | ||
pub(crate) fn wallclock(&self) -> u64 { | ||
self.wallclock | ||
} | ||
|
||
fn get_socket(&self, tag: u8) -> Option<SocketAddr> { | ||
let &(_, ix, port) = self.sockets.iter().find(|(k, _, _)| *k == tag)?; | ||
let addr = self.addrs.get(usize::from(ix))?; | ||
(port != 0u16 && !addr.is_unspecified() && !addr.is_multicast()) | ||
.then_some(SocketAddr::new(*addr, port)) | ||
} | ||
} | ||
|
||
impl Sanitize for ContactInfo { | ||
fn sanitize(&self) -> Result<(), SanitizeError> { | ||
if self.wallclock >= MAX_WALLCLOCK { | ||
return Err(SanitizeError::ValueOutOfBounds); | ||
} | ||
Ok(()) | ||
} | ||
} | ||
|
||
impl Serialize for ContactInfo { | ||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||
where | ||
S: Serializer, | ||
{ | ||
ContactInfoLite { | ||
pubkey: Cow::Borrowed(&self.pubkey), | ||
wallclock: self.wallclock, | ||
shred_version: self.shred_version, | ||
addrs: Cow::Borrowed(&self.addrs), | ||
sockets: Cow::Borrowed(&self.sockets), | ||
} | ||
.serialize(serializer) | ||
} | ||
} | ||
|
||
impl<'de> Deserialize<'de> for ContactInfo { | ||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | ||
where | ||
D: Deserializer<'de>, | ||
{ | ||
let ContactInfoLite { | ||
pubkey, | ||
wallclock, | ||
shred_version, | ||
addrs, | ||
sockets, | ||
} = ContactInfoLite::deserialize(deserializer)?; | ||
// TODO: sanity check on the fields. | ||
let mut node = ContactInfo { | ||
pubkey: pubkey.into_owned(), | ||
wallclock, | ||
shred_version, | ||
addrs: addrs.into_owned(), | ||
sockets: sockets.into_owned(), | ||
..ContactInfo::default() | ||
}; | ||
node.gossip = node.get_socket(SOCKET_TAG_GOSSIP); | ||
node.repair = node.get_socket(SOCKET_TAG_REPAIR); | ||
node.rpc = node.get_socket(SOCKET_TAG_RPC); | ||
node.rpc_pubsub = node.get_socket(SOCKET_TAG_RPC_PUBSUB); | ||
node.serve_repair = node.get_socket(SOCKET_TAG_SERVE_REPAIR); | ||
node.tpu = node.get_socket(SOCKET_TAG_TPU); | ||
node.tpu_forwards = node.get_socket(SOCKET_TAG_TPU_FORWARDS); | ||
node.tpu_vote = node.get_socket(SOCKET_TAG_TPU_VOTE); | ||
node.tvu = node.get_socket(SOCKET_TAG_TVU); | ||
node.tvu_forwards = node.get_socket(SOCKET_TAG_TVU_FORWARDS); | ||
Ok(node) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters