diff --git a/Cargo.lock b/Cargo.lock index 371bb261aa..3432296c86 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -292,14 +292,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", - "axum-core", + "axum-core 0.3.4", "bitflags 1.3.2", "bytes", "futures-util", - "headers", "http 0.2.11", - "http-body", - "hyper", + "http-body 0.4.5", + "hyper 0.14.27", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "202651474fe73c62d9e0a56c6133f7a0ff1dc1c8cf7a5b03381af2a26553ac9d" +dependencies = [ + "async-trait", + "axum-core 0.4.1", + "bytes", + "futures-util", + "http 1.0.0", + "http-body 1.0.0", + "http-body-util", + "hyper 1.1.0", + "hyper-util", "itoa", "matchit", "memchr", @@ -328,25 +360,45 @@ dependencies = [ "bytes", "futures-util", "http 0.2.11", - "http-body", + "http-body 0.4.5", "mime", "rustversion", "tower-layer", "tower-service", ] +[[package]] +name = "axum-core" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77cb22c689c44d4c07b0ab44ebc25d69d8ae601a2f28fb8d672d344178fa17aa" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http 1.0.0", + "http-body 1.0.0", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper", + "tower-layer", + "tower-service", +] + [[package]] name = "axum-extra" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ab90e7b70bea63a153137162affb6a0bce26b584c24a4c7885509783e2cf30b" dependencies = [ - "axum", - "axum-core", + "axum 0.6.20", + "axum-core 0.3.4", "bytes", "futures-util", "http 0.2.11", - "http-body", + "http-body 0.4.5", "mime", "pin-project-lite", "serde", @@ -357,6 +409,29 @@ dependencies = [ "tower-service", ] +[[package]] +name = "axum-extra" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523ae92256049a3b02d3bb4df80152386cd97ddba0c8c5077619bdc8c4b1859b" +dependencies = [ + "axum 0.7.2", + "axum-core 0.4.1", + "bytes", + "futures-util", + "headers", + "http 1.0.0", + "http-body 1.0.0", + "http-body-util", + "mime", + "pin-project-lite", + "serde", + "serde_json", + "tower", + "tower-layer", + "tower-service", +] + [[package]] name = "backoff" version = "0.4.0" @@ -886,6 +961,19 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.2", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "deadline" version = "0.2.0" @@ -1082,6 +1170,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "forwarded-header-value" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835f84f38484cc86f110a805655697908257fb9a7af005234060891557198e9" +dependencies = [ + "nonempty", + "thiserror", +] + [[package]] name = "fragile" version = "2.0.0" @@ -1166,6 +1264,12 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" + [[package]] name = "futures-util" version = "0.3.30" @@ -1247,6 +1351,24 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "governor" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "821239e5672ff23e2a7060901fa622950bbd80b649cdaadd78d1c1767ed14eb4" +dependencies = [ + "cfg-if", + "dashmap", + "futures", + "futures-timer", + "no-std-compat", + "nonzero_ext", + "parking_lot", + "quanta", + "rand", + "smallvec", +] + [[package]] name = "h2" version = "0.3.21" @@ -1266,6 +1388,25 @@ dependencies = [ "tracing", ] +[[package]] +name = "h2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d308f63daf4181410c242d34c11f928dcb3aa105852019e043c9d1f4e4368a" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 1.0.0", + "indexmap 2.1.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1293,14 +1434,14 @@ dependencies = [ [[package]] name = "headers" -version = "0.3.9" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9" dependencies = [ "base64", "bytes", "headers-core", - "http 0.2.11", + "http 1.0.0", "httpdate", "mime", "sha1", @@ -1308,11 +1449,11 @@ dependencies = [ [[package]] name = "headers-core" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" dependencies = [ - "http 0.2.11", + "http 1.0.0", ] [[package]] @@ -1366,6 +1507,29 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.0.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" +dependencies = [ + "bytes", + "futures-util", + "http 1.0.0", + "http-body 1.0.0", + "pin-project-lite", +] + [[package]] name = "http-range-header" version = "0.3.1" @@ -1394,9 +1558,9 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", + "h2 0.3.21", "http 0.2.11", - "http-body", + "http-body 0.4.5", "httparse", "httpdate", "itoa", @@ -1408,6 +1572,25 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5aa53871fc917b1a9ed87b683a5d86db645e23acb32c2e0785a353e522fb75" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.0", + "http 1.0.0", + "http-body 1.0.0", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "tokio", +] + [[package]] name = "hyper-tls" version = "0.5.0" @@ -1415,12 +1598,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper", + "hyper 0.14.27", "native-tls", "tokio", "tokio-native-tls", ] +[[package]] +name = "hyper-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdea9aac0dbe5a9240d68cfd9501e2db94222c6dc06843e06640b9e07f0fdc67" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.0.0", + "http-body 1.0.0", + "hyper 1.1.0", + "pin-project-lite", + "socket2 0.5.5", + "tokio", + "tracing", +] + [[package]] name = "iana-time-zone" version = "0.1.58" @@ -1783,7 +1984,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d4fa7ce7c4862db464a37b0b31d89bca874562f034bd7993895572783d02950" dependencies = [ "base64", - "hyper", + "hyper 0.14.27", "indexmap 1.9.3", "ipnet", "metrics", @@ -1927,6 +2128,12 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + [[package]] name = "nom" version = "7.1.3" @@ -1937,6 +2144,18 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nonempty" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" + +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -2529,10 +2748,10 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", + "h2 0.3.21", "http 0.2.11", - "http-body", - "hyper", + "http-body 0.4.5", + "hyper 0.14.27", "hyper-tls", "ipnet", "js-sys", @@ -2746,7 +2965,7 @@ version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b3c585a1ced6b97ac13bd5e56f66559e5a75f477da5913f70df98e114518446" dependencies = [ - "hyper", + "hyper 0.14.27", "indicatif", "log", "quick-xml", @@ -2765,7 +2984,7 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a34ad8e4a86884ab42e9b8690e9343abdcfe5fa38a0318cfe1565ba9ad437b4" dependencies = [ - "hyper", + "hyper 0.14.27", "indicatif", "log", "quick-xml", @@ -3082,8 +3301,8 @@ dependencies = [ "anyhow", "async-recursion", "async-trait", - "axum", - "axum-extra", + "axum 0.6.20", + "axum-extra 0.8.0", "bytes", "clap", "colored", @@ -3116,7 +3335,7 @@ dependencies = [ "tokio", "tokio-stream", "tokio-util", - "tower-http", + "tower-http 0.4.4", "tracing", "tracing-subscriber 0.3.18", "tracing-test 0.1.0", @@ -3223,8 +3442,8 @@ name = "snarkos-node-rest" version = "2.2.7" dependencies = [ "anyhow", - "axum", - "axum-extra", + "axum 0.7.2", + "axum-extra 0.9.0", "http 1.0.0", "indexmap 2.1.0", "jsonwebtoken", @@ -3239,7 +3458,9 @@ dependencies = [ "snarkvm", "time", "tokio", - "tower-http", + "tower", + "tower-http 0.5.0", + "tower_governor", "tracing", ] @@ -4662,7 +4883,7 @@ dependencies = [ "futures-core", "futures-util", "http 0.2.11", - "http-body", + "http-body 0.4.5", "http-range-header", "httpdate", "mime", @@ -4676,6 +4897,24 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower-http" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09e12e6351354851911bdf8c2b8f2ab15050c567d70a8b9a37ae7b8301a4080d" +dependencies = [ + "bitflags 2.4.1", + "bytes", + "futures-util", + "http 1.0.0", + "http-body 1.0.0", + "http-body-util", + "pin-project-lite", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "tower-layer" version = "0.3.2" @@ -4688,6 +4927,26 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +[[package]] +name = "tower_governor" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4551a0307fd2f95f113688b8c05ec77834af7390293663261621fccd85e97724" +dependencies = [ + "axum 0.7.2", + "forwarded-header-value", + "futures", + "futures-core", + "governor", + "http 1.0.0", + "pin-project", + "thiserror", + "tokio", + "tower", + "tower-layer", + "tracing", +] + [[package]] name = "tracing" version = "0.1.40" diff --git a/cli/src/commands/start.rs b/cli/src/commands/start.rs index b502384089..80c89ea4c4 100644 --- a/cli/src/commands/start.rs +++ b/cli/src/commands/start.rs @@ -90,6 +90,9 @@ pub struct Start { /// Specify the IP address and port for the REST server #[clap(default_value = "0.0.0.0:3033", long = "rest")] pub rest: SocketAddr, + /// Specify the requests per second (RPS) rate limit per IP for the REST server + #[clap(default_value = "10", long = "rest-rps")] + pub rest_rps: u32, /// If the flag is set, the node will not initialize the REST server #[clap(long)] pub norest: bool, @@ -439,9 +442,9 @@ impl Start { // Initialize the node. let bft_ip = if self.dev.is_some() { self.bft } else { None }; match node_type { - NodeType::Validator => Node::new_validator(self.node, rest_ip, bft_ip, account, &trusted_peers, &trusted_validators, genesis, cdn, self.dev).await, + NodeType::Validator => Node::new_validator(self.node, bft_ip, rest_ip, self.rest_rps, account, &trusted_peers, &trusted_validators, genesis, cdn, self.dev).await, NodeType::Prover => Node::new_prover(self.node, account, &trusted_peers, genesis, self.dev).await, - NodeType::Client => Node::new_client(self.node, rest_ip, account, &trusted_peers, genesis, cdn, self.dev).await, + NodeType::Client => Node::new_client(self.node, rest_ip, self.rest_rps, account, &trusted_peers, genesis, cdn, self.dev).await, } } diff --git a/node/rest/Cargo.toml b/node/rest/Cargo.toml index cb2c092b4b..db62ef4e2b 100644 --- a/node/rest/Cargo.toml +++ b/node/rest/Cargo.toml @@ -24,12 +24,11 @@ parallel = [ "rayon" ] version = "1.0.76" [dependencies.axum] -version = "0.6" -features = [ "headers" ] +version = "0.7" [dependencies.axum-extra] -version = "0.8.0" -features = [ "erased-json" ] +version = "0.9.0" +features = [ "erased-json", "typed-header" ] [dependencies.http] version = "1.0" @@ -80,8 +79,14 @@ version = "0.3" [dependencies.tokio] version = "1" -[dependencies.tower-http] +[dependencies.tower] version = "0.4" + +[dependencies.tower_governor] +version = "0.2" + +[dependencies.tower-http] +version = "0.5" features = [ "cors", "trace" ] [dependencies.tracing] diff --git a/node/rest/src/helpers/auth.rs b/node/rest/src/helpers/auth.rs index 8de1d526c7..90f46408bc 100644 --- a/node/rest/src/helpers/auth.rs +++ b/node/rest/src/helpers/auth.rs @@ -17,11 +17,14 @@ use snarkvm::prelude::*; use ::time::OffsetDateTime; use anyhow::{anyhow, Result}; use axum::{ - headers::authorization::{Authorization, Bearer}, + body::Body, http::{Request, StatusCode}, middleware::Next, response::{IntoResponse, Response}, RequestPartsExt, +}; +use axum_extra::{ + headers::authorization::{Authorization, Bearer}, TypedHeader, }; use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation}; @@ -70,10 +73,7 @@ impl Claims { } } -pub async fn auth_middleware(request: Request, next: Next) -> Result -where - B: Send, -{ +pub async fn auth_middleware(request: Request, next: Next) -> Result { // Deconstruct the request to extract the auth token. let (mut parts, body) = request.into_parts(); let auth: TypedHeader> = diff --git a/node/rest/src/lib.rs b/node/rest/src/lib.rs index 8e15baa763..d8117d8261 100644 --- a/node/rest/src/lib.rs +++ b/node/rest/src/lib.rs @@ -35,18 +35,23 @@ use snarkvm::{ use anyhow::Result; use axum::{ + body::Body, + error_handling::HandleErrorLayer, extract::{ConnectInfo, DefaultBodyLimit, Path, Query, State}, http::{header::CONTENT_TYPE, Method, Request, StatusCode}, middleware, middleware::Next, response::Response, routing::{get, post}, + BoxError, Json, }; use axum_extra::response::ErasedJson; use parking_lot::Mutex; use std::{net::SocketAddr, sync::Arc}; -use tokio::task::JoinHandle; +use tokio::{net::TcpListener, task::JoinHandle}; +use tower::ServiceBuilder; +use tower_governor::{errors::display_error, governor::GovernorConfigBuilder, GovernorLayer}; use tower_http::{ cors::{Any, CorsLayer}, trace::TraceLayer, @@ -67,8 +72,9 @@ pub struct Rest, R: Routing> { impl, R: Routing> Rest { /// Initializes a new instance of the server. - pub fn start( + pub async fn start( rest_ip: SocketAddr, + rest_rps: u32, consensus: Option>, ledger: Ledger, routing: Arc, @@ -76,7 +82,7 @@ impl, R: Routing> Rest // Initialize the server. let mut server = Self { consensus, ledger, routing, handles: Default::default() }; // Spawn the server. - server.spawn_server(rest_ip); + server.spawn_server(rest_ip, rest_rps).await; // Return the server. Ok(server) } @@ -95,12 +101,24 @@ impl, R: Routing> Rest { } impl, R: Routing> Rest { - fn spawn_server(&mut self, rest_ip: SocketAddr) { + async fn spawn_server(&mut self, rest_ip: SocketAddr, rest_rps: u32) { let cors = CorsLayer::new() .allow_origin(Any) .allow_methods([Method::GET, Method::POST, Method::OPTIONS]) .allow_headers([CONTENT_TYPE]); + // Log the REST rate limit per IP. + debug!("REST rate limit per IP - {rest_rps} RPS"); + + // Prepare the rate limiting setup. + let governor_config = Box::new( + GovernorConfigBuilder::default() + .per_second(1) + .burst_size(rest_rps) + .finish() + .expect("Couldn't set up rate limiting for the REST server!"), + ); + let router = { axum::Router::new() @@ -174,25 +192,34 @@ impl, R: Routing> Rest { .layer(cors) // Cap body size at 10MB. .layer(DefaultBodyLimit::max(10 * 1024 * 1024)) + .layer( + ServiceBuilder::new() + // this middleware goes above `GovernorLayer` because it will receive + // errors returned by `GovernorLayer` + .layer(HandleErrorLayer::new(|e: BoxError| async move { + display_error(e) + })) + .layer(GovernorLayer { + // We can leak this because it is created only once and it persists. + config: Box::leak(governor_config), + }), + ) }; + let rest_listener = TcpListener::bind(rest_ip).await.unwrap(); self.handles.lock().push(tokio::spawn(async move { - axum::Server::bind(&rest_ip) - .serve(router.into_make_service_with_connect_info::()) + axum::serve(rest_listener, router.into_make_service_with_connect_info::()) .await .expect("couldn't start rest server"); })) } } -async fn log_middleware( +async fn log_middleware( ConnectInfo(addr): ConnectInfo, - request: Request, - next: Next, -) -> Result -where - B: Send, -{ + request: Request, + next: Next, +) -> Result { info!("Received '{} {}' from '{addr}'", request.method(), request.uri()); Ok(next.run(request).await) diff --git a/node/src/client/mod.rs b/node/src/client/mod.rs index 896ee105b8..1878deaeaa 100644 --- a/node/src/client/mod.rs +++ b/node/src/client/mod.rs @@ -76,6 +76,7 @@ impl> Client { pub async fn new( node_ip: SocketAddr, rest_ip: Option, + rest_rps: u32, account: Account, trusted_peers: &[SocketAddr], genesis: Block, @@ -134,7 +135,7 @@ impl> Client { // Initialize the REST server. if let Some(rest_ip) = rest_ip { - node.rest = Some(Rest::start(rest_ip, None, ledger.clone(), Arc::new(node.clone()))?); + node.rest = Some(Rest::start(rest_ip, rest_rps, None, ledger.clone(), Arc::new(node.clone())).await?); } // Initialize the routing. node.initialize_routing().await; diff --git a/node/src/node.rs b/node/src/node.rs index 6049b248f4..9e7075d126 100644 --- a/node/src/node.rs +++ b/node/src/node.rs @@ -40,8 +40,9 @@ impl Node { /// Initializes a new validator node. pub async fn new_validator( node_ip: SocketAddr, - rest_ip: Option, bft_ip: Option, + rest_ip: Option, + rest_rps: u32, account: Account, trusted_peers: &[SocketAddr], trusted_validators: &[SocketAddr], @@ -50,8 +51,19 @@ impl Node { dev: Option, ) -> Result { Ok(Self::Validator(Arc::new( - Validator::new(node_ip, rest_ip, bft_ip, account, trusted_peers, trusted_validators, genesis, cdn, dev) - .await?, + Validator::new( + node_ip, + bft_ip, + rest_ip, + rest_rps, + account, + trusted_peers, + trusted_validators, + genesis, + cdn, + dev, + ) + .await?, ))) } @@ -70,13 +82,16 @@ impl Node { pub async fn new_client( node_ip: SocketAddr, rest_ip: Option, + rest_rps: u32, account: Account, trusted_peers: &[SocketAddr], genesis: Block, cdn: Option, dev: Option, ) -> Result { - Ok(Self::Client(Arc::new(Client::new(node_ip, rest_ip, account, trusted_peers, genesis, cdn, dev).await?))) + Ok(Self::Client(Arc::new( + Client::new(node_ip, rest_ip, rest_rps, account, trusted_peers, genesis, cdn, dev).await?, + ))) } /// Returns the node type. diff --git a/node/src/validator/mod.rs b/node/src/validator/mod.rs index 4e8bdf89e8..ee1ab20c3e 100644 --- a/node/src/validator/mod.rs +++ b/node/src/validator/mod.rs @@ -73,8 +73,9 @@ impl> Validator { /// Initializes a new validator node. pub async fn new( node_ip: SocketAddr, - rest_ip: Option, bft_ip: Option, + rest_ip: Option, + rest_rps: u32, account: Account, trusted_peers: &[SocketAddr], trusted_validators: &[SocketAddr], @@ -141,7 +142,8 @@ impl> Validator { // Initialize the REST server. if let Some(rest_ip) = rest_ip { - node.rest = Some(Rest::start(rest_ip, Some(consensus), ledger.clone(), Arc::new(node.clone()))?); + node.rest = + Some(Rest::start(rest_ip, rest_rps, Some(consensus), ledger.clone(), Arc::new(node.clone())).await?); } // Initialize the routing. node.initialize_routing().await; @@ -483,8 +485,9 @@ mod tests { let validator = Validator::>::new( node, - Some(rest), None, + Some(rest), + 10, account, &[], &[], diff --git a/node/tests/common/node.rs b/node/tests/common/node.rs index a690f4d799..71528ac983 100644 --- a/node/tests/common/node.rs +++ b/node/tests/common/node.rs @@ -23,6 +23,7 @@ pub async fn client() -> Client> Client::new( "127.0.0.1:0".parse().unwrap(), None, + 10, Account::::from_str("APrivateKey1zkp2oVPTci9kKcUprnbzMwq95Di1MQERpYBhEeqvkrDirK1").unwrap(), &[], sample_genesis_block(), @@ -50,6 +51,7 @@ pub async fn validator() -> Validator::from_str("APrivateKey1zkp2oVPTci9kKcUprnbzMwq95Di1MQERpYBhEeqvkrDirK1").unwrap(), &[], &[],