You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

solana-core

Package Overview
Dependencies
Maintainers
0
Versions
448
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

solana-core - cargo Package Compare versions

Comparing version
3.1.8
to
3.1.9
+1
-1
.cargo_vcs_info.json
{
"git": {
"sha1": "2717084afeeb7baad4342468c27f528ef617a3cf"
"sha1": "765ee54adc4f574b1cd4f03a5500bf46c0af0817"
},
"path_in_vcs": "core"
}

@@ -15,3 +15,3 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO

name = "solana-core"
version = "3.1.8"
version = "3.1.9"
authors = ["Anza Maintainers <maintainers@anza.xyz>"]

@@ -123,31 +123,31 @@ build = false

[dependencies.agave-banking-stage-ingress-types]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.agave-feature-set]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.agave-scheduler-bindings]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.agave-scheduling-utils]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.agave-snapshots]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.agave-transaction-view]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.agave-verified-packet-receiver]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.agave-votor]
version = "=3.1.8"
version = "=3.1.9"
features = [

@@ -282,3 +282,3 @@ "agave-unstable-api",

[dependencies.solana-accounts-db]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]

@@ -293,11 +293,11 @@

[dependencies.solana-bloom]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.solana-builtins-default-costs]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.solana-client]
version = "=3.1.8"
version = "=3.1.9"

@@ -311,7 +311,7 @@ [dependencies.solana-clock]

[dependencies.solana-compute-budget]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.solana-compute-budget-instruction]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]

@@ -323,3 +323,3 @@

[dependencies.solana-connection-cache]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]

@@ -329,7 +329,7 @@ default-features = false

[dependencies.solana-cost-model]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.solana-entry]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]

@@ -341,3 +341,3 @@

[dependencies.solana-fee]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]

@@ -365,11 +365,11 @@

[dependencies.solana-genesis-utils]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.solana-geyser-plugin-manager]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.solana-gossip]
version = "=3.1.8"
version = "=3.1.9"
features = [

@@ -393,3 +393,3 @@ "agave-unstable-api",

[dependencies.solana-ledger]
version = "=3.1.8"
version = "=3.1.9"
features = [

@@ -404,3 +404,3 @@ "agave-unstable-api",

[dependencies.solana-measure]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]

@@ -412,3 +412,3 @@

[dependencies.solana-metrics]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]

@@ -420,3 +420,3 @@

[dependencies.solana-net-utils]
version = "=3.1.8"
version = "=3.1.9"
features = [

@@ -437,7 +437,7 @@ "agave-unstable-api",

[dependencies.solana-perf]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.solana-poh]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]

@@ -453,3 +453,3 @@

[dependencies.solana-quic-client]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]

@@ -461,3 +461,3 @@

[dependencies.solana-rayon-threadlimit]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]

@@ -469,14 +469,14 @@

[dependencies.solana-rpc]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.solana-rpc-client-api]
version = "=3.1.8"
version = "=3.1.9"
[dependencies.solana-runtime]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.solana-runtime-transaction]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]

@@ -491,3 +491,3 @@

[dependencies.solana-send-transaction-service]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]

@@ -518,15 +518,15 @@

[dependencies.solana-streamer]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.solana-svm]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.solana-svm-timings]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.solana-svm-transaction]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]

@@ -547,7 +547,7 @@

[dependencies.solana-tls-utils]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.solana-tpu-client]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]

@@ -557,3 +557,3 @@ default-features = false

[dependencies.solana-tpu-client-next]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]

@@ -568,7 +568,7 @@

[dependencies.solana-transaction-status]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.solana-turbine]
version = "=3.1.8"
version = "=3.1.9"
features = [

@@ -580,7 +580,7 @@ "agave-unstable-api",

[dependencies.solana-unified-scheduler-logic]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.solana-unified-scheduler-pool]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]

@@ -592,11 +592,11 @@

[dependencies.solana-version]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.solana-vote]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dependencies.solana-vote-program]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]

@@ -606,3 +606,3 @@ default-features = false

[dependencies.solana-wen-restart]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]

@@ -640,11 +640,11 @@

