Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Organize gossip random packet generation #4880

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 7 additions & 2 deletions gossip/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ license = { workspace = true }
edition = { workspace = true }

[dependencies]
anyhow = { workspace = true }
assert_matches = { workspace = true }
bincode = { workspace = true }
bv = { workspace = true, features = ["serde"] }
cfg-if = { workspace = true }
clap = { workspace = true }
crossbeam-channel = { workspace = true }
flate2 = { workspace = true }
Expand All @@ -21,13 +23,16 @@ itertools = { workspace = true }
log = { workspace = true }
lru = { workspace = true }
num-traits = { workspace = true }
pcap-file = "2.0.0"
rand = { workspace = true }
rand0-7 = { workspace = true }
rand_chacha = { workspace = true }
rayon = { workspace = true }
serde = { workspace = true }
serde-big-array = { workspace = true }
serde_bytes = { workspace = true }
serde_derive = { workspace = true }
serde_json = { workspace = true, optional = true }
siphasher = { workspace = true }
solana-bloom = { workspace = true }
solana-clap-utils = { workspace = true }
Expand Down Expand Up @@ -62,18 +67,17 @@ solana-vote = { workspace = true }
solana-vote-program = { workspace = true }
static_assertions = { workspace = true }
thiserror = { workspace = true }

[dev-dependencies]
bs58 = { workspace = true }
criterion = { workspace = true }
num_cpus = { workspace = true }
rand0-7 = { workspace = true }
rand_chacha0-2 = { workspace = true }
serial_test = { workspace = true }
solana-gossip = { path = ".", features = ["dev-context-only-utils"] }
solana-perf = { workspace = true, features = ["dev-context-only-utils"] }
solana-runtime = { workspace = true, features = ["dev-context-only-utils"] }
test-case = { workspace = true }

