105 lines
3.2 KiB
Rust
Raw Normal View History

use std::{io, net::SocketAddr, sync::Arc};
use actix_cors::Cors;
2025-09-04 14:38:41 +03:00
use actix_web::{App, Error as HttpError, HttpResponse, HttpServer, http, middleware, web};
2025-11-26 00:27:20 +03:00
use common::{
rpc_primitives::{RpcConfig, message::Message},
transaction::NSSATransaction,
2025-11-26 00:27:20 +03:00
};
2026-03-04 18:42:33 +03:00
use futures::{Future, FutureExt as _};
use log::info;
2025-11-18 19:31:03 +03:00
use mempool::MemPoolHandle;
#[cfg(not(feature = "standalone"))]
use sequencer_core::SequencerCore;
#[cfg(feature = "standalone")]
use sequencer_core::SequencerCoreWithMockClients as SequencerCore;
2026-03-04 18:42:33 +03:00
use tokio::sync::Mutex;
#[cfg(not(feature = "standalone"))]
use super::JsonHandler;
use crate::process::Process;
pub const SHUTDOWN_TIMEOUT_SECS: u64 = 10;
2025-04-18 08:15:11 -04:00
pub const NETWORK: &str = "network";
2026-03-04 18:42:33 +03:00
#[cfg(feature = "standalone")]
type JsonHandler = super::JsonHandlerWithMockClients;
pub(crate) fn rpc_handler<P: Process>(
message: web::Json<Message>,
handler: web::Data<P>,
) -> impl Future<Output = Result<HttpResponse, HttpError>> {
let response = async move {
let message = handler.process(message.0).await?;
Ok(HttpResponse::Ok().json(&message))
};
response.boxed()
}
fn get_cors(cors_allowed_origins: &[String]) -> Cors {
let mut cors = Cors::permissive();
2026-03-04 18:42:33 +03:00
if cors_allowed_origins != ["*".to_owned()] {
for origin in cors_allowed_origins {
cors = cors.allowed_origin(origin);
}
}
cors.allowed_methods(vec!["GET", "POST"])
.allowed_headers(vec![http::header::AUTHORIZATION, http::header::ACCEPT])
.allowed_header(http::header::CONTENT_TYPE)
.max_age(3600)
}
2026-02-24 19:41:01 +03:00
pub async fn new_http_server(
config: RpcConfig,
seuquencer_core: Arc<Mutex<SequencerCore>>,
mempool_handle: MemPoolHandle<NSSATransaction>,
) -> io::Result<(actix_web::dev::Server, SocketAddr)> {
let RpcConfig {
addr,
cors_allowed_origins,
limits_config,
} = config;
info!(target:NETWORK, "Starting HTTP server at {addr}");
2026-02-24 19:41:01 +03:00
let max_block_size = seuquencer_core
.lock()
.await
.sequencer_config()
.max_block_size
2026-03-03 23:21:08 +03:00
.as_u64()
.try_into()
.expect("`max_block_size` is expected to fit into usize");
let handler = web::Data::new(JsonHandler {
2026-03-04 18:42:33 +03:00
sequencer_state: Arc::clone(&seuquencer_core),
2025-11-18 19:31:03 +03:00
mempool_handle,
2026-02-24 19:41:01 +03:00
max_block_size,
});
// HTTP server
let http_server = HttpServer::new(move || {
2026-03-03 23:21:08 +03:00
let json_limit = limits_config
.json_payload_max_size
.as_u64()
.try_into()
.expect("`json_payload_max_size` is expected to fit into usize");
App::new()
.wrap(get_cors(&cors_allowed_origins))
.app_data(handler.clone())
2026-03-03 23:21:08 +03:00
.app_data(web::JsonConfig::default().limit(json_limit))
.wrap(middleware::Logger::default())
.service(web::resource("/").route(web::post().to(rpc_handler::<JsonHandler>)))
})
.bind(addr)?
.shutdown_timeout(SHUTDOWN_TIMEOUT_SECS)
.disable_signals();
2026-03-04 18:42:33 +03:00
let [final_addr] = http_server
.addrs()
.try_into()
.expect("Exactly one address bound is expected for sequencer HTTP server");
2026-03-04 18:42:33 +03:00
info!(target:NETWORK, "HTTP server started at {final_addr}");
2026-03-04 18:42:33 +03:00
Ok((http_server.run(), final_addr))
}