diff --git a/.validateignore b/.validateignore deleted file mode 100644 index b145a9d..0000000 --- a/.validateignore +++ /dev/null @@ -1,5 +0,0 @@ -# skip validation for methods listed below -system_health -system_name -system_version -author_pendingExtrinsics \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 1583f10..46ddcaa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,9 +58,6 @@ jsonrpc-pubsub = { version = "18.0.0" } name = "bench" harness = false -[features] -validate = [] - [target.'cfg(tokio_unstable)'.dependencies] console-subscriber = "0.2.0" diff --git a/README.md b/README.md index 7e0e5c3..803bace 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ cargo bench --bench bench ws_round_trip This middleware will intercept all method request/responses and compare the result directly with healthy endpoint responses. This is useful for debugging to make sure the returned values are as expected. -You can use this by compiling with `validate` feature and enable validate middleware on your config file. +You can enable validate middleware on your config file. ```yml middlewares: methods: @@ -89,4 +89,13 @@ middlewares: ``` NOTE: Keep in mind that if you place `validate` middleware before `inject_params` you may get false positive errors because the request will not be the same. -Use `.validateingore` file to list all the methods you want to ignore. +Ignored methods can be defined in extension config: +```yml +extensions: + validate: + ignore_methods: + - system_health + - system_name + - system_version + - author_pendingExtrinsics +``` diff --git a/src/extensions/mod.rs b/src/extensions/mod.rs index 2cf1880..ebc94b1 100644 --- a/src/extensions/mod.rs +++ b/src/extensions/mod.rs @@ -16,6 +16,7 @@ pub mod merge_subscription; pub mod rate_limit; pub mod server; pub mod telemetry; +pub mod validate; #[async_trait] pub trait Extension: Sized { @@ -138,4 +139,5 @@ define_all_extensions! { server: server::SubwayServerBuilder, event_bus: event_bus::EventBus, rate_limit: rate_limit::RateLimitBuilder, + validate: validate::Validate, } diff --git a/src/extensions/validate/mod.rs b/src/extensions/validate/mod.rs new file mode 100644 index 0000000..9b31229 --- /dev/null +++ b/src/extensions/validate/mod.rs @@ -0,0 +1,33 @@ +use async_trait::async_trait; +use serde::Deserialize; + +use super::{Extension, ExtensionRegistry}; + +#[derive(Default)] +pub struct Validate { + pub config: ValidateConfig, +} + +#[derive(Deserialize, Default, Debug, Clone)] +pub struct ValidateConfig { + pub ignore_methods: Vec, +} + +#[async_trait] +impl Extension for Validate { + type Config = ValidateConfig; + + async fn from_config(config: &Self::Config, _registry: &ExtensionRegistry) -> Result { + Ok(Self::new(config.clone())) + } +} + +impl Validate { + pub fn new(config: ValidateConfig) -> Self { + Self { config } + } + + pub fn ignore(&self, method: &String) -> bool { + self.config.ignore_methods.contains(method) + } +} diff --git a/src/middlewares/factory.rs b/src/middlewares/factory.rs index cb7e975..2ac12bc 100644 --- a/src/middlewares/factory.rs +++ b/src/middlewares/factory.rs @@ -30,7 +30,6 @@ pub async fn create_method_middleware( "block_tag" => block_tag::BlockTagMiddleware::build(method, extensions).await, "inject_params" => inject_params::InjectParamsMiddleware::build(method, extensions).await, "delay" => delay::DelayMiddleware::build(method, extensions).await, - #[cfg(feature = "validate")] "validate" => validate::ValidateMiddleware::build(method, extensions).await, #[cfg(test)] "crazy" => testing::CrazyMiddleware::build(method, extensions).await, diff --git a/src/middlewares/methods/mod.rs b/src/middlewares/methods/mod.rs index 71af3fa..420c290 100644 --- a/src/middlewares/methods/mod.rs +++ b/src/middlewares/methods/mod.rs @@ -4,8 +4,6 @@ pub mod delay; pub mod inject_params; pub mod response; pub mod upstream; - -#[cfg(feature = "validate")] pub mod validate; #[cfg(test)] diff --git a/src/middlewares/methods/validate.rs b/src/middlewares/methods/validate.rs index 0b38d25..bd0e6be 100644 --- a/src/middlewares/methods/validate.rs +++ b/src/middlewares/methods/validate.rs @@ -1,22 +1,21 @@ use async_trait::async_trait; use std::sync::Arc; -use std::{fs::File, io::Read}; use crate::utils::errors; use crate::{ - extensions::client::Client, + extensions::{client::Client, validate::Validate}, middlewares::{CallRequest, CallResult, Middleware, MiddlewareBuilder, NextFn, RpcMethod}, utils::{TypeRegistry, TypeRegistryRef}, }; pub struct ValidateMiddleware { + validate: Arc, client: Arc, - ignore_methods: Vec, } impl ValidateMiddleware { - pub fn new(client: Arc, ignore_methods: Vec) -> Self { - Self { client, ignore_methods } + pub fn new(validate: Arc, client: Arc) -> Self { + Self { validate, client } } } @@ -26,26 +25,14 @@ impl MiddlewareBuilder for ValidateMiddlewar _method: &RpcMethod, extensions: &TypeRegistryRef, ) -> Option>> { - // read ignored methods from file - let mut ignore_methods = vec![]; - if let Ok(mut file) = File::open(".validateignore") { - if let Err(err) = file.read_to_end(&mut ignore_methods) { - tracing::error!("Read .validateignore failed: {err:?}"); - } - } - let ignore_methods = String::from_utf8(ignore_methods) - .unwrap_or_default() - .split('\n') - .map(|x| x.trim().to_string()) - .filter(|x| !x.starts_with('#') && !x.starts_with("//")) // filter comments - .collect(); + let validate = extensions.read().await.get::().unwrap_or_default(); let client = extensions .read() .await .get::() .expect("Client extension not found"); - Some(Box::new(ValidateMiddleware::new(client, ignore_methods))) + Some(Box::new(ValidateMiddleware::new(validate, client))) } } @@ -61,7 +48,7 @@ impl Middleware for ValidateMiddleware { let result = next(request.clone(), context).await; let actual = result.clone(); - if self.ignore_methods.contains(&request.method) { + if self.validate.ignore(&request.method) { return result; }