[features]
frozen-abi = [
"dep:solana-frozen-abi",
Expand All @@ -88,6 +92,7 @@ frozen-abi = [
"solana-vote/frozen-abi",
"solana-vote-program/frozen-abi",
]
dev-context-only-utils = []

[[bench]]
name = "crds"
Expand Down
1 change: 1 addition & 0 deletions gossip/benches/crds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use {
crds::{Crds, GossipRoute},
crds_gossip_pull::{CrdsTimeouts, CRDS_GOSSIP_PULL_CRDS_TIMEOUT_MS},
crds_value::CrdsValue,
testing_fixtures::FormatValidation,
},
solana_pubkey::Pubkey,
std::{collections::HashMap, time::Duration},
Expand Down
1 change: 1 addition & 0 deletions gossip/benches/crds_gossip_pull.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use {
crds::{Crds, GossipRoute},
crds_gossip_pull::{CrdsFilter, CrdsGossipPull},
crds_value::CrdsValue,
testing_fixtures::FormatValidation,
},
solana_sdk::hash::Hash,
std::sync::RwLock,
Expand Down
1 change: 1 addition & 0 deletions gossip/benches/crds_shards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use {
crds::{Crds, GossipRoute, VersionedCrdsValue},
crds_shards::CrdsShards,
crds_value::CrdsValue,
testing_fixtures::FormatValidation,
},
solana_sdk::timing::timestamp,
std::iter::repeat_with,
Expand Down
4 changes: 3 additions & 1 deletion gossip/src/cluster_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3126,6 +3126,7 @@ mod tests {
duplicate_shred::tests::new_rand_shred,
protocol::tests::new_rand_remote_node,
socketaddr,
testing_fixtures::{new_insecure_keypair, FormatValidation},
},
bincode::serialize,
itertools::izip,
Expand Down Expand Up @@ -3796,7 +3797,8 @@ mod tests {
#[test]
fn test_append_entrypoint_to_pulls() {
let thread_pool = ThreadPoolBuilder::new().build().unwrap();
let node_keypair = Arc::new(Keypair::new());
let mut rng = rand::thread_rng();
let node_keypair = Arc::new(new_insecure_keypair(&mut rng));
let cluster_info = ClusterInfo::new(
ContactInfo::new_localhost(&node_keypair.pubkey(), timestamp()),
node_keypair,
Expand Down
17 changes: 13 additions & 4 deletions gossip/src/crds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,10 @@ fn should_report_message_signature(signature: &Signature) -> bool {
mod tests {
use {
super::*,
crate::crds_data::{new_rand_timestamp, AccountsHashes, NodeInstance},
crate::{
crds_data::{AccountsHashes, NodeInstance},
testing_fixtures::*,
},
rand::{thread_rng, Rng, SeedableRng},
rand_chacha::ChaChaRng,
rayon::ThreadPoolBuilder,
Expand Down Expand Up @@ -1250,7 +1253,9 @@ mod tests {
#[test]
fn test_crds_value_indices() {
let mut rng = thread_rng();
let keypairs: Vec<_> = repeat_with(Keypair::new).take(128).collect();
let keypairs: Vec<_> = repeat_with(|| new_insecure_keypair(&mut rng))
.take(128)
.collect();
let mut crds = Crds::default();
let mut num_inserts = 0;
for k in 0..4096 {
Expand Down Expand Up @@ -1301,7 +1306,9 @@ mod tests {
}
}
let mut rng = thread_rng();
let keypairs: Vec<_> = repeat_with(Keypair::new).take(128).collect();
let keypairs: Vec<_> = repeat_with(|| new_insecure_keypair(&mut rng))
.take(128)
.collect();
let mut crds = Crds::default();
for k in 0..4096 {
let keypair = &keypairs[rng.gen_range(0..keypairs.len())];
Expand Down Expand Up @@ -1400,7 +1407,9 @@ mod tests {
.len()
}
let mut rng = thread_rng();
let keypairs: Vec<_> = repeat_with(Keypair::new).take(64).collect();
let keypairs: Vec<_> = repeat_with(|| new_insecure_keypair(&mut rng))
.take(64)
.collect();
let stakes = keypairs
.iter()
.map(|k| (k.pubkey(), rng.gen_range(0..1000)))
Expand Down
77 changes: 44 additions & 33 deletions gossip/src/crds_data.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
#[cfg(feature = "dev-context-only-utils")]
use {
crate::testing_fixtures::{new_rand_timestamp, new_random_pubkey, FormatValidation},
rand::Rng,
std::hint::black_box,
};
use {
crate::{
contact_info::ContactInfo,
Expand All @@ -7,16 +13,9 @@ use {
legacy_contact_info::LegacyContactInfo,
restart_crds_values::{RestartHeaviestFork, RestartLastVotedForkSlots},
},
rand::Rng,
serde::de::{Deserialize, Deserializer},
solana_sanitize::{Sanitize, SanitizeError},
solana_sdk::{
clock::Slot,
hash::Hash,
pubkey::{self, Pubkey},
timing::timestamp,
transaction::Transaction,
},
solana_sdk::{clock::Slot, hash::Hash, pubkey::Pubkey, transaction::Transaction},
solana_vote::vote_parser,
std::{cmp::Ordering, collections::BTreeSet},
};
Expand Down Expand Up @@ -107,21 +106,16 @@ impl Sanitize for CrdsData {
}
}

/// Random timestamp for tests and benchmarks.
pub(crate) fn new_rand_timestamp<R: Rng>(rng: &mut R) -> u64 {
const DELAY: u64 = 10 * 60 * 1000; // 10 minutes
timestamp() - DELAY + rng.gen_range(0..2 * DELAY)
}

impl CrdsData {
#[cfg(feature = "dev-context-only-utils")]
impl crate::testing_fixtures::FormatValidation<Pubkey> for CrdsData {
/// New random CrdsData for tests and benchmarks.
pub(crate) fn new_rand<R: Rng>(rng: &mut R, pubkey: Option<Pubkey>) -> CrdsData {
fn new_rand<R: Rng>(rng: &mut R, pubkey: Option<Pubkey>) -> CrdsData {
let kind = rng.gen_range(0..8);
// TODO: Implement other kinds of CrdsData here.
// TODO: Assign ranges to each arm proportional to their frequency in
// the mainnet crds table.
match kind {
0 => CrdsData::from(ContactInfo::new_rand(rng, pubkey)),
0 => CrdsData::ContactInfo(ContactInfo::new_rand(rng, pubkey)),
// Index for LowestSlot is deprecated and should be zero.
1 => CrdsData::LowestSlot(0, LowestSlot::new_rand(rng, pubkey)),
2 => CrdsData::LegacySnapshotHashes(LegacySnapshotHashes::new_rand(rng, pubkey)),
Expand All @@ -137,7 +131,9 @@ impl CrdsData {
),
}
}
}

impl CrdsData {
pub(crate) fn wallclock(&self) -> u64 {
match self {
CrdsData::LegacyContactInfo(contact_info) => contact_info.wallclock(),
Expand Down Expand Up @@ -224,6 +220,9 @@ pub(crate) struct AccountsHashes {
impl Sanitize for AccountsHashes {
fn sanitize(&self) -> Result<(), SanitizeError> {
sanitize_wallclock(self.wallclock)?;
if self.hashes.len() > MAX_ACCOUNTS_HASHES {
return Err(SanitizeError::IndexOutOfBounds);
}
for (slot, _) in &self.hashes {
if *slot >= MAX_SLOT {
return Err(SanitizeError::ValueOutOfBounds);
Expand All @@ -233,9 +232,9 @@ impl Sanitize for AccountsHashes {
}
}

impl AccountsHashes {
/// New random AccountsHashes for tests and benchmarks.
pub(crate) fn new_rand<R: Rng>(rng: &mut R, pubkey: Option<Pubkey>) -> Self {
#[cfg(feature = "dev-context-only-utils")]
impl FormatValidation for AccountsHashes {
fn new_rand<R: Rng>(rng: &mut R, pubkey: Option<Pubkey>) -> Self {
let num_hashes = rng.gen_range(0..MAX_ACCOUNTS_HASHES) + 1;
let hashes = std::iter::repeat_with(|| {
let slot = 47825632 + rng.gen_range(0..512);
Expand All @@ -245,11 +244,18 @@ impl AccountsHashes {
.take(num_hashes)
.collect();
Self {
from: pubkey.unwrap_or_else(pubkey::new_rand),
from: pubkey.unwrap_or_else(|| new_random_pubkey(rng)),
hashes,
wallclock: new_rand_timestamp(rng),
}
}

fn exercise(&self) -> anyhow::Result<()> {
self.sanitize()?;
let s: u64 = self.hashes.iter().map(|v| v.0).sum();
black_box(s);
Ok(())
}
}

type LegacySnapshotHashes = AccountsHashes;
Expand Down Expand Up @@ -303,11 +309,13 @@ impl LowestSlot {
wallclock,
}
}
}

/// New random LowestSlot for tests and benchmarks.
#[cfg(feature = "dev-context-only-utils")]
impl FormatValidation for LowestSlot {
fn new_rand<R: Rng>(rng: &mut R, pubkey: Option<Pubkey>) -> Self {
Self {
from: pubkey.unwrap_or_else(pubkey::new_rand),
from: pubkey.unwrap_or_else(|| new_random_pubkey(rng)),
root: rng.gen(),
lowest: rng.gen(),
slots: BTreeSet::default(),
Expand Down Expand Up @@ -354,6 +362,19 @@ impl Sanitize for Vote {
}
}

#[cfg(feature = "dev-context-only-utils")]
impl FormatValidation for Vote {
/// New random Vote for tests and benchmarks.
fn new_rand<R: Rng>(rng: &mut R, pubkey: Option<Pubkey>) -> Self {
Self {
from: pubkey.unwrap_or_else(|| new_random_pubkey(rng)),
transaction: Transaction::default(),
wallclock: new_rand_timestamp(rng),
slot: None,
}
}
}

impl Vote {
// Returns None if cannot parse transaction into a vote.
pub fn new(from: Pubkey, transaction: Transaction, wallclock: u64) -> Option<Self> {
Expand All @@ -365,16 +386,6 @@ impl Vote {
})
}

/// New random Vote for tests and benchmarks.
fn new_rand<R: Rng>(rng: &mut R, pubkey: Option<Pubkey>) -> Self {
Self {
from: pubkey.unwrap_or_else(pubkey::new_rand),
transaction: Transaction::default(),
wallclock: new_rand_timestamp(rng),
slot: None,
}
}

pub(crate) fn transaction(&self) -> &Transaction {
&self.transaction
}
Expand Down
Loading
Loading