Skip to content

Commit

Permalink
feat: add config with papyrus_config
Browse files Browse the repository at this point in the history
  • Loading branch information
lev-starkware committed Apr 9, 2024
1 parent 9e36a57 commit b3430a8
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 4 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@ as_conversions = "deny"
[workspace.dependencies]
assert_matches = "1.5.0"
axum = "0.6.12"
clap = { version = "4.3.10" }
hyper = "1.2.0"
pretty_assertions = "1.4.0"
rstest = "0.17.0"
serde = { version = "1.0.193", features = ["derive"] }
serde_json = "1.0"
starknet_api = { git = "https://github.com/starkware-libs/starknet-api.git", rev = "51bc38a" }
papyrus_config = "0.3.0"
thiserror = "1.0"
tokio = { version = "1", features = ["full"] }
validator = "0.12"

3 changes: 3 additions & 0 deletions crates/gateway/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ workspace = true

[dependencies]
axum.workspace = true
clap.workspace = true
hyper.workspace = true
serde.workspace = true
serde_json.workspace = true
starknet_api.workspace = true
thiserror.workspace = true
papyrus_config.workspace = true
validator.workspace = true

[dev-dependencies]
assert_matches.workspace = true
Expand Down
47 changes: 47 additions & 0 deletions crates/gateway/src/config_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use crate::GatewayConfig;
use clap::Command;
use papyrus_config::loading::load_and_process_config;
use std::fs::File;
use std::path::Path;
use validator::Validate;

const TEST_FILES_FOLDER: &str = "./src/json_files_for_testing";
const CONFIG_FILE: &str = "gateway_config.json";

fn get_config_file(file_name: &str) -> Result<GatewayConfig, papyrus_config::ConfigError> {
let config_file = File::open(Path::new(TEST_FILES_FOLDER).join(file_name)).unwrap();
load_and_process_config::<GatewayConfig>(config_file, Command::new(""), vec![])
}

#[test]
fn test_valid_config() {
// Read the valid config file and validate its content.
let expected_config = GatewayConfig {
bind_address: String::from("0.0.0.0:8080"),
};
let loaded_config = get_config_file(CONFIG_FILE).unwrap();

assert!(loaded_config.validate().is_ok());
assert_eq!(loaded_config, expected_config);
}

#[test]
fn test_address_validator() {
// Read the vqalid config file and check that the validator finds no errors.
let mut config = get_config_file(CONFIG_FILE).unwrap();

if let Err(e) = config.validate() {
panic!("Unexpected error {e}.");
}

// Invalidate the bind address and check that the validator finds an error.
config.bind_address = String::from("bad_address");

match config.validate() {
Ok(_) => panic!("Expected an error, but got a config."),
Err(e) => assert_eq!(
e.field_errors()["bind_address"][0].code,
"Invalid Socket address.".to_owned()
),
}
}
5 changes: 1 addition & 4 deletions crates/gateway/src/gateway.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::errors::{GatewayConfigError, GatewayError};
use crate::GatewayConfig;
use axum::response::IntoResponse;
use axum::routing::{get, post};
use axum::{Json, Router};
Expand Down Expand Up @@ -38,10 +39,6 @@ impl Gateway {
}
}

pub struct GatewayConfig {
pub bind_address: String,
}

async fn is_alive() -> impl IntoResponse {
unimplemented!("Future handling should be implemented here.");
}
Expand Down
7 changes: 7 additions & 0 deletions crates/gateway/src/json_files_for_testing/gateway_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"bind_address": {
"description": "IP:PORT of the gateway.",
"value": "0.0.0.0:8080",
"privacy": "Public"
}
}
48 changes: 48 additions & 0 deletions crates/gateway/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,51 @@ pub mod errors;
pub mod gateway;
pub mod starknet_api_test_utils;
pub mod transaction_validator;

use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::str::FromStr;

use papyrus_config::dumping::{ser_param, SerializeConfig};
use papyrus_config::{ParamPath, ParamPrivacyInput, SerializedParam};
use std::net::SocketAddr;
use validator::{Validate, ValidationError};

#[cfg(test)]
mod config_test;

/// The gateway configuration.
#[derive(Clone, Debug, Serialize, Deserialize, Validate, PartialEq)]
pub struct GatewayConfig {
/// The gateway socket address, in the form of "IP:port".
#[validate(custom = "validate_socket_address")]
pub bind_address: String,
}

impl SerializeConfig for GatewayConfig {
fn dump(&self) -> BTreeMap<ParamPath, SerializedParam> {
BTreeMap::from_iter([ser_param(
"server_bind_address",
&self.bind_address,
"The server bind addres of a gateway.",
ParamPrivacyInput::Public,
)])
}
}

impl Default for GatewayConfig {
fn default() -> Self {
Self {
bind_address: String::from("0.0.0.0:8080"),
}
}
}

pub fn validate_socket_address(socket_address: &str) -> Result<(), ValidationError> {
if SocketAddr::from_str(socket_address).is_err() {
let mut error = ValidationError::new("Invalid Socket address.");
error.message = Some("Please provide valid Socket address in the configuration.".into());
return Err(error);
}
Ok(())
}

0 comments on commit b3430a8

Please sign in to comment.