Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement : Refactor Settings #106

Merged
merged 8 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ SHARP_PROOF_LAYOUT="small"

DA_LAYER="ethereum"
SETTLEMENT_LAYER="ethereum"
SETTLEMENT_RPC_URL="http://localhost:3001"
SETTLEMENT_RPC_URL="https://eth-mainnet.public.blastapi.io"
MADARA_RPC_URL="http://localhost:3000"
L1_CORE_CONTRACT_ADDRESS="0xc662c410C0ECf747543f5bA90660f6ABeBD9C8c4"
MEMORY_PAGES_CONTRACT_ADDRESS="0x47312450B3Ac8b5b8e247a6bB6d523e7605bDb60"
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## Changed

- settings provider
- refactor AWS config usage and clean .env files
- GitHub's coverage CI yml file for localstack and db testing.
- Orchestrator :Moved TestConfigBuilder to `config.rs` in tests folder.
Expand Down
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 10 additions & 25 deletions crates/da-clients/ethereum/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,19 @@
use std::str::FromStr;
use serde::{Deserialize, Serialize};
use utils::settings::Settings;

use alloy::{network::Ethereum, providers::ProviderBuilder, rpc::client::RpcClient};
use async_trait::async_trait;
use da_client_interface::DaConfig;
use url::Url;
use utils::env_utils::get_env_var_or_panic;

use crate::EthereumDaClient;

#[derive(Clone, Debug)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct EthereumDaConfig {
pub rpc_url: String,
pub memory_pages_contract: String,
pub private_key: String,
}

