Skip to content

Commit

Permalink
fix(cardano-blockchain-types): Fork type
Browse files Browse the repository at this point in the history
Signed-off-by: bkioshn <[email protected]>
  • Loading branch information
bkioshn committed Dec 17, 2024
1 parent aa6bd36 commit e027d8b
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 15 deletions.
41 changes: 41 additions & 0 deletions rust/cardano-blockchain-types/src/fork.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//! Fork count is a counter that is incremented every time there is a roll-back in
//! live-chain It is used to help followers determine how far to roll-back to
//! resynchronize without storing full block history. The fork count starts at 1 for live
//! blocks and increments if the live chain tip is purged due to a detected fork, but it
//! does not track the exact number of forks reported by peers.
//!
//! Note: This fork terminology is different from fork in blockchain.
use crate::conversion::from_saturating;

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
/// Counter that is incremented every time there is a roll-back in live-chain
pub struct Fork(u64);

impl Fork {
/// Convert an `<T>` to Fork. (saturate if out of range.)
pub fn from_saturating<
T: Copy
+ TryInto<u64>
+ std::ops::Sub<Output = T>
+ std::cmp::PartialOrd<T>
+ num_traits::identities::Zero,
>(
value: T,
) -> Self {
let value: u64 = from_saturating(value);
Self(value)
}
}

impl From<u64> for Fork {
fn from(value: u64) -> Self {
Self(value)
}
}

impl From<Fork> for u64 {
fn from(val: Fork) -> Self {
val.0
}
}
1 change: 1 addition & 0 deletions rust/cardano-blockchain-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
mod auxdata;
pub mod conversion;
mod fork;
pub mod hashes;
mod multi_era_block_data;
mod network;
Expand Down
43 changes: 28 additions & 15 deletions rust/cardano-blockchain-types/src/multi_era_block_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::{
auxdata::{
block::BlockAuxData, metadatum_label::MetadatumLabel, metadatum_value::MetadatumValue,
},
fork::Fork,
network::Network,
point::Point,
txn_index::TxnIndex,
Expand Down Expand Up @@ -80,7 +81,7 @@ pub struct MultiEraBlock {
/// It starts at 1 for live blocks, and is only incremented if the live-chain tip is
/// purged because of a detected fork based on data received from the peer node.
/// It does NOT count the strict number of forks reported by the peer node.
fork: u64,
fork: Fork,
/// The Immutable decoded data about the block itself.
inner: Arc<MultiEraBlockInner>,
}
Expand All @@ -92,7 +93,7 @@ impl MultiEraBlock {
///
/// If the given bytes cannot be decoded as a multi-era block, an error is returned.
fn new_block(
chain: Network, raw_data: Vec<u8>, previous: &Point, fork: u64,
chain: Network, raw_data: Vec<u8>, previous: &Point, fork: Fork,
) -> anyhow::Result<Self> {
let builder = SelfReferencedMultiEraBlockTryBuilder {
raw_data,
Expand Down Expand Up @@ -155,13 +156,13 @@ impl MultiEraBlock {
///
/// If the given bytes cannot be decoded as a multi-era block, an error is returned.
pub fn new(
chain: Network, raw_data: Vec<u8>, previous: &Point, fork: u64,
chain: Network, raw_data: Vec<u8>, previous: &Point, fork: Fork,
) -> anyhow::Result<Self> {
MultiEraBlock::new_block(chain, raw_data, previous, fork)
}

/// Remake the block on a new fork.
pub fn set_fork(&mut self, fork: u64) {
pub fn set_fork(&mut self, fork: Fork) {
self.fork = fork;
}

Expand Down Expand Up @@ -212,7 +213,7 @@ impl MultiEraBlock {
/// `true` if the block is immutable, `false` otherwise.
#[must_use]
pub fn immutable(&self) -> bool {
self.fork == 0
self.fork == 0.into()
}

/// What fork is the block from.
Expand All @@ -226,7 +227,7 @@ impl MultiEraBlock {
/// # Returns
/// The fork the block was found on.
#[must_use]
pub fn fork(&self) -> u64 {
pub fn fork(&self) -> Fork {
self.fork
}

Expand Down Expand Up @@ -288,7 +289,7 @@ impl Display for MultiEraBlock {
let fork = if self.immutable() {
"Immutable".to_string()
} else {
format!("Fork: {fork}")
format!("Fork: {fork:?}")
};

let block_era = match block {
Expand Down Expand Up @@ -452,8 +453,12 @@ pub(crate) mod tests {
.into(),
);

let block =
MultiEraBlock::new(Network::Preprod, test_block.raw.clone(), &previous_point, 1);
let block = MultiEraBlock::new(
Network::Preprod,
test_block.raw.clone(),
&previous_point,
1.into(),
);

assert!(block.is_err());
}
Expand All @@ -471,8 +476,12 @@ pub(crate) mod tests {
let previous_point =
Point::new((pallas_block.slot() - 1).into(), vec![0; 32].try_into()?);

let block =
MultiEraBlock::new(Network::Preprod, test_block.raw.clone(), &previous_point, 1);
let block = MultiEraBlock::new(
Network::Preprod,
test_block.raw.clone(),
&previous_point,
1.into(),
);

assert!(block.is_err());
}
Expand All @@ -496,8 +505,12 @@ pub(crate) mod tests {
.into(),
);

let block =
MultiEraBlock::new(Network::Preprod, test_block.raw.clone(), &previous_point, 1)?;
let block = MultiEraBlock::new(
Network::Preprod,
test_block.raw.clone(),
&previous_point,
1.into(),
)?;

assert_eq!(block.decode().hash(), pallas_block.hash());
}
Expand All @@ -523,7 +536,7 @@ pub(crate) mod tests {
})
.expect("cannot create point");

MultiEraBlock::new(Network::Preprod, block.clone(), &prev_point, 1)
MultiEraBlock::new(Network::Preprod, block.clone(), &prev_point, 1.into())
.expect("cannot create multi-era block")
})
.collect()
Expand Down Expand Up @@ -720,7 +733,7 @@ pub(crate) mod tests {
Network::Preprod,
test_block.raw.clone(),
&test_block.previous,
1,
1.into(),
);

assert!(block.is_ok());
Expand Down

0 comments on commit e027d8b

Please sign in to comment.