Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


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

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ members = [
"runtime",
"runtime-transaction",
"send-transaction-service",
"slice-root",
"stake-accounts",
"storage-bigtable",
"storage-bigtable/build-proto",
Expand Down Expand Up @@ -522,6 +523,7 @@ solana-shred-version = "3.0.0"
solana-signature = { version = "3.1.0", default-features = false }
solana-signer = "3.0.0"
solana-signer-store = "0.1.0"
solana-slice-root = { path = "slice-root", version = "=3.1.0" }
solana-slot-hashes = "3.0.0"
solana-slot-history = "3.0.0"
solana-stable-layout = "3.0.0"
Expand Down
3 changes: 2 additions & 1 deletion gossip/src/duplicate_shred.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ pub(crate) mod tests {
solana_hash::Hash,
solana_keypair::Keypair,
solana_ledger::shred::{ProcessShredsStats, ReedSolomonCache, Shredder},
solana_runtime::bank::SliceRoot,
solana_signature::Signature,
solana_signer::Signer,
solana_system_transaction::transfer,
Expand Down Expand Up @@ -457,7 +458,7 @@ pub(crate) mod tests {
&entries,
is_last_in_slot,
// chained_merkle_root
Some(Hash::new_from_array(rng.gen())),
Some(SliceRoot(Hash::new_from_array(rng.gen()))),
next_shred_index,
next_code_index, // next_code_index
&ReedSolomonCache::default(),
Expand Down
86 changes: 46 additions & 40 deletions ledger/src/blockstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ use {
solana_measure::measure::Measure,
solana_metrics::datapoint_error,
solana_pubkey::Pubkey,
solana_runtime::bank::Bank,
solana_runtime::bank::{Bank, SliceRoot},
solana_signature::Signature,
solana_signer::Signer,
solana_storage_proto::{StoredExtendedRewards, StoredTransactionStatusMeta},
Expand Down Expand Up @@ -194,15 +194,15 @@ impl<T> AsRef<T> for WorkingEntry<T> {

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct LastFECSetCheckResults {
last_fec_set_merkle_root: Option<Hash>,
last_fec_set_merkle_root: Option<SliceRoot>,
is_retransmitter_signed: bool,
}

impl LastFECSetCheckResults {
fn get_last_fec_set_merkle_root(
&self,
feature_set: &FeatureSet,
) -> std::result::Result<Option<Hash>, BlockstoreProcessorError> {
) -> std::result::Result<Option<SliceRoot>, BlockstoreProcessorError> {
if self.last_fec_set_merkle_root.is_none() {
return Err(BlockstoreProcessorError::IncompleteFinalFecSet);
} else if feature_set
Expand Down Expand Up @@ -608,7 +608,7 @@ impl Blockstore {
&self,
slot: Slot,
location: BlockLocation,
) -> Result<Option<Hash>> {
) -> Result<Option<SliceRoot>> {
let Some(shred) = self.get_data_shred_from_location(slot, 0, location)? else {
return Ok(None);
};
Expand Down Expand Up @@ -2375,7 +2375,11 @@ impl Blockstore {
/// Checks if the chained merkle root == merkle root
///
/// Returns true if no conflict, or if chained merkle roots are not enabled
fn check_chaining(&self, merkle_root: Option<Hash>, chained_merkle_root: Option<Hash>) -> bool {
fn check_chaining(
&self,
merkle_root: Option<SliceRoot>,
chained_merkle_root: Option<SliceRoot>,
) -> bool {
chained_merkle_root.is_none() // Chained merkle roots have not been enabled yet
|| chained_merkle_root == merkle_root
}
Expand Down Expand Up @@ -2726,7 +2730,8 @@ impl Blockstore {
let mut all_shreds = vec![];
let mut slot_entries = vec![];
let reed_solomon_cache = ReedSolomonCache::default();
let mut chained_merkle_root = Some(Hash::new_from_array(rand::thread_rng().gen()));
let mut chained_merkle_root =
Some(SliceRoot(Hash::new_from_array(rand::thread_rng().gen())));
// Find all the entries for start_slot
for entry in entries.into_iter() {
if remaining_ticks_in_slot == 0 {
Expand Down Expand Up @@ -4154,7 +4159,7 @@ impl Blockstore {
bank_hash: Hash,
is_leader: bool,
feature_set: &FeatureSet,
) -> std::result::Result<Option<Hash>, BlockstoreProcessorError> {
) -> std::result::Result<Option<SliceRoot>, BlockstoreProcessorError> {
let results = self.check_last_fec_set(slot);
let Ok(results) = results else {
if !is_leader {
Expand Down Expand Up @@ -4218,7 +4223,7 @@ impl Blockstore {
.data_shred_cf
.multi_get_keys((start_index..=last_shred_index).map(|index| (slot, index)));

let deduped_shred_checks: Vec<(Hash, bool)> = self
let deduped_shred_checks: Vec<(SliceRoot, bool)> = self
.data_shred_cf
.multi_get_bytes(&keys)
.enumerate()
Expand All @@ -4243,17 +4248,18 @@ impl Blockstore {
Ok((merkle_root, is_retransmitter_signed))
})
.dedup_by(|res1, res2| res1.as_ref().ok() == res2.as_ref().ok())
.collect::<Result<Vec<(Hash, bool)>>>()?;
.collect::<Result<Vec<(SliceRoot, bool)>>>()?;

// After the dedup there should be exactly one Hash left and one true value
let &[(block_id, is_retransmitter_signed)] = deduped_shred_checks.as_slice() else {
let &[(chained_merkle_id, is_retransmitter_signed)] = deduped_shred_checks.as_slice()
else {
return Ok(LastFECSetCheckResults {
last_fec_set_merkle_root: None,
is_retransmitter_signed: false,
});
};
Ok(LastFECSetCheckResults {
last_fec_set_merkle_root: Some(block_id),
last_fec_set_merkle_root: Some(chained_merkle_id),
is_retransmitter_signed,
})
}
Expand Down Expand Up @@ -5277,7 +5283,7 @@ pub fn create_new_ledger(
&entries,
true, // is_last_in_slot
// chained_merkle_root
Some(Hash::new_from_array(rand::thread_rng().gen())),
Some(SliceRoot(Hash::new_from_array(rand::thread_rng().gen()))),
0, // next_shred_index
0, // next_code_index
&ReedSolomonCache::default(),
Expand Down Expand Up @@ -5510,7 +5516,7 @@ pub fn entries_to_test_shreds(
entries,
is_full_slot,
// chained_merkle_root
Some(Hash::new_from_array(rand::thread_rng().gen())),
Some(SliceRoot(Hash::new_from_array(rand::thread_rng().gen()))),
0, // next_shred_index,
0, // next_code_index
&ReedSolomonCache::default(),
Expand Down Expand Up @@ -7335,7 +7341,7 @@ pub mod tests {
&keypair,
&[],
false,
Some(Hash::default()), // merkle_root
Some(SliceRoot(Hash::default())), // merkle_root
(i * gap) as u32,
(i * gap) as u32,
&reed_solomon_cache,
Expand Down Expand Up @@ -7518,7 +7524,7 @@ pub mod tests {
&keypair,
&entries,
true,
Some(Hash::default()), // merkle_root
Some(SliceRoot(Hash::default())), // merkle_root
0,
0,
&rsc,
Expand Down Expand Up @@ -7546,9 +7552,9 @@ pub mod tests {
&keypair,
&[],
true,
Some(Hash::default()), // merkle_root
6, // next_shred_index,
6, // next_code_index
Some(SliceRoot(Hash::default())), // merkle_root
6, // next_shred_index,
6, // next_code_index
&rsc,
&mut ProcessShredsStats::default(),
)
Expand Down Expand Up @@ -7611,9 +7617,9 @@ pub mod tests {
&Keypair::new(),
&entries,
true,
Some(Hash::default()), // merkle_root
last_idx, // next_shred_index,
last_idx, // next_code_index
Some(SliceRoot(Hash::default())), // merkle_root
last_idx, // next_shred_index,
last_idx, // next_code_index
&rsc,
&mut ProcessShredsStats::default(),
)
Expand Down Expand Up @@ -8012,7 +8018,7 @@ pub mod tests {
&keypair,
&[3, 3, 3],
false,
Some(Hash::default()),
Some(SliceRoot(Hash::default())),
new_index,
new_index,
&reed_solomon_cache,
Expand Down Expand Up @@ -8348,7 +8354,7 @@ pub mod tests {
&keypair,
&[1, 1, 1],
true,
Some(Hash::default()),
Some(SliceRoot(Hash::default())),
next_shred_index as u32,
next_shred_index as u32,
&reed_solomon_cache,
Expand Down Expand Up @@ -10630,7 +10636,7 @@ pub mod tests {
parent_slot,
num_entries,
fec_set_index,
Some(Hash::new_from_array(rand::thread_rng().gen())),
Some(SliceRoot(Hash::new_from_array(rand::thread_rng().gen()))),
)
}

Expand All @@ -10639,7 +10645,7 @@ pub mod tests {
parent_slot: u64,
num_entries: u64,
fec_set_index: u32,
chained_merkle_root: Option<Hash>,
chained_merkle_root: Option<SliceRoot>,
) -> (Vec<Shred>, Vec<Shred>, Arc<LeaderScheduleCache>) {
setup_erasure_shreds_with_index_and_chained_merkle_and_last_in_slot(
slot,
Expand All @@ -10656,7 +10662,7 @@ pub mod tests {
parent_slot: u64,
num_entries: u64,
fec_set_index: u32,
chained_merkle_root: Option<Hash>,
chained_merkle_root: Option<SliceRoot>,
is_last_in_slot: bool,
) -> (Vec<Shred>, Vec<Shred>, Arc<LeaderScheduleCache>) {
let entries = make_slot_entries_with_transactions(num_entries);
Expand Down Expand Up @@ -10726,7 +10732,7 @@ pub mod tests {
let leader_keypair = Arc::new(Keypair::new());
let reed_solomon_cache = ReedSolomonCache::default();
let shredder = Shredder::new(slot, 0, 0, 0).unwrap();
let merkle_root = Some(Hash::new_from_array(rand::thread_rng().gen()));
let merkle_root = Some(SliceRoot(Hash::new_from_array(rand::thread_rng().gen())));
let (shreds, _) = shredder.entries_to_merkle_shreds_for_tests(
&leader_keypair,
&entries1,
Expand Down Expand Up @@ -11086,7 +11092,7 @@ pub mod tests {
let version = version_from_hash(&entries[0].hash);
let shredder = Shredder::new(slot, 0, 0, version).unwrap();
let reed_solomon_cache = ReedSolomonCache::default();
let merkle_root = Some(Hash::new_from_array(rand::thread_rng().gen()));
let merkle_root = Some(SliceRoot(Hash::new_from_array(rand::thread_rng().gen())));
let kp = Keypair::new();
// produce normal shreds
let (data1, coding1) = shredder.entries_to_merkle_shreds_for_tests(
Expand Down Expand Up @@ -11202,7 +11208,7 @@ pub mod tests {
&leader_keypair,
&entries,
true, // is_last_in_slot
Some(Hash::new_unique()),
Some(SliceRoot(Hash::new_unique())),
0, // next_shred_index
0, // next_code_index,
&reed_solomon_cache,
Expand Down Expand Up @@ -11693,7 +11699,7 @@ pub mod tests {
.is_empty());

// Incorrectly chained merkle for next slot
let merkle_root = Hash::new_unique();
let merkle_root = SliceRoot(Hash::new_unique());
assert!(merkle_root != data_shred.merkle_root().unwrap());
let (next_slot_data_shreds, next_slot_coding_shreds, leader_schedule) =
setup_erasure_shreds_with_index_and_chained_merkle(
Expand Down Expand Up @@ -11726,7 +11732,7 @@ pub mod tests {
let coding_shred = coding_shreds[0].clone();

// Incorrectly chained merkle for next slot
let merkle_root = Hash::new_unique();
let merkle_root = SliceRoot(Hash::new_unique());
assert!(merkle_root != coding_shred.merkle_root().unwrap());
let (next_slot_data_shreds, _, leader_schedule) =
setup_erasure_shreds_with_index_and_chained_merkle(
Expand Down Expand Up @@ -11767,7 +11773,7 @@ pub mod tests {
.is_empty());

// Incorrectly chained merkle
let merkle_root = Hash::new_unique();
let merkle_root = SliceRoot(Hash::new_unique());
assert!(merkle_root != coding_shred_previous.merkle_root().unwrap());
let (data_shreds, coding_shreds, leader_schedule) =
setup_erasure_shreds_with_index_and_chained_merkle(
Expand Down Expand Up @@ -11815,7 +11821,7 @@ pub mod tests {
.is_empty());

// Incorrectly chained merkle
let merkle_root = Hash::new_unique();
let merkle_root = SliceRoot(Hash::new_unique());
assert!(merkle_root != coding_shred_previous.merkle_root().unwrap());
let (data_shreds, coding_shreds, leader_schedule) =
setup_erasure_shreds_with_index_and_chained_merkle(
Expand Down Expand Up @@ -11859,7 +11865,7 @@ pub mod tests {
let next_fec_set_index = fec_set_index + data_shreds.len() as u32;

// Incorrectly chained merkle
let merkle_root = Hash::new_unique();
let merkle_root = SliceRoot(Hash::new_unique());
assert!(merkle_root != coding_shred.merkle_root().unwrap());
let (next_data_shreds, _, leader_schedule_next) =
setup_erasure_shreds_with_index_and_chained_merkle(
Expand Down Expand Up @@ -11906,7 +11912,7 @@ pub mod tests {
let fec_set_index = prev_fec_set_index + prev_data_shreds.len() as u32;

// Incorrectly chained merkle
let merkle_root = Hash::new_unique();
let merkle_root = SliceRoot(Hash::new_unique());
assert!(merkle_root != prev_coding_shred.merkle_root().unwrap());
let (data_shreds, coding_shreds, leader_schedule) =
setup_erasure_shreds_with_index_and_chained_merkle(
Expand All @@ -11921,7 +11927,7 @@ pub mod tests {
let next_fec_set_index = fec_set_index + prev_data_shreds.len() as u32;

// Incorrectly chained merkle
let merkle_root = Hash::new_unique();
let merkle_root = SliceRoot(Hash::new_unique());
assert!(merkle_root != data_shred.merkle_root().unwrap());
let (next_data_shreds, _, leader_schedule_next) =
setup_erasure_shreds_with_index_and_chained_merkle(
Expand Down Expand Up @@ -12011,7 +12017,7 @@ pub mod tests {

// Add an incorrectly chained merkle from the next set. Although incorrectly chained
// we skip the duplicate check as the first received coding shred index shred is missing
let merkle_root = Hash::new_unique();
let merkle_root = SliceRoot(Hash::new_unique());
assert!(merkle_root != coding_shred_previous.merkle_root().unwrap());
let (data_shreds, coding_shreds, leader_schedule) =
setup_erasure_shreds_with_index_and_chained_merkle(
Expand Down Expand Up @@ -12046,7 +12052,7 @@ pub mod tests {
let next_fec_set_index = fec_set_index + data_shreds.len() as u32;

// Incorrectly chained merkle
let merkle_root = Hash::new_unique();
let merkle_root = SliceRoot(Hash::new_unique());
assert!(merkle_root != coding_shred.merkle_root().unwrap());
let (next_data_shreds, next_coding_shreds, leader_schedule_next) =
setup_erasure_shreds_with_index_and_chained_merkle(
Expand Down Expand Up @@ -12263,7 +12269,7 @@ pub mod tests {
Err(BlockstoreProcessorError::IncompleteFinalFecSet)
);

let block_id = Hash::new_unique();
let block_id = SliceRoot(Hash::new_unique());
let results = LastFECSetCheckResults {
last_fec_set_merkle_root: Some(block_id),
is_retransmitter_signed: false,
Expand All @@ -12290,7 +12296,7 @@ pub mod tests {
Err(BlockstoreProcessorError::IncompleteFinalFecSet)
);

let block_id = Hash::new_unique();
let block_id = SliceRoot(Hash::new_unique());
let results = LastFECSetCheckResults {
last_fec_set_merkle_root: Some(block_id),
is_retransmitter_signed: true,
Expand Down
Loading