Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 0 additions & 5 deletions src/beacon/drand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,6 @@ pub struct DrandConfig<'a> {
pub struct BeaconSchedule(pub Vec<BeaconPoint>);

impl BeaconSchedule {
/// Constructs a new, empty `BeaconSchedule<T>` with the specified capacity.
pub fn with_capacity(capacity: usize) -> Self {
BeaconSchedule(Vec::with_capacity(capacity))
}

/// Returns the beacon entries for a given epoch.
/// When the beacon for the given epoch is on a new beacon, randomness
/// entries are taken from the last two rounds.
Expand Down
6 changes: 3 additions & 3 deletions src/benchmark_private/tipset_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ async fn get_snapshot(chain: &NetworkChain, epoch: i64) -> anyhow::Result<PathBu
async fn prepare_validation(
chain: &NetworkChain,
snapshot: &Path,
) -> anyhow::Result<(Arc<StateManager<ManyCar>>, Arc<Tipset>)> {
) -> anyhow::Result<(Arc<StateManager<ManyCar>>, Tipset)> {
let snap_car = AnyCar::try_from(snapshot)?;
let ts = Arc::new(snap_car.heaviest_tipset()?);
let ts = snap_car.heaviest_tipset()?;
let db = Arc::new(ManyCar::new(MemoryDB::default()).with_read_only(snap_car)?);
let chain_config = Arc::new(ChainConfig::from_chain(chain));
let genesis_header =
Expand All @@ -66,7 +66,7 @@ async fn prepare_validation(
Ok((state_manager, ts))
}

async fn validate(state_manager: Arc<StateManager<ManyCar>>, ts: Arc<Tipset>) {
async fn validate(state_manager: Arc<StateManager<ManyCar>>, ts: Tipset) {
state_manager
.compute_tipset_state(ts, crate::state_manager::NO_CALLBACK, VMTrace::NotTraced)
.await
Expand Down
7 changes: 0 additions & 7 deletions src/blocks/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,6 @@ impl RawBlockHeader {
blk.signature = None;
fvm_ipld_encoding::to_vec(&blk).expect("block serialization cannot fail")
}

/// If the block timestamp is within the allowable clock drift
pub fn is_within_clock_drift(&self) -> bool {
self.timestamp
<= (chrono::Utc::now().timestamp() as u64)
.saturating_add(crate::shim::clock::ALLOWABLE_CLOCK_DRIFT)
}
}

// The derive macro does not compile for some reason
Expand Down
1 change: 1 addition & 0 deletions src/blocks/ticket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub struct Ticket {
}

impl Ticket {
#[cfg(test)]
/// Ticket constructor
pub fn new(vrfproof: VRFProof) -> Self {
Self { vrfproof }
Expand Down
91 changes: 33 additions & 58 deletions src/blocks/tipset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ use num::BigInt;
use nunny::{Vec as NonEmpty, vec as nonempty};
use serde::{Deserialize, Serialize};
use thiserror::Error;
use tracing::info;

/// A set of `CIDs` forming a unique key for a Tipset.
/// Equal keys will have equivalent iteration order, but note that the `CIDs`
Expand Down Expand Up @@ -151,9 +150,9 @@ impl IntoIterator for TipsetKey {
pub struct Tipset {
/// Sorted
#[get_size(size_fn = nunny_vec_heap_size_helper)]
headers: NonEmpty<CachingBlockHeader>,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The major changes are within this file (tipset.rs)

headers: Arc<NonEmpty<CachingBlockHeader>>,
// key is lazily initialized via `fn key()`.
key: OnceLock<TipsetKey>,
key: Arc<OnceLock<TipsetKey>>,
}

impl From<RawBlockHeader> for Tipset {
Expand All @@ -171,17 +170,17 @@ impl From<&CachingBlockHeader> for Tipset {
impl From<CachingBlockHeader> for Tipset {
fn from(value: CachingBlockHeader) -> Self {
Self {
headers: nonempty![value],
key: OnceLock::new(),
headers: nonempty![value].into(),
key: OnceLock::new().into(),
}
}
}

impl From<NonEmpty<CachingBlockHeader>> for Tipset {
fn from(headers: NonEmpty<CachingBlockHeader>) -> Self {
Self {
headers,
key: OnceLock::new(),
headers: headers.into(),
key: OnceLock::new().into(),
}
}
}
Expand All @@ -202,14 +201,12 @@ impl quickcheck::Arbitrary for Tipset {
}

impl From<FullTipset> for Tipset {
fn from(full_tipset: FullTipset) -> Self {
let key = full_tipset.key;
let headers = full_tipset
.blocks
fn from(FullTipset { key, blocks }: FullTipset) -> Self {
let headers = Arc::unwrap_or_clone(blocks)
.into_iter_ne()
.map(|block| block.header)
.collect_vec();

.collect_vec()
.into();
Tipset { headers, key }
}
}
Expand Down Expand Up @@ -254,8 +251,8 @@ impl Tipset {
verify_block_headers(&headers)?;

Ok(Self {
headers,
key: OnceLock::new(),
headers: headers.into(),
key: OnceLock::new().into(),
})
}

Expand Down Expand Up @@ -309,9 +306,6 @@ impl Tipset {
pub fn block_headers(&self) -> &NonEmpty<CachingBlockHeader> {
&self.headers
}
pub fn into_block_headers(self) -> NonEmpty<CachingBlockHeader> {
self.headers
}
/// Returns the smallest ticket of all blocks in the tipset
pub fn min_ticket(&self) -> Option<&Ticket> {
self.min_ticket_block().ticket.as_ref()
Expand Down Expand Up @@ -355,6 +349,7 @@ impl Tipset {
}
/// Returns true if self wins according to the Filecoin tie-break rule
/// (FIP-0023)
#[cfg(test)]
pub fn break_weight_tie(&self, other: &Tipset) -> bool {
// blocks are already sorted by ticket
let broken = self
Expand All @@ -369,9 +364,9 @@ impl Tipset {
ticket.vrfproof < other_ticket.vrfproof
});
if broken {
info!("Weight tie broken in favour of {}", self.key());
tracing::info!("Weight tie broken in favour of {}", self.key());
} else {
info!("Weight tie left unbroken, default to {}", other.key());
tracing::info!("Weight tie left unbroken, default to {}", other.key());
}
broken
}
Expand All @@ -396,21 +391,6 @@ impl Tipset {
})
}

/// Returns an iterator of all tipsets
pub fn chain_arc(
self: Arc<Self>,
store: &impl Blockstore,
) -> impl Iterator<Item = Arc<Tipset>> + '_ {
let mut tipset = Some(self);
std::iter::from_fn(move || {
let child = tipset.take()?;
tipset = Tipset::load_required(store, child.parents())
.ok()
.map(Arc::new);
Some(child)
})
}

/// Fetch the genesis block header for a given tipset.
pub fn genesis(&self, store: &impl Blockstore) -> anyhow::Result<CachingBlockHeader> {
// Scanning through millions of epochs to find the genesis is quite
Expand Down Expand Up @@ -450,22 +430,15 @@ impl Tipset {
}
anyhow::bail!("Genesis block not found")
}

/// Check if `self` is the child of `other`
pub fn is_child_of(&self, other: &Self) -> bool {
// Note: the extra `&& self.epoch() > other.epoch()` check in lotus is dropped
// See <https://github.com/filecoin-project/lotus/blob/01ec22974942fb7328a1e665704c6cfd75d93372/chain/types/tipset.go#L258>
self.parents() == other.key()
}
}

/// `FullTipset` is an expanded version of a tipset that contains all the blocks
/// and messages.
#[derive(Debug, Clone, Eq)]
pub struct FullTipset {
blocks: NonEmpty<Block>,
blocks: Arc<NonEmpty<Block>>,
// key is lazily initialized via `fn key()`.
key: OnceLock<TipsetKey>,
key: Arc<OnceLock<TipsetKey>>,
}

impl std::hash::Hash for FullTipset {
Expand All @@ -478,8 +451,8 @@ impl std::hash::Hash for FullTipset {
impl From<Block> for FullTipset {
fn from(block: Block) -> Self {
FullTipset {
blocks: nonempty![block],
key: OnceLock::new(),
blocks: nonempty![block].into(),
key: OnceLock::new().into(),
}
}
}
Expand All @@ -492,21 +465,23 @@ impl PartialEq for FullTipset {

impl FullTipset {
pub fn new(blocks: impl IntoIterator<Item = Block>) -> Result<Self, CreateTipsetError> {
let blocks = NonEmpty::new(
// sort blocks on creation to allow for more seamless conversions between
// FullTipset and Tipset
blocks
.into_iter()
.sorted_by_cached_key(|it| it.header.tipset_sort_key())
.collect(),
)
.map_err(|_| CreateTipsetError::Empty)?;
let blocks = Arc::new(
NonEmpty::new(
// sort blocks on creation to allow for more seamless conversions between
// FullTipset and Tipset
blocks
.into_iter()
.sorted_by_cached_key(|it| it.header.tipset_sort_key())
.collect(),
)
.map_err(|_| CreateTipsetError::Empty)?,
);

verify_block_headers(blocks.iter().map(|it| &it.header))?;

Ok(Self {
blocks,
key: OnceLock::new(),
key: Arc::new(OnceLock::new()),
})
}
/// Returns the first block of the tipset.
Expand All @@ -519,7 +494,7 @@ impl FullTipset {
}
/// Returns all blocks in a full tipset.
pub fn into_blocks(self) -> NonEmpty<Block> {
self.blocks
Arc::unwrap_or_clone(self.blocks)
}
/// Converts the full tipset into a [Tipset] which removes the messages
/// attached.
Expand Down Expand Up @@ -637,8 +612,8 @@ mod lotus_json {
let Self(tipset) = self;
TipsetLotusJsonInner {
cids: tipset.key().clone(),
blocks: tipset.clone().into_block_headers(),
height: tipset.epoch(),
blocks: tipset.block_headers().clone(),
}
.serialize(serializer)
}
Expand Down
6 changes: 4 additions & 2 deletions src/blocks/vrf_proof.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2019-2025 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use crate::utils::encoding::{blake2b_256, serde_byte_array};
use crate::utils::encoding::serde_byte_array;
use get_size2::GetSize;
use serde::{Deserialize, Serialize};

Expand All @@ -12,6 +12,7 @@ pub struct VRFProof(#[serde(with = "serde_byte_array")] pub Vec<u8>);

impl VRFProof {
/// Creates a `VRFProof` from a raw vector.
#[cfg(test)]
pub fn new(output: Vec<u8>) -> Self {
Self(output)
}
Expand All @@ -22,8 +23,9 @@ impl VRFProof {
}

/// Compute the `BLAKE2b256` digest of the proof.
#[allow(dead_code)]
pub fn digest(&self) -> [u8; 32] {
blake2b_256(&self.0)
crate::utils::encoding::blake2b_256(&self.0)
}
}

Expand Down
20 changes: 10 additions & 10 deletions src/chain/store/chain_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub type ChainEpochDelta = ChainEpoch;
/// contained in message type.
#[derive(Clone, Debug)]
pub enum HeadChange {
Apply(Arc<Tipset>),
Apply(Tipset),
}

/// Stores chain data such as heaviest tipset and cached tipset info at each
Expand Down Expand Up @@ -142,7 +142,7 @@ where
}

/// Sets heaviest tipset
pub fn set_heaviest_tipset(&self, ts: Arc<Tipset>) -> Result<(), Error> {
pub fn set_heaviest_tipset(&self, ts: Tipset) -> Result<(), Error> {
self.heaviest_tipset_key_provider
.set_heaviest_tipset_key(ts.key())?;
if self.publisher.send(HeadChange::Apply(ts)).is_err() {
Expand All @@ -163,7 +163,7 @@ where

// Expand tipset to include other compatible blocks at the epoch.
let expanded = self.expand_tipset(ts.min_ticket_block().clone())?;
self.update_heaviest(Arc::new(expanded))?;
self.update_heaviest(expanded)?;
Ok(())
}

Expand Down Expand Up @@ -218,7 +218,7 @@ where
}

/// Returns the currently tracked heaviest tipset.
pub fn heaviest_tipset(&self) -> Arc<Tipset> {
pub fn heaviest_tipset(&self) -> Tipset {
let tsk = self
.heaviest_tipset_key_provider
.heaviest_tipset_key()
Expand Down Expand Up @@ -261,7 +261,7 @@ where
pub fn load_required_tipset_or_heaviest<'a>(
&self,
maybe_key: impl Into<Option<&'a TipsetKey>>,
) -> Result<Arc<Tipset>, Error> {
) -> Result<Tipset, Error> {
match maybe_key.into() {
Some(key) => self.chain_index.load_required_tipset(key),
None => Ok(self.heaviest_tipset()),
Expand All @@ -270,11 +270,11 @@ where

/// Determines if provided tipset is heavier than existing known heaviest
/// tipset
fn update_heaviest(&self, ts: Arc<Tipset>) -> Result<(), Error> {
fn update_heaviest(&self, ts: Tipset) -> Result<(), Error> {
// Calculate heaviest weight before matching to avoid deadlock with mutex
let heaviest_weight = fil_cns::weight(self.blockstore(), &self.heaviest_tipset())?;

let new_weight = fil_cns::weight(self.blockstore(), ts.as_ref())?;
let new_weight = fil_cns::weight(self.blockstore(), &ts)?;
let curr_weight = heaviest_weight;

if new_weight > curr_weight {
Expand Down Expand Up @@ -321,9 +321,9 @@ where
pub fn get_lookback_tipset_for_round(
chain_index: &Arc<ChainIndex<Arc<DB>>>,
chain_config: &Arc<ChainConfig>,
heaviest_tipset: &Arc<Tipset>,
heaviest_tipset: &Tipset,
round: ChainEpoch,
) -> Result<(Arc<Tipset>, Cid), Error>
) -> Result<(Tipset, Cid), Error>
where
DB: Send + Sync + 'static,
{
Expand All @@ -350,7 +350,7 @@ where
// (takes seconds to minutes). It's only acceptable here because this situation is
// so rare (may happen in dev-networks, doesn't happen in calibnet or mainnet.)
&crate::shim::machine::GLOBAL_MULTI_ENGINE,
Arc::clone(heaviest_tipset),
heaviest_tipset.clone(),
crate::state_manager::NO_CALLBACK,
VMTrace::NotTraced,
)
Expand Down
Loading
Loading