#[async_trait]
impl DaConfig<EthereumDaClient> for EthereumDaConfig {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so we actually did this before but then later in the celestia PR we realised that we wanted it to be async and this was the better way to do it, over here #46

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason for this to be async ? this is config which should not be an async operation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in celestia it wasn't possible to do it sync, can you check with @heemankv once?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let me check

fn new_from_env() -> Self {
Self {
rpc_url: get_env_var_or_panic("SETTLEMENT_RPC_URL"),
memory_pages_contract: get_env_var_or_panic("MEMORY_PAGES_CONTRACT_ADDRESS"),
private_key: get_env_var_or_panic("PRIVATE_KEY"),
}
}
async fn build_client(&self) -> EthereumDaClient {
let client =
RpcClient::new_http(Url::from_str(self.rpc_url.as_str()).expect("Failed to parse SETTLEMENT_RPC_URL"));
let provider = ProviderBuilder::<_, Ethereum>::new().on_client(client);

EthereumDaClient { provider }
impl EthereumDaConfig {
pub fn new_with_settings(settings: &impl Settings) -> color_eyre::Result<Self> {
Ok(Self {
rpc_url: settings.get_settings("SETTLEMENT_RPC_URL")?,
memory_pages_contract: settings.get_settings("MEMORY_PAGES_CONTRACT_ADDRESS")?,
private_key: settings.get_settings("PRIVATE_KEY")?,
})
}
}
21 changes: 20 additions & 1 deletion crates/da-clients/ethereum/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
#![allow(missing_docs)]
#![allow(clippy::missing_docs_in_private_items)]

use crate::config::EthereumDaConfig;
use alloy::network::Ethereum;
use alloy::providers::RootProvider;
use alloy::providers::{ProviderBuilder, RootProvider};
use alloy::rpc::client::RpcClient;
use alloy::transports::http::Http;
use async_trait::async_trait;
use color_eyre::Result;
use da_client_interface::{DaClient, DaVerificationStatus};
use mockall::automock;
use mockall::predicate::*;
use reqwest::Client;
use std::str::FromStr;
use url::Url;
use utils::settings::Settings;

pub const DA_SETTINGS_NAME: &str = "ethereum";

pub mod config;
pub struct EthereumDaClient {
#[allow(dead_code)]
Expand Down Expand Up @@ -37,3 +45,14 @@ impl DaClient for EthereumDaClient {
131072
}
}

impl EthereumDaClient {
pub fn new_with_settings(settings: &impl Settings) -> Self {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should restore the build_client one as mentioned above

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let config = EthereumDaConfig::new_with_settings(settings)
.expect("Not able to create EthereumDaClient from given settings.");
let client =
RpcClient::new_http(Url::from_str(config.rpc_url.as_str()).expect("Failed to parse SETTLEMENT_RPC_URL"));
let provider = ProviderBuilder::<_, Ethereum>::new().on_client(client);
EthereumDaClient { provider }
}
}
19 changes: 19 additions & 0 deletions crates/orchestrator/src/alerts/aws_sns/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use serde::{Deserialize, Serialize};
use utils::settings::Settings;

#[derive(Clone, Serialize, Deserialize)]
pub struct AWSSNSConfig {
/// AWS SNS ARN
pub sns_arn: String,
/// AWS SNS region
pub sns_arn_region: String,
}

impl AWSSNSConfig {
pub fn new_with_settings(settings: &impl Settings) -> color_eyre::Result<Self> {
Ok(Self {
sns_arn: settings.get_settings("AWS_SNS_ARN")?,
sns_arn_region: settings.get_settings("AWS_SNS_REGION")?,
})
}
}
21 changes: 13 additions & 8 deletions crates/orchestrator/src/alerts/aws_sns/mod.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
mod config;

use crate::alerts::aws_sns::config::AWSSNSConfig;
use crate::alerts::Alerts;
use async_trait::async_trait;
use aws_sdk_sns::config::Region;
use aws_sdk_sns::Client;
use utils::env_utils::get_env_var_or_panic;
use utils::settings::Settings;

pub const AWS_SNS_SETTINGS_NAME: &str = "sns";

pub struct AWSSNS {
client: Client,
topic_arn: String,
apoorvsadana marked this conversation as resolved.
Show resolved Hide resolved
}

impl AWSSNS {
/// To create a new SNS client
pub async fn new() -> Self {
let sns_region = get_env_var_or_panic("AWS_SNS_REGION");
let config = aws_config::from_env().region(Region::new(sns_region)).load().await;
AWSSNS { client: Client::new(&config) }
pub async fn new_with_settings(settings: &impl Settings) -> Self {
let sns_config =
AWSSNSConfig::new_with_settings(settings).expect("Not able to get Aws sns config from provided settings");
let config = aws_config::from_env().region(Region::new(sns_config.sns_arn_region)).load().await;
Self { client: Client::new(&config), topic_arn: sns_config.sns_arn }
}
}

#[async_trait]
impl Alerts for AWSSNS {
async fn send_alert_message(&self, message_body: String) -> color_eyre::Result<()> {
let topic_arn = get_env_var_or_panic("AWS_SNS_ARN");
self.client.publish().topic_arn(topic_arn).message(message_body).send().await?;
self.client.publish().topic_arn(self.topic_arn.clone()).message(message_body).send().await?;
Ok(())
}
}
62 changes: 26 additions & 36 deletions crates/orchestrator/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ use std::sync::Arc;

use crate::alerts::aws_sns::AWSSNS;
use crate::alerts::Alerts;
use crate::data_storage::aws_s3::config::AWSS3Config;
use crate::data_storage::aws_s3::AWSS3;
use crate::data_storage::{DataStorage, DataStorageConfig};
use crate::data_storage::DataStorage;
use arc_swap::{ArcSwap, Guard};
use aws_config::SdkConfig;
use da_client_interface::{DaClient, DaConfig};
use da_client_interface::DaClient;
use dotenvy::dotenv;
use ethereum_da_client::config::EthereumDaConfig;
use ethereum_da_client::EthereumDaClient;
use ethereum_settlement_client::EthereumSettlementClient;
use prover_client_interface::ProverClient;
use settlement_client_interface::SettlementClient;
Expand All @@ -19,12 +18,11 @@ use starknet::providers::{JsonRpcClient, Url};
use starknet_settlement_client::StarknetSettlementClient;
use tokio::sync::OnceCell;
use utils::env_utils::get_env_var_or_panic;
use utils::settings::default::DefaultSettingsProvider;
use utils::settings::SettingsProvider;
use utils::settings::env::EnvSettingsProvider;
use utils::settings::Settings;

use crate::database::mongodb::config::MongoDbConfig;
use crate::database::mongodb::MongoDb;
use crate::database::{Database, DatabaseConfig};
use crate::database::Database;
use crate::queue::sqs::SqsQueue;
use crate::queue::QueueProvider;

Expand Down Expand Up @@ -58,9 +56,6 @@ pub async fn init_config() -> Config {
Url::parse(get_env_var_or_panic("MADARA_RPC_URL").as_str()).expect("Failed to parse URL"),
));

// init database
let database = build_database_client().await;

// init AWS
let aws_config = aws_config::load_from_env().await;

Expand All @@ -70,15 +65,14 @@ pub async fn init_config() -> Config {
// us stop using the generic omniqueue abstractions for message ack/nack
let queue = build_queue_client(&aws_config);

let da_client = build_da_client().await;

let settings_provider = DefaultSettingsProvider {};
let settings_provider = EnvSettingsProvider {};
// init database
let database = build_database_client(&settings_provider).await;
let da_client = build_da_client(&settings_provider).await;
let settlement_client = build_settlement_client(&settings_provider).await;
let prover_client = build_prover_service(&settings_provider);

let storage_client = build_storage_client(&aws_config).await;

let alerts_client = build_alert_client().await;
let storage_client = build_storage_client(&settings_provider).await;
let alerts_client = build_alert_client(&settings_provider).await;

Config::new(
Arc::new(provider),
Expand Down Expand Up @@ -177,58 +171,54 @@ pub async fn config_force_init(config: Config) {
}

/// Builds the DA client based on the environment variable DA_LAYER
pub async fn build_da_client() -> Box<dyn DaClient + Send + Sync> {
pub async fn build_da_client(settings_provider: &impl Settings) -> Box<dyn DaClient + Send + Sync> {
match get_env_var_or_panic("DA_LAYER").as_str() {
"ethereum" => {
let config = EthereumDaConfig::new_from_env();
Box::new(config.build_client().await)
}
"ethereum" => Box::new(EthereumDaClient::new_with_settings(settings_provider)),
_ => panic!("Unsupported DA layer"),
}
}

/// Builds the prover service based on the environment variable PROVER_SERVICE
pub fn build_prover_service(settings_provider: &impl SettingsProvider) -> Box<dyn ProverClient> {
pub fn build_prover_service(settings_provider: &impl Settings) -> Box<dyn ProverClient> {
match get_env_var_or_panic("PROVER_SERVICE").as_str() {
"sharp" => Box::new(SharpProverService::with_settings(settings_provider)),
"sharp" => Box::new(SharpProverService::new_with_settings(settings_provider)),
_ => panic!("Unsupported prover service"),
}
}

/// Builds the settlement client depending on the env variable SETTLEMENT_LAYER
pub async fn build_settlement_client(
settings_provider: &impl SettingsProvider,
) -> Box<dyn SettlementClient + Send + Sync> {
pub async fn build_settlement_client(settings_provider: &impl Settings) -> Box<dyn SettlementClient + Send + Sync> {
match get_env_var_or_panic("SETTLEMENT_LAYER").as_str() {
"ethereum" => Box::new(EthereumSettlementClient::with_settings(settings_provider)),
"starknet" => Box::new(StarknetSettlementClient::with_settings(settings_provider).await),
"ethereum" => Box::new(EthereumSettlementClient::new_with_settings(settings_provider)),
"starknet" => Box::new(StarknetSettlementClient::new_with_settings(settings_provider).await),
_ => panic!("Unsupported Settlement layer"),
}
}

pub async fn build_storage_client(aws_config: &SdkConfig) -> Box<dyn DataStorage + Send + Sync> {
pub async fn build_storage_client(settings_provider: &impl Settings) -> Box<dyn DataStorage + Send + Sync> {
match get_env_var_or_panic("DATA_STORAGE").as_str() {
"s3" => Box::new(AWSS3::new(AWSS3Config::new_from_env(), aws_config)),
"s3" => Box::new(AWSS3::new_with_settings(settings_provider).await),
_ => panic!("Unsupported Storage Client"),
}
}

pub async fn build_alert_client() -> Box<dyn Alerts + Send + Sync> {
pub async fn build_alert_client(settings_provider: &impl Settings) -> Box<dyn Alerts + Send + Sync> {
match get_env_var_or_panic("ALERTS").as_str() {
"sns" => Box::new(AWSSNS::new().await),
"sns" => Box::new(AWSSNS::new_with_settings(settings_provider).await),
_ => panic!("Unsupported Alert Client"),
}
}

pub fn build_queue_client(_aws_config: &SdkConfig) -> Box<dyn QueueProvider + Send + Sync> {
match get_env_var_or_panic("QUEUE_PROVIDER").as_str() {
"sqs" => Box::new(SqsQueue {}),
_ => panic!("Unsupported Queue Client"),
}
}

pub async fn build_database_client() -> Box<dyn Database + Send + Sync> {
pub async fn build_database_client(settings_provider: &impl Settings) -> Box<dyn Database + Send + Sync> {
match get_env_var_or_panic("DATABASE").as_str() {
"mongodb" => Box::new(MongoDb::new(MongoDbConfig::new_from_env()).await),
"mongodb" => Box::new(MongoDb::new_with_settings(settings_provider).await),
_ => panic!("Unsupported Database Client"),
}
}
13 changes: 9 additions & 4 deletions crates/orchestrator/src/data_storage/aws_s3/config.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use utils::env_utils::get_env_var_or_panic;
use serde::{Deserialize, Serialize};
use utils::settings::Settings;

use crate::data_storage::DataStorageConfig;

/// Represents AWS S3 config struct with all the necessary variables.
#[derive(Clone)]
#[derive(Clone, Serialize, Deserialize)]
pub struct AWSS3Config {
/// S3 Bucket Name
pub bucket_name: String,
Expand All @@ -12,7 +13,11 @@ pub struct AWSS3Config {
/// Implementation of `DataStorageConfig` for `AWSS3Config`
impl DataStorageConfig for AWSS3Config {
/// To return the config struct by creating it from the environment variables.
fn new_from_env() -> Self {
Self { bucket_name: get_env_var_or_panic("AWS_S3_BUCKET_NAME") }
fn new_with_settings(settings: &impl Settings) -> Self {
Self {
bucket_name: settings
.get_settings("AWS_S3_BUCKET_NAME")
.expect("Not able to get AWS_S3_BUCKET_NAME from settings provided."),
}
}
}
16 changes: 10 additions & 6 deletions crates/orchestrator/src/data_storage/aws_s3/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use crate::data_storage::aws_s3::config::AWSS3Config;
use crate::data_storage::DataStorage;
use crate::data_storage::{DataStorage, DataStorageConfig};
use async_trait::async_trait;
use aws_config::SdkConfig;
use aws_sdk_s3::primitives::ByteStream;
use aws_sdk_s3::Client;
use bytes::Bytes;
use color_eyre::Result;
use utils::settings::Settings;

pub const S3_SETTINGS_NAME: &str = "s3";

/// Module for AWS S3 config structs and implementations
pub mod config;
Expand All @@ -20,11 +22,13 @@ pub struct AWSS3 {
///
/// - initializing a new AWS S3 client
impl AWSS3 {
/// Initializes a new AWS S3 client by passing the config
/// and returning it.
pub fn new(s3_config: AWSS3Config, aws_config: &SdkConfig) -> Self {
/// To init the struct with main settings
pub async fn new_with_settings(settings: &impl Settings) -> Self {
let s3_config = AWSS3Config::new_with_settings(settings);
let aws_config = aws_config::load_from_env().await;
apoorvsadana marked this conversation as resolved.
Show resolved Hide resolved

// Building AWS S3 config
let mut s3_config_builder = aws_sdk_s3::config::Builder::from(aws_config);
let mut s3_config_builder = aws_sdk_s3::config::Builder::from(&aws_config);

// this is necessary for it to work with localstack in test cases
s3_config_builder.set_force_path_style(Some(true));
Expand Down
3 changes: 2 additions & 1 deletion crates/orchestrator/src/data_storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use async_trait::async_trait;
use bytes::Bytes;
use color_eyre::Result;
use mockall::automock;
use utils::settings::Settings;

/// DataStorage trait contains the functions used to store and get the data from
/// the cloud provider storage.
Expand All @@ -26,5 +27,5 @@ pub trait DataStorage: Send + Sync {
pub trait DataStorageConfig {
/// Get a config file from environment vars in system or
/// dotenv file.
fn new_from_env() -> Self;
fn new_with_settings(settings: &impl Settings) -> Self;
}
Loading
Loading