diff --git a/fendermint/actors/chainmetadata/src/actor.rs b/fendermint/actors/chainmetadata/src/actor.rs index 21bbe5dee..e140a685e 100644 --- a/fendermint/actors/chainmetadata/src/actor.rs +++ b/fendermint/actors/chainmetadata/src/actor.rs @@ -1,8 +1,6 @@ // Copyright 2021-2023 Protocol Labs // SPDX-License-Identifier: Apache-2.0, MIT -use cid::multihash::Code; -use cid::multihash::MultihashDigest; use cid::Cid; use fil_actors_runtime::actor_dispatch; use fil_actors_runtime::actor_error; @@ -11,7 +9,6 @@ use fil_actors_runtime::runtime::{ActorCode, Runtime}; use fil_actors_runtime::ActorDowncast; use fil_actors_runtime::ActorError; use fil_actors_runtime::Array; -use fvm_ipld_encoding::DAG_CBOR; use fvm_shared::clock::ChainEpoch; use fvm_shared::error::ExitCode; @@ -83,26 +80,17 @@ impl Actor { fn block_cid(rt: &impl Runtime, epoch: ChainEpoch) -> Result, ActorError> { let st: State = rt.state()?; - // load the blockhashes AMT - let blockhashes = Array::load(&st.blockhashes, rt.store()).map_err(|e| { - e.downcast_default( - ExitCode::USR_ILLEGAL_STATE, - "failed to load blockhashes states", - ) - })?; - - // get the block cid from the AMT, if it does not exist return None - let blockhash: &BlockHash = match blockhashes.get(epoch as u64).unwrap() { - Some(v) => v, - None => { + match st.get_block_cid(rt.store(), epoch) { + Ok(Some(cid)) => Ok(Some(cid)), + Ok(None) => { return Ok(None); } - }; - - Ok(Some(Cid::new_v1( - DAG_CBOR, - Code::Blake2b256.digest(blockhash), - ))) + Err(err) => { + return Err( + err.downcast_default(ExitCode::USR_ILLEGAL_STATE, "failed to get blockhash") + ); + } + } } } diff --git a/fendermint/actors/chainmetadata/src/shared.rs b/fendermint/actors/chainmetadata/src/shared.rs index 3962d74e5..6e00d9207 100644 --- a/fendermint/actors/chainmetadata/src/shared.rs +++ b/fendermint/actors/chainmetadata/src/shared.rs @@ -1,10 +1,16 @@ // Copyright 2021-2023 Protocol Labs // SPDX-License-Identifier: Apache-2.0, MIT -use cid::Cid; +use cid::{ + multihash::{Code, MultihashDigest}, + Cid, +}; use fil_actors_runtime::Array; use fvm_ipld_blockstore::Blockstore; -use fvm_ipld_encoding::tuple::{Deserialize_tuple, Serialize_tuple}; +use fvm_ipld_encoding::{ + tuple::{Deserialize_tuple, Serialize_tuple}, + DAG_CBOR, +}; use fvm_shared::{clock::ChainEpoch, METHOD_CONSTRUCTOR}; use num_derive::FromPrimitive; @@ -36,6 +42,46 @@ impl State { lookback_len, }) } + + // loads the blockhashes array from the AMT root cid and returns the blockhash + // at the given epoch + pub fn get_block_cid( + &self, + store: &BS, + epoch: ChainEpoch, + ) -> anyhow::Result> { + // load the blockhashes Array from the AMT root cid + let blockhashes = match Array::load(&self.blockhashes, &store) { + Ok(v) => v, + Err(e) => { + return Err(anyhow::anyhow!( + "failed to load blockhashes from AMT cid {}, error: {}", + self.blockhashes, + e + )); + } + }; + + // get the block hash at the given epoch + let blockhash: &BlockHash = match blockhashes.get(epoch as u64) { + Ok(Some(v)) => v, + Ok(None) => { + return Ok(None); + } + Err(err) => { + return Err(anyhow::anyhow!( + "failed to get blockhash at epoch {}, error: {}", + epoch, + err + )); + } + }; + + Ok(Some(Cid::new_v1( + DAG_CBOR, + Code::Blake2b256.digest(blockhash), + ))) + } } // the default lookback length is 256 epochs diff --git a/fendermint/vm/interpreter/src/fvm/externs.rs b/fendermint/vm/interpreter/src/fvm/externs.rs index 83d1c743a..c7df30f65 100644 --- a/fendermint/vm/interpreter/src/fvm/externs.rs +++ b/fendermint/vm/interpreter/src/fvm/externs.rs @@ -1,19 +1,14 @@ // Copyright 2022-2024 Protocol Labs // SPDX-License-Identifier: Apache-2.0, MIT use anyhow::anyhow; -use cid::{ - multihash::{Code, MultihashDigest}, - Cid, -}; -use fendermint_actor_chainmetadata::BlockHash; +use cid::Cid; use fendermint_actors::CHAINMETADATA_ACTOR_ID; -use fil_actors_runtime::Array; use fvm::{ externs::{Chain, Consensus, Externs, Rand}, state_tree::StateTree, }; use fvm_ipld_blockstore::Blockstore; -use fvm_ipld_encoding::{CborStore, DAG_CBOR}; +use fvm_ipld_encoding::CborStore; use fvm_shared::clock::ChainEpoch; use super::store::ReadOnlyBlockstore; @@ -113,22 +108,11 @@ where } }; - // load the blockhashe Array from the AMT root cid - let blockhashes = Array::load(&actor_state.blockhashes, &bstore)?; - - // get the block hash at the given epoch - let blockhash: &BlockHash = match blockhashes.get(epoch as u64).unwrap() { - Some(v) => v, - None => { - return Ok(Cid::default()); - } - }; - - let cid = Cid::new_v1(DAG_CBOR, Code::Blake2b256.digest(blockhash)); - - tracing::info!("get_tipset_cid returned cid: {} at epoch: {}", cid, epoch); - - Ok(cid) + match actor_state.get_block_cid(&bstore, epoch) { + Ok(Some(cid)) => Ok(cid), + Ok(None) => Ok(Cid::default()), + Err(err) => return Err(err), + } } }