From 750a38b600e322288f682ccb053ba51af0091f4a Mon Sep 17 00:00:00 2001 From: Moncef AOUDIA Date: Thu, 17 Nov 2022 18:24:53 +0100 Subject: [PATCH] refactor: add server settings --- Cargo.lock | 11 ------ massa-api/src/config.rs | 16 +++++++++ massa-api/src/lib.rs | 32 +++++++++++++++--- massa-api/src/private.rs | 8 +++-- massa-api/src/public.rs | 10 ++++-- massa-node/base_config/config.toml | 54 +++++++++++++++++++----------- massa-node/src/main.rs | 14 ++++++-- massa-node/src/settings.rs | 10 +++++- massa-sdk/src/lib.rs | 4 +-- 9 files changed, 113 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a8706b6013..35f9bd2ec88 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1839,7 +1839,6 @@ dependencies = [ "async-speed-limit", "bitvec", "displaydoc", - "fix-hidden-lifetime-bug", "futures", "lazy_static", "massa_async_pool", @@ -2621,16 +2620,6 @@ dependencies = [ "hashbrown 0.12.3", ] -[[package]] -name = "ordered-multimap" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" -dependencies = [ - "dlv-list", - "hashbrown 0.12.3", -] - [[package]] name = "output_vt100" version = "0.1.3" diff --git a/massa-api/src/config.rs b/massa-api/src/config.rs index 166297fd210..a04d500035d 100644 --- a/massa-api/src/config.rs +++ b/massa-api/src/config.rs @@ -20,6 +20,22 @@ pub struct APIConfig { pub max_arguments: u64, /// openrpc specification path pub openrpc_spec_path: PathBuf, + /// maximum size in bytes of a request. + pub max_request_body_size: u32, + /// maximum size in bytes of a response. + pub max_response_body_size: u32, + /// maximum number of incoming connections allowed. + pub max_connections: u32, + /// maximum number of subscriptions per connection. + pub max_subscriptions_per_connection: u32, + /// max length for logging for requests and responses. Logs bigger than this limit will be truncated. + pub max_log_length: u32, + /// host filtering. + pub allow_hosts: Vec, + /// whether batch requests are supported by this server or not. + pub batch_requests_supported: bool, + /// the interval at which `Ping` frames are submitted. + pub ping_interval: MassaTime, /// max datastore value length pub max_datastore_value_length: u64, /// max op datastore entry diff --git a/massa-api/src/lib.rs b/massa-api/src/lib.rs index 75039f5ad7c..fd03036368c 100644 --- a/massa-api/src/lib.rs +++ b/massa-api/src/lib.rs @@ -6,7 +6,7 @@ use crate::error::ApiError::WrongAPI; use jsonrpsee::core::{Error as JsonRpseeError, RpcResult}; use jsonrpsee::proc_macros::rpc; -use jsonrpsee::server::{ServerBuilder, ServerHandle}; +use jsonrpsee::server::{AllowHosts, ServerBuilder, ServerHandle}; use massa_consensus_exports::ConsensusController; use massa_execution_exports::ExecutionController; use massa_models::api::{ @@ -97,12 +97,36 @@ pub struct API(T); #[async_trait::async_trait] pub trait RpcServer: MassaRpcServer { /// Start the API - async fn serve(self, url: &SocketAddr) -> Result; + async fn serve( + self, + url: &SocketAddr, + api_config: &APIConfig, + ) -> Result; } -async fn serve(api: impl MassaRpcServer, url: &SocketAddr) -> Result { +async fn serve( + api: impl MassaRpcServer, + url: &SocketAddr, + api_config: &APIConfig, +) -> Result { + let allowed_hosts = if api_config.allow_hosts.is_empty() { + AllowHosts::Any + } else { + let hosts = api_config + .allow_hosts + .iter() + .map(|hostname| hostname.into()) + .collect(); + AllowHosts::Only(hosts) + }; + let server = ServerBuilder::new() - .max_request_body_size(50 * 1024 * 1024) + .max_request_body_size(api_config.max_request_body_size) + .max_response_body_size(api_config.max_response_body_size) + .max_connections(api_config.max_connections) + .set_host_filtering(allowed_hosts) + .batch_requests_supported(api_config.batch_requests_supported) + .ping_interval(api_config.ping_interval.to_duration()) .build(url) .await .expect("server builder failed"); diff --git a/massa-api/src/private.rs b/massa-api/src/private.rs index 7ec0d646d3d..161b2610053 100644 --- a/massa-api/src/private.rs +++ b/massa-api/src/private.rs @@ -59,8 +59,12 @@ impl API { #[async_trait] impl RpcServer for API { - async fn serve(self, url: &SocketAddr) -> Result { - crate::serve(self, url).await + async fn serve( + self, + url: &SocketAddr, + settings: &APIConfig, + ) -> Result { + crate::serve(self, url, settings).await } } diff --git a/massa-api/src/public.rs b/massa-api/src/public.rs index 31980b1238a..7fe9f7f32e2 100644 --- a/massa-api/src/public.rs +++ b/massa-api/src/public.rs @@ -90,8 +90,12 @@ impl API { #[async_trait] impl RpcServer for API { - async fn serve(self, url: &SocketAddr) -> Result { - crate::serve(self, url).await + async fn serve( + self, + url: &SocketAddr, + api_config: &APIConfig, + ) -> Result { + crate::serve(self, url, api_config).await } } @@ -377,7 +381,7 @@ impl MassaRpcServer for API { next_slot, execution_stats, consensus_stats, - network_stats, + network_stats, pool_stats, config, current_cycle: last_slot diff --git a/massa-node/base_config/config.toml b/massa-node/base_config/config.toml index 67a69978aa9..e8062a680fa 100644 --- a/massa-node/base_config/config.toml +++ b/massa-node/base_config/config.toml @@ -13,8 +13,24 @@ bind_public = "0.0.0.0:33035" # max number of arguments per RPC call max_arguments = 128 - # Path to the openrpc specification file used in `rpc.discover` method. + # path to the openrpc specification file used in `rpc.discover` method. openrpc_spec_path = "base_config/openrpc.json" + # maximum size in bytes of a request. + max_request_body_size = 52428800 + # maximum size in bytes of a response. + max_response_body_size = 52428800 + # maximum number of incoming connections allowed. + max_connections = 100 + # maximum number of subscriptions per connection. + max_subscriptions_per_connection = 1024 + # max length for logging for requests and responses. Logs bigger than this limit will be truncated. + max_log_length = 4096 + # host filtering. + allow_hosts = [] + # whether batch requests are supported by this server or not. + batch_requests_supported = true + # the interval at which `Ping` frames are submitted in milliseconds. + ping_interval = 60000 [execution] # max number of generated events kept in RAM @@ -80,22 +96,22 @@ max_known_endorsements_size = 2048 # max cache size for which endorsements a foreign node knows about max_node_known_endorsements_size = 2048 - # Maximum number of batches in the memory buffer. - # Dismiss the new batches if overflow + # maximum number of batches in the memory buffer. + # dismiss the new batches if overflow operation_batch_buffer_capacity = 10024 - # Immediately announce ops if overflow + # immediately announce ops if overflow operation_announcement_buffer_capacity = 2000 - # Start processing batches in the buffer each `operation_batch_proc_period` in millisecond + # start processing batches in the buffer each `operation_batch_proc_period` in millisecond operation_batch_proc_period = 500 - # All operations asked are prune each `operation_asked_pruning_period` millisecond + # all operations asked are prune each `operation_asked_pruning_period` millisecond asked_operations_pruning_period = 100000 - # Interval at which operations are announced in batches. + # interval at which operations are announced in batches. operation_announcement_interval = 300 - # Max number of operation per message, same as network param but can be smaller + # max number of operation per message, same as network param but can be smaller max_operations_per_message = 1024 - # Time threshold after which operation are not propagated + # time threshold after which operation are not propagated max_operations_propagation_time = 32000 - # Time threshold after which operation are not propagated + # time threshold after which operation are not propagated max_endorsements_propagation_time = 48000 [network] @@ -141,15 +157,15 @@ max_send_wait_network_event = 0 # we forget we banned a node after ban_timeout milliseconds ban_timeout = 3600000 - # Timeout duration when in handshake we respond with a PeerList + # timeout duration when in handshake we respond with a PeerList # (on max in connection reached we send a list of peers) peer_list_send_timeout = 100 - # Max number of in connection overflowed managed by the handshake + # max number of in connection overflowed managed by the handshake # that send a list of peers max_in_connection_overflow = 100 - # Read limitation for a connection in bytes per seconds + # read limitation for a connection in bytes per seconds max_bytes_read = 20_000_000.0 - # Write limitation for a connection in bytes per seconds + # write limitation for a connection in bytes per seconds max_bytes_write = 20_000_000.0 [network.peer_types_config] @@ -169,9 +185,9 @@ ["54.36.174.177:31245", "P1gEdBVEbRFbBxBtrjcTDDK9JPbJFDay27uiJRE3vmbFAFDKNh7"], ["51.75.60.228:31245", "P13Ykon8Zo73PTKMruLViMMtE2rEG646JQ4sCcee2DnopmVM3P5"] ] - # Path to the bootstrap whitelist file. This whitelist define IPs that can bootstrap on your node. + # path to the bootstrap whitelist file. This whitelist define IPs that can bootstrap on your node. bootstrap_whitelist_file = "base_config/bootstrap_whitelist.json" - # Path to the bootstrap blacklist file. This whitelist define IPs that will not be able to bootstrap on your node. This list is optional. + # path to the bootstrap blacklist file. This whitelist define IPs that will not be able to bootstrap on your node. This list is optional. bootstrap_blacklist_file = "base_config/bootstrap_blacklist.json" # [optionnal] port on which to listen for incoming bootstrap requests bind = "[::]:31245" @@ -199,7 +215,7 @@ ip_list_max_size = 10000 # refuse consecutive bootstrap attempts from a given IP when the interval between them is lower than per_ip_min_interval milliseconds per_ip_min_interval = 180000 - # Read-Write limitation for a connection in bytes per seconds (about the bootstrap specifically) + # read-write limitation for a connection in bytes per seconds (about the bootstrap specifically) max_bytes_read_write = 20_000_000.0 [pool] @@ -213,9 +229,9 @@ max_item_return_count = 100 [selector] - # Maximum number of computed cycle's draws we keep in cache + # maximum number of computed cycle's draws we keep in cache max_draw_cache = 10 - # Path to the initial roll distribution + # path to the initial roll distribution initial_rolls_path = "base_config/initial_rolls.json" [factory] diff --git a/massa-node/src/main.rs b/massa-node/src/main.rs index 4fc46d1a608..13f40e59b1b 100644 --- a/massa-node/src/main.rs +++ b/massa-node/src/main.rs @@ -479,6 +479,14 @@ async fn launch( draw_lookahead_period_count: SETTINGS.api.draw_lookahead_period_count, max_arguments: SETTINGS.api.max_arguments, openrpc_spec_path: SETTINGS.api.openrpc_spec_path.clone(), + max_request_body_size: SETTINGS.api.max_request_body_size, + max_response_body_size: SETTINGS.api.max_response_body_size, + max_connections: SETTINGS.api.max_connections, + max_subscriptions_per_connection: SETTINGS.api.max_subscriptions_per_connection, + max_log_length: SETTINGS.api.max_log_length, + allow_hosts: SETTINGS.api.allow_hosts.clone(), + batch_requests_supported: SETTINGS.api.batch_requests_supported, + ping_interval: SETTINGS.api.ping_interval, max_datastore_value_length: MAX_DATASTORE_VALUE_LENGTH, max_op_datastore_entry_count: MAX_OPERATION_DATASTORE_ENTRY_COUNT, max_op_datastore_key_length: MAX_OPERATION_DATASTORE_KEY_LENGTH, @@ -498,7 +506,7 @@ async fn launch( node_wallet, ); let api_private_handle = api_private - .serve(&SETTINGS.api.bind_private) + .serve(&SETTINGS.api.bind_private, &api_config) .await .expect("failed to start PRIVATE API"); @@ -506,7 +514,7 @@ async fn launch( let api_public = API::::new( consensus_controller.clone(), execution_controller.clone(), - api_config, + api_config.clone(), selector_controller.clone(), pool_controller.clone(), ProtocolCommandSender(protocol_command_sender.clone()), @@ -518,7 +526,7 @@ async fn launch( shared_storage.clone(), ); let api_public_handle = api_public - .serve(&SETTINGS.api.bind_public) + .serve(&SETTINGS.api.bind_public, &api_config) .await .expect("failed to start PUBLIC API"); diff --git a/massa-node/src/settings.rs b/massa-node/src/settings.rs index 9b0cb228b18..db9edf135ff 100644 --- a/massa-node/src/settings.rs +++ b/massa-node/src/settings.rs @@ -109,7 +109,7 @@ pub struct PoolSettings { pub max_item_return_count: usize, } -/// API configuration, read from a file configuration +/// API and server configuration, read from a file configuration. #[derive(Debug, Deserialize, Clone)] pub struct APISettings { pub draw_lookahead_period_count: u64, @@ -117,6 +117,14 @@ pub struct APISettings { pub bind_public: SocketAddr, pub max_arguments: u64, pub openrpc_spec_path: PathBuf, + pub max_request_body_size: u32, + pub max_response_body_size: u32, + pub max_connections: u32, + pub max_subscriptions_per_connection: u32, + pub max_log_length: u32, + pub allow_hosts: Vec, + pub batch_requests_supported: bool, + pub ping_interval: MassaTime, } #[derive(Debug, Deserialize, Clone)] diff --git a/massa-sdk/src/lib.rs b/massa-sdk/src/lib.rs index d64521a0aea..621bb08cb8f 100644 --- a/massa-sdk/src/lib.rs +++ b/massa-sdk/src/lib.rs @@ -56,9 +56,7 @@ impl RpcClient { /// Default constructor pub async fn from_url(url: &str) -> RpcClient { match HttpClientBuilder::default().build(url) { - Ok(http_client) => RpcClient { - http_client, - }, + Ok(http_client) => RpcClient { http_client }, Err(_) => panic!("unable to connect to Node."), } }