filecoin_f3_lightclient/
lib.rs1mod rpc_to_internal;
5
6extern crate core;
7
8use anyhow::{Context, Result};
9use filecoin_f3_blssig::BLSVerifier;
10use filecoin_f3_certs as certs;
11use filecoin_f3_certs::validate_finality_certificates;
12use filecoin_f3_gpbft::{ECChain, NetworkName, PowerEntries};
13use filecoin_f3_rpc::RPCClient;
14
15pub struct LightClient {
16 rpc: RPCClient,
17 network: NetworkName,
18 verifier: BLSVerifier,
19}
20
21#[derive(Debug, Clone)]
22pub struct LightClientState {
23 pub instance: u64,
24 pub chain: Option<ECChain>,
25 pub power_table: PowerEntries,
26}
27
28impl LightClient {
29 pub fn new(endpoint: &str, network_name: &str) -> Result<Self> {
30 Ok(Self {
31 rpc: RPCClient::new(endpoint)?,
32 network: network_name.to_string().parse().context("network_name")?,
33 verifier: BLSVerifier::new(),
34 })
35 }
36
37 pub async fn initialize(&mut self, instance: u64) -> Result<LightClientState> {
38 let power_table = self.rpc.get_power_table(instance).await?;
39 let power_table = power_table
40 .into_iter()
41 .map(rpc_to_internal::convert_power_entry)
42 .collect::<Result<Vec<_>, _>>()?;
43
44 Ok(LightClientState {
45 instance,
46 chain: None,
47 power_table: PowerEntries(power_table),
48 })
49 }
50
51 pub async fn get_certificate(&self, instance: u64) -> Result<certs::FinalityCertificate> {
52 let rpc_cert = self.rpc.get_certificate(instance).await?;
53 rpc_to_internal::convert_certificate(rpc_cert)
54 }
55
56 pub fn validate_certificates(
57 &mut self,
58 state: &LightClientState,
59 certs: &[certs::FinalityCertificate],
60 ) -> certs::Result<LightClientState> {
61 let (new_instance, new_chain, new_power_table) = validate_finality_certificates(
62 &self.verifier,
63 self.network,
64 state.power_table.clone(),
65 state.instance,
66 state.chain.as_ref().and_then(|c| c.last()),
67 certs,
68 )?;
69
70 Ok(LightClientState {
71 instance: new_instance,
72 chain: Some(new_chain),
73 power_table: new_power_table,
74 })
75 }
76}