-
Notifications
You must be signed in to change notification settings - Fork 181
feat(api): implement the ChainGetFinalizedTipset API
#6133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -140,11 +140,62 @@ impl RpcMethod<0> for ChainGetFinalizedTipset { | |
| type Params = (); | ||
| type Ok = Tipset; | ||
|
|
||
| async fn handle(_ctx: Ctx<impl Blockstore>, (): Self::Params) -> Result<Self::Ok, ServerError> { | ||
| Err(ServerError::stubbed_for_openrpc()) | ||
| async fn handle( | ||
| ctx: Ctx<impl Blockstore + Send + Sync + 'static>, | ||
| (): Self::Params, | ||
| ) -> Result<Self::Ok, ServerError> { | ||
| let head = ctx.chain_store().heaviest_tipset(); | ||
| let ec_finality_epoch = (head.epoch() - ctx.chain_config().policy.chain_finality).max(0); | ||
|
|
||
| // Either get the f3 finalized tipset or the ec finalized tipset | ||
| 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()) | ||
| } | ||
| Err(_) => { | ||
| // fallback to ec finality | ||
| tracing::warn!("F3 finalization unavailable, falling back to EC finality"); | ||
| let ec_tipset = ctx.chain_index().tipset_by_height( | ||
| ec_finality_epoch, | ||
| head, | ||
| ResolveNullTipset::TakeOlder, | ||
| )?; | ||
| Ok((*ec_tipset).clone()) | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // get f3 finalized tipset based on ec finality epoch | ||
| async fn get_f3_finality_tipset<DB: Blockstore + Sync + Send + 'static>( | ||
| ctx: &Ctx<DB>, | ||
| ec_finality_epoch: ChainEpoch, | ||
| ) -> Result<Arc<Tipset>> { | ||
| let f3_finalized_cert = crate::rpc::f3::F3GetLatestCertificate::handle(ctx.clone(), ()) | ||
| .await | ||
| .map_err(|e| anyhow::anyhow!("Failed to get F3 certificate: {}", e))?; | ||
|
|
||
| let f3_finalized_head = f3_finalized_cert.chain_head(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could track this in a separate issue, for now the logic matches Lotus |
||
| if f3_finalized_head.epoch < ec_finality_epoch { | ||
| return Err(anyhow::anyhow!( | ||
| "F3 finalized tipset epoch {} is further back than EC finalized tipset epoch {}", | ||
| f3_finalized_head.epoch, | ||
| ec_finality_epoch | ||
| )); | ||
| } | ||
|
|
||
| ctx.chain_index() | ||
| .load_required_tipset(&f3_finalized_head.key) | ||
| .map_err(|e| { | ||
| anyhow::anyhow!( | ||
| "Failed to load F3 finalized tipset at epoch {}: {}", | ||
| f3_finalized_head.epoch, | ||
| e | ||
| ) | ||
| }) | ||
| } | ||
|
|
||
| pub enum ChainGetMessage {} | ||
| impl RpcMethod<1> for ChainGetMessage { | ||
| const NAME: &'static str = "Filecoin.ChainGetMessage"; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we avoid cloning here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so
f3_tipsetwrapped inArcso we will have to clone only.