[dev-dependencies.agave-logger]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dev-dependencies.agave-reserved-account-keys]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dev-dependencies.agave-scheduler-bindings]
version = "=3.1.8"
version = "=3.1.9"
features = [

@@ -675,7 +675,7 @@ "agave-unstable-api",

[dev-dependencies.solana-bpf-loader-program]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dev-dependencies.solana-client]
version = "=3.1.8"
version = "=3.1.9"
features = ["dev-context-only-utils"]

@@ -687,7 +687,7 @@

[dev-dependencies.solana-compute-budget-program]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dev-dependencies.solana-cost-model]
version = "=3.1.8"
version = "=3.1.9"
features = [

@@ -702,3 +702,3 @@ "agave-unstable-api",

[dev-dependencies.solana-ledger]
version = "=3.1.8"
version = "=3.1.9"
features = [

@@ -710,3 +710,3 @@ "agave-unstable-api",

[dev-dependencies.solana-net-utils]
version = "=3.1.8"
version = "=3.1.9"
features = [

@@ -718,3 +718,3 @@ "agave-unstable-api",

[dev-dependencies.solana-poh]
version = "=3.1.8"
version = "=3.1.9"
features = [

@@ -726,7 +726,7 @@ "agave-unstable-api",

[dev-dependencies.solana-program-binaries]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dev-dependencies.solana-program-runtime]
version = "=3.1.8"
version = "=3.1.9"
features = [

@@ -738,3 +738,3 @@ "agave-unstable-api",

[dev-dependencies.solana-rpc]
version = "=3.1.8"
version = "=3.1.9"
features = [

@@ -746,7 +746,7 @@ "agave-unstable-api",

[dev-dependencies.solana-system-program]
version = "=3.1.8"
version = "=3.1.9"
features = ["agave-unstable-api"]
[dev-dependencies.solana-unified-scheduler-pool]
version = "=3.1.8"
version = "=3.1.9"
features = [

@@ -758,3 +758,3 @@ "agave-unstable-api",

[dev-dependencies.solana-vote]
version = "=3.1.8"
version = "=3.1.9"
features = [

@@ -761,0 +761,0 @@ "agave-unstable-api",

@@ -12,5 +12,8 @@ use {

solana_pubkey::Pubkey,
solana_runtime::{bank::Bank, epoch_stakes::VersionedEpochStakes},
solana_runtime::{
bank::Bank,
epoch_stakes::{EpochAuthorizedVoters, VersionedEpochStakes},
},
solana_sysvar::{self as sysvar, slot_hashes::SlotHashes},
std::cmp,
std::{cmp, sync::Arc},
};

@@ -46,2 +49,7 @@

cached_epoch_stakes: VersionedEpochStakes,
/// Authorized voters for the current epoch. This is separate from
/// cached_epoch_stakes because stakes are offset by one epoch (we use
/// epoch E + 1 for stake in epoch E), but authorized voters must
/// match the epoch of the bank slot
cached_epoch_authorized_voters: Arc<EpochAuthorizedVoters>,
deprecate_legacy_vote_ixs: bool,

@@ -53,6 +61,13 @@ current_epoch: Epoch,

pub fn new(bank: &Bank) -> Self {
let cached_epoch_stakes = bank.current_epoch_stakes().clone();
let cached_epoch_authorized_voters = bank
.epoch_stakes(bank.epoch())
.expect("Current epoch stakes must exist")
.epoch_authorized_voters()
.clone();
Self {
latest_vote_per_vote_pubkey: HashMap::default(),
num_unprocessed_votes: 0,
cached_epoch_stakes: bank.current_epoch_stakes().clone(),
cached_epoch_stakes,
cached_epoch_authorized_voters,
current_epoch: bank.epoch(),

@@ -74,2 +89,4 @@ deprecate_legacy_vote_ixs: bank

let epoch_stakes = VersionedEpochStakes::new_for_tests(vote_accounts, 0);
// Authorized voters don't change in tests so it's fine to use the authorized voters from the "wrong" epoch
let epoch_authorized_voters = epoch_stakes.epoch_authorized_voters().clone();

@@ -80,2 +97,3 @@ Self {

cached_epoch_stakes: epoch_stakes,
cached_epoch_authorized_voters: epoch_authorized_voters,
current_epoch: 0,

@@ -179,3 +197,12 @@ deprecate_legacy_vote_ixs: true,

{
self.cached_epoch_stakes = bank.current_epoch_stakes().clone();
// Stakes are offset by one epoch
let current_epoch_stakes = bank.current_epoch_stakes().clone();
// Authorized voters use the same epoch as the leader bank
self.cached_epoch_authorized_voters = bank
.epoch_stakes(bank.epoch())
.map(|stakes| stakes.epoch_authorized_voters().clone())
// Should be fine to expect as the current epoch must exist in epoch_stakes,
// will cleanup in a follow up
.unwrap_or_else(|| current_epoch_stakes.epoch_authorized_voters().clone());
self.cached_epoch_stakes = current_epoch_stakes;
self.current_epoch = bank.epoch();

@@ -224,4 +251,3 @@ self.deprecate_legacy_vote_ixs = bank

if self
.cached_epoch_stakes
.epoch_authorized_voters()
.cached_epoch_authorized_voters
.get(&vote.vote_pubkey())

@@ -360,2 +386,3 @@ .is_none_or(|authorized| authorized != &vote.authorized_voter_pubkey())

solana_hash::Hash,
solana_keypair::Keypair,
solana_perf::packet::{BytesPacket, PacketFlags},

@@ -369,2 +396,37 @@ solana_runtime::genesis_utils::{self, ValidatorVoteKeypairs},

/// Create a VoteAccount with a specific authorized voter for the given epoch
fn vote_account_with_authorized_voter(
vote_pubkey: &Pubkey,
authorized_voter: &Pubkey,
epoch: solana_clock::Epoch,
) -> solana_vote::vote_account::VoteAccount {
use {
solana_account::AccountSharedData,
solana_vote_program::vote_state::{VoteInit, VoteStateV4, VoteStateVersions},
};
let vote_init = VoteInit {
node_pubkey: Pubkey::new_unique(),
authorized_voter: *authorized_voter,
authorized_withdrawer: Pubkey::new_unique(),
commission: 0,
};
let clock = solana_clock::Clock {
slot: 0,
epoch_start_timestamp: 0,
epoch,
leader_schedule_epoch: epoch,
unix_timestamp: 0,
};
let vote_state = VoteStateV4::new(vote_pubkey, &vote_init, &clock);
let account = AccountSharedData::new_data(
1_000_000,
&VoteStateVersions::new_v4(vote_state),
&solana_sdk_ids::vote::id(),
)
.unwrap();
solana_vote::vote_account::VoteAccount::try_from(account).unwrap()
}
pub(crate) fn packet_from_slots(

@@ -404,2 +466,28 @@ slots: Vec<(u64, u32)>,

/// Create a vote packet with a custom authorized voter keypair
fn packet_from_slots_with_authorized_voter(
slots: Vec<(u64, u32)>,
keypairs: &ValidatorVoteKeypairs,
authorized_voter: &Keypair,
timestamp: Option<UnixTimestamp>,
) -> BytesPacket {
let mut vote = TowerSync::from(slots);
vote.timestamp = timestamp;
let vote_tx = new_tower_sync_transaction(
vote,
Hash::new_unique(),
&keypairs.node_keypair,
&keypairs.vote_keypair,
authorized_voter,
None,
);
let mut packet = BytesPacket::from_data(None, vote_tx).unwrap();
packet
.meta_mut()
.flags
.set(PacketFlags::SIMPLE_VOTE_TX, true);
packet
}
fn to_sanitized_view(packet: BytesPacket) -> SanitizedTransactionView<SharedBytes> {

@@ -674,2 +762,157 @@ SanitizedTransactionView::try_new_sanitized(Arc::new(packet.buffer().to_vec()), false)

#[test]
fn test_insert_batch_authorized_voter() {
// Test that votes are only accepted when signed by the correct authorized voter.
let keypair = ValidatorVoteKeypairs::new_rand();
let unauthorized_keypair = solana_keypair::Keypair::new();
let genesis_config =
genesis_utils::create_genesis_config_with_vote_accounts(100, &[&keypair], vec![200])
.genesis_config;
let (bank, _bank_forks) = Bank::new_with_bank_forks_for_tests(&genesis_config);
let mut vote_storage = VoteStorage::new(&bank);
// Vote signed by the correct authorized voter (vote_keypair) should be accepted
let correct_vote = packet_from_slots_with_authorized_voter(
vec![(0, 1)],
&keypair,
&keypair.vote_keypair,
None,
);
vote_storage.insert_batch(
VoteSource::Tpu,
std::iter::once(to_sanitized_view(correct_vote)),
);
assert_eq!(1, vote_storage.len());
assert_eq!(
Some(0),
vote_storage.get_latest_vote_slot(keypair.vote_keypair.pubkey())
);
// Vote signed by an unauthorized keypair should be filtered out
let unauthorized_vote = packet_from_slots_with_authorized_voter(
vec![(1, 1)],
&keypair,
&unauthorized_keypair,
None,
);
vote_storage.insert_batch(
VoteSource::Tpu,
std::iter::once(to_sanitized_view(unauthorized_vote)),
);
// Should still be 1 (unauthorized vote was filtered)
assert_eq!(1, vote_storage.len());
// Slot should still be 0 (the authorized vote), not 1 (the unauthorized one)
assert_eq!(
Some(0),
vote_storage.get_latest_vote_slot(keypair.vote_keypair.pubkey())
);
// Update with a valid vote for a later slot - should succeed
let correct_vote_2 = packet_from_slots_with_authorized_voter(
vec![(2, 1)],
&keypair,
&keypair.vote_keypair,
None,
);
vote_storage.insert_batch(
VoteSource::Tpu,
std::iter::once(to_sanitized_view(correct_vote_2)),
);
assert_eq!(1, vote_storage.len());
assert_eq!(
Some(2),
vote_storage.get_latest_vote_slot(keypair.vote_keypair.pubkey())
);
}
/// Test that authorized voters are checked against the current epoch, not the next epoch.
/// This verifies that cache_epoch_boundary_info uses epoch_stakes(bank.epoch()) for
/// authorized voters, not current_epoch_stakes() which returns epoch E+1.
#[test]
fn test_authorized_voter_uses_current_epoch_not_next() {
let keypair = ValidatorVoteKeypairs::new_rand();
let vote_pubkey = keypair.vote_keypair.pubkey();
// Create two different authorized voters: one for epoch 1, one for epoch 2
let epoch1_authorized_voter_keypair = keypair.node_keypair.insecure_clone();
let epoch1_authorized_voter = epoch1_authorized_voter_keypair.pubkey();
let epoch2_authorized_voter_keypair = Keypair::new();
let epoch2_authorized_voter = epoch2_authorized_voter_keypair.pubkey();
// Create vote accounts with different authorized voters for different epochs
let vote_account_epoch1 =
vote_account_with_authorized_voter(&vote_pubkey, &epoch1_authorized_voter, 1);
let vote_account_epoch2 =
vote_account_with_authorized_voter(&vote_pubkey, &epoch2_authorized_voter, 2);
// Create epoch stakes for epochs 1 and 2
let epoch1_stakes = VersionedEpochStakes::new_for_tests(
[(vote_pubkey, (100, vote_account_epoch1))]
.into_iter()
.collect(),
1, // leader_schedule_epoch
);
let epoch2_stakes = VersionedEpochStakes::new_for_tests(
[(vote_pubkey, (100, vote_account_epoch2))]
.into_iter()
.collect(),
2, // leader_schedule_epoch
);
// Create a bank in epoch 1 with custom epoch stakes
let genesis_config =
genesis_utils::create_genesis_config_with_vote_accounts(100, &[&keypair], vec![200])
.genesis_config;
let bank_0 = Bank::new_for_tests(&genesis_config);
let mut bank = Bank::new_from_parent(
Arc::new(bank_0),
&Pubkey::new_unique(),
MINIMUM_SLOTS_PER_EPOCH, // This puts us in epoch 1
);
assert_eq!(bank.epoch(), 1);
// Set custom epoch stakes: epoch 1 has epoch1_authorized_voter, epoch 2 has epoch2_authorized_voter
bank.set_epoch_stakes_for_test(1, epoch1_stakes);
bank.set_epoch_stakes_for_test(2, epoch2_stakes);
let mut vote_storage = VoteStorage::new(&bank);
// Vote signed by epoch 1's authorized voter (vote_keypair) should be accepted
let epoch1_vote = packet_from_slots_with_authorized_voter(
vec![(MINIMUM_SLOTS_PER_EPOCH, 1)],
&keypair,
&epoch1_authorized_voter_keypair,
None,
);
vote_storage.insert_batch(
VoteSource::Tpu,
std::iter::once(to_sanitized_view(epoch1_vote)),
);
assert_eq!(
1,
vote_storage.len(),
"Vote with epoch 1 authorized voter should be accepted"
);
// Vote signed by epoch 2's authorized voter should be REJECTED
// If we were incorrectly using current_epoch_stakes() (epoch 2), this would be accepted
let wrong_epoch_vote = packet_from_slots_with_authorized_voter(
vec![(MINIMUM_SLOTS_PER_EPOCH + 1, 1)],
&keypair,
&epoch2_authorized_voter_keypair, // This won't match epoch 1's authorized voter
None,
);
vote_storage.insert_batch(
VoteSource::Tpu,
std::iter::once(to_sanitized_view(wrong_epoch_vote)),
);
// Should still be 1 - the vote with wrong authorized voter was rejected
assert_eq!(
1,
vote_storage.len(),
"Vote with wrong authorized voter should be rejected"
);
}
#[test]
fn test_insert_batch_unstaked() {

@@ -676,0 +919,0 @@ let keypair_a = ValidatorVoteKeypairs::new_rand();

@@ -5,3 +5,3 @@ //! The `fetch_stage` batches input from a UDP socket and sends it to a channel.

crate::result::{Error, Result},
crossbeam_channel::{unbounded, RecvTimeoutError},
crossbeam_channel::{unbounded, RecvTimeoutError, TrySendError},
solana_clock::{DEFAULT_TICKS_PER_SLOT, HOLD_TRANSACTIONS_SLOT_OFFSET},

@@ -128,9 +128,20 @@ solana_metrics::{inc_new_counter_debug, inc_new_counter_info},

{
inc_new_counter_debug!("fetch_stage-honor_forwards", num_packets);
let mut packets_sent = 0usize;
let mut packets_dropped = 0usize;
for packet_batch in packet_batches {
#[allow(clippy::question_mark)]
if sendr.send(packet_batch).is_err() {
return Err(Error::Send);
}
let packets_in_batch = packet_batch.len();
match sendr.try_send(packet_batch) {
Ok(()) => {
packets_sent += packets_in_batch;
}
Err(TrySendError::Full(_)) => {
packets_dropped += packets_in_batch;
}
Err(TrySendError::Disconnected(_)) => return Err(Error::Send),
};
}
inc_new_counter_debug!("fetch_stage-honor_forwards", packets_sent);
if packets_dropped > 0 {
inc_new_counter_error!("fetch_stage-dropped_forwards", packets_dropped);
}
} else {

@@ -137,0 +148,0 @@ inc_new_counter_info!("fetch_stage-discard_forwards", num_packets);

@@ -296,3 +296,5 @@ //! The `sigverify_stage` implements the signature verification stage of the TPU. It

) -> Result<(), T::SendType> {
let (mut batches, num_packets, recv_duration) = streamer::recv_packet_batches(recvr)?;
const SOFT_RECEIVE_CAP: usize = 5_000;
let (mut batches, num_packets, recv_duration) =
streamer::recv_packet_batches(recvr, SOFT_RECEIVE_CAP)?;

@@ -299,0 +301,0 @@ let batches_len = batches.len();

@@ -105,2 +105,6 @@ //! The `tpu` module implements the Transaction Processing Unit, a

/// Size of the channel between streamer and TPU sigverify stage. The values have been selected to
/// be conservative max of obsersed on mnb during high-load events.
const TPU_CHANNEL_SIZE: usize = 50_000;
pub struct Tpu {

@@ -180,3 +184,3 @@ fetch_stage: FetchStage,

let (packet_sender, packet_receiver) = unbounded();
let (packet_sender, packet_receiver) = bounded(TPU_CHANNEL_SIZE);
let (vote_packet_sender, vote_packet_receiver) = unbounded();

@@ -183,0 +187,0 @@ let (forwarded_packet_sender, forwarded_packet_receiver) = unbounded();

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display