kaspa_consensus/processes/ghostdag/
ordering.rs

1use std::cmp::Ordering;
2
3use kaspa_consensus_core::BlueWorkType;
4use kaspa_hashes::Hash;
5use serde::{Deserialize, Serialize};
6
7use crate::model::{
8    services::reachability::ReachabilityService,
9    stores::{ghostdag::GhostdagStoreReader, headers::HeaderStoreReader, relations::RelationsStoreReader},
10};
11
12use super::protocol::GhostdagManager;
13
14#[derive(Eq, Clone, Serialize, Deserialize)]
15pub struct SortableBlock {
16    pub hash: Hash,
17    pub blue_work: BlueWorkType,
18}
19
20impl SortableBlock {
21    pub fn new(hash: Hash, blue_work: BlueWorkType) -> Self {
22        Self { hash, blue_work }
23    }
24}
25
26impl PartialEq for SortableBlock {
27    fn eq(&self, other: &Self) -> bool {
28        self.hash == other.hash
29    }
30}
31
32impl PartialOrd for SortableBlock {
33    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
34        Some(self.cmp(other))
35    }
36}
37
38impl Ord for SortableBlock {
39    fn cmp(&self, other: &Self) -> Ordering {
40        self.blue_work.cmp(&other.blue_work).then_with(|| self.hash.cmp(&other.hash))
41    }
42}
43
44impl<T: GhostdagStoreReader, S: RelationsStoreReader, U: ReachabilityService, V: HeaderStoreReader> GhostdagManager<T, S, U, V> {
45    pub fn sort_blocks(&self, blocks: impl IntoIterator<Item = Hash>) -> Vec<Hash> {
46        let mut sorted_blocks: Vec<Hash> = blocks.into_iter().collect();
47        sorted_blocks
48            .sort_by_cached_key(|block| SortableBlock { hash: *block, blue_work: self.ghostdag_store.get_blue_work(*block).unwrap() });
49        sorted_blocks
50    }
51}