11use std:: path:: PathBuf ;
22
3- use anyhow:: { anyhow , Result } ;
3+ use anyhow:: { Context , Result } ;
44pub use clap:: Parser ;
5+ use katana_node:: config:: db:: DbConfig ;
6+ use katana_node:: config:: metrics:: MetricsConfig ;
7+ use katana_node:: config:: rpc:: RpcConfig ;
8+ use katana_node:: full;
9+ use katana_node:: full:: Network ;
510use serde:: { Deserialize , Serialize } ;
11+ use tracing:: info;
612
713use crate :: options:: * ;
814
15+ pub ( crate ) const LOG_TARGET : & str = "katana::cli::full" ;
16+
917#[ derive( Parser , Debug , Serialize , Deserialize , Default , Clone , PartialEq ) ]
1018#[ command( next_help_heading = "Full node options" ) ]
1119pub struct FullNodeArgs {
@@ -19,7 +27,19 @@ pub struct FullNodeArgs {
1927 /// previously initialized Katana database.
2028 #[ arg( long) ]
2129 #[ arg( value_name = "PATH" ) ]
22- pub db_dir : Option < PathBuf > ,
30+ pub db_dir : PathBuf ,
31+
32+ #[ arg( long = "eth.rpc" ) ]
33+ #[ arg( value_name = "PATH" ) ]
34+ pub eth_rpc_url : String ,
35+
36+ #[ arg( long) ]
37+ pub network : Network ,
38+
39+ /// Gateway API key for accessing the sequencer gateway.
40+ #[ arg( long) ]
41+ #[ arg( value_name = "KEY" ) ]
42+ pub gateway_api_key : Option < String > ,
2343
2444 #[ command( flatten) ]
2545 pub logging : LoggingOptions ,
@@ -42,6 +62,102 @@ pub struct FullNodeArgs {
4262
4363impl FullNodeArgs {
4464 pub async fn execute ( & self ) -> Result < ( ) > {
45- Err ( anyhow ! ( "Full node is not implemented yet!" ) )
65+ // Initialize logging with tracer
66+ let tracer_config = self . tracer_config ( ) ;
67+ katana_tracing:: init ( self . logging . log_format , tracer_config) . await ?;
68+ self . start_node ( ) . await
69+ }
70+
71+ async fn start_node ( & self ) -> Result < ( ) > {
72+ // Build the node
73+ let config = self . config ( ) ?;
74+ let node = full:: Node :: build ( config) . context ( "failed to build full node" ) ?;
75+
76+ if !self . silent {
77+ info ! ( target: LOG_TARGET , "Starting full node" ) ;
78+ }
79+
80+ // Launch the node
81+ let handle = node. launch ( ) . await . context ( "failed to launch full node" ) ?;
82+
83+ // Wait until an OS signal (ie SIGINT, SIGTERM) is received or the node is shutdown.
84+ tokio:: select! {
85+ _ = katana_utils:: wait_shutdown_signals( ) => {
86+ // Gracefully shutdown the node before exiting
87+ handle. stop( ) . await ?;
88+ } ,
89+
90+ _ = handle. stopped( ) => { }
91+ }
92+
93+ info ! ( "Shutting down." ) ;
94+
95+ Ok ( ( ) )
96+ }
97+
98+ fn config ( & self ) -> Result < full:: Config > {
99+ let db = self . db_config ( ) ;
100+ let rpc = self . rpc_config ( ) ?;
101+ let metrics = self . metrics_config ( ) ;
102+
103+ Ok ( full:: Config {
104+ db,
105+ rpc,
106+ metrics,
107+ network : self . network ,
108+ eth_rpc_url : self . eth_rpc_url . clone ( ) ,
109+ gateway_api_key : self . gateway_api_key . clone ( ) ,
110+ } )
111+ }
112+
113+ fn db_config ( & self ) -> DbConfig {
114+ DbConfig { dir : Some ( self . db_dir . clone ( ) ) }
115+ }
116+
117+ fn rpc_config ( & self ) -> Result < RpcConfig > {
118+ #[ cfg( feature = "server" ) ]
119+ {
120+ use std:: time:: Duration ;
121+
122+ let cors_origins = self . server . http_cors_origins . clone ( ) ;
123+
124+ Ok ( RpcConfig {
125+ apis : Default :: default ( ) ,
126+ port : self . server . http_port ,
127+ addr : self . server . http_addr ,
128+ max_connections : self . server . max_connections ,
129+ max_concurrent_estimate_fee_requests : None ,
130+ max_request_body_size : None ,
131+ max_response_body_size : None ,
132+ timeout : self . server . timeout . map ( Duration :: from_secs) ,
133+ cors_origins,
134+ #[ cfg( feature = "explorer" ) ]
135+ explorer : self . explorer . explorer ,
136+ max_event_page_size : Some ( self . server . max_event_page_size ) ,
137+ max_proof_keys : Some ( self . server . max_proof_keys ) ,
138+ max_call_gas : Some ( self . server . max_call_gas ) ,
139+ } )
140+ }
141+
142+ #[ cfg( not( feature = "server" ) ) ]
143+ {
144+ Ok ( RpcConfig :: default ( ) )
145+ }
146+ }
147+
148+ fn metrics_config ( & self ) -> Option < MetricsConfig > {
149+ #[ cfg( feature = "server" ) ]
150+ if self . metrics . metrics {
151+ Some ( MetricsConfig { addr : self . metrics . metrics_addr , port : self . metrics . metrics_port } )
152+ } else {
153+ None
154+ }
155+
156+ #[ cfg( not( feature = "server" ) ) ]
157+ None
158+ }
159+
160+ fn tracer_config ( & self ) -> Option < katana_tracing:: TracerConfig > {
161+ self . tracer . config ( )
46162 }
47163}
0 commit comments