Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions src/benchmark_private/tipset_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ 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 db = Arc::new(ManyCar::new(MemoryDB::default()).with_read_only(snap_car)?);
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