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
6 changes: 3 additions & 3 deletions src/cli/subcommands/chain_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use list::ChainListCommand;
mod prune;
use prune::ChainPruneCommands;

use super::print_pretty_lotus_json;
use crate::blocks::{Tipset, TipsetKey};
use crate::lotus_json::HasLotusJson;
use crate::message::ChainMessage;
Expand All @@ -15,8 +16,7 @@ use anyhow::{bail, ensure};
use cid::Cid;
use clap::Subcommand;
use nunny::Vec as NonEmpty;

use super::print_pretty_lotus_json;
use std::sync::Arc;

#[derive(Debug, Clone, clap::ValueEnum)]
pub enum Format {
Expand Down Expand Up @@ -143,7 +143,7 @@ impl ChainCommands {
async fn tipset_by_epoch_or_offset(
client: &rpc::Client,
epoch_or_offset: i64,
) -> Result<Tipset, jsonrpsee::core::ClientError> {
) -> Result<Arc<Tipset>, jsonrpsee::core::ClientError> {
let current_head = ChainHead::call(client, ()).await?;

let target_epoch = match epoch_or_offset.is_negative() {
Expand Down
4 changes: 2 additions & 2 deletions src/cli/subcommands/f3_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mod tests;

use std::{
borrow::Cow,
sync::LazyLock,
sync::{Arc, LazyLock},
time::{Duration, Instant},
};

Expand Down Expand Up @@ -151,7 +151,7 @@ impl F3Commands {

async fn get_heads(
client: &rpc::Client,
) -> anyhow::Result<(Tipset, FinalityCertificate)> {
) -> anyhow::Result<(Arc<Tipset>, FinalityCertificate)> {
let cert_head = client.call(F3GetLatestCertificate::request(())?).await?;
let chain_head = client.call(ChainHead::request(())?).await?;
Ok((chain_head, cert_head))
Expand Down
25 changes: 25 additions & 0 deletions src/lotus_json/arc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2019-2025 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use super::*;
use std::sync::Arc;

impl<T: HasLotusJson + Clone> HasLotusJson for Arc<T> {
type LotusJson = T::LotusJson;

#[cfg(test)]
fn snapshots() -> Vec<(serde_json::Value, Self)> {
T::snapshots()
.into_iter()
.map(|(k, v)| (k, Arc::new(v)))
.collect()
}

fn into_lotus_json(self) -> Self::LotusJson {
(*self).clone().into_lotus_json()
}

fn from_lotus_json(lotus_json: Self::LotusJson) -> Self {
Arc::new(T::from_lotus_json(lotus_json))
}
}
1 change: 1 addition & 0 deletions src/lotus_json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ decl_and_test!(
// but you MUST document any tech debt - the reason WHY it cannot be tested above.
mod actors;
mod allocation;
mod arc;
mod beneficiary_term; // fil_actor_miner_state::v12::BeneficiaryTerm: !quickcheck::Arbitrary
mod bit_field; // fil_actors_shared::fvm_ipld_bitfield::BitField: !quickcheck::Arbitrary
mod bytecode_hash;
Expand Down
39 changes: 15 additions & 24 deletions src/rpc/methods/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ impl RpcMethod<0> for ChainGetFinalizedTipset {
);

type Params = ();
type Ok = Tipset;
type Ok = Arc<Tipset>;

async fn handle(
ctx: Ctx<impl Blockstore + Send + Sync + 'static>,
Expand All @@ -154,7 +154,7 @@ impl RpcMethod<0> for ChainGetFinalizedTipset {
match get_f3_finality_tipset(&ctx, ec_finality_epoch).await {
Ok(f3_tipset) => {
tracing::debug!("Using F3 finalized tipset at epoch {}", f3_tipset.epoch());
Ok((*f3_tipset).clone())
Ok(f3_tipset)
}
Err(_) => {
// fallback to ec finality
Expand All @@ -164,7 +164,7 @@ impl RpcMethod<0> for ChainGetFinalizedTipset {
head,
ResolveNullTipset::TakeOlder,
)?;
Ok((*ec_tipset).clone())
Ok(ec_tipset)
}
}
}
Expand Down Expand Up @@ -867,7 +867,7 @@ impl RpcMethod<2> for ChainGetTipSetByHeight {
const DESCRIPTION: Option<&'static str> = Some("Returns the tipset at the specified height.");

type Params = (ChainEpoch, ApiTipsetKey);
type Ok = Tipset;
type Ok = Arc<Tipset>;

async fn handle(
ctx: Ctx<impl Blockstore>,
Expand All @@ -879,7 +879,7 @@ impl RpcMethod<2> for ChainGetTipSetByHeight {
let tss = ctx
.chain_index()
.tipset_by_height(height, ts, ResolveNullTipset::TakeOlder)?;
Ok((*tss).clone())
Ok(tss)
}
}

Expand All @@ -896,7 +896,7 @@ impl RpcMethod<2> for ChainGetTipSetAfterHeight {
);

type Params = (ChainEpoch, ApiTipsetKey);
type Ok = Tipset;
type Ok = Arc<Tipset>;

async fn handle(
ctx: Ctx<impl Blockstore>,
Expand All @@ -908,7 +908,7 @@ impl RpcMethod<2> for ChainGetTipSetAfterHeight {
let tss = ctx
.chain_index()
.tipset_by_height(height, ts, ResolveNullTipset::TakeNewer)?;
Ok((*tss).clone())
Ok(tss)
}
}

Expand Down Expand Up @@ -937,11 +937,11 @@ impl RpcMethod<0> for ChainHead {
const DESCRIPTION: Option<&'static str> = Some("Returns the chain head (heaviest tipset).");

type Params = ();
type Ok = Tipset;
type Ok = Arc<Tipset>;

async fn handle(ctx: Ctx<impl Blockstore>, (): Self::Params) -> Result<Self::Ok, ServerError> {
let heaviest = ctx.chain_store().heaviest_tipset();
Ok((*heaviest).clone())
Ok(heaviest)
}
}

Expand Down Expand Up @@ -974,7 +974,7 @@ impl RpcMethod<1> for ChainGetTipSet {
const DESCRIPTION: Option<&'static str> = Some("Returns the tipset with the specified CID.");

type Params = (ApiTipsetKey,);
type Ok = Tipset;
type Ok = Arc<Tipset>;

async fn handle(
ctx: Ctx<impl Blockstore>,
Expand All @@ -983,7 +983,7 @@ impl RpcMethod<1> for ChainGetTipSet {
let ts = ctx
.chain_store()
.load_required_tipset_or_heaviest(&tipset_key)?;
Ok((*ts).clone())
Ok(ts)
}
}

Expand All @@ -996,7 +996,7 @@ impl RpcMethod<1> for ChainGetTipSetV2 {
const DESCRIPTION: Option<&'static str> = Some("Returns the tipset with the specified CID.");

type Params = (ApiTipsetKey,);
type Ok = Tipset;
type Ok = Arc<Tipset>;

async fn handle(_: Ctx<impl Blockstore>, _: Self::Params) -> Result<Self::Ok, ServerError> {
Err(ServerError::unsupported_method())
Expand Down Expand Up @@ -1098,10 +1098,7 @@ pub(crate) fn chain_notify<DB: Blockstore>(
let current = data.chain_store().heaviest_tipset();
let (change, tipset) = ("current".into(), current);
sender
.send(vec![ApiHeadChange {
change,
tipset: tipset.as_ref().clone(),
}])
.send(vec![ApiHeadChange { change, tipset }])
.expect("receiver is not dropped");

let mut subscriber = data.chain_store().publisher().subscribe();
Expand All @@ -1115,13 +1112,7 @@ pub(crate) fn chain_notify<DB: Blockstore>(
HeadChange::Apply(ts) => ("apply".into(), ts),
};

if sender
.send(vec![ApiHeadChange {
change,
tipset: tipset.as_ref().clone(),
}])
.is_err()
{
if sender.send(vec![ApiHeadChange { change, tipset }]).is_err() {
break;
}
}
Expand Down Expand Up @@ -1254,7 +1245,7 @@ pub struct ApiHeadChange {
pub change: String,
#[serde(rename = "Val", with = "crate::lotus_json")]
#[schemars(with = "LotusJson<Tipset>")]
pub tipset: Tipset,
pub tipset: Arc<Tipset>,
}
lotus_json_with_self!(ApiHeadChange);

Expand Down
Loading