11use base_reth_flashblocks_rpc:: rpc:: EthApiExt ;
22use futures_util:: { FutureExt , TryStreamExt } ;
3+ use jsonrpsee:: core:: { async_trait, RpcResult } ;
4+ use jsonrpsee:: proc_macros:: rpc;
35use reth:: version:: {
46 default_reth_version_metadata, try_init_version_metadata, RethCliVersionConsts ,
57} ;
68use reth_exex:: ExExEvent ;
7- use std:: cell:: { OnceCell } ;
9+ use reth_optimism_trie:: OpProofsStore ;
10+ use serde:: { Deserialize , Serialize } ;
811use std:: path:: PathBuf ;
912use std:: sync:: { Arc , LazyLock , OnceLock } ;
1013
@@ -19,18 +22,74 @@ use reth::{
1922 api:: FullNodeComponents ,
2023 builder:: { EngineNodeLauncher , TreeConfig } ,
2124 providers:: providers:: BlockchainProvider ,
25+ rpc:: result:: internal_rpc_err,
2226} ;
2327use reth_optimism_cli:: { chainspec:: OpChainSpecParser , Cli } ;
2428use reth_optimism_exex:: OpProofsExEx ;
25- use reth_optimism_trie:: { OpProofsStorage , db:: MdbxProofsStorage , OpProofsStorageError } ;
26- use reth_optimism_rpc:: { debug:: { DebugApiExt , DebugApiOverrideServer } , eth:: proofs:: { EthApiExt as OpEthApiExt , EthApiOverrideServer as OpEthApiOverrideServer } } ;
2729use reth_optimism_node:: args:: RollupArgs ;
2830use reth_optimism_node:: OpNode ;
31+ use reth_optimism_rpc:: {
32+ debug:: { DebugApiExt , DebugApiOverrideServer } ,
33+ eth:: proofs:: { EthApiExt as OpEthApiExt , EthApiOverrideServer as OpEthApiOverrideServer } ,
34+ } ;
35+ use reth_optimism_trie:: { db:: MdbxProofsStorage , OpProofsStorage } ;
2936use tracing:: info;
3037use url:: Url ;
3138
3239pub const NODE_RETH_CLIENT_VERSION : & str = concat ! ( "base/v" , env!( "CARGO_PKG_VERSION" ) ) ;
3340
41+ #[ derive( Debug , Serialize , Deserialize , Clone , PartialEq , Eq ) ]
42+ pub struct ProofsSyncStatus {
43+ earliest : Option < u64 > ,
44+ latest : Option < u64 > ,
45+ }
46+
47+ #[ cfg_attr( not( test) , rpc( server, namespace = "base" ) ) ]
48+ #[ cfg_attr( test, rpc( server, client, namespace = "base" ) ) ]
49+ trait BaseApiRpc {
50+ #[ method( name = "proofsSyncStatus" ) ]
51+ async fn proofs_sync_status ( & self ) -> RpcResult < ProofsSyncStatus > ;
52+ }
53+
54+ #[ derive( Debug ) ]
55+ /// Overrides applied to the `eth_` namespace of the RPC API for historical proofs ExEx.
56+ pub struct BaseApiRpc < P > {
57+ external_storage : P ,
58+ }
59+
60+ impl < P > BaseApiRpc < P >
61+ where
62+ P : OpProofsStore + Clone + ' static ,
63+ {
64+ pub fn new ( external_storage : P ) -> Self {
65+ Self { external_storage }
66+ }
67+ }
68+
69+ #[ async_trait]
70+ impl < P > BaseApiRpcServer for BaseApiRpc < P >
71+ where
72+ P : OpProofsStore + Clone + ' static ,
73+ {
74+ async fn proofs_sync_status ( & self ) -> RpcResult < ProofsSyncStatus > {
75+ let earliest = self
76+ . external_storage
77+ . get_earliest_block_number ( )
78+ . await
79+ . map_err ( |err| internal_rpc_err ( err. to_string ( ) ) ) ?;
80+ let latest = self
81+ . external_storage
82+ . get_latest_block_number ( )
83+ . await
84+ . map_err ( |err| internal_rpc_err ( err. to_string ( ) ) ) ?;
85+
86+ Ok ( ProofsSyncStatus {
87+ earliest : earliest. map ( |( block_number, _) | block_number) ,
88+ latest : latest. map ( |( block_number, _) | block_number) ,
89+ } )
90+ }
91+ }
92+
3493#[ global_allocator]
3594static ALLOC : reth_cli_util:: allocator:: Allocator = reth_cli_util:: allocator:: new_allocator ( ) ;
3695
@@ -74,7 +133,7 @@ struct Args {
74133 #[ arg(
75134 long = "proofs-history.storage-path" ,
76135 value_name = "PROOFS_HISTORY_STORAGE_PATH" ,
77- required_if_eq( "proofs-history " , "true" )
136+ required_if_eq( "proofs_history " , "true" )
78137 ) ]
79138 pub proofs_history_storage_path : Option < PathBuf > ,
80139}
@@ -122,8 +181,8 @@ fn main() {
122181
123182 let fb_cell: Arc < OnceLock < Arc < FlashblocksState < _ > > > > = Arc :: new ( OnceLock :: new ( ) ) ;
124183
125- let proofs_storage_cell =
126- Arc :: new ( LazyLock :: new ( || -> Arc < OpProofsStorage < MdbxProofsStorage > > {
184+ let proofs_storage_cell = Arc :: new ( LazyLock :: new (
185+ || -> Arc < OpProofsStorage < MdbxProofsStorage > > {
127186 let path = args
128187 . proofs_history_storage_path
129188 . expect ( "path must be set when proofs history is enabled" ) ;
@@ -133,7 +192,8 @@ fn main() {
133192 . into ( ) ;
134193
135194 result
136- } ) ) ;
195+ } ,
196+ ) ) ;
137197
138198 let proofs_storage_cell_exex = proofs_storage_cell. clone ( ) ;
139199 let proofs_storage_cell_rpc = proofs_storage_cell. clone ( ) ;
@@ -231,15 +291,19 @@ fn main() {
231291 . extend_rpc_modules ( move |ctx| {
232292 if proofs_history_enabled {
233293 let proofs_storage = ( * ( proofs_storage_cell_rpc) ) . clone ( ) ;
234- let api_ext =
235- OpEthApiExt :: new ( ctx. registry . eth_api ( ) . clone ( ) , proofs_storage. clone ( ) ) ;
294+ let api_ext = OpEthApiExt :: new (
295+ ctx. registry . eth_api ( ) . clone ( ) ,
296+ proofs_storage. clone ( ) ,
297+ ) ;
236298 let debug_ext = DebugApiExt :: new (
237299 ctx. node ( ) . provider ( ) . clone ( ) ,
238300 ctx. registry . eth_api ( ) . clone ( ) ,
239301 proofs_storage. clone ( ) ,
240302 Box :: new ( ctx. node ( ) . task_executor ( ) . clone ( ) ) ,
241303 ctx. node ( ) . evm_config ( ) . clone ( ) ,
242304 ) ;
305+ let base_api_rpc = BaseApiRpc :: new ( proofs_storage. clone ( ) ) ;
306+ ctx. modules . replace_configured ( base_api_rpc. into_rpc ( ) ) ?;
243307 ctx. modules . replace_configured ( api_ext. into_rpc ( ) ) ?;
244308 ctx. modules . replace_configured ( debug_ext. into_rpc ( ) ) ?;
245309 }
0 commit comments