diff --git a/Cargo.lock b/Cargo.lock index 08b72f01c491..a3a2be5ae11a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2019,7 +2019,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ab67060fc6b8ef687992d439ca0fa36e7ed17e9a0b16b25b601e8757df720de" dependencies = [ "data-encoding", - "syn 1.0.109", + "syn 2.0.117", ] [[package]] @@ -3379,6 +3379,7 @@ dependencies = [ "rlimit", "rlp", "rs-car-ipfs", + "rstest", "rust2go", "schemars 1.2.1", "scopeguard", @@ -4612,7 +4613,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.5.10", + "socket2 0.6.2", "tokio", "tower-service", "tracing", @@ -7515,7 +7516,7 @@ dependencies = [ "quinn-udp", "rustc-hash 2.1.1", "rustls", - "socket2 0.5.10", + "socket2 0.6.2", "thiserror 2.0.18", "tokio", "tracing", @@ -7553,9 +7554,9 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.5.10", + "socket2 0.6.2", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -7906,6 +7907,12 @@ version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + [[package]] name = "rend" version = "0.5.3" @@ -8126,6 +8133,35 @@ dependencies = [ "rs-car", ] +[[package]] +name = "rstest" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5a3193c063baaa2a95a33f03035c8a72b83d97a54916055ba22d35ed3839d49" +dependencies = [ + "futures-timer", + "futures-util", + "rstest_macros", +] + +[[package]] +name = "rstest_macros" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c845311f0ff7951c5506121a9ad75aec44d083c31583b2ea5a30bcb0b0abba0" +dependencies = [ + "cfg-if", + "glob", + "proc-macro-crate 3.5.0", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version", + "syn 2.0.117", + "unicode-ident", +] + [[package]] name = "rtnetlink" version = "0.20.0" diff --git a/Cargo.toml b/Cargo.toml index 35400a0913a9..e398bd941388 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -259,6 +259,7 @@ quickcheck = "1" quickcheck_macros = "1" ra_ap_syntax = "0.0.323" regex-automata = "0.4" +rstest = "0.26" serial_test = "3" syn = { version = "2", default-features = false, features = ["full", "parsing", "visit", "printing", "extra-traits"] } tokio-test = "0.4" diff --git a/src/blocks/tipset.rs b/src/blocks/tipset.rs index 7bb72d2fcfab..ecda41502ddf 100644 --- a/src/blocks/tipset.rs +++ b/src/blocks/tipset.rs @@ -3,7 +3,7 @@ use std::{ fmt, - sync::{Arc, OnceLock}, + sync::{Arc, LazyLock, OnceLock}, }; use super::{Block, CachingBlockHeader, RawBlockHeader, Ticket}; @@ -12,7 +12,12 @@ use crate::{ cid_collections::SmallCidNonEmptyVec, networks::{calibnet, mainnet}, shim::clock::ChainEpoch, - utils::{cid::CidCborExt, get_size::nunny_vec_heap_size_helper}, + utils::{ + cid::CidCborExt, + db::{CborStoreExt, car_stream::CarBlock}, + get_size::nunny_vec_heap_size_helper, + multihash::MultihashCode, + }, }; use ahash::HashMap; use anyhow::Context as _; @@ -21,6 +26,7 @@ use fvm_ipld_blockstore::Blockstore; use fvm_ipld_encoding::CborStore; use get_size2::GetSize; use itertools::Itertools as _; +use multihash_derive::MultihashDigest as _; use num::BigInt; use nunny::{Vec as NonEmpty, vec as nonempty}; use serde::{Deserialize, Serialize}; @@ -43,13 +49,18 @@ use thiserror::Error; GetSize, derive_more::IntoIterator, )] -#[cfg_attr(test, derive(derive_quickcheck_arbitrary::Arbitrary))] pub struct TipsetKey(#[into_iterator(owned, ref)] SmallCidNonEmptyVec); impl TipsetKey { // Special encoding to match Lotus. pub fn cid(&self) -> anyhow::Result { - Ok(Cid::from_cbor_blake2b256(&self.bytes())?) + Ok(self.car_block()?.cid) + } + + pub fn car_block(&self) -> anyhow::Result { + let data = fvm_ipld_encoding::to_vec(&self.bytes())?; + let cid = Cid::from_cbor_encoded_raw_bytes_blake2b256(&data); + Ok(CarBlock { cid, data }) } /// Returns `true` if the tipset key contains the given CID. @@ -109,6 +120,37 @@ impl TipsetKey { pub fn bytes(&self) -> fvm_ipld_encoding::RawBytes { fvm_ipld_encoding::RawBytes::new(self.iter().flat_map(|cid| cid.to_bytes()).collect()) } + + /// Construct from bytes representation + pub fn from_bytes(bytes: fvm_ipld_encoding::RawBytes) -> anyhow::Result { + static BLOCK_HEADER_CID_LEN: LazyLock = LazyLock::new(|| { + let buf = [0_u8; 256]; + let cid = Cid::new_v1( + fvm_ipld_encoding::DAG_CBOR, + MultihashCode::Blake2b256.digest(&buf), + ); + cid.encoded_len() + }); + + let cids: Vec = Vec::::from(bytes) + .chunks(*BLOCK_HEADER_CID_LEN) + .map(Cid::read_bytes) + .try_collect()?; + + Ok(nunny::Vec::new(cids) + .map_err(|_| anyhow::anyhow!("tipset key cannot be empty"))? + .into()) + } + + /// Save tipset key to block store + pub fn save(&self, bs: &impl Blockstore) -> anyhow::Result { + bs.put_cbor_default(&self.bytes()) + } + + /// Load tipset key from block store by its CID + pub fn load(bs: &impl Blockstore, cid: &Cid) -> anyhow::Result { + Self::from_bytes(bs.get_cbor_required(cid)?) + } } impl From> for TipsetKey { @@ -654,15 +696,17 @@ mod lotus_json { #[cfg(test)] mod test { use super::*; - use crate::blocks::VRFProof; use crate::blocks::{ - CachingBlockHeader, ElectionProof, Ticket, Tipset, TipsetKey, header::RawBlockHeader, + CachingBlockHeader, ElectionProof, Ticket, Tipset, TipsetKey, VRFProof, + header::RawBlockHeader, }; + use crate::db::MemoryDB; use crate::shim::address::Address; - use crate::utils::multihash::prelude::*; use cid::Cid; use fvm_ipld_encoding::DAG_CBOR; use num_bigint::BigInt; + use quickcheck::Arbitrary; + use quickcheck_macros::quickcheck; use std::iter; pub fn mock_block(id: u64, weight: u64, ticket_sequence: u64) -> CachingBlockHeader { @@ -810,4 +854,35 @@ mod test { CreateTipsetError::Empty ); } + + impl Arbitrary for TipsetKey { + fn arbitrary(g: &mut quickcheck::Gen) -> Self { + let blocks: nunny::Vec> = nunny::Vec::arbitrary(g); + let cids = nunny::Vec::new( + blocks + .into_iter() + .map(|b| { + Cid::new_v1( + fvm_ipld_encoding::DAG_CBOR, + MultihashCode::Blake2b256.digest(&b), + ) + }) + .collect_vec(), + ) + .expect("infallible"); + cids.into() + } + } + + #[quickcheck] + fn tipset_key_bytes(tsk: TipsetKey) { + let bytes = tsk.bytes(); + let tsk2 = TipsetKey::from_bytes(bytes).unwrap(); + assert_eq!(tsk, tsk2); + + let bs = MemoryDB::default(); + let cid = tsk.save(&bs).unwrap(); + let tsk3 = TipsetKey::load(&bs, &cid).unwrap(); + assert_eq!(tsk, tsk3); + } } diff --git a/src/chain/mod.rs b/src/chain/mod.rs index 5940ac5e0154..b16679c41bec 100644 --- a/src/chain/mod.rs +++ b/src/chain/mod.rs @@ -35,6 +35,7 @@ pub struct ExportOptions { pub skip_checksum: bool, pub include_receipts: bool, pub include_events: bool, + pub include_tipset_keys: bool, pub seen: CidHashSet, } @@ -144,6 +145,7 @@ async fn export_to_forest_car( skip_checksum, include_receipts, include_events, + include_tipset_keys, seen, } = options.unwrap_or_default(); @@ -171,6 +173,7 @@ async fn export_to_forest_car( .with_seen(seen) .with_message_receipts(include_receipts) .with_events(include_events) + .with_tipset_keys(include_tipset_keys) .track_progress(true), ); diff --git a/src/chain/store/chain_store.rs b/src/chain/store/chain_store.rs index f920c4f55e76..fb18955ed0f5 100644 --- a/src/chain/store/chain_store.rs +++ b/src/chain/store/chain_store.rs @@ -146,6 +146,7 @@ where self.heaviest_tipset_key_provider .set_heaviest_tipset_key(ts.key())?; *self.heaviest_tipset_cache.write() = Some(ts.clone()); + ts.key().save(self.blockstore())?; if self.publisher.send(HeadChange::Apply(ts)).is_err() { debug!("did not publish head change, no active receivers"); } @@ -168,23 +169,9 @@ where Ok(()) } - /// Writes the `TipsetKey` to the blockstore for `EthAPI` queries. - pub fn put_tipset_key(&self, tsk: &TipsetKey) -> Result<(), Error> { - let tsk_bytes = tsk.bytes(); - let tsk_cid = self.blockstore().put_cbor_default(&tsk_bytes)?; - let hash = tsk_cid.into(); - self.eth_mappings.write_obj(&hash, tsk)?; - Ok(()) - } - /// Reads the `TipsetKey` from the blockstore for `EthAPI` queries. pub fn get_required_tipset_key(&self, hash: &EthHash) -> Result { - let tsk = self - .eth_mappings - .read_obj::(hash)? - .with_context(|| format!("cannot find tipset with hash {hash}"))?; - - Ok(tsk) + Ok(TipsetKey::load(self.blockstore(), &hash.to_cid())?) } /// Writes with timestamp the `Hash` to `Cid` mapping to the blockstore for `EthAPI` queries. diff --git a/src/cli/subcommands/snapshot_cmd.rs b/src/cli/subcommands/snapshot_cmd.rs index 399aeee62bfe..10880d73cc6e 100644 --- a/src/cli/subcommands/snapshot_cmd.rs +++ b/src/cli/subcommands/snapshot_cmd.rs @@ -145,6 +145,7 @@ impl SnapshotCommands { tipset_keys: tipset.key().clone().into(), include_receipts: false, include_events: false, + include_tipset_keys: false, skip_checksum, dry_run, }; diff --git a/src/daemon/db_util.rs b/src/daemon/db_util.rs index a43c180c4212..88533ed8d3da 100644 --- a/src/daemon/db_util.rs +++ b/src/daemon/db_util.rs @@ -349,7 +349,7 @@ where .headers_delegated_messages(ts.block_headers().iter())?, ); tracing::trace!("Indexing tipset @{}: {}", epoch, &tsk); - state_manager.chain_store().put_tipset_key(&tsk)?; + tsk.save(state_manager.blockstore())?; Ok(()) } diff --git a/src/daemon/mod.rs b/src/daemon/mod.rs index d929473877cd..765519caba4b 100644 --- a/src/daemon/mod.rs +++ b/src/daemon/mod.rs @@ -505,13 +505,10 @@ fn maybe_start_indexer_service( // Continuously listen for head changes loop { - let msg = receiver.recv().await?; + let HeadChange::Apply(ts) = receiver.recv().await?; - let HeadChange::Apply(ts) = msg; tracing::debug!("Indexing tipset {}", ts.key()); - chain_store.put_tipset_key(ts.key())?; - let delegated_messages = chain_store.headers_delegated_messages(ts.block_headers().iter())?; diff --git a/src/db/gc/snapshot.rs b/src/db/gc/snapshot.rs index 0f3bb9852b4b..6417214988dc 100644 --- a/src/db/gc/snapshot.rs +++ b/src/db/gc/snapshot.rs @@ -259,6 +259,7 @@ where skip_checksum: true, include_receipts: true, include_events: true, + include_tipset_keys: true, seen: Default::default(), }), ) diff --git a/src/ipld/util.rs b/src/ipld/util.rs index 0f019929cf93..f0b89e2f93b8 100644 --- a/src/ipld/util.rs +++ b/src/ipld/util.rs @@ -160,6 +160,7 @@ pin_project! { fail_on_dead_links: bool, message_receipts: bool, events: bool, + tipset_keys:bool, track_progress: bool, } } @@ -180,19 +181,25 @@ impl ChainStream { self } - /// Enable traversal of message receipt roots during chain export. + /// Whether to enable traversal of message receipt roots during chain export. pub fn with_message_receipts(mut self, message_receipts: bool) -> Self { self.message_receipts = message_receipts; self } - /// Enable traversal of events roots during chain export. + /// Whether to enable traversal of events roots during chain export. /// Requires message receipts to be enabled as well. pub fn with_events(mut self, events: bool) -> Self { self.events = events; self } + /// Whether to export tipset keys. + pub fn with_tipset_keys(mut self, tipset_keys: bool) -> Self { + self.tipset_keys = tipset_keys; + self + } + #[allow(dead_code)] pub fn into_seen(self) -> CidHashSet { self.seen @@ -224,6 +231,7 @@ pub fn stream_chain, ITER: Iterator fail_on_dead_links: true, message_receipts: false, events: false, + tipset_keys: false, track_progress: false, } } @@ -246,6 +254,7 @@ impl, ITER: Iterator + Unpin> Stream fn poll_next(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { use Task::*; + let export_tipset_keys = self.tipset_keys; let fail_on_dead_links = self.fail_on_dead_links; let stateroot_limit_exclusive = self.stateroot_limit_exclusive; let this = self.project(); @@ -326,6 +335,13 @@ impl, ITER: Iterator + Unpin> Stream // enclosing loop is processing the queue. Once the desired depth has been reached - // yield the block without walking the graph it represents. if let Some(tipset) = this.tipset_iter.next() { + // Tipset key cid can be convert from and to eth hash, which is useful for Eth APIs + if export_tipset_keys + && let Ok(CarBlock { cid, data }) = tipset.borrow().key().car_block() + { + this.dfs.push_back(Emit(cid, Some(data))); + } + for block in tipset.borrow().block_headers() { let (cid, data) = block.car_block()?; if this.seen.insert(cid) { diff --git a/src/rpc/methods/chain.rs b/src/rpc/methods/chain.rs index a3e5df878b94..136c386cecdb 100644 --- a/src/rpc/methods/chain.rs +++ b/src/rpc/methods/chain.rs @@ -427,6 +427,7 @@ impl RpcMethod<1> for ForestChainExport { tipset_keys: ApiTipsetKey(tsk), include_receipts, include_events, + include_tipset_keys, skip_checksum, dry_run, } = params; @@ -452,6 +453,7 @@ impl RpcMethod<1> for ForestChainExport { skip_checksum, include_receipts, include_events, + include_tipset_keys, seen: Default::default(), }); let writer = if dry_run { @@ -688,6 +690,7 @@ impl RpcMethod<1> for ChainExport { tipset_keys, include_receipts: false, include_events: false, + include_tipset_keys: false, skip_checksum, dry_run, },), @@ -1463,6 +1466,8 @@ pub struct ForestChainExportParams { pub include_receipts: bool, #[serde(default)] pub include_events: bool, + #[serde(default)] + pub include_tipset_keys: bool, pub skip_checksum: bool, pub dry_run: bool, } diff --git a/src/rpc/methods/eth.rs b/src/rpc/methods/eth.rs index 13a0ae4ec3f5..47a88cbee672 100644 --- a/src/rpc/methods/eth.rs +++ b/src/rpc/methods/eth.rs @@ -3832,6 +3832,7 @@ mod test { use fvm_shared4::event::Flags; use quickcheck::Arbitrary; use quickcheck_macros::quickcheck; + use rstest::rstest; impl Arbitrary for EthHash { fn arbitrary(g: &mut quickcheck::Gen) -> Self { @@ -3925,20 +3926,14 @@ mod test { } } - #[test] - fn test_hash() { - let test_cases = [ - r#""0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184""#, - r#""0xab8653edf9f51785664a643b47605a7ba3d917b5339a0724e7642c114d0e4738""#, - ]; - - for hash in test_cases { - let h: EthHash = serde_json::from_str(hash).unwrap(); - - let c = h.to_cid(); - let h1: EthHash = c.into(); - assert_eq!(h, h1); - } + #[rstest] + #[case("\"0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184\"")] + #[case("\"0xab8653edf9f51785664a643b47605a7ba3d917b5339a0724e7642c114d0e4738\"")] + fn test_hash_serde_json(#[case] hash: &str) { + let h: EthHash = serde_json::from_str(hash).unwrap(); + let c = h.to_cid(); + let h1: EthHash = c.into(); + assert_eq!(h, h1); } #[quickcheck] diff --git a/src/rpc/methods/f3/types.rs b/src/rpc/methods/f3/types.rs index 4b3ca5dadc3d..2f5c8ea33718 100644 --- a/src/rpc/methods/f3/types.rs +++ b/src/rpc/methods/f3/types.rs @@ -7,7 +7,7 @@ use crate::{ lotus_json::{HasLotusJson, LotusJson, base64_standard, lotus_json_with_self}, networks::NetworkChain, shim::{executor::Receipt, fvm_shared_latest::bigint::bigint_ser}, - utils::{encoding::serde_byte_array, multihash::prelude::*}, + utils::encoding::serde_byte_array, }; use byteorder::ByteOrder as _; use cid::Cid; @@ -15,7 +15,6 @@ use fil_actors_shared::fvm_ipld_bitfield::BitField; use flate2::read::DeflateDecoder; use fvm_ipld_encoding::tuple::*; use fvm_shared4::ActorID; -use itertools::Itertools as _; use libp2p::PeerId; use num::Zero as _; use nunny::Vec as NonEmpty; @@ -23,7 +22,6 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use serde_with::{DisplayFromStr, serde_as}; use std::io::Read as _; -use std::sync::LazyLock; use std::{cmp::Ordering, time::Duration}; const MAX_LEASE_INSTANCES: u64 = 5; @@ -53,24 +51,7 @@ impl TryFrom for TipsetKey { type Error = anyhow::Error; fn try_from(tsk: F3TipSetKey) -> Result { - static BLOCK_HEADER_CID_LEN: LazyLock = LazyLock::new(|| { - let buf = [0_u8; 256]; - let cid = Cid::new_v1( - fvm_ipld_encoding::DAG_CBOR, - MultihashCode::Blake2b256.digest(&buf), - ); - cid.to_bytes().len() - }); - - let cids: Vec = tsk - .0 - .chunks(*BLOCK_HEADER_CID_LEN) - .map(Cid::read_bytes) - .try_collect()?; - - Ok(nunny::Vec::new(cids) - .map_err(|_| anyhow::anyhow!("tipset key cannot be empty"))? - .into()) + Self::from_bytes(tsk.0.into()) } } diff --git a/src/rpc/snapshots/forest__rpc__tests__rpc__v0.snap b/src/rpc/snapshots/forest__rpc__tests__rpc__v0.snap index bfa2a88f14c1..f38d34079dcb 100644 --- a/src/rpc/snapshots/forest__rpc__tests__rpc__v0.snap +++ b/src/rpc/snapshots/forest__rpc__tests__rpc__v0.snap @@ -6015,6 +6015,9 @@ components: include_receipts: type: boolean default: false + include_tipset_keys: + type: boolean + default: false output_path: type: string recent_roots: diff --git a/src/rpc/snapshots/forest__rpc__tests__rpc__v1.snap b/src/rpc/snapshots/forest__rpc__tests__rpc__v1.snap index 9d8ceb01e118..bd521775b553 100644 --- a/src/rpc/snapshots/forest__rpc__tests__rpc__v1.snap +++ b/src/rpc/snapshots/forest__rpc__tests__rpc__v1.snap @@ -6253,6 +6253,9 @@ components: include_receipts: type: boolean default: false + include_tipset_keys: + type: boolean + default: false output_path: type: string recent_roots: diff --git a/src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap b/src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap index 4004cc4beba1..616856ec9bdf 100644 --- a/src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap +++ b/src/rpc/snapshots/forest__rpc__tests__rpc__v2.snap @@ -2439,6 +2439,9 @@ components: include_receipts: type: boolean default: false + include_tipset_keys: + type: boolean + default: false output_path: type: string recent_roots: diff --git a/src/tool/subcommands/api_cmd/test_snapshots.txt b/src/tool/subcommands/api_cmd/test_snapshots.txt index e9b9478b5f2f..8671ff36db09 100644 --- a/src/tool/subcommands/api_cmd/test_snapshots.txt +++ b/src/tool/subcommands/api_cmd/test_snapshots.txt @@ -58,22 +58,22 @@ filecoin_ethchainid_1736937942819147.rpcsnap.json.zst filecoin_ethfeehistory_1737446676883828.rpcsnap.json.zst filecoin_ethfeehistory_v2_1767605175056660.rpcsnap.json.zst filecoin_ethgasprice_1758725940980141.rpcsnap.json.zst -filecoin_ethgetbalance_1740048634848277.rpcsnap.json.zst +filecoin_ethgetbalance_1773156637422018.rpcsnap.json.zst filecoin_ethgetbalance_v1_unknown_addr_1770287845559622.rpcsnap.json.zst filecoin_ethgetbalance_v2_latest_1770291948779489.rpcsnap.json.zst filecoin_ethgetbalance_v2_pending_1770291949065157.rpcsnap.json.zst filecoin_ethgetbalance_v2_safe_1770291948803158.rpcsnap.json.zst filecoin_ethgetbalance_v2_unknown_addr_1770287845559744.rpcsnap.json.zst -filecoin_ethgetblockbyhash_1740132537807408.rpcsnap.json.zst +filecoin_ethgetblockbyhash_1773157415768830.rpcsnap.json.zst filecoin_ethgetblockbynumber_1737446676696328.rpcsnap.json.zst filecoin_ethgetblockbynumber_v2_1768192171057588.rpcsnap.json.zst -filecoin_ethgetblockreceipts_1740132537907751.rpcsnap.json.zst -filecoin_ethgetblockreceipts_v2_1769603485649087.rpcsnap.json.zst +filecoin_ethgetblockreceipts_1773157886472662.rpcsnap.json.zst +filecoin_ethgetblockreceipts_v2_1773157886472662.rpcsnap.json.zst filecoin_ethgetblockreceipts_v2_finalized_1769603486031510.rpcsnap.json.zst filecoin_ethgetblockreceipts_v2_safe_1769603485649367.rpcsnap.json.zst -filecoin_ethgetblockreceiptslimited_1740132537908421.rpcsnap.json.zst -filecoin_ethgetblockreceiptslimited_v2_1769630813979893.rpcsnap.json.zst -filecoin_ethgetblocktransactioncountbyhash_1740132538001911.rpcsnap.json.zst +filecoin_ethgetblockreceiptslimited_1773157887312363.rpcsnap.json.zst +filecoin_ethgetblockreceiptslimited_v2_1773157887312363.rpcsnap.json.zst +filecoin_ethgetblocktransactioncountbyhash_1773159049678664.rpcsnap.json.zst filecoin_ethgetblocktransactioncountbynumber_1737446676697272.rpcsnap.json.zst filecoin_ethgetblocktransactioncountbynumber_v2_1769099953133906.rpcsnap.json.zst filecoin_ethgetblocktransactioncountbynumber_v2_1769099953134061.rpcsnap.json.zst @@ -96,7 +96,7 @@ filecoin_ethgetstorageat_v2_1769611091439289.rpcsnap.json.zst filecoin_ethgetstorageat_v2_finalized_1769611091511354.rpcsnap.json.zst filecoin_ethgetstorageat_v2_safe_1769611091439347.rpcsnap.json.zst filecoin_ethgetstorageat_v2_unknown_addr_1770288667897031.rpcsnap.json.zst -filecoin_ethgettransactionbyblockhashandindex_1740132538373654.rpcsnap.json.zst +filecoin_ethgettransactionbyblockhashandindex_1773159088537607.rpcsnap.json.zst filecoin_ethgettransactionbyblocknumberandindex_1740132538304408.rpcsnap.json.zst filecoin_ethgettransactionbyblocknumberandindex_latest_1769103643171646.rpcsnap.json.zst filecoin_ethgettransactionbyblocknumberandindex_pending_1769103643171774.rpcsnap.json.zst diff --git a/src/tool/subcommands/archive_cmd.rs b/src/tool/subcommands/archive_cmd.rs index 8c418f524c96..9f275c1eeca6 100644 --- a/src/tool/subcommands/archive_cmd.rs +++ b/src/tool/subcommands/archive_cmd.rs @@ -630,6 +630,7 @@ pub async fn do_export( skip_checksum: true, include_receipts: false, include_events: false, + include_tipset_keys: false, seen, }), ) diff --git a/src/utils/cid/mod.rs b/src/utils/cid/mod.rs index 2f712b82085a..000c2fc59a7d 100644 --- a/src/utils/cid/mod.rs +++ b/src/utils/cid/mod.rs @@ -15,10 +15,15 @@ pub trait CidCborExt { /// This matches [`abi.CidBuilder`](https://github.com/filecoin-project/go-state-types/blob/master/abi/cid.go#L49) in go fn from_cbor_blake2b256(obj: &S) -> Result { let bytes = fvm_ipld_encoding::to_vec(obj)?; - Ok(Cid::new_v1( + Ok(Self::from_cbor_encoded_raw_bytes_blake2b256(&bytes)) + } + + /// Build CID v1 with `Blake2b256` hasher from `DAG_CBOR` encoded bytes + fn from_cbor_encoded_raw_bytes_blake2b256(bytes: &[u8]) -> Cid { + Cid::new_v1( fvm_ipld_encoding::DAG_CBOR, - MultihashCode::Blake2b256.digest(&bytes), - )) + MultihashCode::Blake2b256.digest(bytes), + ) } }