parent
f9a9b7f610
commit
50a17fc00b
|
@ -1,11 +1,12 @@
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
|
use solana_sdk::clock::{Epoch, Slot};
|
||||||
use std::{error, fmt};
|
use std::{error, fmt};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct RpcEpochInfo {
|
pub struct RpcEpochInfo {
|
||||||
/// The current epoch
|
/// The current epoch
|
||||||
pub epoch: u64,
|
pub epoch: Epoch,
|
||||||
|
|
||||||
/// The current slot, relative to the start of the current epoch
|
/// The current slot, relative to the start of the current epoch
|
||||||
pub slot_index: u64,
|
pub slot_index: u64,
|
||||||
|
@ -14,7 +15,7 @@ pub struct RpcEpochInfo {
|
||||||
pub slots_in_epoch: u64,
|
pub slots_in_epoch: u64,
|
||||||
|
|
||||||
/// The absolute current slot
|
/// The absolute current slot
|
||||||
pub absolute_slot: u64,
|
pub absolute_slot: Slot,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
|
@ -46,7 +47,7 @@ pub struct RpcVoteAccountInfo {
|
||||||
pub last_vote: u64,
|
pub last_vote: u64,
|
||||||
|
|
||||||
/// Current root slot for this vote account (0 if not root slot exists)
|
/// Current root slot for this vote account (0 if not root slot exists)
|
||||||
pub root_slot: u64,
|
pub root_slot: Slot,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
|
|
|
@ -7,9 +7,11 @@ extern crate test;
|
||||||
extern crate solana_ledger;
|
extern crate solana_ledger;
|
||||||
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use solana_ledger::blocktree::{entries_to_test_shreds, get_tmp_ledger_path, Blocktree};
|
use solana_ledger::{
|
||||||
use solana_ledger::entry::{create_ticks, Entry};
|
blocktree::{entries_to_test_shreds, get_tmp_ledger_path, Blocktree},
|
||||||
use solana_sdk::hash::Hash;
|
entry::{create_ticks, Entry},
|
||||||
|
};
|
||||||
|
use solana_sdk::{clock::Slot, hash::Hash};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
|
|
||||||
|
@ -30,7 +32,7 @@ fn setup_read_bench(
|
||||||
blocktree: &mut Blocktree,
|
blocktree: &mut Blocktree,
|
||||||
num_small_shreds: u64,
|
num_small_shreds: u64,
|
||||||
num_large_shreds: u64,
|
num_large_shreds: u64,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
) {
|
) {
|
||||||
// Make some big and small entries
|
// Make some big and small entries
|
||||||
let entries = create_ticks(
|
let entries = create_ticks(
|
||||||
|
|
|
@ -1,54 +1,58 @@
|
||||||
use crate::chacha::{chacha_cbc_encrypt_ledger, CHACHA_BLOCK_SIZE};
|
use crate::{
|
||||||
use crate::cluster_info::{ClusterInfo, Node, VALIDATOR_PORT_RANGE};
|
chacha::{chacha_cbc_encrypt_ledger, CHACHA_BLOCK_SIZE},
|
||||||
use crate::contact_info::ContactInfo;
|
cluster_info::{ClusterInfo, Node, VALIDATOR_PORT_RANGE},
|
||||||
use crate::gossip_service::GossipService;
|
contact_info::ContactInfo,
|
||||||
use crate::packet::to_shared_blob;
|
gossip_service::GossipService,
|
||||||
use crate::recycler::Recycler;
|
packet::to_shared_blob,
|
||||||
use crate::repair_service;
|
recycler::Recycler,
|
||||||
use crate::repair_service::{RepairService, RepairSlotRange, RepairStrategy};
|
repair_service,
|
||||||
use crate::result::{Error, Result};
|
repair_service::{RepairService, RepairSlotRange, RepairStrategy},
|
||||||
use crate::service::Service;
|
result::{Error, Result},
|
||||||
use crate::shred_fetch_stage::ShredFetchStage;
|
service::Service,
|
||||||
use crate::sigverify_stage::{DisabledSigVerifier, SigVerifyStage};
|
shred_fetch_stage::ShredFetchStage,
|
||||||
use crate::storage_stage::NUM_STORAGE_SAMPLES;
|
sigverify_stage::{DisabledSigVerifier, SigVerifyStage},
|
||||||
use crate::streamer::{receiver, responder, PacketReceiver};
|
storage_stage::NUM_STORAGE_SAMPLES,
|
||||||
use crate::window_service::WindowService;
|
streamer::{receiver, responder, PacketReceiver},
|
||||||
|
window_service::WindowService,
|
||||||
|
};
|
||||||
use bincode::deserialize;
|
use bincode::deserialize;
|
||||||
use crossbeam_channel::unbounded;
|
use crossbeam_channel::unbounded;
|
||||||
use rand::thread_rng;
|
use rand::{thread_rng, Rng, SeedableRng};
|
||||||
use rand::Rng;
|
|
||||||
use rand::SeedableRng;
|
|
||||||
use rand_chacha::ChaChaRng;
|
use rand_chacha::ChaChaRng;
|
||||||
use solana_client::rpc_client::RpcClient;
|
use solana_client::{rpc_client::RpcClient, rpc_request::RpcRequest, thin_client::ThinClient};
|
||||||
use solana_client::rpc_request::RpcRequest;
|
|
||||||
use solana_client::thin_client::ThinClient;
|
|
||||||
use solana_ed25519_dalek as ed25519_dalek;
|
use solana_ed25519_dalek as ed25519_dalek;
|
||||||
use solana_ledger::blocktree::Blocktree;
|
use solana_ledger::{
|
||||||
use solana_ledger::leader_schedule_cache::LeaderScheduleCache;
|
blocktree::Blocktree, leader_schedule_cache::LeaderScheduleCache, shred::Shred,
|
||||||
use solana_ledger::shred::Shred;
|
};
|
||||||
use solana_netutil::bind_in_range;
|
use solana_netutil::bind_in_range;
|
||||||
use solana_sdk::account_utils::State;
|
use solana_sdk::{
|
||||||
use solana_sdk::client::{AsyncClient, SyncClient};
|
account_utils::State,
|
||||||
use solana_sdk::clock::{get_complete_segment_from_slot, get_segment_from_slot};
|
client::{AsyncClient, SyncClient},
|
||||||
use solana_sdk::hash::{Hash, Hasher};
|
clock::{get_complete_segment_from_slot, get_segment_from_slot, Slot},
|
||||||
use solana_sdk::message::Message;
|
hash::{Hash, Hasher},
|
||||||
use solana_sdk::signature::{Keypair, KeypairUtil, Signature};
|
message::Message,
|
||||||
use solana_sdk::timing::timestamp;
|
signature::{Keypair, KeypairUtil, Signature},
|
||||||
use solana_sdk::transaction::Transaction;
|
timing::timestamp,
|
||||||
use solana_sdk::transport::TransportError;
|
transaction::Transaction,
|
||||||
use solana_storage_api::storage_contract::StorageContract;
|
transport::TransportError,
|
||||||
use solana_storage_api::storage_instruction::{self, StorageAccountType};
|
};
|
||||||
use std::fs::File;
|
use solana_storage_api::{
|
||||||
use std::io::{self, BufReader, ErrorKind, Read, Seek, SeekFrom};
|
storage_contract::StorageContract,
|
||||||
use std::mem::size_of;
|
storage_instruction::{self, StorageAccountType},
|
||||||
use std::net::{SocketAddr, UdpSocket};
|
};
|
||||||
use std::path::{Path, PathBuf};
|
use std::{
|
||||||
use std::result;
|
fs::File,
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
io::{self, BufReader, ErrorKind, Read, Seek, SeekFrom},
|
||||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
mem::size_of,
|
||||||
use std::sync::{Arc, RwLock};
|
net::{SocketAddr, UdpSocket},
|
||||||
use std::thread::{sleep, spawn, JoinHandle};
|
path::{Path, PathBuf},
|
||||||
use std::time::Duration;
|
result,
|
||||||
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
|
sync::mpsc::{channel, Receiver, Sender},
|
||||||
|
sync::{Arc, RwLock},
|
||||||
|
thread::{sleep, spawn, JoinHandle},
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
static ENCRYPTED_FILENAME: &str = "ledger.enc";
|
static ENCRYPTED_FILENAME: &str = "ledger.enc";
|
||||||
|
|
||||||
|
@ -65,7 +69,7 @@ pub struct Archiver {
|
||||||
// Shared Archiver Meta struct used internally
|
// Shared Archiver Meta struct used internally
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct ArchiverMeta {
|
struct ArchiverMeta {
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
slots_per_segment: u64,
|
slots_per_segment: u64,
|
||||||
ledger_path: PathBuf,
|
ledger_path: PathBuf,
|
||||||
signature: Signature,
|
signature: Signature,
|
||||||
|
@ -497,7 +501,7 @@ impl Archiver {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wait_for_segment_download(
|
fn wait_for_segment_download(
|
||||||
start_slot: u64,
|
start_slot: Slot,
|
||||||
slots_per_segment: u64,
|
slots_per_segment: u64,
|
||||||
blocktree: &Arc<Blocktree>,
|
blocktree: &Arc<Blocktree>,
|
||||||
exit: &Arc<AtomicBool>,
|
exit: &Arc<AtomicBool>,
|
||||||
|
@ -905,7 +909,7 @@ impl Archiver {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn segment_complete(
|
fn segment_complete(
|
||||||
start_slot: u64,
|
start_slot: Slot,
|
||||||
slots_per_segment: u64,
|
slots_per_segment: u64,
|
||||||
blocktree: &Arc<Blocktree>,
|
blocktree: &Arc<Blocktree>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
|
|
@ -23,7 +23,7 @@ use solana_runtime::{accounts_db::ErrorCounters, bank::Bank, transaction_batch::
|
||||||
use solana_sdk::clock::MAX_TRANSACTION_FORWARDING_DELAY_GPU;
|
use solana_sdk::clock::MAX_TRANSACTION_FORWARDING_DELAY_GPU;
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
clock::{
|
clock::{
|
||||||
DEFAULT_TICKS_PER_SECOND, DEFAULT_TICKS_PER_SLOT, MAX_PROCESSING_AGE,
|
Slot, DEFAULT_TICKS_PER_SECOND, DEFAULT_TICKS_PER_SLOT, MAX_PROCESSING_AGE,
|
||||||
MAX_TRANSACTION_FORWARDING_DELAY,
|
MAX_TRANSACTION_FORWARDING_DELAY,
|
||||||
},
|
},
|
||||||
poh_config::PohConfig,
|
poh_config::PohConfig,
|
||||||
|
@ -428,7 +428,7 @@ impl BankingStage {
|
||||||
|
|
||||||
#[allow(clippy::match_wild_err_arm)]
|
#[allow(clippy::match_wild_err_arm)]
|
||||||
fn record_transactions(
|
fn record_transactions(
|
||||||
bank_slot: u64,
|
bank_slot: Slot,
|
||||||
txs: &[Transaction],
|
txs: &[Transaction],
|
||||||
results: &[transaction::Result<()>],
|
results: &[transaction::Result<()>],
|
||||||
poh: &Arc<Mutex<PohRecorder>>,
|
poh: &Arc<Mutex<PohRecorder>>,
|
||||||
|
|
|
@ -7,8 +7,7 @@ use bincode::serialize;
|
||||||
use chrono::{SecondsFormat, Utc};
|
use chrono::{SecondsFormat, Utc};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use solana_ledger::entry::Entry;
|
use solana_ledger::entry::Entry;
|
||||||
use solana_sdk::hash::Hash;
|
use solana_sdk::{clock::Slot, hash::Hash, pubkey::Pubkey};
|
||||||
use solana_sdk::pubkey::Pubkey;
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
@ -72,14 +71,14 @@ impl EntryWriter for EntrySocket {
|
||||||
pub trait BlockstreamEvents {
|
pub trait BlockstreamEvents {
|
||||||
fn emit_entry_event(
|
fn emit_entry_event(
|
||||||
&self,
|
&self,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
tick_height: u64,
|
tick_height: u64,
|
||||||
leader_pubkey: &Pubkey,
|
leader_pubkey: &Pubkey,
|
||||||
entries: &Entry,
|
entries: &Entry,
|
||||||
) -> Result<()>;
|
) -> Result<()>;
|
||||||
fn emit_block_event(
|
fn emit_block_event(
|
||||||
&self,
|
&self,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
tick_height: u64,
|
tick_height: u64,
|
||||||
leader_pubkey: &Pubkey,
|
leader_pubkey: &Pubkey,
|
||||||
blockhash: Hash,
|
blockhash: Hash,
|
||||||
|
@ -97,7 +96,7 @@ where
|
||||||
{
|
{
|
||||||
fn emit_entry_event(
|
fn emit_entry_event(
|
||||||
&self,
|
&self,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
tick_height: u64,
|
tick_height: u64,
|
||||||
leader_pubkey: &Pubkey,
|
leader_pubkey: &Pubkey,
|
||||||
entry: &Entry,
|
entry: &Entry,
|
||||||
|
@ -123,7 +122,7 @@ where
|
||||||
|
|
||||||
fn emit_block_event(
|
fn emit_block_event(
|
||||||
&self,
|
&self,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
tick_height: u64,
|
tick_height: u64,
|
||||||
leader_pubkey: &Pubkey,
|
leader_pubkey: &Pubkey,
|
||||||
blockhash: Hash,
|
blockhash: Hash,
|
||||||
|
|
|
@ -2,9 +2,12 @@ use crate::poh_recorder::WorkingBankEntry;
|
||||||
use crate::result::Result;
|
use crate::result::Result;
|
||||||
use solana_ledger::entry::Entry;
|
use solana_ledger::entry::Entry;
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::bank::Bank;
|
||||||
use std::sync::mpsc::Receiver;
|
use solana_sdk::clock::Slot;
|
||||||
use std::sync::Arc;
|
use std::{
|
||||||
use std::time::{Duration, Instant};
|
sync::mpsc::Receiver,
|
||||||
|
sync::Arc,
|
||||||
|
time::{Duration, Instant},
|
||||||
|
};
|
||||||
|
|
||||||
pub(super) struct ReceiveResults {
|
pub(super) struct ReceiveResults {
|
||||||
pub entries: Vec<Entry>,
|
pub entries: Vec<Entry>,
|
||||||
|
@ -16,8 +19,8 @@ pub(super) struct ReceiveResults {
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct UnfinishedSlotInfo {
|
pub struct UnfinishedSlotInfo {
|
||||||
pub next_shred_index: u32,
|
pub next_shred_index: u32,
|
||||||
pub slot: u64,
|
pub slot: Slot,
|
||||||
pub parent: u64,
|
pub parent: Slot,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This parameter tunes how many entries are received in one iteration of recv loop
|
/// This parameter tunes how many entries are received in one iteration of recv loop
|
||||||
|
|
|
@ -282,17 +282,22 @@ mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::cluster_info::{ClusterInfo, Node};
|
use crate::cluster_info::{ClusterInfo, Node};
|
||||||
use crate::genesis_utils::create_genesis_block;
|
use crate::genesis_utils::create_genesis_block;
|
||||||
use solana_ledger::blocktree::{get_tmp_ledger_path, Blocktree};
|
use solana_ledger::{
|
||||||
use solana_ledger::entry::create_ticks;
|
blocktree::{get_tmp_ledger_path, Blocktree},
|
||||||
use solana_ledger::shred::max_ticks_per_n_shreds;
|
entry::create_ticks,
|
||||||
|
shred::max_ticks_per_n_shreds,
|
||||||
|
};
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::bank::Bank;
|
||||||
use solana_sdk::genesis_block::GenesisBlock;
|
use solana_sdk::{
|
||||||
use solana_sdk::signature::{Keypair, KeypairUtil};
|
clock::Slot,
|
||||||
|
genesis_block::GenesisBlock,
|
||||||
|
signature::{Keypair, KeypairUtil},
|
||||||
|
};
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
fn setup(
|
fn setup(
|
||||||
num_shreds_per_slot: u64,
|
num_shreds_per_slot: Slot,
|
||||||
) -> (
|
) -> (
|
||||||
Arc<Blocktree>,
|
Arc<Blocktree>,
|
||||||
GenesisBlock,
|
GenesisBlock,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use solana_ledger::blocktree::Blocktree;
|
use solana_ledger::blocktree::Blocktree;
|
||||||
|
use solana_sdk::clock::Slot;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::{BufWriter, Write};
|
use std::io::{BufWriter, Write};
|
||||||
|
@ -12,7 +13,7 @@ pub const CHACHA_KEY_SIZE: usize = 32;
|
||||||
|
|
||||||
pub fn chacha_cbc_encrypt_ledger(
|
pub fn chacha_cbc_encrypt_ledger(
|
||||||
blocktree: &Arc<Blocktree>,
|
blocktree: &Arc<Blocktree>,
|
||||||
start_slot: u64,
|
start_slot: Slot,
|
||||||
slots_per_segment: u64,
|
slots_per_segment: u64,
|
||||||
out_path: &Path,
|
out_path: &Path,
|
||||||
ivec: &mut [u8; CHACHA_BLOCK_SIZE],
|
ivec: &mut [u8; CHACHA_BLOCK_SIZE],
|
||||||
|
|
|
@ -12,43 +12,48 @@
|
||||||
//! * layer 2 - Everyone else, if layer 1 is `2^10`, layer 2 should be able to fit `2^20` number of nodes.
|
//! * layer 2 - Everyone else, if layer 1 is `2^10`, layer 2 should be able to fit `2^20` number of nodes.
|
||||||
//!
|
//!
|
||||||
//! Bank needs to provide an interface for us to query the stake weight
|
//! Bank needs to provide an interface for us to query the stake weight
|
||||||
use crate::contact_info::ContactInfo;
|
use crate::{
|
||||||
use crate::crds_gossip::CrdsGossip;
|
contact_info::ContactInfo,
|
||||||
use crate::crds_gossip_error::CrdsGossipError;
|
crds_gossip::CrdsGossip,
|
||||||
use crate::crds_gossip_pull::{CrdsFilter, CRDS_GOSSIP_PULL_CRDS_TIMEOUT_MS};
|
crds_gossip_error::CrdsGossipError,
|
||||||
use crate::crds_value::{CrdsValue, CrdsValueLabel, EpochSlots, Vote};
|
crds_gossip_pull::{CrdsFilter, CRDS_GOSSIP_PULL_CRDS_TIMEOUT_MS},
|
||||||
use crate::packet::{to_shared_blob, Blob, Packet, SharedBlob};
|
crds_value::{CrdsValue, CrdsValueLabel, EpochSlots, Vote},
|
||||||
use crate::repair_service::RepairType;
|
packet::{to_shared_blob, Blob, Packet, SharedBlob},
|
||||||
use crate::result::{Error, Result};
|
repair_service::RepairType,
|
||||||
use crate::sendmmsg::{multicast, send_mmsg};
|
result::{Error, Result},
|
||||||
use crate::streamer::{BlobReceiver, BlobSender};
|
sendmmsg::{multicast, send_mmsg},
|
||||||
use crate::weighted_shuffle::{weighted_best, weighted_shuffle};
|
streamer::{BlobReceiver, BlobSender},
|
||||||
|
weighted_shuffle::{weighted_best, weighted_shuffle},
|
||||||
|
};
|
||||||
use bincode::{deserialize, serialize, serialized_size};
|
use bincode::{deserialize, serialize, serialized_size};
|
||||||
use core::cmp;
|
use core::cmp;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
use solana_ledger::bank_forks::BankForks;
|
use solana_ledger::{bank_forks::BankForks, blocktree::Blocktree, staking_utils};
|
||||||
use solana_ledger::blocktree::Blocktree;
|
|
||||||
use solana_ledger::staking_utils;
|
|
||||||
use solana_metrics::{datapoint_debug, inc_new_counter_debug, inc_new_counter_error};
|
use solana_metrics::{datapoint_debug, inc_new_counter_debug, inc_new_counter_error};
|
||||||
use solana_netutil::{
|
use solana_netutil::{
|
||||||
bind_common, bind_common_in_range, bind_in_range, find_available_port_in_range,
|
bind_common, bind_common_in_range, bind_in_range, find_available_port_in_range,
|
||||||
multi_bind_in_range, PortRange,
|
multi_bind_in_range, PortRange,
|
||||||
};
|
};
|
||||||
use solana_sdk::packet::PACKET_DATA_SIZE;
|
use solana_sdk::{
|
||||||
use solana_sdk::pubkey::Pubkey;
|
clock::Slot,
|
||||||
use solana_sdk::signature::{Keypair, KeypairUtil, Signable, Signature};
|
packet::PACKET_DATA_SIZE,
|
||||||
use solana_sdk::timing::{duration_as_ms, timestamp};
|
pubkey::Pubkey,
|
||||||
use solana_sdk::transaction::Transaction;
|
signature::{Keypair, KeypairUtil, Signable, Signature},
|
||||||
use std::borrow::Cow;
|
timing::{duration_as_ms, timestamp},
|
||||||
use std::cmp::min;
|
transaction::Transaction,
|
||||||
use std::collections::{BTreeSet, HashMap, HashSet};
|
};
|
||||||
use std::fmt;
|
use std::{
|
||||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener, UdpSocket};
|
borrow::Cow,
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
cmp::min,
|
||||||
use std::sync::{Arc, RwLock};
|
collections::{BTreeSet, HashMap, HashSet},
|
||||||
use std::thread::{sleep, Builder, JoinHandle};
|
fmt,
|
||||||
use std::time::{Duration, Instant};
|
net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener, UdpSocket},
|
||||||
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
|
sync::{Arc, RwLock},
|
||||||
|
thread::{sleep, Builder, JoinHandle},
|
||||||
|
time::{Duration, Instant},
|
||||||
|
};
|
||||||
|
|
||||||
pub const VALIDATOR_PORT_RANGE: PortRange = (8000, 10_000);
|
pub const VALIDATOR_PORT_RANGE: PortRange = (8000, 10_000);
|
||||||
|
|
||||||
|
@ -776,19 +781,19 @@ impl ClusterInfo {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn window_index_request_bytes(&self, slot: u64, blob_index: u64) -> Result<Vec<u8>> {
|
pub fn window_index_request_bytes(&self, slot: Slot, blob_index: u64) -> Result<Vec<u8>> {
|
||||||
let req = Protocol::RequestWindowIndex(self.my_data().clone(), slot, blob_index);
|
let req = Protocol::RequestWindowIndex(self.my_data().clone(), slot, blob_index);
|
||||||
let out = serialize(&req)?;
|
let out = serialize(&req)?;
|
||||||
Ok(out)
|
Ok(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn window_highest_index_request_bytes(&self, slot: u64, blob_index: u64) -> Result<Vec<u8>> {
|
fn window_highest_index_request_bytes(&self, slot: Slot, blob_index: u64) -> Result<Vec<u8>> {
|
||||||
let req = Protocol::RequestHighestWindowIndex(self.my_data().clone(), slot, blob_index);
|
let req = Protocol::RequestHighestWindowIndex(self.my_data().clone(), slot, blob_index);
|
||||||
let out = serialize(&req)?;
|
let out = serialize(&req)?;
|
||||||
Ok(out)
|
Ok(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn orphan_bytes(&self, slot: u64) -> Result<Vec<u8>> {
|
fn orphan_bytes(&self, slot: Slot) -> Result<Vec<u8>> {
|
||||||
let req = Protocol::RequestOrphan(self.my_data().clone(), slot);
|
let req = Protocol::RequestOrphan(self.my_data().clone(), slot);
|
||||||
let out = serialize(&req)?;
|
let out = serialize(&req)?;
|
||||||
Ok(out)
|
Ok(out)
|
||||||
|
@ -1043,7 +1048,7 @@ impl ClusterInfo {
|
||||||
|
|
||||||
fn get_data_shred_as_blob(
|
fn get_data_shred_as_blob(
|
||||||
blocktree: &Arc<Blocktree>,
|
blocktree: &Arc<Blocktree>,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
shred_index: u64,
|
shred_index: u64,
|
||||||
) -> Result<Option<Blob>> {
|
) -> Result<Option<Blob>> {
|
||||||
let bytes = blocktree.get_data_shred(slot, shred_index)?;
|
let bytes = blocktree.get_data_shred(slot, shred_index)?;
|
||||||
|
@ -1055,7 +1060,7 @@ impl ClusterInfo {
|
||||||
from_addr: &SocketAddr,
|
from_addr: &SocketAddr,
|
||||||
blocktree: Option<&Arc<Blocktree>>,
|
blocktree: Option<&Arc<Blocktree>>,
|
||||||
me: &ContactInfo,
|
me: &ContactInfo,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
blob_index: u64,
|
blob_index: u64,
|
||||||
) -> Vec<SharedBlob> {
|
) -> Vec<SharedBlob> {
|
||||||
if let Some(blocktree) = blocktree {
|
if let Some(blocktree) = blocktree {
|
||||||
|
@ -1085,7 +1090,7 @@ impl ClusterInfo {
|
||||||
fn run_highest_window_request(
|
fn run_highest_window_request(
|
||||||
from_addr: &SocketAddr,
|
from_addr: &SocketAddr,
|
||||||
blocktree: Option<&Arc<Blocktree>>,
|
blocktree: Option<&Arc<Blocktree>>,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
highest_index: u64,
|
highest_index: u64,
|
||||||
) -> Vec<SharedBlob> {
|
) -> Vec<SharedBlob> {
|
||||||
if let Some(blocktree) = blocktree {
|
if let Some(blocktree) = blocktree {
|
||||||
|
@ -1111,7 +1116,7 @@ impl ClusterInfo {
|
||||||
fn run_orphan(
|
fn run_orphan(
|
||||||
from_addr: &SocketAddr,
|
from_addr: &SocketAddr,
|
||||||
blocktree: Option<&Arc<Blocktree>>,
|
blocktree: Option<&Arc<Blocktree>>,
|
||||||
mut slot: u64,
|
mut slot: Slot,
|
||||||
max_responses: usize,
|
max_responses: usize,
|
||||||
) -> Vec<SharedBlob> {
|
) -> Vec<SharedBlob> {
|
||||||
let mut res = vec![];
|
let mut res = vec![];
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
use crate::result::{Error, Result};
|
use crate::{
|
||||||
use crate::service::Service;
|
result::{Error, Result},
|
||||||
|
service::Service,
|
||||||
|
};
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::bank::Bank;
|
||||||
use solana_vote_api::vote_state::VoteState;
|
use solana_sdk::clock::Slot;
|
||||||
use solana_vote_api::vote_state::MAX_LOCKOUT_HISTORY;
|
use solana_vote_api::{vote_state::VoteState, vote_state::MAX_LOCKOUT_HISTORY};
|
||||||
use std::collections::HashMap;
|
use std::{
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
collections::HashMap,
|
||||||
use std::sync::mpsc::{channel, Receiver, RecvTimeoutError, Sender};
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
use std::sync::{Arc, RwLock};
|
sync::mpsc::{channel, Receiver, RecvTimeoutError, Sender},
|
||||||
use std::thread::{self, Builder, JoinHandle};
|
sync::{Arc, RwLock},
|
||||||
use std::time::Duration;
|
thread::{self, Builder, JoinHandle},
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct BankConfidence {
|
pub struct BankConfidence {
|
||||||
|
@ -33,20 +37,20 @@ impl BankConfidence {
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct ForkConfidenceCache {
|
pub struct ForkConfidenceCache {
|
||||||
bank_confidence: HashMap<u64, BankConfidence>,
|
bank_confidence: HashMap<Slot, BankConfidence>,
|
||||||
total_stake: u64,
|
total_stake: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ForkConfidenceCache {
|
impl ForkConfidenceCache {
|
||||||
pub fn new(bank_confidence: HashMap<u64, BankConfidence>, total_stake: u64) -> Self {
|
pub fn new(bank_confidence: HashMap<Slot, BankConfidence>, total_stake: u64) -> Self {
|
||||||
Self {
|
Self {
|
||||||
bank_confidence,
|
bank_confidence,
|
||||||
total_stake,
|
total_stake,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_fork_confidence(&self, fork: u64) -> Option<&BankConfidence> {
|
pub fn get_fork_confidence(&self, slot: Slot) -> Option<&BankConfidence> {
|
||||||
self.bank_confidence.get(&fork)
|
self.bank_confidence.get(&slot)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn total_stake(&self) -> u64 {
|
pub fn total_stake(&self) -> u64 {
|
||||||
|
@ -57,7 +61,7 @@ impl ForkConfidenceCache {
|
||||||
&self,
|
&self,
|
||||||
minimum_depth: usize,
|
minimum_depth: usize,
|
||||||
minimum_stake_percentage: f64,
|
minimum_stake_percentage: f64,
|
||||||
) -> Option<u64> {
|
) -> Option<Slot> {
|
||||||
self.bank_confidence
|
self.bank_confidence
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|&(_, bank_confidence)| {
|
.filter(|&(_, bank_confidence)| {
|
||||||
|
@ -160,7 +164,7 @@ impl AggregateConfidenceService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn aggregate_confidence(ancestors: &[u64], bank: &Bank) -> HashMap<u64, BankConfidence> {
|
pub fn aggregate_confidence(ancestors: &[Slot], bank: &Bank) -> HashMap<Slot, BankConfidence> {
|
||||||
assert!(!ancestors.is_empty());
|
assert!(!ancestors.is_empty());
|
||||||
|
|
||||||
// Check ancestors is sorted
|
// Check ancestors is sorted
|
||||||
|
@ -191,9 +195,9 @@ impl AggregateConfidenceService {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn aggregate_confidence_for_vote_account(
|
fn aggregate_confidence_for_vote_account(
|
||||||
confidence: &mut HashMap<u64, BankConfidence>,
|
confidence: &mut HashMap<Slot, BankConfidence>,
|
||||||
vote_state: &VoteState,
|
vote_state: &VoteState,
|
||||||
ancestors: &[u64],
|
ancestors: &[Slot],
|
||||||
lamports: u64,
|
lamports: u64,
|
||||||
) {
|
) {
|
||||||
assert!(!ancestors.is_empty());
|
assert!(!ancestors.is_empty());
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use solana_ledger::bank_forks::BankForks;
|
use solana_ledger::bank_forks::BankForks;
|
||||||
use solana_metrics::datapoint_debug;
|
use solana_metrics::datapoint_debug;
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::bank::Bank;
|
||||||
use solana_sdk::account::Account;
|
use solana_sdk::{account::Account, clock::Slot, hash::Hash, pubkey::Pubkey};
|
||||||
use solana_sdk::hash::Hash;
|
|
||||||
use solana_sdk::pubkey::Pubkey;
|
|
||||||
use solana_vote_api::vote_state::{Lockout, Vote, VoteState, MAX_LOCKOUT_HISTORY};
|
use solana_vote_api::vote_state::{Lockout, Vote, VoteState, MAX_LOCKOUT_HISTORY};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::{
|
||||||
use std::sync::Arc;
|
collections::{HashMap, HashSet},
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
|
||||||
pub const VOTE_THRESHOLD_DEPTH: usize = 8;
|
pub const VOTE_THRESHOLD_DEPTH: usize = 8;
|
||||||
pub const VOTE_THRESHOLD_SIZE: f64 = 2f64 / 3f64;
|
pub const VOTE_THRESHOLD_SIZE: f64 = 2f64 / 3f64;
|
||||||
|
@ -66,8 +66,8 @@ impl Tower {
|
||||||
&self,
|
&self,
|
||||||
bank_slot: u64,
|
bank_slot: u64,
|
||||||
vote_accounts: F,
|
vote_accounts: F,
|
||||||
ancestors: &HashMap<u64, HashSet<u64>>,
|
ancestors: &HashMap<Slot, HashSet<u64>>,
|
||||||
) -> (HashMap<u64, StakeLockout>, u64)
|
) -> (HashMap<Slot, StakeLockout>, u64)
|
||||||
where
|
where
|
||||||
F: Iterator<Item = (Pubkey, (u64, Account))>,
|
F: Iterator<Item = (Pubkey, (u64, Account))>,
|
||||||
{
|
{
|
||||||
|
@ -167,11 +167,12 @@ impl Tower {
|
||||||
.map(|lockout| (lockout.stake as f64 / total_staked as f64) > self.threshold_size)
|
.map(|lockout| (lockout.stake as f64 / total_staked as f64) > self.threshold_size)
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_vote(
|
fn new_vote(
|
||||||
local_vote_state: &VoteState,
|
local_vote_state: &VoteState,
|
||||||
slot: u64,
|
slot: u64,
|
||||||
hash: Hash,
|
hash: Hash,
|
||||||
last_bank_slot: Option<u64>,
|
last_bank_slot: Option<Slot>,
|
||||||
) -> Vote {
|
) -> Vote {
|
||||||
let mut local_vote_state = local_vote_state.clone();
|
let mut local_vote_state = local_vote_state.clone();
|
||||||
let vote = Vote {
|
let vote = Vote {
|
||||||
|
@ -179,12 +180,12 @@ impl Tower {
|
||||||
hash,
|
hash,
|
||||||
};
|
};
|
||||||
local_vote_state.process_vote_unchecked(&vote);
|
local_vote_state.process_vote_unchecked(&vote);
|
||||||
let slots = if let Some(lbs) = last_bank_slot {
|
let slots = if let Some(last_bank_slot) = last_bank_slot {
|
||||||
local_vote_state
|
local_vote_state
|
||||||
.votes
|
.votes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|v| v.slot)
|
.map(|v| v.slot)
|
||||||
.skip_while(|s| *s <= lbs)
|
.skip_while(|s| *s <= last_bank_slot)
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
local_vote_state.votes.iter().map(|v| v.slot).collect()
|
local_vote_state.votes.iter().map(|v| v.slot).collect()
|
||||||
|
@ -197,7 +198,8 @@ impl Tower {
|
||||||
);
|
);
|
||||||
Vote { slots, hash }
|
Vote { slots, hash }
|
||||||
}
|
}
|
||||||
fn last_bank_vote(bank: &Bank, vote_account_pubkey: &Pubkey) -> Option<u64> {
|
|
||||||
|
fn last_bank_vote(bank: &Bank, vote_account_pubkey: &Pubkey) -> Option<Slot> {
|
||||||
let vote_account = bank.vote_accounts().get(vote_account_pubkey)?.1.clone();
|
let vote_account = bank.vote_accounts().get(vote_account_pubkey)?.1.clone();
|
||||||
let bank_vote_state = VoteState::deserialize(&vote_account.data).ok()?;
|
let bank_vote_state = VoteState::deserialize(&vote_account.data).ok()?;
|
||||||
bank_vote_state.votes.iter().map(|v| v.slot).last()
|
bank_vote_state.votes.iter().map(|v| v.slot).last()
|
||||||
|
@ -207,7 +209,8 @@ impl Tower {
|
||||||
let last_vote = Self::last_bank_vote(bank, vote_account_pubkey);
|
let last_vote = Self::last_bank_vote(bank, vote_account_pubkey);
|
||||||
Self::new_vote(&self.lockouts, bank.slot(), bank.hash(), last_vote)
|
Self::new_vote(&self.lockouts, bank.slot(), bank.hash(), last_vote)
|
||||||
}
|
}
|
||||||
pub fn record_bank_vote(&mut self, vote: Vote) -> Option<u64> {
|
|
||||||
|
pub fn record_bank_vote(&mut self, vote: Vote) -> Option<Slot> {
|
||||||
let slot = *vote.slots.last().unwrap_or(&0);
|
let slot = *vote.slots.last().unwrap_or(&0);
|
||||||
trace!("{} record_vote for {}", self.node_pubkey, slot);
|
trace!("{} record_vote for {}", self.node_pubkey, slot);
|
||||||
let root_slot = self.lockouts.root_slot;
|
let root_slot = self.lockouts.root_slot;
|
||||||
|
@ -225,7 +228,8 @@ impl Tower {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn record_vote(&mut self, slot: u64, hash: Hash) -> Option<u64> {
|
|
||||||
|
pub fn record_vote(&mut self, slot: Slot, hash: Hash) -> Option<Slot> {
|
||||||
let vote = Vote {
|
let vote = Vote {
|
||||||
slots: vec![slot],
|
slots: vec![slot],
|
||||||
hash,
|
hash,
|
||||||
|
@ -237,11 +241,11 @@ impl Tower {
|
||||||
self.last_vote.clone()
|
self.last_vote.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn root(&self) -> Option<u64> {
|
pub fn root(&self) -> Option<Slot> {
|
||||||
self.lockouts.root_slot
|
self.lockouts.root_slot
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn calculate_weight(&self, stake_lockouts: &HashMap<u64, StakeLockout>) -> u128 {
|
pub fn calculate_weight(&self, stake_lockouts: &HashMap<Slot, StakeLockout>) -> u128 {
|
||||||
let mut sum = 0u128;
|
let mut sum = 0u128;
|
||||||
let root_slot = self.lockouts.root_slot.unwrap_or(0);
|
let root_slot = self.lockouts.root_slot.unwrap_or(0);
|
||||||
for (slot, stake_lockout) in stake_lockouts {
|
for (slot, stake_lockout) in stake_lockouts {
|
||||||
|
@ -272,7 +276,7 @@ impl Tower {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_locked_out(&self, slot: u64, ancestors: &HashMap<u64, HashSet<u64>>) -> bool {
|
pub fn is_locked_out(&self, slot: Slot, ancestors: &HashMap<Slot, HashSet<Slot>>) -> bool {
|
||||||
assert!(ancestors.contains_key(&slot));
|
assert!(ancestors.contains_key(&slot));
|
||||||
|
|
||||||
if !self.is_recent(slot) {
|
if !self.is_recent(slot) {
|
||||||
|
@ -290,11 +294,11 @@ impl Tower {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(root) = lockouts.root_slot {
|
if let Some(root_slot) = lockouts.root_slot {
|
||||||
// This case should never happen because bank forks purges all
|
// This case should never happen because bank forks purges all
|
||||||
// non-descendants of the root every time root is set
|
// non-descendants of the root every time root is set
|
||||||
if slot != root {
|
if slot != root_slot {
|
||||||
assert!(ancestors[&slot].contains(&root));
|
assert!(ancestors[&slot].contains(&root_slot));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,9 +327,9 @@ impl Tower {
|
||||||
|
|
||||||
/// Update lockouts for all the ancestors
|
/// Update lockouts for all the ancestors
|
||||||
fn update_ancestor_lockouts(
|
fn update_ancestor_lockouts(
|
||||||
stake_lockouts: &mut HashMap<u64, StakeLockout>,
|
stake_lockouts: &mut HashMap<Slot, StakeLockout>,
|
||||||
vote: &Lockout,
|
vote: &Lockout,
|
||||||
ancestors: &HashMap<u64, HashSet<u64>>,
|
ancestors: &HashMap<Slot, HashSet<Slot>>,
|
||||||
) {
|
) {
|
||||||
// If there's no ancestors, that means this slot must be from before the current root,
|
// If there's no ancestors, that means this slot must be from before the current root,
|
||||||
// in which case the lockouts won't be calculated in bank_weight anyways, so ignore
|
// in which case the lockouts won't be calculated in bank_weight anyways, so ignore
|
||||||
|
@ -345,10 +349,10 @@ impl Tower {
|
||||||
/// Update stake for all the ancestors.
|
/// Update stake for all the ancestors.
|
||||||
/// Note, stake is the same for all the ancestor.
|
/// Note, stake is the same for all the ancestor.
|
||||||
fn update_ancestor_stakes(
|
fn update_ancestor_stakes(
|
||||||
stake_lockouts: &mut HashMap<u64, StakeLockout>,
|
stake_lockouts: &mut HashMap<Slot, StakeLockout>,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
lamports: u64,
|
lamports: u64,
|
||||||
ancestors: &HashMap<u64, HashSet<u64>>,
|
ancestors: &HashMap<Slot, HashSet<Slot>>,
|
||||||
) {
|
) {
|
||||||
// If there's no ancestors, that means this slot must be from before the current root,
|
// If there's no ancestors, that means this slot must be from before the current root,
|
||||||
// in which case the lockouts won't be calculated in bank_weight anyways, so ignore
|
// in which case the lockouts won't be calculated in bank_weight anyways, so ignore
|
||||||
|
@ -365,7 +369,7 @@ impl Tower {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bank_weight(&self, bank: &Bank, ancestors: &HashMap<u64, HashSet<u64>>) -> u128 {
|
fn bank_weight(&self, bank: &Bank, ancestors: &HashMap<Slot, HashSet<Slot>>) -> u128 {
|
||||||
let (stake_lockouts, _) =
|
let (stake_lockouts, _) =
|
||||||
self.collect_vote_lockouts(bank.slot(), bank.vote_accounts().into_iter(), ancestors);
|
self.collect_vote_lockouts(bank.slot(), bank.vote_accounts().into_iter(), ancestors);
|
||||||
self.calculate_weight(&stake_lockouts)
|
self.calculate_weight(&stake_lockouts)
|
||||||
|
|
|
@ -1,28 +1,32 @@
|
||||||
//! The `packet` module defines data structures and methods to pull data from the network.
|
//! The `packet` module defines data structures and methods to pull data from the network.
|
||||||
use crate::cuda_runtime::PinnedVec;
|
use crate::{
|
||||||
use crate::recvmmsg::{recv_mmsg, NUM_RCVMMSGS};
|
cuda_runtime::PinnedVec,
|
||||||
use crate::recycler::{Recycler, Reset};
|
recvmmsg::{recv_mmsg, NUM_RCVMMSGS},
|
||||||
use crate::result::{Error, Result};
|
recycler::{Recycler, Reset},
|
||||||
|
result::{Error, Result},
|
||||||
|
};
|
||||||
use bincode;
|
use bincode;
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use solana_ledger::erasure::ErasureConfig;
|
use solana_ledger::erasure::ErasureConfig;
|
||||||
use solana_metrics::inc_new_counter_debug;
|
use solana_metrics::inc_new_counter_debug;
|
||||||
pub use solana_sdk::packet::{Meta, Packet, PACKET_DATA_SIZE};
|
pub use solana_sdk::packet::{Meta, Packet, PACKET_DATA_SIZE};
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::{
|
||||||
use solana_sdk::signature::Signable;
|
clock::Slot,
|
||||||
use solana_sdk::signature::Signature;
|
pubkey::Pubkey,
|
||||||
use std::borrow::Cow;
|
signature::{Signable, Signature},
|
||||||
use std::cmp;
|
};
|
||||||
use std::fmt;
|
use std::{
|
||||||
use std::io;
|
borrow::Cow,
|
||||||
use std::io::Cursor;
|
cmp, fmt, io,
|
||||||
use std::mem;
|
io::Cursor,
|
||||||
use std::mem::size_of;
|
mem,
|
||||||
use std::net::{SocketAddr, UdpSocket};
|
mem::size_of,
|
||||||
use std::ops::{Deref, DerefMut};
|
net::{SocketAddr, UdpSocket},
|
||||||
use std::sync::{Arc, RwLock};
|
ops::{Deref, DerefMut},
|
||||||
use std::time::Instant;
|
sync::{Arc, RwLock},
|
||||||
|
time::Instant,
|
||||||
|
};
|
||||||
|
|
||||||
pub type SharedBlob = Arc<RwLock<Blob>>;
|
pub type SharedBlob = Arc<RwLock<Blob>>;
|
||||||
pub type SharedBlobs = Vec<SharedBlob>;
|
pub type SharedBlobs = Vec<SharedBlob>;
|
||||||
|
@ -531,7 +535,13 @@ impl Signable for Blob {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn index_blobs(blobs: &[SharedBlob], id: &Pubkey, mut blob_index: u64, slot: u64, parent: u64) {
|
pub fn index_blobs(
|
||||||
|
blobs: &[SharedBlob],
|
||||||
|
id: &Pubkey,
|
||||||
|
mut blob_index: u64,
|
||||||
|
slot: Slot,
|
||||||
|
parent: Slot,
|
||||||
|
) {
|
||||||
// enumerate all the blobs, those are the indices
|
// enumerate all the blobs, those are the indices
|
||||||
for blob in blobs.iter() {
|
for blob in blobs.iter() {
|
||||||
let mut blob = blob.write().unwrap();
|
let mut blob = blob.write().unwrap();
|
||||||
|
|
|
@ -4,9 +4,11 @@ use crate::{
|
||||||
cluster_info::ClusterInfo, cluster_info_repair_listener::ClusterInfoRepairListener,
|
cluster_info::ClusterInfo, cluster_info_repair_listener::ClusterInfoRepairListener,
|
||||||
result::Result, service::Service,
|
result::Result, service::Service,
|
||||||
};
|
};
|
||||||
use solana_ledger::bank_forks::BankForks;
|
use solana_ledger::{
|
||||||
use solana_ledger::blocktree::{Blocktree, CompletedSlotsReceiver, SlotMeta};
|
bank_forks::BankForks,
|
||||||
use solana_sdk::{epoch_schedule::EpochSchedule, pubkey::Pubkey};
|
blocktree::{Blocktree, CompletedSlotsReceiver, SlotMeta},
|
||||||
|
};
|
||||||
|
use solana_sdk::{clock::Slot, epoch_schedule::EpochSchedule, pubkey::Pubkey};
|
||||||
use std::{
|
use std::{
|
||||||
collections::BTreeSet,
|
collections::BTreeSet,
|
||||||
net::UdpSocket,
|
net::UdpSocket,
|
||||||
|
@ -241,7 +243,7 @@ impl RepairService {
|
||||||
|
|
||||||
fn generate_repairs_for_slot(
|
fn generate_repairs_for_slot(
|
||||||
blocktree: &Blocktree,
|
blocktree: &Blocktree,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
slot_meta: &SlotMeta,
|
slot_meta: &SlotMeta,
|
||||||
max_repairs: usize,
|
max_repairs: usize,
|
||||||
) -> Vec<RepairType> {
|
) -> Vec<RepairType> {
|
||||||
|
@ -272,7 +274,7 @@ impl RepairService {
|
||||||
blocktree: &Blocktree,
|
blocktree: &Blocktree,
|
||||||
repairs: &mut Vec<RepairType>,
|
repairs: &mut Vec<RepairType>,
|
||||||
max_repairs: usize,
|
max_repairs: usize,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
) {
|
) {
|
||||||
let mut pending_slots = vec![slot];
|
let mut pending_slots = vec![slot];
|
||||||
while repairs.len() < max_repairs && !pending_slots.is_empty() {
|
while repairs.len() < max_repairs && !pending_slots.is_empty() {
|
||||||
|
|
|
@ -9,30 +9,37 @@ use crate::poh_recorder::PohRecorder;
|
||||||
use crate::result::{Error, Result};
|
use crate::result::{Error, Result};
|
||||||
use crate::rpc_subscriptions::RpcSubscriptions;
|
use crate::rpc_subscriptions::RpcSubscriptions;
|
||||||
use crate::service::Service;
|
use crate::service::Service;
|
||||||
use solana_ledger::bank_forks::BankForks;
|
use solana_ledger::{
|
||||||
use solana_ledger::block_error::BlockError;
|
bank_forks::BankForks,
|
||||||
use solana_ledger::blocktree::{Blocktree, BlocktreeError};
|
block_error::BlockError,
|
||||||
use solana_ledger::blocktree_processor;
|
blocktree::{Blocktree, BlocktreeError},
|
||||||
use solana_ledger::entry::{Entry, EntrySlice};
|
blocktree_processor,
|
||||||
use solana_ledger::leader_schedule_cache::LeaderScheduleCache;
|
entry::{Entry, EntrySlice},
|
||||||
use solana_ledger::snapshot_package::SnapshotPackageSender;
|
leader_schedule_cache::LeaderScheduleCache,
|
||||||
|
snapshot_package::SnapshotPackageSender,
|
||||||
|
};
|
||||||
use solana_measure::measure::Measure;
|
use solana_measure::measure::Measure;
|
||||||
use solana_metrics::{datapoint_warn, inc_new_counter_info};
|
use solana_metrics::{datapoint_warn, inc_new_counter_info};
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::bank::Bank;
|
||||||
use solana_sdk::hash::Hash;
|
use solana_sdk::{
|
||||||
use solana_sdk::pubkey::Pubkey;
|
clock::Slot,
|
||||||
use solana_sdk::signature::KeypairUtil;
|
hash::Hash,
|
||||||
use solana_sdk::timing::{self, duration_as_ms};
|
pubkey::Pubkey,
|
||||||
use solana_sdk::transaction::Transaction;
|
signature::KeypairUtil,
|
||||||
|
timing::{self, duration_as_ms},
|
||||||
|
transaction::Transaction,
|
||||||
|
};
|
||||||
use solana_vote_api::vote_instruction;
|
use solana_vote_api::vote_instruction;
|
||||||
use std::collections::HashMap;
|
use std::{
|
||||||
use std::collections::HashSet;
|
collections::HashMap,
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
collections::HashSet,
|
||||||
use std::sync::mpsc::{channel, Receiver, RecvTimeoutError, Sender};
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
sync::mpsc::{channel, Receiver, RecvTimeoutError, Sender},
|
||||||
use std::thread::{self, Builder, JoinHandle};
|
sync::{Arc, Mutex, RwLock},
|
||||||
use std::time::Duration;
|
thread::{self, Builder, JoinHandle},
|
||||||
use std::time::Instant;
|
time::Duration,
|
||||||
|
time::Instant,
|
||||||
|
};
|
||||||
|
|
||||||
pub const MAX_ENTRY_RECV_PER_ITER: usize = 512;
|
pub const MAX_ENTRY_RECV_PER_ITER: usize = 512;
|
||||||
|
|
||||||
|
@ -62,7 +69,7 @@ pub struct ReplayStage {
|
||||||
|
|
||||||
struct ReplaySlotStats {
|
struct ReplaySlotStats {
|
||||||
// Per-slot elapsed time
|
// Per-slot elapsed time
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
fetch_entries_elapsed: u64,
|
fetch_entries_elapsed: u64,
|
||||||
fetch_entries_fail_elapsed: u64,
|
fetch_entries_fail_elapsed: u64,
|
||||||
entry_verification_elapsed: u64,
|
entry_verification_elapsed: u64,
|
||||||
|
@ -71,7 +78,7 @@ struct ReplaySlotStats {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReplaySlotStats {
|
impl ReplaySlotStats {
|
||||||
pub fn new(slot: u64) -> Self {
|
pub fn new(slot: Slot) -> Self {
|
||||||
Self {
|
Self {
|
||||||
slot,
|
slot,
|
||||||
fetch_entries_elapsed: 0,
|
fetch_entries_elapsed: 0,
|
||||||
|
@ -120,7 +127,7 @@ struct ForkProgress {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ForkProgress {
|
impl ForkProgress {
|
||||||
pub fn new(slot: u64, last_entry: Hash) -> Self {
|
pub fn new(slot: Slot, last_entry: Hash) -> Self {
|
||||||
Self {
|
Self {
|
||||||
last_entry,
|
last_entry,
|
||||||
num_shreds: 0,
|
num_shreds: 0,
|
||||||
|
@ -300,7 +307,7 @@ impl ReplayStage {
|
||||||
|
|
||||||
fn log_leader_change(
|
fn log_leader_change(
|
||||||
my_pubkey: &Pubkey,
|
my_pubkey: &Pubkey,
|
||||||
bank_slot: u64,
|
bank_slot: Slot,
|
||||||
current_leader: &mut Option<Pubkey>,
|
current_leader: &mut Option<Pubkey>,
|
||||||
new_leader: &Pubkey,
|
new_leader: &Pubkey,
|
||||||
) {
|
) {
|
||||||
|
@ -451,7 +458,11 @@ impl ReplayStage {
|
||||||
(replay_result, tx_count)
|
(replay_result, tx_count)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mark_dead_slot(slot: u64, blocktree: &Blocktree, progress: &mut HashMap<u64, ForkProgress>) {
|
fn mark_dead_slot(
|
||||||
|
slot: Slot,
|
||||||
|
blocktree: &Blocktree,
|
||||||
|
progress: &mut HashMap<u64, ForkProgress>,
|
||||||
|
) {
|
||||||
// Remove from progress map so we no longer try to replay this bank
|
// Remove from progress map so we no longer try to replay this bank
|
||||||
let mut progress_entry = progress
|
let mut progress_entry = progress
|
||||||
.get_mut(&slot)
|
.get_mut(&slot)
|
||||||
|
|
|
@ -18,6 +18,7 @@ use solana_ledger::bank_forks::BankForks;
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::bank::Bank;
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account::Account,
|
account::Account,
|
||||||
|
clock::Slot,
|
||||||
epoch_schedule::EpochSchedule,
|
epoch_schedule::EpochSchedule,
|
||||||
fee_calculator::FeeCalculator,
|
fee_calculator::FeeCalculator,
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
|
@ -215,7 +216,7 @@ impl JsonRpcRequestProcessor {
|
||||||
Ok(self.bank().slots_per_segment())
|
Ok(self.bank().slots_per_segment())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_storage_pubkeys_for_slot(&self, slot: u64) -> Result<Vec<Pubkey>> {
|
fn get_storage_pubkeys_for_slot(&self, slot: Slot) -> Result<Vec<Pubkey>> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.storage_state
|
.storage_state
|
||||||
.get_pubkeys_for_slot(slot, &self.bank_forks))
|
.get_pubkeys_for_slot(slot, &self.bank_forks))
|
||||||
|
@ -710,7 +711,11 @@ impl RpcSol for RpcSolImpl {
|
||||||
.get_slots_per_segment()
|
.get_slots_per_segment()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_storage_pubkeys_for_slot(&self, meta: Self::Metadata, slot: u64) -> Result<Vec<Pubkey>> {
|
fn get_storage_pubkeys_for_slot(
|
||||||
|
&self,
|
||||||
|
meta: Self::Metadata,
|
||||||
|
slot: Slot,
|
||||||
|
) -> Result<Vec<Pubkey>> {
|
||||||
meta.request_processor
|
meta.request_processor
|
||||||
.read()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
|
@ -2,15 +2,13 @@
|
||||||
|
|
||||||
use core::hash::Hash;
|
use core::hash::Hash;
|
||||||
use jsonrpc_core::futures::Future;
|
use jsonrpc_core::futures::Future;
|
||||||
use jsonrpc_pubsub::typed::Sink;
|
use jsonrpc_pubsub::{typed::Sink, SubscriptionId};
|
||||||
use jsonrpc_pubsub::SubscriptionId;
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use solana_ledger::bank_forks::BankForks;
|
use solana_ledger::bank_forks::BankForks;
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::bank::Bank;
|
||||||
use solana_sdk::account::Account;
|
use solana_sdk::{
|
||||||
use solana_sdk::pubkey::Pubkey;
|
account::Account, clock::Slot, pubkey::Pubkey, signature::Signature, transaction,
|
||||||
use solana_sdk::signature::Signature;
|
};
|
||||||
use solana_sdk::transaction;
|
|
||||||
use solana_vote_api::vote_state::MAX_LOCKOUT_HISTORY;
|
use solana_vote_api::vote_state::MAX_LOCKOUT_HISTORY;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
@ -74,7 +72,7 @@ where
|
||||||
fn check_confirmations_and_notify<K, S, F, N, X>(
|
fn check_confirmations_and_notify<K, S, F, N, X>(
|
||||||
subscriptions: &HashMap<K, HashMap<SubscriptionId, (Sink<S>, Confirmations)>>,
|
subscriptions: &HashMap<K, HashMap<SubscriptionId, (Sink<S>, Confirmations)>>,
|
||||||
hashmap_key: &K,
|
hashmap_key: &K,
|
||||||
current_slot: u64,
|
current_slot: Slot,
|
||||||
bank_forks: &Arc<RwLock<BankForks>>,
|
bank_forks: &Arc<RwLock<BankForks>>,
|
||||||
bank_method: F,
|
bank_method: F,
|
||||||
notify: N,
|
notify: N,
|
||||||
|
@ -169,7 +167,7 @@ impl RpcSubscriptions {
|
||||||
pub fn check_account(
|
pub fn check_account(
|
||||||
&self,
|
&self,
|
||||||
pubkey: &Pubkey,
|
pubkey: &Pubkey,
|
||||||
current_slot: u64,
|
current_slot: Slot,
|
||||||
bank_forks: &Arc<RwLock<BankForks>>,
|
bank_forks: &Arc<RwLock<BankForks>>,
|
||||||
) {
|
) {
|
||||||
let subscriptions = self.account_subscriptions.read().unwrap();
|
let subscriptions = self.account_subscriptions.read().unwrap();
|
||||||
|
@ -186,7 +184,7 @@ impl RpcSubscriptions {
|
||||||
pub fn check_program(
|
pub fn check_program(
|
||||||
&self,
|
&self,
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
current_slot: u64,
|
current_slot: Slot,
|
||||||
bank_forks: &Arc<RwLock<BankForks>>,
|
bank_forks: &Arc<RwLock<BankForks>>,
|
||||||
) {
|
) {
|
||||||
let subscriptions = self.program_subscriptions.write().unwrap();
|
let subscriptions = self.program_subscriptions.write().unwrap();
|
||||||
|
@ -203,7 +201,7 @@ impl RpcSubscriptions {
|
||||||
pub fn check_signature(
|
pub fn check_signature(
|
||||||
&self,
|
&self,
|
||||||
signature: &Signature,
|
signature: &Signature,
|
||||||
current_slot: u64,
|
current_slot: Slot,
|
||||||
bank_forks: &Arc<RwLock<BankForks>>,
|
bank_forks: &Arc<RwLock<BankForks>>,
|
||||||
) {
|
) {
|
||||||
let mut subscriptions = self.signature_subscriptions.write().unwrap();
|
let mut subscriptions = self.signature_subscriptions.write().unwrap();
|
||||||
|
@ -268,7 +266,7 @@ impl RpcSubscriptions {
|
||||||
|
|
||||||
/// Notify subscribers of changes to any accounts or new signatures since
|
/// Notify subscribers of changes to any accounts or new signatures since
|
||||||
/// the bank's last checkpoint.
|
/// the bank's last checkpoint.
|
||||||
pub fn notify_subscribers(&self, current_slot: u64, bank_forks: &Arc<RwLock<BankForks>>) {
|
pub fn notify_subscribers(&self, current_slot: Slot, bank_forks: &Arc<RwLock<BankForks>>) {
|
||||||
let pubkeys: Vec<_> = {
|
let pubkeys: Vec<_> = {
|
||||||
let subs = self.account_subscriptions.read().unwrap();
|
let subs = self.account_subscriptions.read().unwrap();
|
||||||
subs.keys().cloned().collect()
|
subs.keys().cloned().collect()
|
||||||
|
|
|
@ -2,38 +2,45 @@
|
||||||
// for storage mining. Archivers submit storage proofs, validator then bundles them
|
// for storage mining. Archivers submit storage proofs, validator then bundles them
|
||||||
// to submit its proof for mining to be rewarded.
|
// to submit its proof for mining to be rewarded.
|
||||||
|
|
||||||
use crate::chacha_cuda::chacha_cbc_encrypt_file_many_keys;
|
use crate::{
|
||||||
use crate::cluster_info::ClusterInfo;
|
chacha_cuda::chacha_cbc_encrypt_file_many_keys,
|
||||||
use crate::contact_info::ContactInfo;
|
cluster_info::ClusterInfo,
|
||||||
use crate::result::{Error, Result};
|
contact_info::ContactInfo,
|
||||||
use crate::service::Service;
|
result::{Error, Result},
|
||||||
|
service::Service,
|
||||||
|
};
|
||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
use rand_chacha::ChaChaRng;
|
use rand_chacha::ChaChaRng;
|
||||||
use solana_ledger::bank_forks::BankForks;
|
use solana_ledger::{bank_forks::BankForks, blocktree::Blocktree};
|
||||||
use solana_ledger::blocktree::Blocktree;
|
use solana_runtime::{bank::Bank, storage_utils::archiver_accounts};
|
||||||
use solana_runtime::bank::Bank;
|
use solana_sdk::{
|
||||||
use solana_runtime::storage_utils::archiver_accounts;
|
account::Account,
|
||||||
use solana_sdk::account::Account;
|
account_utils::State,
|
||||||
use solana_sdk::account_utils::State;
|
clock::{get_segment_from_slot, Slot},
|
||||||
use solana_sdk::clock::get_segment_from_slot;
|
hash::Hash,
|
||||||
use solana_sdk::hash::Hash;
|
instruction::Instruction,
|
||||||
use solana_sdk::instruction::Instruction;
|
message::Message,
|
||||||
use solana_sdk::message::Message;
|
pubkey::Pubkey,
|
||||||
use solana_sdk::pubkey::Pubkey;
|
signature::{Keypair, KeypairUtil, Signature},
|
||||||
use solana_sdk::signature::{Keypair, KeypairUtil, Signature};
|
transaction::Transaction,
|
||||||
use solana_sdk::transaction::Transaction;
|
};
|
||||||
use solana_storage_api::storage_contract::{Proof, ProofStatus, StorageContract};
|
use solana_storage_api::{
|
||||||
use solana_storage_api::storage_instruction;
|
storage_contract::{Proof, ProofStatus, StorageContract},
|
||||||
use solana_storage_api::storage_instruction::proof_validation;
|
storage_instruction,
|
||||||
use std::collections::HashMap;
|
storage_instruction::proof_validation,
|
||||||
use std::mem::size_of;
|
};
|
||||||
use std::net::UdpSocket;
|
use std::{
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
cmp,
|
||||||
use std::sync::mpsc::{channel, Receiver, RecvTimeoutError, Sender};
|
collections::HashMap,
|
||||||
use std::sync::{Arc, RwLock};
|
io,
|
||||||
use std::thread::{self, sleep, Builder, JoinHandle};
|
mem::size_of,
|
||||||
use std::time::{Duration, Instant};
|
net::UdpSocket,
|
||||||
use std::{cmp, io};
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
|
sync::mpsc::{channel, Receiver, RecvTimeoutError, Sender},
|
||||||
|
sync::{Arc, RwLock},
|
||||||
|
thread::{self, sleep, Builder, JoinHandle},
|
||||||
|
time::{Duration, Instant},
|
||||||
|
};
|
||||||
|
|
||||||
// Block of hash answers to validate against
|
// Block of hash answers to validate against
|
||||||
// Vec of [ledger blocks] x [keys]
|
// Vec of [ledger blocks] x [keys]
|
||||||
|
@ -47,7 +54,7 @@ pub struct StorageStateInner {
|
||||||
pub storage_keys: StorageKeys,
|
pub storage_keys: StorageKeys,
|
||||||
archiver_map: ArchiverMap,
|
archiver_map: ArchiverMap,
|
||||||
storage_blockhash: Hash,
|
storage_blockhash: Hash,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
slots_per_segment: u64,
|
slots_per_segment: u64,
|
||||||
slots_per_turn: u64,
|
slots_per_turn: u64,
|
||||||
}
|
}
|
||||||
|
@ -133,7 +140,7 @@ impl StorageState {
|
||||||
|
|
||||||
pub fn get_pubkeys_for_slot(
|
pub fn get_pubkeys_for_slot(
|
||||||
&self,
|
&self,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
bank_forks: &Arc<RwLock<BankForks>>,
|
bank_forks: &Arc<RwLock<BankForks>>,
|
||||||
) -> Vec<Pubkey> {
|
) -> Vec<Pubkey> {
|
||||||
// TODO: keep track of age?
|
// TODO: keep track of age?
|
||||||
|
@ -364,7 +371,7 @@ impl StorageStage {
|
||||||
state: &Arc<RwLock<StorageStateInner>>,
|
state: &Arc<RwLock<StorageStateInner>>,
|
||||||
_blocktree: &Arc<Blocktree>,
|
_blocktree: &Arc<Blocktree>,
|
||||||
blockhash: Hash,
|
blockhash: Hash,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
slots_per_segment: u64,
|
slots_per_segment: u64,
|
||||||
instruction_sender: &InstructionSender,
|
instruction_sender: &InstructionSender,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
@ -440,7 +447,7 @@ impl StorageStage {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_proofs(
|
fn collect_proofs(
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
slots_per_segment: u64,
|
slots_per_segment: u64,
|
||||||
account_id: Pubkey,
|
account_id: Pubkey,
|
||||||
account: Account,
|
account: Account,
|
||||||
|
|
|
@ -295,6 +295,7 @@ mod test {
|
||||||
shred::Shredder,
|
shred::Shredder,
|
||||||
};
|
};
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
|
clock::Slot,
|
||||||
epoch_schedule::MINIMUM_SLOTS_PER_EPOCH,
|
epoch_schedule::MINIMUM_SLOTS_PER_EPOCH,
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
signature::{Keypair, KeypairUtil},
|
signature::{Keypair, KeypairUtil},
|
||||||
|
@ -310,8 +311,8 @@ mod test {
|
||||||
|
|
||||||
fn local_entries_to_shred(
|
fn local_entries_to_shred(
|
||||||
entries: &[Entry],
|
entries: &[Entry],
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
parent: u64,
|
parent: Slot,
|
||||||
keypair: &Arc<Keypair>,
|
keypair: &Arc<Keypair>,
|
||||||
) -> Vec<Shred> {
|
) -> Vec<Shred> {
|
||||||
let shredder = Shredder::new(slot, parent, 0.0, keypair.clone())
|
let shredder = Shredder::new(slot, parent, 0.0, keypair.clone())
|
||||||
|
|
|
@ -5,26 +5,36 @@ mod tests {
|
||||||
use bincode::serialize_into;
|
use bincode::serialize_into;
|
||||||
use fs_extra::dir::CopyOptions;
|
use fs_extra::dir::CopyOptions;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use solana_core::genesis_utils::{create_genesis_block, GenesisBlockInfo};
|
use solana_core::{
|
||||||
use solana_core::service::Service;
|
genesis_utils::{create_genesis_block, GenesisBlockInfo},
|
||||||
use solana_core::snapshot_packager_service::SnapshotPackagerService;
|
service::Service,
|
||||||
use solana_ledger::bank_forks::{BankForks, SnapshotConfig};
|
snapshot_packager_service::SnapshotPackagerService,
|
||||||
use solana_ledger::snapshot_utils;
|
};
|
||||||
use solana_runtime::bank::Bank;
|
use solana_ledger::{
|
||||||
use solana_runtime::status_cache::SlotDelta;
|
bank_forks::{BankForks, SnapshotConfig},
|
||||||
use solana_runtime::status_cache::MAX_CACHE_ENTRIES;
|
snapshot_utils,
|
||||||
use solana_sdk::hash::hashv;
|
};
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_runtime::{
|
||||||
use solana_sdk::signature::{Keypair, KeypairUtil};
|
bank::Bank,
|
||||||
use solana_sdk::system_transaction;
|
status_cache::{SlotDelta, MAX_CACHE_ENTRIES},
|
||||||
use solana_sdk::transaction::Result as TransactionResult;
|
};
|
||||||
use std::fs;
|
use solana_sdk::{
|
||||||
use std::fs::File;
|
clock::Slot,
|
||||||
use std::io::{BufWriter, Write};
|
hash::hashv,
|
||||||
use std::path::PathBuf;
|
pubkey::Pubkey,
|
||||||
use std::sync::atomic::AtomicBool;
|
signature::{Keypair, KeypairUtil},
|
||||||
use std::sync::mpsc::channel;
|
system_transaction,
|
||||||
use std::sync::Arc;
|
transaction::Result as TransactionResult,
|
||||||
|
};
|
||||||
|
use std::{
|
||||||
|
fs,
|
||||||
|
fs::File,
|
||||||
|
io::{BufWriter, Write},
|
||||||
|
path::PathBuf,
|
||||||
|
sync::atomic::AtomicBool,
|
||||||
|
sync::mpsc::channel,
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
|
|
||||||
struct SnapshotTestConfig {
|
struct SnapshotTestConfig {
|
||||||
|
@ -100,7 +110,7 @@ mod tests {
|
||||||
// also marks each bank as root and generates snapshots
|
// also marks each bank as root and generates snapshots
|
||||||
// finally tries to restore from the last bank's snapshot and compares the restored bank to the
|
// finally tries to restore from the last bank's snapshot and compares the restored bank to the
|
||||||
// `last_slot` bank
|
// `last_slot` bank
|
||||||
fn run_bank_forks_snapshot_n<F>(last_slot: u64, f: F, set_root_interval: u64)
|
fn run_bank_forks_snapshot_n<F>(last_slot: Slot, f: F, set_root_interval: u64)
|
||||||
where
|
where
|
||||||
F: Fn(&mut Bank, &Keypair),
|
F: Fn(&mut Bank, &Keypair),
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,7 +17,7 @@ enum LedgerOutputMethod {
|
||||||
Json,
|
Json,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_slot(blocktree: &Blocktree, slot: u64, method: &LedgerOutputMethod) {
|
fn output_slot(blocktree: &Blocktree, slot: Slot, method: &LedgerOutputMethod) {
|
||||||
let entries = blocktree
|
let entries = blocktree
|
||||||
.get_slot_entries(slot, 0, None)
|
.get_slot_entries(slot, 0, None)
|
||||||
.unwrap_or_else(|err| {
|
.unwrap_or_else(|err| {
|
||||||
|
@ -36,7 +36,7 @@ fn output_slot(blocktree: &Blocktree, slot: u64, method: &LedgerOutputMethod) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_ledger(blocktree: Blocktree, starting_slot: u64, method: LedgerOutputMethod) {
|
fn output_ledger(blocktree: Blocktree, starting_slot: Slot, method: LedgerOutputMethod) {
|
||||||
let rooted_slot_iterator =
|
let rooted_slot_iterator =
|
||||||
RootedSlotIterator::new(starting_slot, &blocktree).unwrap_or_else(|err| {
|
RootedSlotIterator::new(starting_slot, &blocktree).unwrap_or_else(|err| {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
|
|
|
@ -5,14 +5,15 @@ use crate::snapshot_utils::{self, SnapshotError};
|
||||||
use log::*;
|
use log::*;
|
||||||
use solana_measure::measure::Measure;
|
use solana_measure::measure::Measure;
|
||||||
use solana_metrics::inc_new_counter_info;
|
use solana_metrics::inc_new_counter_info;
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::{bank::Bank, status_cache::MAX_CACHE_ENTRIES};
|
||||||
use solana_runtime::status_cache::MAX_CACHE_ENTRIES;
|
use solana_sdk::{clock::Slot, timing};
|
||||||
use solana_sdk::timing;
|
use std::{
|
||||||
use std::collections::{HashMap, HashSet};
|
collections::{HashMap, HashSet},
|
||||||
use std::ops::Index;
|
ops::Index,
|
||||||
use std::path::{Path, PathBuf};
|
path::{Path, PathBuf},
|
||||||
use std::sync::Arc;
|
sync::Arc,
|
||||||
use std::time::Instant;
|
time::Instant,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct SnapshotConfig {
|
pub struct SnapshotConfig {
|
||||||
|
@ -46,22 +47,22 @@ impl std::convert::From<SnapshotPackageSendError> for BankForksError {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BankForks {
|
pub struct BankForks {
|
||||||
pub banks: HashMap<u64, Arc<Bank>>,
|
pub banks: HashMap<Slot, Arc<Bank>>,
|
||||||
working_bank: Arc<Bank>,
|
working_bank: Arc<Bank>,
|
||||||
root: u64,
|
root: Slot,
|
||||||
pub snapshot_config: Option<SnapshotConfig>,
|
pub snapshot_config: Option<SnapshotConfig>,
|
||||||
last_snapshot_slot: u64,
|
last_snapshot_slot: Slot,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Index<u64> for BankForks {
|
impl Index<u64> for BankForks {
|
||||||
type Output = Arc<Bank>;
|
type Output = Arc<Bank>;
|
||||||
fn index(&self, bank_slot: u64) -> &Arc<Bank> {
|
fn index(&self, bank_slot: Slot) -> &Arc<Bank> {
|
||||||
&self.banks[&bank_slot]
|
&self.banks[&bank_slot]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BankForks {
|
impl BankForks {
|
||||||
pub fn new(bank_slot: u64, bank: Bank) -> Self {
|
pub fn new(bank_slot: Slot, bank: Bank) -> Self {
|
||||||
let mut banks = HashMap::new();
|
let mut banks = HashMap::new();
|
||||||
let working_bank = Arc::new(bank);
|
let working_bank = Arc::new(bank);
|
||||||
banks.insert(bank_slot, working_bank.clone());
|
banks.insert(bank_slot, working_bank.clone());
|
||||||
|
@ -75,11 +76,11 @@ impl BankForks {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a map of bank slot id to the set of ancestors for the bank slot.
|
/// Create a map of bank slot id to the set of ancestors for the bank slot.
|
||||||
pub fn ancestors(&self) -> HashMap<u64, HashSet<u64>> {
|
pub fn ancestors(&self) -> HashMap<Slot, HashSet<Slot>> {
|
||||||
let mut ancestors = HashMap::new();
|
let mut ancestors = HashMap::new();
|
||||||
let root = self.root;
|
let root = self.root;
|
||||||
for bank in self.banks.values() {
|
for bank in self.banks.values() {
|
||||||
let mut set: HashSet<u64> = bank
|
let mut set: HashSet<Slot> = bank
|
||||||
.ancestors
|
.ancestors
|
||||||
.keys()
|
.keys()
|
||||||
.filter(|k| **k >= root)
|
.filter(|k| **k >= root)
|
||||||
|
@ -93,11 +94,11 @@ impl BankForks {
|
||||||
|
|
||||||
/// Create a map of bank slot id to the set of all of its descendants
|
/// Create a map of bank slot id to the set of all of its descendants
|
||||||
#[allow(clippy::or_fun_call)]
|
#[allow(clippy::or_fun_call)]
|
||||||
pub fn descendants(&self) -> HashMap<u64, HashSet<u64>> {
|
pub fn descendants(&self) -> HashMap<Slot, HashSet<Slot>> {
|
||||||
let mut descendants = HashMap::new();
|
let mut descendants = HashMap::new();
|
||||||
for bank in self.banks.values() {
|
for bank in self.banks.values() {
|
||||||
let _ = descendants.entry(bank.slot()).or_insert(HashSet::new());
|
let _ = descendants.entry(bank.slot()).or_insert(HashSet::new());
|
||||||
let mut set: HashSet<u64> = bank.ancestors.keys().cloned().collect();
|
let mut set: HashSet<Slot> = bank.ancestors.keys().cloned().collect();
|
||||||
set.remove(&bank.slot());
|
set.remove(&bank.slot());
|
||||||
for parent in set {
|
for parent in set {
|
||||||
descendants
|
descendants
|
||||||
|
@ -109,7 +110,7 @@ impl BankForks {
|
||||||
descendants
|
descendants
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn frozen_banks(&self) -> HashMap<u64, Arc<Bank>> {
|
pub fn frozen_banks(&self) -> HashMap<Slot, Arc<Bank>> {
|
||||||
self.banks
|
self.banks
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_, b)| b.is_frozen())
|
.filter(|(_, b)| b.is_frozen())
|
||||||
|
@ -117,7 +118,7 @@ impl BankForks {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn active_banks(&self) -> Vec<u64> {
|
pub fn active_banks(&self) -> Vec<Slot> {
|
||||||
self.banks
|
self.banks
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_, v)| !v.is_frozen())
|
.filter(|(_, v)| !v.is_frozen())
|
||||||
|
@ -125,11 +126,11 @@ impl BankForks {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, bank_slot: u64) -> Option<&Arc<Bank>> {
|
pub fn get(&self, bank_slot: Slot) -> Option<&Arc<Bank>> {
|
||||||
self.banks.get(&bank_slot)
|
self.banks.get(&bank_slot)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_from_banks(initial_forks: &[Arc<Bank>], rooted_path: Vec<u64>) -> Self {
|
pub fn new_from_banks(initial_forks: &[Arc<Bank>], rooted_path: Vec<Slot>) -> Self {
|
||||||
let mut banks = HashMap::new();
|
let mut banks = HashMap::new();
|
||||||
let working_bank = initial_forks[0].clone();
|
let working_bank = initial_forks[0].clone();
|
||||||
|
|
||||||
|
@ -169,7 +170,11 @@ impl BankForks {
|
||||||
self.working_bank.clone()
|
self.working_bank.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_root(&mut self, root: u64, snapshot_package_sender: &Option<SnapshotPackageSender>) {
|
pub fn set_root(
|
||||||
|
&mut self,
|
||||||
|
root: Slot,
|
||||||
|
snapshot_package_sender: &Option<SnapshotPackageSender>,
|
||||||
|
) {
|
||||||
self.root = root;
|
self.root = root;
|
||||||
let set_root_start = Instant::now();
|
let set_root_start = Instant::now();
|
||||||
let root_bank = self
|
let root_bank = self
|
||||||
|
@ -190,7 +195,7 @@ impl BankForks {
|
||||||
if self.snapshot_config.is_some() && snapshot_package_sender.is_some() {
|
if self.snapshot_config.is_some() && snapshot_package_sender.is_some() {
|
||||||
let config = self.snapshot_config.as_ref().unwrap();
|
let config = self.snapshot_config.as_ref().unwrap();
|
||||||
info!("setting snapshot root: {}", root);
|
info!("setting snapshot root: {}", root);
|
||||||
if root - self.last_snapshot_slot >= config.snapshot_interval_slots as u64 {
|
if root - self.last_snapshot_slot >= config.snapshot_interval_slots as Slot {
|
||||||
let mut snapshot_time = Measure::start("total-snapshot-ms");
|
let mut snapshot_time = Measure::start("total-snapshot-ms");
|
||||||
let r = self.generate_snapshot(
|
let r = self.generate_snapshot(
|
||||||
root,
|
root,
|
||||||
|
@ -223,7 +228,7 @@ impl BankForks {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn root(&self) -> u64 {
|
pub fn root(&self) -> Slot {
|
||||||
self.root
|
self.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,8 +247,8 @@ impl BankForks {
|
||||||
|
|
||||||
pub fn generate_snapshot<P: AsRef<Path>>(
|
pub fn generate_snapshot<P: AsRef<Path>>(
|
||||||
&self,
|
&self,
|
||||||
root: u64,
|
root: Slot,
|
||||||
slots_to_snapshot: &[u64],
|
slots_to_snapshot: &[Slot],
|
||||||
snapshot_package_sender: &SnapshotPackageSender,
|
snapshot_package_sender: &SnapshotPackageSender,
|
||||||
tar_output_file: P,
|
tar_output_file: P,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
@ -281,7 +286,7 @@ impl BankForks {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prune_non_root(&mut self, root: u64) {
|
fn prune_non_root(&mut self, root: Slot) {
|
||||||
let descendants = self.descendants();
|
let descendants = self.descendants();
|
||||||
self.banks
|
self.banks
|
||||||
.retain(|slot, _| slot == &root || descendants[&root].contains(slot));
|
.retain(|slot, _| slot == &root || descendants[&root].contains(slot));
|
||||||
|
|
|
@ -201,11 +201,11 @@ impl Blocktree {
|
||||||
Database::destroy(&blocktree_path)
|
Database::destroy(&blocktree_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn meta(&self, slot: u64) -> Result<Option<SlotMeta>> {
|
pub fn meta(&self, slot: Slot) -> Result<Option<SlotMeta>> {
|
||||||
self.meta_cf.get(slot)
|
self.meta_cf.get(slot)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_full(&self, slot: u64) -> bool {
|
pub fn is_full(&self, slot: Slot) -> bool {
|
||||||
if let Ok(meta) = self.meta_cf.get(slot) {
|
if let Ok(meta) = self.meta_cf.get(slot) {
|
||||||
if let Some(meta) = meta {
|
if let Some(meta) = meta {
|
||||||
return meta.is_full();
|
return meta.is_full();
|
||||||
|
@ -293,17 +293,17 @@ impl Blocktree {
|
||||||
Ok(end)
|
Ok(end)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn erasure_meta(&self, slot: u64, set_index: u64) -> Result<Option<ErasureMeta>> {
|
pub fn erasure_meta(&self, slot: Slot, set_index: u64) -> Result<Option<ErasureMeta>> {
|
||||||
self.erasure_meta_cf.get((slot, set_index))
|
self.erasure_meta_cf.get((slot, set_index))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn orphan(&self, slot: u64) -> Result<Option<bool>> {
|
pub fn orphan(&self, slot: Slot) -> Result<Option<bool>> {
|
||||||
self.orphans_cf.get(slot)
|
self.orphans_cf.get(slot)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn slot_meta_iterator<'a>(
|
pub fn slot_meta_iterator<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
) -> Result<impl Iterator<Item = (u64, SlotMeta)> + 'a> {
|
) -> Result<impl Iterator<Item = (u64, SlotMeta)> + 'a> {
|
||||||
let meta_iter = self
|
let meta_iter = self
|
||||||
.db
|
.db
|
||||||
|
@ -319,7 +319,7 @@ impl Blocktree {
|
||||||
|
|
||||||
pub fn slot_data_iterator<'a>(
|
pub fn slot_data_iterator<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
) -> Result<impl Iterator<Item = ((u64, u64), Box<[u8]>)> + 'a> {
|
) -> Result<impl Iterator<Item = ((u64, u64), Box<[u8]>)> + 'a> {
|
||||||
let slot_iterator = self
|
let slot_iterator = self
|
||||||
.db
|
.db
|
||||||
|
@ -837,13 +837,13 @@ impl Blocktree {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_data_shred(&self, slot: u64, index: u64) -> Result<Option<Vec<u8>>> {
|
pub fn get_data_shred(&self, slot: Slot, index: u64) -> Result<Option<Vec<u8>>> {
|
||||||
self.data_shred_cf.get_bytes((slot, index))
|
self.data_shred_cf.get_bytes((slot, index))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_data_shreds(
|
pub fn get_data_shreds(
|
||||||
&self,
|
&self,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
from_index: u64,
|
from_index: u64,
|
||||||
to_index: u64,
|
to_index: u64,
|
||||||
buffer: &mut [u8],
|
buffer: &mut [u8],
|
||||||
|
@ -880,13 +880,13 @@ impl Blocktree {
|
||||||
Ok((last_index, buffer_offset))
|
Ok((last_index, buffer_offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_coding_shred(&self, slot: u64, index: u64) -> Result<Option<Vec<u8>>> {
|
pub fn get_coding_shred(&self, slot: Slot, index: u64) -> Result<Option<Vec<u8>>> {
|
||||||
self.code_shred_cf.get_bytes((slot, index))
|
self.code_shred_cf.get_bytes((slot, index))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_entries(
|
pub fn write_entries(
|
||||||
&self,
|
&self,
|
||||||
start_slot: u64,
|
start_slot: Slot,
|
||||||
num_ticks_in_start_slot: u64,
|
num_ticks_in_start_slot: u64,
|
||||||
start_index: u32,
|
start_index: u32,
|
||||||
ticks_per_slot: u64,
|
ticks_per_slot: u64,
|
||||||
|
@ -946,14 +946,14 @@ impl Blocktree {
|
||||||
Ok(num_shreds)
|
Ok(num_shreds)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_index(&self, slot: u64) -> Result<Option<Index>> {
|
pub fn get_index(&self, slot: Slot) -> Result<Option<Index>> {
|
||||||
self.index_cf.get(slot)
|
self.index_cf.get(slot)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Manually update the meta for a slot.
|
/// Manually update the meta for a slot.
|
||||||
/// Can interfere with automatic meta update and potentially break chaining.
|
/// Can interfere with automatic meta update and potentially break chaining.
|
||||||
/// Dangerous. Use with care.
|
/// Dangerous. Use with care.
|
||||||
pub fn put_meta_bytes(&self, slot: u64, bytes: &[u8]) -> Result<()> {
|
pub fn put_meta_bytes(&self, slot: Slot, bytes: &[u8]) -> Result<()> {
|
||||||
self.meta_cf.put_bytes(slot, bytes)
|
self.meta_cf.put_bytes(slot, bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -962,7 +962,7 @@ impl Blocktree {
|
||||||
// for the slot with the specified slot
|
// for the slot with the specified slot
|
||||||
fn find_missing_indexes<C>(
|
fn find_missing_indexes<C>(
|
||||||
db_iterator: &mut DBRawIterator,
|
db_iterator: &mut DBRawIterator,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
start_index: u64,
|
start_index: u64,
|
||||||
end_index: u64,
|
end_index: u64,
|
||||||
max_missing: usize,
|
max_missing: usize,
|
||||||
|
@ -1027,7 +1027,7 @@ impl Blocktree {
|
||||||
|
|
||||||
pub fn find_missing_data_indexes(
|
pub fn find_missing_data_indexes(
|
||||||
&self,
|
&self,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
start_index: u64,
|
start_index: u64,
|
||||||
end_index: u64,
|
end_index: u64,
|
||||||
max_missing: usize,
|
max_missing: usize,
|
||||||
|
@ -1051,7 +1051,7 @@ impl Blocktree {
|
||||||
/// Returns the entry vector for the slot starting with `shred_start_index`
|
/// Returns the entry vector for the slot starting with `shred_start_index`
|
||||||
pub fn get_slot_entries(
|
pub fn get_slot_entries(
|
||||||
&self,
|
&self,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
shred_start_index: u64,
|
shred_start_index: u64,
|
||||||
_max_entries: Option<u64>,
|
_max_entries: Option<u64>,
|
||||||
) -> Result<Vec<Entry>> {
|
) -> Result<Vec<Entry>> {
|
||||||
|
@ -1061,7 +1061,7 @@ impl Blocktree {
|
||||||
|
|
||||||
pub fn get_slot_entries_with_shred_count(
|
pub fn get_slot_entries_with_shred_count(
|
||||||
&self,
|
&self,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
start_index: u64,
|
start_index: u64,
|
||||||
) -> Result<(Vec<Entry>, usize)> {
|
) -> Result<(Vec<Entry>, usize)> {
|
||||||
let slot_meta_cf = self.db.column::<cf::SlotMeta>();
|
let slot_meta_cf = self.db.column::<cf::SlotMeta>();
|
||||||
|
@ -1127,7 +1127,7 @@ impl Blocktree {
|
||||||
|
|
||||||
fn get_entries_in_data_block(
|
fn get_entries_in_data_block(
|
||||||
&self,
|
&self,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
start_index: u32,
|
start_index: u32,
|
||||||
end_index: u32,
|
end_index: u32,
|
||||||
) -> Result<Vec<Entry>> {
|
) -> Result<Vec<Entry>> {
|
||||||
|
@ -1196,7 +1196,7 @@ impl Blocktree {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_root(&self, slot: u64) -> bool {
|
pub fn is_root(&self, slot: Slot) -> bool {
|
||||||
if let Ok(Some(true)) = self.db.get::<cf::Root>(slot) {
|
if let Ok(Some(true)) = self.db.get::<cf::Root>(slot) {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
|
@ -1220,7 +1220,7 @@ impl Blocktree {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_dead(&self, slot: u64) -> bool {
|
pub fn is_dead(&self, slot: Slot) -> bool {
|
||||||
if let Some(true) = self
|
if let Some(true) = self
|
||||||
.db
|
.db
|
||||||
.get::<cf::DeadSlots>(slot)
|
.get::<cf::DeadSlots>(slot)
|
||||||
|
@ -1232,7 +1232,7 @@ impl Blocktree {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_dead_slot(&self, slot: u64) -> Result<()> {
|
pub fn set_dead_slot(&self, slot: Slot) -> Result<()> {
|
||||||
self.dead_slots_cf.put(slot, &true)
|
self.dead_slots_cf.put(slot, &true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1258,7 +1258,7 @@ impl Blocktree {
|
||||||
|
|
||||||
/// Prune blocktree such that slots higher than `target_slot` are deleted and all references to
|
/// Prune blocktree such that slots higher than `target_slot` are deleted and all references to
|
||||||
/// higher slots are removed
|
/// higher slots are removed
|
||||||
pub fn prune(&self, target_slot: u64) {
|
pub fn prune(&self, target_slot: Slot) {
|
||||||
let mut meta = self
|
let mut meta = self
|
||||||
.meta(target_slot)
|
.meta(target_slot)
|
||||||
.expect("couldn't read slot meta")
|
.expect("couldn't read slot meta")
|
||||||
|
@ -1332,7 +1332,7 @@ fn update_slot_meta(
|
||||||
|
|
||||||
fn get_index_meta_entry<'a>(
|
fn get_index_meta_entry<'a>(
|
||||||
db: &Database,
|
db: &Database,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
index_working_set: &'a mut HashMap<u64, IndexMetaWorkingSetEntry>,
|
index_working_set: &'a mut HashMap<u64, IndexMetaWorkingSetEntry>,
|
||||||
index_meta_time: &mut u64,
|
index_meta_time: &mut u64,
|
||||||
) -> &'a mut IndexMetaWorkingSetEntry {
|
) -> &'a mut IndexMetaWorkingSetEntry {
|
||||||
|
@ -1356,8 +1356,8 @@ fn get_index_meta_entry<'a>(
|
||||||
fn get_slot_meta_entry<'a>(
|
fn get_slot_meta_entry<'a>(
|
||||||
db: &Database,
|
db: &Database,
|
||||||
slot_meta_working_set: &'a mut HashMap<u64, SlotMetaWorkingSetEntry>,
|
slot_meta_working_set: &'a mut HashMap<u64, SlotMetaWorkingSetEntry>,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
parent_slot: u64,
|
parent_slot: Slot,
|
||||||
) -> &'a mut SlotMetaWorkingSetEntry {
|
) -> &'a mut SlotMetaWorkingSetEntry {
|
||||||
let meta_cf = db.column::<cf::SlotMeta>();
|
let meta_cf = db.column::<cf::SlotMeta>();
|
||||||
|
|
||||||
|
@ -1384,7 +1384,7 @@ fn get_slot_meta_entry<'a>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_valid_write_to_slot_0(slot_to_write: u64, parent_slot: u64, last_root: u64) -> bool {
|
fn is_valid_write_to_slot_0(slot_to_write: u64, parent_slot: Slot, last_root: u64) -> bool {
|
||||||
slot_to_write == 0 && last_root == 0 && parent_slot == 0
|
slot_to_write == 0 && last_root == 0 && parent_slot == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1475,7 +1475,7 @@ fn find_slot_meta_else_create<'a>(
|
||||||
// create a dummy orphan slot in the database
|
// create a dummy orphan slot in the database
|
||||||
fn find_slot_meta_in_db_else_create<'a>(
|
fn find_slot_meta_in_db_else_create<'a>(
|
||||||
db: &Database,
|
db: &Database,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
insert_map: &'a mut HashMap<u64, Rc<RefCell<SlotMeta>>>,
|
insert_map: &'a mut HashMap<u64, Rc<RefCell<SlotMeta>>>,
|
||||||
) -> Result<Rc<RefCell<SlotMeta>>> {
|
) -> Result<Rc<RefCell<SlotMeta>>> {
|
||||||
if let Some(slot_meta) = db.column::<cf::SlotMeta>().get(slot)? {
|
if let Some(slot_meta) = db.column::<cf::SlotMeta>().get(slot)? {
|
||||||
|
@ -1497,7 +1497,7 @@ fn find_slot_meta_in_db_else_create<'a>(
|
||||||
fn find_slot_meta_in_cached_state<'a>(
|
fn find_slot_meta_in_cached_state<'a>(
|
||||||
working_set: &'a HashMap<u64, SlotMetaWorkingSetEntry>,
|
working_set: &'a HashMap<u64, SlotMetaWorkingSetEntry>,
|
||||||
chained_slots: &'a HashMap<u64, Rc<RefCell<SlotMeta>>>,
|
chained_slots: &'a HashMap<u64, Rc<RefCell<SlotMeta>>>,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
) -> Result<Option<Rc<RefCell<SlotMeta>>>> {
|
) -> Result<Option<Rc<RefCell<SlotMeta>>>> {
|
||||||
if let Some(entry) = working_set.get(&slot) {
|
if let Some(entry) = working_set.get(&slot) {
|
||||||
Ok(Some(entry.new_slot_meta.clone()))
|
Ok(Some(entry.new_slot_meta.clone()))
|
||||||
|
@ -1535,7 +1535,7 @@ fn handle_chaining_for_slot(
|
||||||
write_batch: &mut WriteBatch,
|
write_batch: &mut WriteBatch,
|
||||||
working_set: &HashMap<u64, SlotMetaWorkingSetEntry>,
|
working_set: &HashMap<u64, SlotMetaWorkingSetEntry>,
|
||||||
new_chained_slots: &mut HashMap<u64, Rc<RefCell<SlotMeta>>>,
|
new_chained_slots: &mut HashMap<u64, Rc<RefCell<SlotMeta>>>,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let slot_meta_entry = working_set
|
let slot_meta_entry = working_set
|
||||||
.get(&slot)
|
.get(&slot)
|
||||||
|
@ -1614,7 +1614,7 @@ fn handle_chaining_for_slot(
|
||||||
|
|
||||||
fn traverse_children_mut<F>(
|
fn traverse_children_mut<F>(
|
||||||
db: &Database,
|
db: &Database,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
slot_meta: &Rc<RefCell<(SlotMeta)>>,
|
slot_meta: &Rc<RefCell<(SlotMeta)>>,
|
||||||
working_set: &HashMap<u64, SlotMetaWorkingSetEntry>,
|
working_set: &HashMap<u64, SlotMetaWorkingSetEntry>,
|
||||||
new_chained_slots: &mut HashMap<u64, Rc<RefCell<SlotMeta>>>,
|
new_chained_slots: &mut HashMap<u64, Rc<RefCell<SlotMeta>>>,
|
||||||
|
@ -1654,7 +1654,7 @@ fn is_orphan(meta: &SlotMeta) -> bool {
|
||||||
// 2) Determine whether to set the is_connected flag
|
// 2) Determine whether to set the is_connected flag
|
||||||
fn chain_new_slot_to_prev_slot(
|
fn chain_new_slot_to_prev_slot(
|
||||||
prev_slot_meta: &mut SlotMeta,
|
prev_slot_meta: &mut SlotMeta,
|
||||||
current_slot: u64,
|
current_slot: Slot,
|
||||||
current_slot_meta: &mut SlotMeta,
|
current_slot_meta: &mut SlotMeta,
|
||||||
) {
|
) {
|
||||||
prev_slot_meta.next_slots.push(current_slot);
|
prev_slot_meta.next_slots.push(current_slot);
|
||||||
|
@ -1747,7 +1747,7 @@ macro_rules! create_new_tmp_ledger {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify_shred_slots(slot: u64, parent_slot: u64, last_root: u64) -> bool {
|
pub fn verify_shred_slots(slot: Slot, parent_slot: Slot, last_root: u64) -> bool {
|
||||||
if !is_valid_write_to_slot_0(slot, parent_slot, last_root) {
|
if !is_valid_write_to_slot_0(slot, parent_slot, last_root) {
|
||||||
// Check that the parent_slot < slot
|
// Check that the parent_slot < slot
|
||||||
if parent_slot >= slot {
|
if parent_slot >= slot {
|
||||||
|
@ -1777,8 +1777,8 @@ pub fn create_new_tmp_ledger(name: &str, genesis_block: &GenesisBlock) -> (PathB
|
||||||
|
|
||||||
pub fn entries_to_test_shreds(
|
pub fn entries_to_test_shreds(
|
||||||
entries: Vec<Entry>,
|
entries: Vec<Entry>,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
parent_slot: u64,
|
parent_slot: Slot,
|
||||||
is_full_slot: bool,
|
is_full_slot: bool,
|
||||||
) -> Vec<Shred> {
|
) -> Vec<Shred> {
|
||||||
let shredder = Shredder::new(slot, parent_slot, 0.0, Arc::new(Keypair::new()))
|
let shredder = Shredder::new(slot, parent_slot, 0.0, Arc::new(Keypair::new()))
|
||||||
|
@ -1789,8 +1789,8 @@ pub fn entries_to_test_shreds(
|
||||||
|
|
||||||
// used for tests only
|
// used for tests only
|
||||||
pub fn make_slot_entries(
|
pub fn make_slot_entries(
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
parent_slot: u64,
|
parent_slot: Slot,
|
||||||
num_entries: u64,
|
num_entries: u64,
|
||||||
) -> (Vec<Shred>, Vec<Entry>) {
|
) -> (Vec<Shred>, Vec<Entry>) {
|
||||||
let entries = create_ticks(num_entries, 0, Hash::default());
|
let entries = create_ticks(num_entries, 0, Hash::default());
|
||||||
|
@ -1800,7 +1800,7 @@ pub fn make_slot_entries(
|
||||||
|
|
||||||
// used for tests only
|
// used for tests only
|
||||||
pub fn make_many_slot_entries(
|
pub fn make_many_slot_entries(
|
||||||
start_slot: u64,
|
start_slot: Slot,
|
||||||
num_slots: u64,
|
num_slots: u64,
|
||||||
entries_per_slot: u64,
|
entries_per_slot: u64,
|
||||||
) -> (Vec<Shred>, Vec<Entry>) {
|
) -> (Vec<Shred>, Vec<Entry>) {
|
||||||
|
|
|
@ -299,7 +299,7 @@ impl Column for columns::Index {
|
||||||
const NAME: &'static str = INDEX_CF;
|
const NAME: &'static str = INDEX_CF;
|
||||||
type Index = u64;
|
type Index = u64;
|
||||||
|
|
||||||
fn key(slot: u64) -> Vec<u8> {
|
fn key(slot: Slot) -> Vec<u8> {
|
||||||
let mut key = vec![0; 8];
|
let mut key = vec![0; 8];
|
||||||
BigEndian::write_u64(&mut key[..], slot);
|
BigEndian::write_u64(&mut key[..], slot);
|
||||||
key
|
key
|
||||||
|
@ -326,7 +326,7 @@ impl Column for columns::DeadSlots {
|
||||||
const NAME: &'static str = DEAD_SLOTS_CF;
|
const NAME: &'static str = DEAD_SLOTS_CF;
|
||||||
type Index = u64;
|
type Index = u64;
|
||||||
|
|
||||||
fn key(slot: u64) -> Vec<u8> {
|
fn key(slot: Slot) -> Vec<u8> {
|
||||||
let mut key = vec![0; 8];
|
let mut key = vec![0; 8];
|
||||||
BigEndian::write_u64(&mut key[..], slot);
|
BigEndian::write_u64(&mut key[..], slot);
|
||||||
key
|
key
|
||||||
|
@ -353,7 +353,7 @@ impl Column for columns::Orphans {
|
||||||
const NAME: &'static str = ORPHANS_CF;
|
const NAME: &'static str = ORPHANS_CF;
|
||||||
type Index = u64;
|
type Index = u64;
|
||||||
|
|
||||||
fn key(slot: u64) -> Vec<u8> {
|
fn key(slot: Slot) -> Vec<u8> {
|
||||||
let mut key = vec![0; 8];
|
let mut key = vec![0; 8];
|
||||||
BigEndian::write_u64(&mut key[..], slot);
|
BigEndian::write_u64(&mut key[..], slot);
|
||||||
key
|
key
|
||||||
|
@ -380,7 +380,7 @@ impl Column for columns::Root {
|
||||||
const NAME: &'static str = ROOT_CF;
|
const NAME: &'static str = ROOT_CF;
|
||||||
type Index = u64;
|
type Index = u64;
|
||||||
|
|
||||||
fn key(slot: u64) -> Vec<u8> {
|
fn key(slot: Slot) -> Vec<u8> {
|
||||||
let mut key = vec![0; 8];
|
let mut key = vec![0; 8];
|
||||||
BigEndian::write_u64(&mut key[..], slot);
|
BigEndian::write_u64(&mut key[..], slot);
|
||||||
key
|
key
|
||||||
|
@ -407,7 +407,7 @@ impl Column for columns::SlotMeta {
|
||||||
const NAME: &'static str = META_CF;
|
const NAME: &'static str = META_CF;
|
||||||
type Index = u64;
|
type Index = u64;
|
||||||
|
|
||||||
fn key(slot: u64) -> Vec<u8> {
|
fn key(slot: Slot) -> Vec<u8> {
|
||||||
let mut key = vec![0; 8];
|
let mut key = vec![0; 8];
|
||||||
BigEndian::write_u64(&mut key[..], slot);
|
BigEndian::write_u64(&mut key[..], slot);
|
||||||
key
|
key
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::erasure::ErasureConfig;
|
use crate::erasure::ErasureConfig;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use solana_metrics::datapoint;
|
use solana_metrics::datapoint;
|
||||||
|
use solana_sdk::clock::Slot;
|
||||||
use std::{collections::BTreeSet, ops::RangeBounds};
|
use std::{collections::BTreeSet, ops::RangeBounds};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize, Eq, PartialEq)]
|
#[derive(Clone, Debug, Default, Deserialize, Serialize, Eq, PartialEq)]
|
||||||
|
@ -8,7 +9,7 @@ use std::{collections::BTreeSet, ops::RangeBounds};
|
||||||
pub struct SlotMeta {
|
pub struct SlotMeta {
|
||||||
// The number of slots above the root (the genesis block). The first
|
// The number of slots above the root (the genesis block). The first
|
||||||
// slot has slot 0.
|
// slot has slot 0.
|
||||||
pub slot: u64,
|
pub slot: Slot,
|
||||||
// The total number of consecutive blobs starting from index 0
|
// The total number of consecutive blobs starting from index 0
|
||||||
// we have received for this slot.
|
// we have received for this slot.
|
||||||
pub consumed: u64,
|
pub consumed: u64,
|
||||||
|
@ -19,10 +20,10 @@ pub struct SlotMeta {
|
||||||
// The index of the blob that is flagged as the last blob for this slot.
|
// The index of the blob that is flagged as the last blob for this slot.
|
||||||
pub last_index: u64,
|
pub last_index: u64,
|
||||||
// The slot height of the block this one derives from.
|
// The slot height of the block this one derives from.
|
||||||
pub parent_slot: u64,
|
pub parent_slot: Slot,
|
||||||
// The list of slot heights, each of which contains a block that derives
|
// The list of slots, each of which contains a block that derives
|
||||||
// from this one.
|
// from this one.
|
||||||
pub next_slots: Vec<u64>,
|
pub next_slots: Vec<Slot>,
|
||||||
// True if this slot is full (consumed == last_index + 1) and if every
|
// True if this slot is full (consumed == last_index + 1) and if every
|
||||||
// slot that is a parent of this slot is also connected.
|
// slot that is a parent of this slot is also connected.
|
||||||
pub is_connected: bool,
|
pub is_connected: bool,
|
||||||
|
@ -33,7 +34,7 @@ pub struct SlotMeta {
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)]
|
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)]
|
||||||
/// Index recording presence/absence of blobs
|
/// Index recording presence/absence of blobs
|
||||||
pub struct Index {
|
pub struct Index {
|
||||||
pub slot: u64,
|
pub slot: Slot,
|
||||||
data: DataIndex,
|
data: DataIndex,
|
||||||
coding: CodingIndex,
|
coding: CodingIndex,
|
||||||
}
|
}
|
||||||
|
@ -70,7 +71,7 @@ pub enum ErasureMetaStatus {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Index {
|
impl Index {
|
||||||
pub(crate) fn new(slot: u64) -> Self {
|
pub(crate) fn new(slot: Slot) -> Self {
|
||||||
Index {
|
Index {
|
||||||
slot,
|
slot,
|
||||||
data: DataIndex::default(),
|
data: DataIndex::default(),
|
||||||
|
@ -174,7 +175,7 @@ impl SlotMeta {
|
||||||
self.parent_slot != std::u64::MAX
|
self.parent_slot != std::u64::MAX
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new(slot: u64, parent_slot: u64) -> Self {
|
pub(crate) fn new(slot: Slot, parent_slot: Slot) -> Self {
|
||||||
SlotMeta {
|
SlotMeta {
|
||||||
slot,
|
slot,
|
||||||
consumed: 0,
|
consumed: 0,
|
||||||
|
|
|
@ -132,6 +132,7 @@ impl Default for Session {
|
||||||
pub mod test {
|
pub mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use log::*;
|
use log::*;
|
||||||
|
use solana_sdk::clock::Slot;
|
||||||
|
|
||||||
/// Specifies the contents of a 16-data-blob and 4-coding-blob erasure set
|
/// Specifies the contents of a 16-data-blob and 4-coding-blob erasure set
|
||||||
/// Exists to be passed to `generate_blocktree_with_coding`
|
/// Exists to be passed to `generate_blocktree_with_coding`
|
||||||
|
@ -147,7 +148,7 @@ pub mod test {
|
||||||
/// Exists to be passed to `generate_blocktree_with_coding`
|
/// Exists to be passed to `generate_blocktree_with_coding`
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct SlotSpec {
|
pub struct SlotSpec {
|
||||||
pub slot: u64,
|
pub slot: Slot,
|
||||||
pub set_specs: Vec<ErasureSpec>,
|
pub set_specs: Vec<ErasureSpec>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
use crate::{blocktree::Blocktree, leader_schedule::LeaderSchedule, leader_schedule_utils};
|
use crate::{blocktree::Blocktree, leader_schedule::LeaderSchedule, leader_schedule_utils};
|
||||||
use log::*;
|
use log::*;
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::bank::Bank;
|
||||||
use solana_sdk::{epoch_schedule::EpochSchedule, pubkey::Pubkey};
|
use solana_sdk::{
|
||||||
|
clock::{Epoch, Slot},
|
||||||
|
epoch_schedule::EpochSchedule,
|
||||||
|
pubkey::Pubkey,
|
||||||
|
};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{hash_map::Entry, HashMap, VecDeque},
|
collections::{hash_map::Entry, HashMap, VecDeque},
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
type CachedSchedules = (HashMap<u64, Arc<LeaderSchedule>>, VecDeque<u64>);
|
type CachedSchedules = (HashMap<Epoch, Arc<LeaderSchedule>>, VecDeque<u64>);
|
||||||
const MAX_SCHEDULES: usize = 10;
|
const MAX_SCHEDULES: usize = 10;
|
||||||
|
|
||||||
struct CacheCapacity(usize);
|
struct CacheCapacity(usize);
|
||||||
|
@ -22,7 +26,7 @@ pub struct LeaderScheduleCache {
|
||||||
// Map from an epoch to a leader schedule for that epoch
|
// Map from an epoch to a leader schedule for that epoch
|
||||||
pub cached_schedules: RwLock<CachedSchedules>,
|
pub cached_schedules: RwLock<CachedSchedules>,
|
||||||
epoch_schedule: EpochSchedule,
|
epoch_schedule: EpochSchedule,
|
||||||
max_epoch: RwLock<u64>,
|
max_epoch: RwLock<Epoch>,
|
||||||
max_schedules: CacheCapacity,
|
max_schedules: CacheCapacity,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +83,7 @@ impl LeaderScheduleCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn slot_leader_at(&self, slot: u64, bank: Option<&Bank>) -> Option<Pubkey> {
|
pub fn slot_leader_at(&self, slot: Slot, bank: Option<&Bank>) -> Option<Pubkey> {
|
||||||
if let Some(bank) = bank {
|
if let Some(bank) = bank {
|
||||||
self.slot_leader_at_else_compute(slot, bank)
|
self.slot_leader_at_else_compute(slot, bank)
|
||||||
} else if self.epoch_schedule.slots_per_epoch == 0 {
|
} else if self.epoch_schedule.slots_per_epoch == 0 {
|
||||||
|
@ -93,10 +97,10 @@ impl LeaderScheduleCache {
|
||||||
pub fn next_leader_slot(
|
pub fn next_leader_slot(
|
||||||
&self,
|
&self,
|
||||||
pubkey: &Pubkey,
|
pubkey: &Pubkey,
|
||||||
mut current_slot: u64,
|
mut current_slot: Slot,
|
||||||
bank: &Bank,
|
bank: &Bank,
|
||||||
blocktree: Option<&Blocktree>,
|
blocktree: Option<&Blocktree>,
|
||||||
) -> Option<(u64, u64)> {
|
) -> Option<(Slot, Slot)> {
|
||||||
let (mut epoch, mut start_index) = bank.get_epoch_and_slot_index(current_slot + 1);
|
let (mut epoch, mut start_index) = bank.get_epoch_and_slot_index(current_slot + 1);
|
||||||
let mut first_slot = None;
|
let mut first_slot = None;
|
||||||
let mut last_slot = current_slot;
|
let mut last_slot = current_slot;
|
||||||
|
@ -149,7 +153,7 @@ impl LeaderScheduleCache {
|
||||||
first_slot.and_then(|slot| Some((slot, last_slot)))
|
first_slot.and_then(|slot| Some((slot, last_slot)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn slot_leader_at_no_compute(&self, slot: u64) -> Option<Pubkey> {
|
fn slot_leader_at_no_compute(&self, slot: Slot) -> Option<Pubkey> {
|
||||||
let (epoch, slot_index) = self.epoch_schedule.get_epoch_and_slot_index(slot);
|
let (epoch, slot_index) = self.epoch_schedule.get_epoch_and_slot_index(slot);
|
||||||
self.cached_schedules
|
self.cached_schedules
|
||||||
.read()
|
.read()
|
||||||
|
@ -159,7 +163,7 @@ impl LeaderScheduleCache {
|
||||||
.map(|schedule| schedule[slot_index])
|
.map(|schedule| schedule[slot_index])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn slot_leader_at_else_compute(&self, slot: u64, bank: &Bank) -> Option<Pubkey> {
|
fn slot_leader_at_else_compute(&self, slot: Slot, bank: &Bank) -> Option<Pubkey> {
|
||||||
let cache_result = self.slot_leader_at_no_compute(slot);
|
let cache_result = self.slot_leader_at_no_compute(slot);
|
||||||
// Forbid asking for slots in an unconfirmed epoch
|
// Forbid asking for slots in an unconfirmed epoch
|
||||||
let bank_epoch = self.epoch_schedule.get_epoch_and_slot_index(slot).0;
|
let bank_epoch = self.epoch_schedule.get_epoch_and_slot_index(slot).0;
|
||||||
|
@ -184,7 +188,7 @@ impl LeaderScheduleCache {
|
||||||
|
|
||||||
fn get_epoch_schedule_else_compute(
|
fn get_epoch_schedule_else_compute(
|
||||||
&self,
|
&self,
|
||||||
epoch: u64,
|
epoch: Epoch,
|
||||||
bank: &Bank,
|
bank: &Bank,
|
||||||
) -> Option<Arc<LeaderSchedule>> {
|
) -> Option<Arc<LeaderSchedule>> {
|
||||||
let epoch_schedule = self.cached_schedules.read().unwrap().0.get(&epoch).cloned();
|
let epoch_schedule = self.cached_schedules.read().unwrap().0.get(&epoch).cloned();
|
||||||
|
@ -198,7 +202,7 @@ impl LeaderScheduleCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_epoch_schedule(&self, epoch: u64, bank: &Bank) -> Option<Arc<LeaderSchedule>> {
|
fn compute_epoch_schedule(&self, epoch: Epoch, bank: &Bank) -> Option<Arc<LeaderSchedule>> {
|
||||||
let leader_schedule = leader_schedule_utils::leader_schedule(epoch, bank);
|
let leader_schedule = leader_schedule_utils::leader_schedule(epoch, bank);
|
||||||
leader_schedule.map(|leader_schedule| {
|
leader_schedule.map(|leader_schedule| {
|
||||||
let leader_schedule = Arc::new(leader_schedule);
|
let leader_schedule = Arc::new(leader_schedule);
|
||||||
|
@ -216,7 +220,7 @@ impl LeaderScheduleCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn retain_latest(
|
fn retain_latest(
|
||||||
schedules: &mut HashMap<u64, Arc<LeaderSchedule>>,
|
schedules: &mut HashMap<Epoch, Arc<LeaderSchedule>>,
|
||||||
order: &mut VecDeque<u64>,
|
order: &mut VecDeque<u64>,
|
||||||
max_schedules: usize,
|
max_schedules: usize,
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
use crate::leader_schedule::LeaderSchedule;
|
use crate::leader_schedule::LeaderSchedule;
|
||||||
use crate::staking_utils;
|
use crate::staking_utils;
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::bank::Bank;
|
||||||
use solana_sdk::clock::NUM_CONSECUTIVE_LEADER_SLOTS;
|
use solana_sdk::{
|
||||||
use solana_sdk::pubkey::Pubkey;
|
clock::{Epoch, Slot, NUM_CONSECUTIVE_LEADER_SLOTS},
|
||||||
|
pubkey::Pubkey,
|
||||||
|
};
|
||||||
|
|
||||||
/// Return the leader schedule for the given epoch.
|
/// Return the leader schedule for the given epoch.
|
||||||
pub fn leader_schedule(epoch: u64, bank: &Bank) -> Option<LeaderSchedule> {
|
pub fn leader_schedule(epoch: Epoch, bank: &Bank) -> Option<LeaderSchedule> {
|
||||||
staking_utils::staked_nodes_at_epoch(bank, epoch).map(|stakes| {
|
staking_utils::staked_nodes_at_epoch(bank, epoch).map(|stakes| {
|
||||||
let mut seed = [0u8; 32];
|
let mut seed = [0u8; 32];
|
||||||
seed[0..8].copy_from_slice(&epoch.to_le_bytes());
|
seed[0..8].copy_from_slice(&epoch.to_le_bytes());
|
||||||
|
@ -21,7 +23,7 @@ pub fn leader_schedule(epoch: u64, bank: &Bank) -> Option<LeaderSchedule> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the leader for the given slot.
|
/// Return the leader for the given slot.
|
||||||
pub fn slot_leader_at(slot: u64, bank: &Bank) -> Option<Pubkey> {
|
pub fn slot_leader_at(slot: Slot, bank: &Bank) -> Option<Pubkey> {
|
||||||
let (epoch, slot_index) = bank.get_epoch_and_slot_index(slot);
|
let (epoch, slot_index) = bank.get_epoch_and_slot_index(slot);
|
||||||
|
|
||||||
leader_schedule(epoch, bank).map(|leader_schedule| leader_schedule[slot_index])
|
leader_schedule(epoch, bank).map(|leader_schedule| leader_schedule[slot_index])
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
use crate::blocktree::*;
|
use crate::{blocktree::*, blocktree_meta::SlotMeta};
|
||||||
use crate::blocktree_meta::SlotMeta;
|
|
||||||
use log::*;
|
use log::*;
|
||||||
|
use solana_sdk::clock::Slot;
|
||||||
|
|
||||||
pub struct RootedSlotIterator<'a> {
|
pub struct RootedSlotIterator<'a> {
|
||||||
next_slots: Vec<u64>,
|
next_slots: Vec<Slot>,
|
||||||
blocktree: &'a Blocktree,
|
blocktree: &'a Blocktree,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> RootedSlotIterator<'a> {
|
impl<'a> RootedSlotIterator<'a> {
|
||||||
pub fn new(start_slot: u64, blocktree: &'a Blocktree) -> Result<Self> {
|
pub fn new(start_slot: Slot, blocktree: &'a Blocktree) -> Result<Self> {
|
||||||
if blocktree.is_root(start_slot) {
|
if blocktree.is_root(start_slot) {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
next_slots: vec![start_slot],
|
next_slots: vec![start_slot],
|
||||||
|
@ -20,7 +20,7 @@ impl<'a> RootedSlotIterator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a> Iterator for RootedSlotIterator<'a> {
|
impl<'a> Iterator for RootedSlotIterator<'a> {
|
||||||
type Item = (u64, SlotMeta);
|
type Item = (Slot, SlotMeta);
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
// Clone b/c passing the closure to the map below requires exclusive access to
|
// Clone b/c passing the closure to the map below requires exclusive access to
|
||||||
|
|
|
@ -1,19 +1,25 @@
|
||||||
//! The `shred` module defines data structures and methods to pull MTU sized data frames from the network.
|
//! The `shred` module defines data structures and methods to pull MTU sized data frames from the network.
|
||||||
use crate::entry::{create_ticks, Entry};
|
use crate::{
|
||||||
use crate::erasure::Session;
|
entry::{create_ticks, Entry},
|
||||||
|
erasure::Session,
|
||||||
|
};
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
use rayon::iter::{IndexedParallelIterator, IntoParallelRefMutIterator, ParallelIterator};
|
use rayon::{
|
||||||
use rayon::slice::ParallelSlice;
|
iter::{IndexedParallelIterator, IntoParallelRefMutIterator, ParallelIterator},
|
||||||
use rayon::ThreadPool;
|
slice::ParallelSlice,
|
||||||
|
ThreadPool,
|
||||||
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use solana_metrics::datapoint_debug;
|
use solana_metrics::datapoint_debug;
|
||||||
use solana_rayon_threadlimit::get_thread_count;
|
use solana_rayon_threadlimit::get_thread_count;
|
||||||
use solana_sdk::hash::Hash;
|
use solana_sdk::{
|
||||||
use solana_sdk::packet::PACKET_DATA_SIZE;
|
clock::Slot,
|
||||||
use solana_sdk::pubkey::Pubkey;
|
hash::Hash,
|
||||||
use solana_sdk::signature::{Keypair, KeypairUtil, Signature};
|
packet::PACKET_DATA_SIZE,
|
||||||
use std::sync::Arc;
|
pubkey::Pubkey,
|
||||||
use std::time::Instant;
|
signature::{Keypair, KeypairUtil, Signature},
|
||||||
|
};
|
||||||
|
use std::{sync::Arc, time::Instant};
|
||||||
|
|
||||||
/// The following constants are computed by hand, and hardcoded.
|
/// The following constants are computed by hand, and hardcoded.
|
||||||
/// `test_shred_constants` ensures that the values are correct.
|
/// `test_shred_constants` ensures that the values are correct.
|
||||||
|
@ -52,7 +58,7 @@ pub const DATA_COMPLETE_SHRED: u8 = 0b0000_0010;
|
||||||
pub enum ShredError {
|
pub enum ShredError {
|
||||||
InvalidShredType,
|
InvalidShredType,
|
||||||
InvalidFecRate(f32), // FEC rate must be more than 0.0 and less than 1.0
|
InvalidFecRate(f32), // FEC rate must be more than 0.0 and less than 1.0
|
||||||
SlotTooLow { slot: u64, parent_slot: u64 }, // "Current slot must be > Parent slot, but the difference must not be > u16::MAX
|
SlotTooLow { slot: Slot, parent_slot: Slot }, // "Current slot must be > Parent slot, but the difference must not be > u16::MAX
|
||||||
Serialize(std::boxed::Box<bincode::ErrorKind>),
|
Serialize(std::boxed::Box<bincode::ErrorKind>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +83,7 @@ impl Default for ShredType {
|
||||||
pub struct ShredCommonHeader {
|
pub struct ShredCommonHeader {
|
||||||
pub signature: Signature,
|
pub signature: Signature,
|
||||||
pub shred_type: ShredType,
|
pub shred_type: ShredType,
|
||||||
pub slot: u64,
|
pub slot: Slot,
|
||||||
pub index: u32,
|
pub index: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +135,7 @@ impl Shred {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_from_data(
|
pub fn new_from_data(
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
index: u32,
|
index: u32,
|
||||||
parent_offset: u16,
|
parent_offset: u16,
|
||||||
data: Option<&[u8]>,
|
data: Option<&[u8]>,
|
||||||
|
@ -256,11 +262,11 @@ impl Shred {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn slot(&self) -> u64 {
|
pub fn slot(&self) -> Slot {
|
||||||
self.common_header.slot
|
self.common_header.slot
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parent(&self) -> u64 {
|
pub fn parent(&self) -> Slot {
|
||||||
if self.is_data() {
|
if self.is_data() {
|
||||||
self.common_header.slot - u64::from(self.data_header.parent_offset)
|
self.common_header.slot - u64::from(self.data_header.parent_offset)
|
||||||
} else {
|
} else {
|
||||||
|
@ -280,7 +286,7 @@ impl Shred {
|
||||||
|
|
||||||
/// This is not a safe function. It only changes the meta information.
|
/// This is not a safe function. It only changes the meta information.
|
||||||
/// Use this only for test code which doesn't care about actual shred
|
/// Use this only for test code which doesn't care about actual shred
|
||||||
pub fn set_slot(&mut self, slot: u64) {
|
pub fn set_slot(&mut self, slot: Slot) {
|
||||||
self.common_header.slot = slot
|
self.common_header.slot = slot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,15 +341,20 @@ impl Shred {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Shredder {
|
pub struct Shredder {
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
parent_slot: u64,
|
parent_slot: Slot,
|
||||||
fec_rate: f32,
|
fec_rate: f32,
|
||||||
keypair: Arc<Keypair>,
|
keypair: Arc<Keypair>,
|
||||||
pub signing_coding_time: u128,
|
pub signing_coding_time: u128,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Shredder {
|
impl Shredder {
|
||||||
pub fn new(slot: u64, parent_slot: u64, fec_rate: f32, keypair: Arc<Keypair>) -> Result<Self> {
|
pub fn new(
|
||||||
|
slot: Slot,
|
||||||
|
parent_slot: Slot,
|
||||||
|
fec_rate: f32,
|
||||||
|
keypair: Arc<Keypair>,
|
||||||
|
) -> Result<Self> {
|
||||||
if fec_rate > 1.0 || fec_rate < 0.0 {
|
if fec_rate > 1.0 || fec_rate < 0.0 {
|
||||||
Err(ShredError::InvalidFecRate(fec_rate))
|
Err(ShredError::InvalidFecRate(fec_rate))
|
||||||
} else if slot < parent_slot || slot - parent_slot > u64::from(std::u16::MAX) {
|
} else if slot < parent_slot || slot - parent_slot > u64::from(std::u16::MAX) {
|
||||||
|
@ -450,7 +461,7 @@ impl Shredder {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_coding_shred_header(
|
pub fn new_coding_shred_header(
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
index: u32,
|
index: u32,
|
||||||
num_data: usize,
|
num_data: usize,
|
||||||
num_code: usize,
|
num_code: usize,
|
||||||
|
@ -472,7 +483,7 @@ impl Shredder {
|
||||||
|
|
||||||
/// Generates coding shreds for the data shreds in the current FEC set
|
/// Generates coding shreds for the data shreds in the current FEC set
|
||||||
pub fn generate_coding_shreds(
|
pub fn generate_coding_shreds(
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
fec_rate: f32,
|
fec_rate: f32,
|
||||||
data_shred_batch: &[Shred],
|
data_shred_batch: &[Shred],
|
||||||
) -> Vec<Shred> {
|
) -> Vec<Shred> {
|
||||||
|
@ -583,7 +594,7 @@ impl Shredder {
|
||||||
num_data: usize,
|
num_data: usize,
|
||||||
num_coding: usize,
|
num_coding: usize,
|
||||||
first_index: usize,
|
first_index: usize,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
) -> std::result::Result<Vec<Shred>, reed_solomon_erasure::Error> {
|
) -> std::result::Result<Vec<Shred>, reed_solomon_erasure::Error> {
|
||||||
let mut recovered_data = vec![];
|
let mut recovered_data = vec![];
|
||||||
let fec_set_size = num_data + num_coding;
|
let fec_set_size = num_data + num_coding;
|
||||||
|
@ -760,8 +771,8 @@ pub mod tests {
|
||||||
fn verify_test_data_shred(
|
fn verify_test_data_shred(
|
||||||
shred: &Shred,
|
shred: &Shred,
|
||||||
index: u32,
|
index: u32,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
parent: u64,
|
parent: Slot,
|
||||||
pk: &Pubkey,
|
pk: &Pubkey,
|
||||||
verify: bool,
|
verify: bool,
|
||||||
is_last_in_slot: bool,
|
is_last_in_slot: bool,
|
||||||
|
@ -785,7 +796,7 @@ pub mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_test_code_shred(shred: &Shred, index: u32, slot: u64, pk: &Pubkey, verify: bool) {
|
fn verify_test_code_shred(shred: &Shred, index: u32, slot: Slot, pk: &Pubkey, verify: bool) {
|
||||||
assert_eq!(shred.payload.len(), PACKET_DATA_SIZE);
|
assert_eq!(shred.payload.len(), PACKET_DATA_SIZE);
|
||||||
assert!(!shred.is_data());
|
assert!(!shred.is_data());
|
||||||
assert_eq!(shred.index(), index);
|
assert_eq!(shred.index(), index);
|
||||||
|
|
|
@ -4,14 +4,15 @@ use bzip2::bufread::BzDecoder;
|
||||||
use fs_extra::dir::CopyOptions;
|
use fs_extra::dir::CopyOptions;
|
||||||
use log::*;
|
use log::*;
|
||||||
use solana_measure::measure::Measure;
|
use solana_measure::measure::Measure;
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::{bank::Bank, status_cache::SlotDelta};
|
||||||
use solana_runtime::status_cache::SlotDelta;
|
use solana_sdk::{clock::Slot, transaction};
|
||||||
use solana_sdk::transaction;
|
use std::{
|
||||||
use std::cmp::Ordering;
|
cmp::Ordering,
|
||||||
use std::fs;
|
fs,
|
||||||
use std::fs::File;
|
fs::File,
|
||||||
use std::io::{BufReader, BufWriter, Error as IOError, ErrorKind};
|
io::{BufReader, BufWriter, Error as IOError, ErrorKind},
|
||||||
use std::path::{Path, PathBuf};
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
use tar::Archive;
|
use tar::Archive;
|
||||||
|
|
||||||
pub const SNAPSHOT_STATUS_CACHE_FILE_NAME: &str = "status_cache";
|
pub const SNAPSHOT_STATUS_CACHE_FILE_NAME: &str = "status_cache";
|
||||||
|
@ -20,7 +21,7 @@ pub const TAR_ACCOUNTS_DIR: &str = "accounts";
|
||||||
|
|
||||||
#[derive(PartialEq, Ord, Eq, Debug)]
|
#[derive(PartialEq, Ord, Eq, Debug)]
|
||||||
pub struct SlotSnapshotPaths {
|
pub struct SlotSnapshotPaths {
|
||||||
pub slot: u64,
|
pub slot: Slot,
|
||||||
pub snapshot_file_path: PathBuf,
|
pub snapshot_file_path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +78,7 @@ pub fn package_snapshot<P: AsRef<Path>, Q: AsRef<Path>>(
|
||||||
snapshot_files: &SlotSnapshotPaths,
|
snapshot_files: &SlotSnapshotPaths,
|
||||||
snapshot_package_output_file: P,
|
snapshot_package_output_file: P,
|
||||||
snapshot_path: Q,
|
snapshot_path: Q,
|
||||||
slots_to_snapshot: &[u64],
|
slots_to_snapshot: &[Slot],
|
||||||
) -> Result<SnapshotPackage> {
|
) -> Result<SnapshotPackage> {
|
||||||
// Hard link all the snapshots we need for this package
|
// Hard link all the snapshots we need for this package
|
||||||
let snapshot_hard_links_dir = tempfile::tempdir_in(snapshot_path)?;
|
let snapshot_hard_links_dir = tempfile::tempdir_in(snapshot_path)?;
|
||||||
|
@ -183,7 +184,7 @@ pub fn add_snapshot<P: AsRef<Path>>(snapshot_path: P, bank: &Bank) -> Result<()>
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_snapshot<P: AsRef<Path>>(slot: u64, snapshot_path: P) -> Result<()> {
|
pub fn remove_snapshot<P: AsRef<Path>>(slot: Slot, snapshot_path: P) -> Result<()> {
|
||||||
let slot_snapshot_dir = get_bank_snapshot_dir(&snapshot_path, slot);
|
let slot_snapshot_dir = get_bank_snapshot_dir(&snapshot_path, slot);
|
||||||
// Remove the snapshot directory for this slot
|
// Remove the snapshot directory for this slot
|
||||||
fs::remove_dir_all(slot_snapshot_dir)?;
|
fs::remove_dir_all(slot_snapshot_dir)?;
|
||||||
|
@ -295,11 +296,11 @@ where
|
||||||
Ok(bank)
|
Ok(bank)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_snapshot_file_name(slot: u64) -> String {
|
fn get_snapshot_file_name(slot: Slot) -> String {
|
||||||
slot.to_string()
|
slot.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_bank_snapshot_dir<P: AsRef<Path>>(path: P, slot: u64) -> PathBuf {
|
fn get_bank_snapshot_dir<P: AsRef<Path>>(path: P, slot: Slot) -> PathBuf {
|
||||||
path.as_ref().join(slot.to_string())
|
path.as_ref().join(slot.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::bank::Bank;
|
||||||
use solana_sdk::{account::Account, pubkey::Pubkey};
|
use solana_sdk::{
|
||||||
|
account::Account,
|
||||||
|
clock::{Epoch, Slot},
|
||||||
|
pubkey::Pubkey,
|
||||||
|
};
|
||||||
use solana_vote_api::vote_state::VoteState;
|
use solana_vote_api::vote_state::VoteState;
|
||||||
use std::{borrow::Borrow, collections::HashMap};
|
use std::{borrow::Borrow, collections::HashMap};
|
||||||
|
|
||||||
/// Looks through vote accounts, and finds the latest slot that has achieved
|
/// Looks through vote accounts, and finds the latest slot that has achieved
|
||||||
/// supermajority lockout
|
/// supermajority lockout
|
||||||
pub fn get_supermajority_slot(bank: &Bank, epoch_height: u64) -> Option<u64> {
|
pub fn get_supermajority_slot(bank: &Bank, epoch: Epoch) -> Option<u64> {
|
||||||
// Find the amount of stake needed for supermajority
|
// Find the amount of stake needed for supermajority
|
||||||
let stakes_and_lockouts = epoch_stakes_and_lockouts(bank, epoch_height);
|
let stakes_and_lockouts = epoch_stakes_and_lockouts(bank, epoch);
|
||||||
let total_stake: u64 = stakes_and_lockouts.iter().map(|s| s.0).sum();
|
let total_stake: u64 = stakes_and_lockouts.iter().map(|s| s.0).sum();
|
||||||
let supermajority_stake = total_stake * 2 / 3;
|
let supermajority_stake = total_stake * 2 / 3;
|
||||||
|
|
||||||
|
@ -29,8 +33,8 @@ pub fn staked_nodes(bank: &Bank) -> HashMap<Pubkey, u64> {
|
||||||
|
|
||||||
/// At the specified epoch, collect the delegate account balance and vote states for delegates
|
/// At the specified epoch, collect the delegate account balance and vote states for delegates
|
||||||
/// that have non-zero balance in any of their managed staking accounts
|
/// that have non-zero balance in any of their managed staking accounts
|
||||||
pub fn staked_nodes_at_epoch(bank: &Bank, epoch_height: u64) -> Option<HashMap<Pubkey, u64>> {
|
pub fn staked_nodes_at_epoch(bank: &Bank, epoch: Epoch) -> Option<HashMap<Pubkey, u64>> {
|
||||||
bank.epoch_vote_accounts(epoch_height)
|
bank.epoch_vote_accounts(epoch)
|
||||||
.map(|vote_accounts| to_staked_nodes(to_vote_states(vote_accounts.iter())))
|
.map(|vote_accounts| to_staked_nodes(to_vote_states(vote_accounts.iter())))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,9 +62,9 @@ fn to_staked_nodes(
|
||||||
map
|
map
|
||||||
}
|
}
|
||||||
|
|
||||||
fn epoch_stakes_and_lockouts(bank: &Bank, epoch_height: u64) -> Vec<(u64, Option<u64>)> {
|
fn epoch_stakes_and_lockouts(bank: &Bank, epoch: Epoch) -> Vec<(u64, Option<u64>)> {
|
||||||
let node_staked_accounts = bank
|
let node_staked_accounts = bank
|
||||||
.epoch_vote_accounts(epoch_height)
|
.epoch_vote_accounts(epoch)
|
||||||
.expect("Bank state for epoch is missing")
|
.expect("Bank state for epoch is missing")
|
||||||
.iter();
|
.iter();
|
||||||
|
|
||||||
|
@ -69,7 +73,7 @@ fn epoch_stakes_and_lockouts(bank: &Bank, epoch_height: u64) -> Vec<(u64, Option
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_supermajority_slot<'a, I>(supermajority_stake: u64, stakes_and_lockouts: I) -> Option<u64>
|
fn find_supermajority_slot<'a, I>(supermajority_stake: u64, stakes_and_lockouts: I) -> Option<Slot>
|
||||||
where
|
where
|
||||||
I: Iterator<Item = &'a (u64, Option<u64>)>,
|
I: Iterator<Item = &'a (u64, Option<u64>)>,
|
||||||
{
|
{
|
||||||
|
@ -111,7 +115,7 @@ pub(crate) mod tests {
|
||||||
use solana_vote_api::{vote_instruction, vote_state::VoteInit};
|
use solana_vote_api::{vote_instruction, vote_state::VoteInit};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
fn new_from_parent(parent: &Arc<Bank>, slot: u64) -> Bank {
|
fn new_from_parent(parent: &Arc<Bank>, slot: Slot) -> Bank {
|
||||||
Bank::new_from_parent(parent, &Pubkey::default(), slot)
|
Bank::new_from_parent(parent, &Pubkey::default(), slot)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ use solana_ledger::{
|
||||||
};
|
};
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
client::SyncClient,
|
client::SyncClient,
|
||||||
clock::{DEFAULT_TICKS_PER_SECOND, DEFAULT_TICKS_PER_SLOT, NUM_CONSECUTIVE_LEADER_SLOTS},
|
clock::{Slot, DEFAULT_TICKS_PER_SECOND, DEFAULT_TICKS_PER_SLOT, NUM_CONSECUTIVE_LEADER_SLOTS},
|
||||||
epoch_schedule::MINIMUM_SLOTS_PER_EPOCH,
|
epoch_schedule::MINIMUM_SLOTS_PER_EPOCH,
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
poh_config::PohConfig,
|
poh_config::PohConfig,
|
||||||
|
@ -282,7 +282,7 @@ fn poll_all_nodes_for_signature(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_and_verify_slot_entries(blocktree: &Blocktree, slot: u64, last_entry: &Hash) -> Vec<Entry> {
|
fn get_and_verify_slot_entries(blocktree: &Blocktree, slot: Slot, last_entry: &Hash) -> Vec<Entry> {
|
||||||
let entries = blocktree.get_slot_entries(slot, 0, None).unwrap();
|
let entries = blocktree.get_slot_entries(slot, 0, None).unwrap();
|
||||||
assert!(entries.verify(last_entry));
|
assert!(entries.verify(last_entry));
|
||||||
entries
|
entries
|
||||||
|
@ -290,7 +290,7 @@ fn get_and_verify_slot_entries(blocktree: &Blocktree, slot: u64, last_entry: &Ha
|
||||||
|
|
||||||
fn verify_slot_ticks(
|
fn verify_slot_ticks(
|
||||||
blocktree: &Blocktree,
|
blocktree: &Blocktree,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
last_entry: &Hash,
|
last_entry: &Hash,
|
||||||
expected_num_ticks: Option<usize>,
|
expected_num_ticks: Option<usize>,
|
||||||
) -> Hash {
|
) -> Hash {
|
||||||
|
|
|
@ -424,7 +424,7 @@ impl Stake {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deactivate(&mut self, epoch: u64) -> Result<(), StakeError> {
|
fn deactivate(&mut self, epoch: Epoch) -> Result<(), StakeError> {
|
||||||
if self.deactivation_epoch != std::u64::MAX {
|
if self.deactivation_epoch != std::u64::MAX {
|
||||||
Err(StakeError::AlreadyDeactivated)
|
Err(StakeError::AlreadyDeactivated)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2,14 +2,16 @@ use crate::storage_instruction::StorageAccountType;
|
||||||
use log::*;
|
use log::*;
|
||||||
use num_derive::FromPrimitive;
|
use num_derive::FromPrimitive;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use solana_sdk::account::Account;
|
use solana_sdk::{
|
||||||
use solana_sdk::account::KeyedAccount;
|
account::{Account, KeyedAccount},
|
||||||
use solana_sdk::account_utils::State;
|
account_utils::State,
|
||||||
use solana_sdk::hash::Hash;
|
clock::Epoch,
|
||||||
use solana_sdk::instruction::InstructionError;
|
hash::Hash,
|
||||||
use solana_sdk::pubkey::Pubkey;
|
instruction::InstructionError,
|
||||||
use solana_sdk::signature::Signature;
|
pubkey::Pubkey,
|
||||||
use solana_sdk::sysvar;
|
signature::Signature,
|
||||||
|
sysvar,
|
||||||
|
};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
// Todo Tune this for actual use cases when PoRep is feature complete
|
// Todo Tune this for actual use cases when PoRep is feature complete
|
||||||
|
@ -19,15 +21,15 @@ pub const MAX_PROOFS_PER_SEGMENT: usize = 80;
|
||||||
#[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq)]
|
#[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||||
pub struct Credits {
|
pub struct Credits {
|
||||||
// current epoch
|
// current epoch
|
||||||
epoch: u64,
|
epoch: Epoch,
|
||||||
// currently pending credits
|
// currently pending credits
|
||||||
pub current_epoch: u64,
|
pub current_epoch: Epoch,
|
||||||
// credits ready to be claimed
|
// credits ready to be claimed
|
||||||
pub redeemable: u64,
|
pub redeemable: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Credits {
|
impl Credits {
|
||||||
pub fn update_epoch(&mut self, current_epoch: u64) {
|
pub fn update_epoch(&mut self, current_epoch: Epoch) {
|
||||||
if self.epoch != current_epoch {
|
if self.epoch != current_epoch {
|
||||||
self.epoch = current_epoch;
|
self.epoch = current_epoch;
|
||||||
self.redeemable += self.current_epoch;
|
self.redeemable += self.current_epoch;
|
||||||
|
|
|
@ -313,7 +313,7 @@ impl VoteState {
|
||||||
self.epoch_credits.iter()
|
self.epoch_credits.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pop_expired_votes(&mut self, slot: u64) {
|
fn pop_expired_votes(&mut self, slot: Slot) {
|
||||||
loop {
|
loop {
|
||||||
if self.votes.back().map_or(false, |v| v.is_expired(slot)) {
|
if self.votes.back().map_or(false, |v| v.is_expired(slot)) {
|
||||||
self.votes.pop_back();
|
self.votes.pop_back();
|
||||||
|
@ -465,9 +465,7 @@ pub fn create_account(
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::vote_state;
|
use crate::vote_state;
|
||||||
use solana_sdk::account::Account;
|
use solana_sdk::{account::Account, account_utils::State, hash::hash};
|
||||||
use solana_sdk::account_utils::State;
|
|
||||||
use solana_sdk::hash::hash;
|
|
||||||
|
|
||||||
const MAX_RECENT_VOTES: usize = 16;
|
const MAX_RECENT_VOTES: usize = 16;
|
||||||
|
|
||||||
|
@ -528,7 +526,7 @@ mod tests {
|
||||||
vote_account: &mut Account,
|
vote_account: &mut Account,
|
||||||
vote: &Vote,
|
vote: &Vote,
|
||||||
slot_hashes: &[SlotHash],
|
slot_hashes: &[SlotHash],
|
||||||
epoch: u64,
|
epoch: Epoch,
|
||||||
) -> Result<VoteState, InstructionError> {
|
) -> Result<VoteState, InstructionError> {
|
||||||
process_vote(
|
process_vote(
|
||||||
&mut KeyedAccount::new(vote_pubkey, true, vote_account),
|
&mut KeyedAccount::new(vote_pubkey, true, vote_account),
|
||||||
|
|
|
@ -673,7 +673,12 @@ impl Accounts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_test_accounts(accounts: &Accounts, pubkeys: &mut Vec<Pubkey>, num: usize, slot: u64) {
|
pub fn create_test_accounts(
|
||||||
|
accounts: &Accounts,
|
||||||
|
pubkeys: &mut Vec<Pubkey>,
|
||||||
|
num: usize,
|
||||||
|
slot: Slot,
|
||||||
|
) {
|
||||||
for t in 0..num {
|
for t in 0..num {
|
||||||
let pubkey = Pubkey::new_rand();
|
let pubkey = Pubkey::new_rand();
|
||||||
let account = Account::new((t + 1) as u64, 0, &Account::default().owner);
|
let account = Account::new((t + 1) as u64, 0, &Account::default().owner);
|
||||||
|
|
|
@ -115,10 +115,10 @@ impl<'de> Visitor<'de> for AccountStorageVisitor {
|
||||||
|
|
||||||
pub struct AccountStorageSerialize<'a> {
|
pub struct AccountStorageSerialize<'a> {
|
||||||
account_storage: &'a AccountStorage,
|
account_storage: &'a AccountStorage,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
}
|
}
|
||||||
impl<'a> AccountStorageSerialize<'a> {
|
impl<'a> AccountStorageSerialize<'a> {
|
||||||
pub fn new(account_storage: &'a AccountStorage, slot: u64) -> Self {
|
pub fn new(account_storage: &'a AccountStorage, slot: Slot) -> Self {
|
||||||
Self {
|
Self {
|
||||||
account_storage,
|
account_storage,
|
||||||
slot,
|
slot,
|
||||||
|
@ -323,11 +323,11 @@ pub fn get_temp_accounts_paths(count: u32) -> IOResult<(Vec<TempDir>, String)> {
|
||||||
|
|
||||||
pub struct AccountsDBSerialize<'a> {
|
pub struct AccountsDBSerialize<'a> {
|
||||||
accounts_db: &'a AccountsDB,
|
accounts_db: &'a AccountsDB,
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> AccountsDBSerialize<'a> {
|
impl<'a> AccountsDBSerialize<'a> {
|
||||||
pub fn new(accounts_db: &'a AccountsDB, slot: u64) -> Self {
|
pub fn new(accounts_db: &'a AccountsDB, slot: Slot) -> Self {
|
||||||
Self { accounts_db, slot }
|
Self { accounts_db, slot }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,11 +64,11 @@ pub struct BankRc {
|
||||||
parent: RwLock<Option<Arc<Bank>>>,
|
parent: RwLock<Option<Arc<Bank>>>,
|
||||||
|
|
||||||
/// Current slot
|
/// Current slot
|
||||||
slot: u64,
|
slot: Slot,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BankRc {
|
impl BankRc {
|
||||||
pub fn new(account_paths: String, id: AppendVecId, slot: u64) -> Self {
|
pub fn new(account_paths: String, id: AppendVecId, slot: Slot) -> Self {
|
||||||
let accounts = Accounts::new(Some(account_paths));
|
let accounts = Accounts::new(Some(account_paths));
|
||||||
accounts
|
accounts
|
||||||
.accounts_db
|
.accounts_db
|
||||||
|
@ -133,7 +133,7 @@ impl StatusCacheRc {
|
||||||
sc.slot_deltas(slots)
|
sc.slot_deltas(slots)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn roots(&self) -> Vec<u64> {
|
pub fn roots(&self) -> Vec<Slot> {
|
||||||
self.status_cache
|
self.status_cache
|
||||||
.read()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -166,7 +166,7 @@ pub struct Bank {
|
||||||
blockhash_queue: RwLock<BlockhashQueue>,
|
blockhash_queue: RwLock<BlockhashQueue>,
|
||||||
|
|
||||||
/// The set of parents including this bank
|
/// The set of parents including this bank
|
||||||
pub ancestors: HashMap<u64, usize>,
|
pub ancestors: HashMap<Slot, usize>,
|
||||||
|
|
||||||
/// Hash of this Bank's state. Only meaningful after freezing.
|
/// Hash of this Bank's state. Only meaningful after freezing.
|
||||||
hash: RwLock<Hash>,
|
hash: RwLock<Hash>,
|
||||||
|
@ -246,7 +246,7 @@ pub struct Bank {
|
||||||
|
|
||||||
/// staked nodes on epoch boundaries, saved off when a bank.slot() is at
|
/// staked nodes on epoch boundaries, saved off when a bank.slot() is at
|
||||||
/// a leader schedule calculation boundary
|
/// a leader schedule calculation boundary
|
||||||
epoch_stakes: HashMap<u64, Stakes>,
|
epoch_stakes: HashMap<Epoch, Stakes>,
|
||||||
|
|
||||||
/// A boolean reflecting whether any entries were recorded into the PoH
|
/// A boolean reflecting whether any entries were recorded into the PoH
|
||||||
/// stream for the slot == self.slot
|
/// stream for the slot == self.slot
|
||||||
|
@ -295,7 +295,7 @@ impl Bank {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new bank that points to an immutable checkpoint of another bank.
|
/// Create a new bank that points to an immutable checkpoint of another bank.
|
||||||
pub fn new_from_parent(parent: &Arc<Bank>, collector_id: &Pubkey, slot: u64) -> Self {
|
pub fn new_from_parent(parent: &Arc<Bank>, collector_id: &Pubkey, slot: Slot) -> Self {
|
||||||
parent.freeze();
|
parent.freeze();
|
||||||
assert_ne!(slot, parent.slot());
|
assert_ne!(slot, parent.slot());
|
||||||
|
|
||||||
|
@ -408,11 +408,11 @@ impl Bank {
|
||||||
bank
|
bank
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn slot(&self) -> u64 {
|
pub fn slot(&self) -> Slot {
|
||||||
self.slot
|
self.slot
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn epoch(&self) -> u64 {
|
pub fn epoch(&self) -> Epoch {
|
||||||
self.epoch
|
self.epoch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -772,7 +772,7 @@ impl Bank {
|
||||||
/// tick that has achieved confirmation
|
/// tick that has achieved confirmation
|
||||||
pub fn get_confirmation_timestamp(
|
pub fn get_confirmation_timestamp(
|
||||||
&self,
|
&self,
|
||||||
mut slots_and_stakes: Vec<(u64, u64)>,
|
mut slots_and_stakes: Vec<(Slot, u64)>,
|
||||||
supermajority_stake: u64,
|
supermajority_stake: u64,
|
||||||
) -> Option<u64> {
|
) -> Option<u64> {
|
||||||
// Sort by slot height
|
// Sort by slot height
|
||||||
|
@ -1473,7 +1473,7 @@ impl Bank {
|
||||||
|
|
||||||
/// returns the epoch for which this bank's leader_schedule_slot_offset and slot would
|
/// returns the epoch for which this bank's leader_schedule_slot_offset and slot would
|
||||||
/// need to cache leader_schedule
|
/// need to cache leader_schedule
|
||||||
pub fn get_leader_schedule_epoch(&self, slot: u64) -> u64 {
|
pub fn get_leader_schedule_epoch(&self, slot: Slot) -> Epoch {
|
||||||
self.epoch_schedule.get_leader_schedule_epoch(slot)
|
self.epoch_schedule.get_leader_schedule_epoch(slot)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1544,7 +1544,7 @@ impl Bank {
|
||||||
///
|
///
|
||||||
/// ( slot/slots_per_epoch, slot % slots_per_epoch )
|
/// ( slot/slots_per_epoch, slot % slots_per_epoch )
|
||||||
///
|
///
|
||||||
pub fn get_epoch_and_slot_index(&self, slot: u64) -> (u64, u64) {
|
pub fn get_epoch_and_slot_index(&self, slot: Slot) -> (u64, u64) {
|
||||||
self.epoch_schedule.get_epoch_and_slot_index(slot)
|
self.epoch_schedule.get_epoch_and_slot_index(slot)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,15 +7,18 @@
|
||||||
//! Asynchronous implementations are expected to create transactions, sign them, and send
|
//! Asynchronous implementations are expected to create transactions, sign them, and send
|
||||||
//! them but without waiting to see if the server accepted it.
|
//! them but without waiting to see if the server accepted it.
|
||||||
|
|
||||||
use crate::account::Account;
|
use crate::{
|
||||||
use crate::fee_calculator::FeeCalculator;
|
account::Account,
|
||||||
use crate::hash::Hash;
|
clock::Slot,
|
||||||
use crate::instruction::Instruction;
|
fee_calculator::FeeCalculator,
|
||||||
use crate::message::Message;
|
hash::Hash,
|
||||||
use crate::pubkey::Pubkey;
|
instruction::Instruction,
|
||||||
use crate::signature::{Keypair, Signature};
|
message::Message,
|
||||||
use crate::transaction;
|
pubkey::Pubkey,
|
||||||
use crate::transport::Result;
|
signature::{Keypair, Signature},
|
||||||
|
transaction,
|
||||||
|
transport::Result,
|
||||||
|
};
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
pub trait Client: SyncClient + AsyncClient {
|
pub trait Client: SyncClient + AsyncClient {
|
||||||
|
@ -54,7 +57,7 @@ pub trait SyncClient {
|
||||||
) -> Result<Option<transaction::Result<()>>>;
|
) -> Result<Option<transaction::Result<()>>>;
|
||||||
|
|
||||||
/// Get last known slot
|
/// Get last known slot
|
||||||
fn get_slot(&self) -> Result<u64>;
|
fn get_slot(&self) -> Result<Slot>;
|
||||||
|
|
||||||
/// Get transaction count
|
/// Get transaction count
|
||||||
fn get_transaction_count(&self) -> Result<u64>;
|
fn get_transaction_count(&self) -> Result<u64>;
|
||||||
|
|
|
@ -45,7 +45,7 @@ impl EpochSchedule {
|
||||||
pub fn new(slots_per_epoch: u64) -> Self {
|
pub fn new(slots_per_epoch: u64) -> Self {
|
||||||
Self::custom(slots_per_epoch, slots_per_epoch, true)
|
Self::custom(slots_per_epoch, slots_per_epoch, true)
|
||||||
}
|
}
|
||||||
pub fn custom(slots_per_epoch: u64, leader_schedule_slot_offset: u64, warmup: bool) -> Self {
|
pub fn custom(slots_per_epoch: Epoch, leader_schedule_slot_offset: u64, warmup: bool) -> Self {
|
||||||
assert!(slots_per_epoch >= MINIMUM_SLOTS_PER_EPOCH as u64);
|
assert!(slots_per_epoch >= MINIMUM_SLOTS_PER_EPOCH as u64);
|
||||||
let (first_normal_epoch, first_normal_slot) = if warmup {
|
let (first_normal_epoch, first_normal_slot) = if warmup {
|
||||||
let next_power_of_two = slots_per_epoch.next_power_of_two();
|
let next_power_of_two = slots_per_epoch.next_power_of_two();
|
||||||
|
@ -70,7 +70,7 @@ impl EpochSchedule {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// get the length of the given epoch (in slots)
|
/// get the length of the given epoch (in slots)
|
||||||
pub fn get_slots_in_epoch(&self, epoch: u64) -> u64 {
|
pub fn get_slots_in_epoch(&self, epoch: Epoch) -> u64 {
|
||||||
if epoch < self.first_normal_epoch {
|
if epoch < self.first_normal_epoch {
|
||||||
2u64.pow(epoch as u32 + MINIMUM_SLOTS_PER_EPOCH.trailing_zeros() as u32)
|
2u64.pow(epoch as u32 + MINIMUM_SLOTS_PER_EPOCH.trailing_zeros() as u32)
|
||||||
} else {
|
} else {
|
||||||
|
@ -80,7 +80,7 @@ impl EpochSchedule {
|
||||||
|
|
||||||
/// get the epoch for which the given slot should save off
|
/// get the epoch for which the given slot should save off
|
||||||
/// information about stakers
|
/// information about stakers
|
||||||
pub fn get_leader_schedule_epoch(&self, slot: u64) -> u64 {
|
pub fn get_leader_schedule_epoch(&self, slot: Slot) -> Epoch {
|
||||||
if slot < self.first_normal_slot {
|
if slot < self.first_normal_slot {
|
||||||
// until we get to normal slots, behave as if leader_schedule_slot_offset == slots_per_epoch
|
// until we get to normal slots, behave as if leader_schedule_slot_offset == slots_per_epoch
|
||||||
self.get_epoch_and_slot_index(slot).0 + 1
|
self.get_epoch_and_slot_index(slot).0 + 1
|
||||||
|
@ -92,12 +92,12 @@ impl EpochSchedule {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// get epoch for the given slot
|
/// get epoch for the given slot
|
||||||
pub fn get_epoch(&self, slot: u64) -> u64 {
|
pub fn get_epoch(&self, slot: Slot) -> Epoch {
|
||||||
self.get_epoch_and_slot_index(slot).0
|
self.get_epoch_and_slot_index(slot).0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// get epoch and offset into the epoch for the given slot
|
/// get epoch and offset into the epoch for the given slot
|
||||||
pub fn get_epoch_and_slot_index(&self, slot: u64) -> (u64, u64) {
|
pub fn get_epoch_and_slot_index(&self, slot: Slot) -> (Epoch, u64) {
|
||||||
if slot < self.first_normal_slot {
|
if slot < self.first_normal_slot {
|
||||||
let epoch = (slot + MINIMUM_SLOTS_PER_EPOCH + 1)
|
let epoch = (slot + MINIMUM_SLOTS_PER_EPOCH + 1)
|
||||||
.next_power_of_two()
|
.next_power_of_two()
|
||||||
|
@ -119,7 +119,7 @@ impl EpochSchedule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_first_slot_in_epoch(&self, epoch: u64) -> u64 {
|
pub fn get_first_slot_in_epoch(&self, epoch: Epoch) -> Slot {
|
||||||
if epoch <= self.first_normal_epoch {
|
if epoch <= self.first_normal_epoch {
|
||||||
(2u64.pow(epoch as u32) - 1) * MINIMUM_SLOTS_PER_EPOCH
|
(2u64.pow(epoch as u32) - 1) * MINIMUM_SLOTS_PER_EPOCH
|
||||||
} else {
|
} else {
|
||||||
|
@ -127,7 +127,7 @@ impl EpochSchedule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_last_slot_in_epoch(&self, epoch: u64) -> u64 {
|
pub fn get_last_slot_in_epoch(&self, epoch: Epoch) -> Slot {
|
||||||
self.get_first_slot_in_epoch(epoch) + self.get_slots_in_epoch(epoch) - 1
|
self.get_first_slot_in_epoch(epoch) + self.get_slots_in_epoch(epoch) - 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::clock::Slot;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
|
||||||
|
|
||||||
|
@ -18,7 +19,7 @@ pub struct Meta {
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
pub v6: bool,
|
pub v6: bool,
|
||||||
pub seed: [u8; 32],
|
pub seed: [u8; 32],
|
||||||
pub slot: u64,
|
pub slot: Slot,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|
Loading…
Reference in New Issue