Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
84b740c
[WIP] draft changes
Jul 25, 2023
08d9345
[WIP] `CidVec` updates
Jul 25, 2023
738c0cd
changes to `Tipset::cids` and `quickcheck`
Jul 25, 2023
3e82f76
updates to `cid_vec`
Jul 26, 2023
4adae1a
resolve issue with `From` impl
Jul 27, 2023
27d655c
Merge branch 'main' into jdjaustin/issue-3232-impl-opt-cidvec
Jul 27, 2023
97dc34f
fix issues from merge conflict resolution
Jul 27, 2023
f7a1680
update `CidVec` (de)serialization
Jul 31, 2023
b0184d8
Merge branch 'main' into jdjaustin/issue-3232-impl-opt-cidvec
Jul 31, 2023
02f7ee2
fix issues from merge conflict resolution
Jul 31, 2023
455625a
modify (de)serialization
Aug 1, 2023
064a6ad
Merge branch 'main' into jdjaustin/issue-3232-impl-opt-cidvec
Aug 1, 2023
0057d8d
rm unused import
Aug 1, 2023
e89e123
add doc comments
Aug 1, 2023
24cf7db
Apply suggestions from code review
Aug 2, 2023
e175e17
changes from initial code review
Aug 2, 2023
fe015b5
rm `cids()` method
Aug 2, 2023
5d6151d
replace `CidVec` with `FrozenCids`
Aug 3, 2023
f03c98c
Merge branch 'main' into jdjaustin/issue-3232-impl-opt-cidvec
Aug 3, 2023
bf55861
resolve issue in new `benchmark_cmd`
Aug 3, 2023
e825824
update code documentation
Aug 3, 2023
f72fb81
cargo fmt
Aug 4, 2023
883ad0e
Merge branch 'main' into jdjaustin/issue-3232-impl-opt-cidvec
Aug 4, 2023
23a6dbb
update from merge conflict
Aug 4, 2023
2ed5647
Merge branch 'main' into jdjaustin/issue-3232-impl-opt-cidvec
Aug 7, 2023
6c2ba6b
modify `FrozenCids` implementation
Aug 7, 2023
2204e19
Apply suggestions from code review
Aug 8, 2023
5513c48
update `Inline` instances
Aug 8, 2023
48c5506
modify `CidVariant` to replace `SmallCid`
Aug 8, 2023
2bbf9ef
spellcheck
Aug 8, 2023
709f3ab
additional changes from code review
Aug 8, 2023
71b9cac
modify `IntoIterator` impl
Aug 9, 2023
90d2b1f
some changes from code review
Aug 9, 2023
487ef9b
code review change: modify (de)serialization impl
Aug 9, 2023
1b0d306
Apply suggestions from code review
Aug 14, 2023
bf05dbe
Merge branch 'main' into jdjaustin/issue-3232-impl-opt-cidvec
Aug 14, 2023
65e9fb1
fix JSON issues
Aug 14, 2023
a276249
changes from code review
Aug 14, 2023
bb0fb89
derive `Arbitrary` for `CidVariant`
Aug 14, 2023
d7a9e31
derive `Arbitrary` for `FrozenCids`
Aug 14, 2023
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
1 change: 1 addition & 0 deletions .config/forest.dic
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ milliGas
multihash
multisig
mutex
overallocation
P2P
parsable
pointer/SM
Expand Down
41 changes: 22 additions & 19 deletions src/blocks/tipset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use std::{fmt, sync::OnceLock};

use crate::ipld::FrozenCids;
use crate::networks::{calibnet, mainnet};
use crate::shim::{address::Address, clock::ChainEpoch};
use crate::utils::cid::CidCborExt;
Expand All @@ -26,35 +27,36 @@ use super::{Block, BlockHeader, Error, Ticket};
#[cfg_attr(test, derive(derive_quickcheck_arbitrary::Arbitrary))]
#[serde(transparent)]
pub struct TipsetKeys {
pub cids: Vec<Cid>,
pub cids: FrozenCids,
}

impl TipsetKeys {
pub fn new(cids: Vec<Cid>) -> Self {
pub fn new(cids: FrozenCids) -> Self {
Self { cids }
}

/// Returns tipset header `cids`
pub fn cids(&self) -> &[Cid] {
&self.cids
}

// Special encoding to match Lotus.
pub fn cid(&self) -> anyhow::Result<Cid> {
use fvm_ipld_encoding::RawBytes;
let mut bytes = Vec::new();
for cid in self.cids() {
for cid in &self.cids {
bytes.append(&mut cid.to_bytes())
}
Ok(Cid::from_cbor_blake2b256(&RawBytes::new(bytes))?)
}
}

impl From<Vec<Cid>> for TipsetKeys {
fn from(cids: Vec<Cid>) -> Self {
Self::new(FrozenCids::from(cids))
}
}

impl fmt::Display for TipsetKeys {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let s = self
.cids()
.iter()
.cids
.into_iter()
.map(|cid| cid.to_string())
.collect::<Vec<_>>()
.join(", ");
Expand Down Expand Up @@ -141,9 +143,9 @@ impl Tipset {
/// present but invalid. If the tipset is missing, None is returned.
pub fn load(store: impl Blockstore, tsk: &TipsetKeys) -> anyhow::Result<Option<Tipset>> {
Ok(tsk
Comment thread
jdjaustin marked this conversation as resolved.
.cids()
.iter()
.map(|key| BlockHeader::load(&store, *key))
.cids
.into_iter()
.map(|key| BlockHeader::load(&store, key))
.collect::<anyhow::Result<Option<_>>>()?
.map(Tipset::new)
.transpose()?)
Expand Down Expand Up @@ -220,8 +222,8 @@ impl Tipset {
})
}
/// Returns slice of `CIDs` for the current tipset
pub fn cids(&self) -> &[Cid] {
self.key().cids()
pub fn cids(&self) -> Vec<Cid> {
Vec::<Cid>::from(&self.key().cids)
}
/// Returns the keys of the parents of the blocks in the tipset.
pub fn parents(&self) -> &TipsetKeys {
Expand Down Expand Up @@ -447,15 +449,15 @@ pub mod tipset_keys_json {
where
S: Serializer,
{
crate::json::cid::vec::serialize(m.cids(), serializer)
crate::json::cid::vec::serialize(&Vec::<Cid>::from(&m.cids), serializer)
}

pub fn deserialize<'de, D>(deserializer: D) -> Result<TipsetKeys, D::Error>
where
D: Deserializer<'de>,
{
Ok(TipsetKeys {
cids: crate::json::cid::vec::deserialize(deserializer)?,
cids: crate::json::cid::vec::deserialize(deserializer)?.into(),
})
}
}
Expand Down Expand Up @@ -563,6 +565,7 @@ mod property_tests {
#[cfg(test)]
mod test {
use crate::blocks::VRFProof;
use crate::ipld::FrozenCids;
use crate::shim::address::Address;
use cid::{
multihash::{Code::Identity, MultihashDigest},
Expand Down Expand Up @@ -712,10 +715,10 @@ mod test {
.unwrap();
let h1 = BlockHeader::builder()
.miner_address(Address::new_id(1))
.parents(TipsetKeys::new(vec![Cid::new_v1(
.parents(TipsetKeys::new(FrozenCids::from_iter([Cid::new_v1(
DAG_CBOR,
Identity.digest(&[]),
)]))
)])))
.build()
.unwrap();
assert_eq!(
Expand Down
3 changes: 2 additions & 1 deletion src/chain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::ipld::{stream_chain, CidHashSet};
use crate::utils::io::{AsyncWriterWithChecksum, Checksum};
use crate::utils::stream::par_buffer;
use anyhow::{Context, Result};
use cid::Cid;
use digest::Digest;
use fvm_ipld_blockstore::Blockstore;
use std::sync::Arc;
Expand All @@ -25,7 +26,7 @@ pub async fn export<D: Digest>(
) -> Result<Option<digest::Output<D>>, Error> {
let db = Arc::new(db);
let stateroot_lookup_limit = tipset.epoch() - lookup_depth;
let roots = tipset.key().cids().to_vec();
let roots = Vec::<Cid>::from(&tipset.key().cids);

// Wrap writer in optional checksum calculator
let mut writer = AsyncWriterWithChecksum::<D, _>::new(BufWriter::new(writer), !skip_checksum);
Expand Down
5 changes: 3 additions & 2 deletions src/chain/store/chain_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::sync::Arc;

use crate::blocks::{BlockHeader, Tipset, TipsetKeys, TxMeta};
use crate::interpreter::BlockMessages;
use crate::ipld::FrozenCids;
use crate::libp2p_bitswap::{BitswapStoreRead, BitswapStoreReadWrite};
use crate::message::{ChainMessage, Message as MessageTrait, SignedMessage};
use crate::networks::ChainConfig;
Expand Down Expand Up @@ -114,7 +115,7 @@ where
.read_obj::<TipsetKeys>(HEAD_KEY)?
.is_some_and(|tipset_keys| chain_index.load_tipset(&tipset_keys).is_ok())
{
let tipset_keys = TipsetKeys::new(vec![*genesis_block_header.cid()]);
let tipset_keys = TipsetKeys::new(FrozenCids::from_iter([*genesis_block_header.cid()]));
settings.write_obj(HEAD_KEY, &tipset_keys)?;
}

Expand Down Expand Up @@ -206,7 +207,7 @@ where
/// Returns Tipset from key-value store from provided CIDs
#[tracing::instrument(skip_all)]
pub fn tipset_from_keys(&self, tsk: &TipsetKeys) -> Result<Arc<Tipset>, Error> {
if tsk.cids().is_empty() {
if tsk.cids.is_empty() {
return Ok(self.heaviest_tipset());
}
self.chain_index.load_tipset(tsk)
Expand Down
4 changes: 2 additions & 2 deletions src/chain_sync/chain_muxer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ where
if network.peer_manager().is_peer_new(&peer_id).await {
// Since the peer is new, send them a hello request
let request = HelloRequest {
heaviest_tip_set: heaviest.cids().to_vec(),
heaviest_tip_set: heaviest.cids(),
heaviest_tipset_height: heaviest.epoch(),
heaviest_tipset_weight: heaviest.weight().clone().into(),
genesis_cid: genesis_block_cid,
Expand Down Expand Up @@ -372,7 +372,7 @@ where
metrics::LIBP2P_MESSAGE_TOTAL
.with_label_values(&[metrics::values::HELLO_RESPONSE_OUTBOUND])
.inc();
let tipset_keys = TipsetKeys::new(request.heaviest_tip_set);
let tipset_keys = TipsetKeys::from(request.heaviest_tip_set);
let tipset = match Self::get_full_tipset(
network.clone(),
chain_store.clone(),
Expand Down
2 changes: 1 addition & 1 deletion src/chain_sync/network_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ where
T: TryFrom<TipsetBundle, Error = String> + Send + Sync + 'static,
{
let request = ChainExchangeRequest {
start: tsk.cids().to_vec(),
start: Vec::<Cid>::from(&tsk.cids),
request_len,
options,
};
Expand Down
14 changes: 6 additions & 8 deletions src/chain_sync/tipset_syncer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,7 @@ async fn sync_headers_in_reverse<DB: Blockstore + Sync + Send + 'static, C: Cons
}
// Attempt to load the parent tipset from local store
if let Ok(tipset) = chain_store.tipset_from_keys(oldest_parent.parents()) {
parent_blocks.extend_from_slice(tipset.cids());
parent_blocks.extend(tipset.cids());
Comment thread
jdjaustin marked this conversation as resolved.
parent_tipsets.push(tipset);
continue;
}
Expand All @@ -901,7 +901,7 @@ async fn sync_headers_in_reverse<DB: Blockstore + Sync + Send + 'static, C: Cons
break 'sync;
}
validate_tipset_against_cache(bad_block_cache, tipset.key(), &parent_blocks)?;
parent_blocks.extend_from_slice(tipset.cids());
parent_blocks.extend(tipset.cids());
tracker.write().set_epoch(tipset.epoch());
parent_tipsets.push(tipset);
}
Expand Down Expand Up @@ -936,7 +936,7 @@ async fn sync_headers_in_reverse<DB: Blockstore + Sync + Send + 'static, C: Cons
// iterator is immediately dropped
let mut fork_tipsets = fork_tipsets;
fork_tipsets.drain((i + 1)..);
parent_tipsets.extend_from_slice(&fork_tipsets);
parent_tipsets.extend(fork_tipsets);
break;
}

Expand Down Expand Up @@ -1593,14 +1593,12 @@ fn validate_tipset_against_cache<C: Consensus>(
tipset: &TipsetKeys,
descendant_blocks: &[Cid],
) -> Result<(), TipsetRangeSyncerError<C>> {
for cid in tipset.cids() {
if let Some(reason) = bad_block_cache.get(cid) {
for cid in &tipset.cids {
if let Some(reason) = bad_block_cache.get(&cid) {
for block_cid in descendant_blocks {
bad_block_cache.put(*block_cid, format!("chain contained {cid}"));
}
return Err(TipsetRangeSyncerError::TipsetRangeWithBadBlock(
*cid, reason,
));
return Err(TipsetRangeSyncerError::TipsetRangeWithBadBlock(cid, reason));
}
}
Ok(())
Expand Down
9 changes: 3 additions & 6 deletions src/cli/subcommands/chain_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,9 @@ impl ChainCommands {
force: no_confirm,
} => {
maybe_confirm(*no_confirm, SET_HEAD_CONFIRMATION_MESSAGE)?;
chain_set_head(
(TipsetKeys { cids: cids.clone() },),
&config.client.rpc_token,
)
.await
.map_err(handle_rpc_err)
chain_set_head((TipsetKeys::from(cids.clone()),), &config.client.rpc_token)
.await
.map_err(handle_rpc_err)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/db/car/forest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl<ReaderT: super::RandomAccessFileReader> ForestCar<ReaderT> {
}

pub fn heaviest_tipset(&self) -> anyhow::Result<Tipset> {
Tipset::load_required(self, &TipsetKeys::new(self.roots()))
Tipset::load_required(self, &TipsetKeys::from(self.roots()))
}

pub fn into_dyn(self) -> ForestCar<Box<dyn super::RandomAccessFileReader>> {
Expand Down
2 changes: 1 addition & 1 deletion src/db/car/plain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ impl<ReaderT: super::RandomAccessFileReader> PlainCar<ReaderT> {
}

pub fn heaviest_tipset(&self) -> anyhow::Result<Tipset> {
Tipset::load_required(self, &TipsetKeys::new(self.roots()))
Tipset::load_required(self, &TipsetKeys::from(self.roots()))
}

/// In an arbitrary order
Expand Down
2 changes: 1 addition & 1 deletion src/genesis/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ where
sm.chain_store().set_estimated_records(n_records as u64)?;
}

let ts = sm.chain_store().tipset_from_keys(&TipsetKeys::new(cids))?;
let ts = sm.chain_store().tipset_from_keys(&TipsetKeys::from(cids))?;

if !skip_load {
let gb = sm.chain_store().chain_index.tipset_by_height(
Expand Down
4 changes: 2 additions & 2 deletions src/interpreter/fvm2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,8 @@ impl<DB: Blockstore + Send + Sync + 'static> Consensus for ForestExternsV2<DB> {
let bh_3 = from_slice_with_fallback::<BlockHeader>(extra)?;
if bh_1.parents() == bh_3.parents()
&& bh_1.epoch() == bh_3.epoch()
&& bh_2.parents().cids().contains(bh_3.cid())
&& !bh_2.parents().cids().contains(bh_1.cid())
&& bh_2.parents().cids.contains(*bh_3.cid())
&& !bh_2.parents().cids.contains(*bh_1.cid())
{
fault_type = Some(ConsensusFaultType::ParentGrinding);
}
Expand Down
4 changes: 2 additions & 2 deletions src/interpreter/fvm3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,8 @@ impl<DB: Blockstore + Send + Sync + 'static> Consensus for ForestExterns<DB> {
let bh_3 = from_slice_with_fallback::<BlockHeader>(extra)?;
if bh_1.parents() == bh_3.parents()
&& bh_1.epoch() == bh_3.epoch()
&& bh_2.parents().cids().contains(bh_3.cid())
&& !bh_2.parents().cids().contains(bh_1.cid())
&& bh_2.parents().cids.contains(*bh_3.cid())
&& !bh_2.parents().cids.contains(*bh_1.cid())
{
fault_type = Some(ConsensusFaultType::ParentGrinding);
}
Expand Down
26 changes: 12 additions & 14 deletions src/ipld/cid_hashmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,32 +33,30 @@ impl<V> CidHashMap<V> {

/// Returns `true` if the map contains a value for the specified key.
pub fn contains_key(&self, k: Cid) -> bool {
match k.try_into() {
Ok(CidVariant::V1DagCborBlake2b(bytes)) => {
match k.into() {
CidVariant::V1DagCborBlake2b(bytes) => {
self.v1_dagcbor_blake2b_hash_map.contains_key(&bytes)
}
Err(()) => self.fallback_hash_map.contains_key(&k),
CidVariant::Generic(_) => self.fallback_hash_map.contains_key(&k),
}
}

/// Inserts a key-value pair into the map; if the map did not have this key present, [`None`] is returned.
pub fn insert(&mut self, k: Cid, v: V) -> Option<V> {
match k.try_into() {
Ok(CidVariant::V1DagCborBlake2b(bytes)) => {
match k.into() {
CidVariant::V1DagCborBlake2b(bytes) => {
self.v1_dagcbor_blake2b_hash_map.insert(bytes, v)
}
Err(()) => self.fallback_hash_map.insert(k, v),
CidVariant::Generic(_) => self.fallback_hash_map.insert(k, v),
}
}

/// Removes a key from the map, returning the value at the key if the key
/// was previously in the map.
pub fn remove(&mut self, k: Cid) -> Option<V> {
match k.try_into() {
Ok(CidVariant::V1DagCborBlake2b(bytes)) => {
self.v1_dagcbor_blake2b_hash_map.remove(&bytes)
}
Err(()) => self.fallback_hash_map.remove(&k),
match k.into() {
CidVariant::V1DagCborBlake2b(bytes) => self.v1_dagcbor_blake2b_hash_map.remove(&bytes),
CidVariant::Generic(_) => self.fallback_hash_map.remove(&k),
}
}

Expand All @@ -69,9 +67,9 @@ impl<V> CidHashMap<V> {

/// Returns a reference to the value corresponding to the key.
pub fn get(&self, k: Cid) -> Option<&V> {
match k.try_into() {
Ok(CidVariant::V1DagCborBlake2b(bytes)) => self.v1_dagcbor_blake2b_hash_map.get(&bytes),
Err(()) => self.fallback_hash_map.get(&k),
match k.into() {
CidVariant::V1DagCborBlake2b(bytes) => self.v1_dagcbor_blake2b_hash_map.get(&bytes),
CidVariant::Generic(_) => self.fallback_hash_map.get(&k),
}
}

Expand Down
Loading