From 21d0a3bc3a37e9357807c621cad95aa89fd412f9 Mon Sep 17 00:00:00 2001 From: Heemank Verma Date: Thu, 5 Dec 2024 12:58:52 +0530 Subject: [PATCH] PR corrections --- .env.test | 8 +- Dockerfile | 116 +++++++++++++----- .../orchestrator/src/cli/cron/event_bridge.rs | 8 ++ crates/orchestrator/src/cli/mod.rs | 12 ++ crates/orchestrator/src/cron/event_bridge.rs | 12 +- .../src/data_storage/aws_s3/mod.rs | 17 +-- crates/orchestrator/src/setup/mod.rs | 31 +++-- .../orchestrator/src/workers/update_state.rs | 2 +- .../atlantic-service/src/lib.rs | 5 - e2e-tests/tests.rs | 9 +- scripts/init_state.js | 2 +- 11 files changed, 150 insertions(+), 72 deletions(-) diff --git a/.env.test b/.env.test index 80a7258f..d7a31179 100644 --- a/.env.test +++ b/.env.test @@ -3,7 +3,7 @@ AWS_ACCESS_KEY_ID=AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY=AWS_SECRET_ACCESS_KEY -AWS_REGION=us-east-1 +AWS_REGION=us-west-1 # For Aws sdk AWS_ENDPOINT_URL=http://localhost.localstack.cloud:4566 @@ -18,7 +18,7 @@ MADARA_ORCHESTRATOR_EVENT_BRIDGE_TRIGGER_RULE_NAME=madara-orchestrator-worker-tr #### ALERTS #### -MADARA_ORCHESTRATOR_AWS_SNS_ARN=arn:aws:sns:us-east-1:000000000000:madara-orchestrator-arn +MADARA_ORCHESTRATOR_AWS_SNS_ARN=arn:aws:sns:us-west-1:000000000000:madara-orchestrator-arn #### DATA AVAILABILITY #### @@ -51,7 +51,7 @@ MADARA_ORCHESTRATOR_GPS_VERIFIER_CONTRACT_ADDRESS=0x07ec0D28e50322Eb0C159B9090ec ## ATLANTIC ## -MADARA_ORCHESTRATOR_ATLANTIC_API_KEY="73307f1b-6464-412d-8cce-9473b5073cc2" +MADARA_ORCHESTRATOR_ATLANTIC_API_KEY="API-KEY" MADARA_ORCHESTRATOR_ATLANTIC_SERVICE_URL="https://atlantic.api.herodotus.cloud" MADARA_ORCHESTRATOR_ATLANTIC_MOCK_FACT_HASH="false" # Whether to use mock fact registry MADARA_ORCHESTRATOR_ATLANTIC_PROVER_TYPE="herodotus" # ("herodotus" | "starkware") @@ -65,7 +65,7 @@ MADARA_ORCHESTRATOR_ATLANTIC_RPC_NODE_URL=http://127.0.0.1:8545 MADARA_ORCHESTRATOR_SQS_PREFIX=madara_orchestrator MADARA_ORCHESTRATOR_SQS_SUFFIX=queue MADARA_ORCHESTRATOR_EVENT_BRIDGE_TARGET_QUEUE_NAME=madara_orchestrator_worker_trigger_queue -MADARA_ORCHESTRATOR_SQS_BASE_QUEUE_URL=http://sqs.us-east-1.localhost.localstack.cloud:4566/000000000000 +MADARA_ORCHESTRATOR_SQS_BASE_QUEUE_URL=http://sqs.us-west-1.localhost.localstack.cloud:4566/000000000000 #### SETTLEMENT #### diff --git a/Dockerfile b/Dockerfile index e124880e..e428b3d7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,38 +1,92 @@ -# Use latest Ubuntu -FROM ubuntu:latest - -# Install necessary runtime dependencies -RUN apt-get update && \ - apt-get install -y \ - ca-certificates \ - && \ - apt-get clean && \ +FROM rust:1.81 AS builder + +# Set the working directory in the container +WORKDIR /usr/src/madara-orchestrator + +# Install system dependencies +RUN apt update && apt install -y \ + libgmp3-dev \ + software-properties-common \ + wget \ + bash \ + nodejs \ + npm + +# Install Python 3.9 +RUN wget https://www.python.org/ftp/python/3.9.16/Python-3.9.16.tgz \ + && tar xzf Python-3.9.16.tgz \ + && cd Python-3.9.16 \ + && ./configure --enable-optimizations \ + && make altinstall \ + && cd .. \ + && rm -rf Python-3.9.16 Python-3.9.16.tgz + +# Install pip and venv for Python 3.9 +RUN wget https://bootstrap.pypa.io/get-pip.py \ + && python3.9 get-pip.py \ + && rm get-pip.py \ + && python3.9 -m pip install virtualenv + +# Copy the current directory contents into the container +COPY . . + + +# Check rust version (this also installs version from rust-toolchain file) +RUN rustup show + +# ############################################################# +# TODO : remove this step after snos build is sorted +# Build cairo lang +RUN cargo fetch +RUN python3.9 -m venv orchestrator_venv +RUN . ./orchestrator_venv/bin/activate +RUN pip install cairo-lang==0.13.2 "sympy<1.13.0" +RUN mkdir -p build +RUN git submodule update --init --recursive +RUN cd cairo-lang +RUN cd .. +RUN cairo-compile cairo-lang/src/starkware/starknet/core/os/os.cairo --output build/os_latest.json --cairo_path cairo-lang/src +# ############################################################# + +WORKDIR /usr/src/madara-orchestrator + +# Build the project +RUN cargo build --release + +# Install Node.js dependencies for migrations +RUN npm install + + +FROM debian:bookworm + +# Install runtime dependencies +RUN apt-get -y update && \ + apt-get install -y openssl ca-certificates nodejs npm &&\ + apt-get autoremove -y; \ + apt-get clean; \ rm -rf /var/lib/apt/lists/* # Set the working directory WORKDIR /usr/local/bin -# Copy the pre-built binary -COPY target/release/orchestrator . +# Copy the compiled binary from the builder stage +COPY --from=builder /usr/src/madara-orchestrator/target/release/orchestrator . # Copy Node.js files and dependencies -COPY node_modules ./node_modules -COPY package.json . -COPY migrate-mongo-config.js . -COPY migrations ./migrations - -# Create required directories and copy setup files -RUN mkdir -p /home/ubuntu/.cargo/git/checkouts/snos-59fe8329bb16fe65/2c47281/crates/starknet-os/kzg -RUN mkdir -p /usr/src/madara-orchestrator/crates/settlement-clients/ethereum/src - -# Copy trusted setup files to required locations -COPY ./crates/da-clients/ethereum/trusted_setup.txt /home/ubuntu/.cargo/git/checkouts/snos-59fe8329bb16fe65/2c47281/crates/starknet-os/kzg/trusted_setup.txt -COPY ./crates/da-clients/ethereum/trusted_setup.txt /home/ubuntu/madara-orchestrator/crates/settlement-clients/ethereum/src/trusted_setup.txt - -# Make sure the binary is executable -RUN chmod +x orchestrator - -# Set the entrypoint to the binary -ENTRYPOINT ["./orchestrator"] -# Allow passing arguments -CMD [] +COPY --from=builder /usr/src/madara-orchestrator/node_modules ./node_modules +COPY --from=builder /usr/src/madara-orchestrator/package.json . +COPY --from=builder /usr/src/madara-orchestrator/migrate-mongo-config.js . +COPY --from=builder /usr/src/madara-orchestrator/migrations ./migrations + +# To be fixed by this https://github.com/keep-starknet-strange/snos/issues/404 +RUN mkdir -p /usr/local/cargo/git/checkouts/snos-59fe8329bb16fe65/662d170/crates/starknet-os/kzg +COPY ./crates/da-clients/ethereum/trusted_setup.txt /usr/local/cargo/git/checkouts/snos-59fe8329bb16fe65/662d170/crates/starknet-os/kzg/trusted_setup.txt +COPY ./crates/da-clients/ethereum/trusted_setup.txt /usr/src/madara-orchestrator/crates/settlement-clients/ethereum/src/trusted_setup.txt + +# Create a startup script +RUN echo '#!/bin/bash\n\ + npm run migrate up\n\ + ./orchestrator' > start.sh && chmod +x start.sh + +# Set the entrypoint to the startup script +ENTRYPOINT ["./start.sh"] \ No newline at end of file diff --git a/crates/orchestrator/src/cli/cron/event_bridge.rs b/crates/orchestrator/src/cli/cron/event_bridge.rs index cc70b18c..e9e83c25 100644 --- a/crates/orchestrator/src/cli/cron/event_bridge.rs +++ b/crates/orchestrator/src/cli/cron/event_bridge.rs @@ -18,4 +18,12 @@ pub struct AWSEventBridgeCliArgs { /// The name of the event bridge trigger rule. #[arg(env = "MADARA_ORCHESTRATOR_EVENT_BRIDGE_TRIGGER_RULE_NAME", long, default_value = Some("madara-orchestrator-worker-trigger"), help = "The name of the event bridge trigger rule.")] pub trigger_rule_name: Option, + + /// The name of the queue for the event bridge + #[arg(env = "MADARA_ORCHESTRATOR_EVENT_BRIDGE_TRIGGER_ROLE_NAME", long, default_value = Some("madara-orchestrator-worker-trigger-role"), help = "The name of the Trigger Role to assign to the event bridge")] + pub trigger_role_name: Option, + + /// The name of the queue for the event bridge + #[arg(env = "MADARA_ORCHESTRATOR_EVENT_BRIDGE_TRIGGER_POLICY_NAME", long, default_value = Some("madara-orchestrator-worker-trigger-policy"), help = "The name of the Trigger Policy to assign to the event bridge")] + pub trigger_policy_name: Option, } diff --git a/crates/orchestrator/src/cli/mod.rs b/crates/orchestrator/src/cli/mod.rs index 0ff780d7..d4333cb4 100644 --- a/crates/orchestrator/src/cli/mod.rs +++ b/crates/orchestrator/src/cli/mod.rs @@ -421,6 +421,16 @@ pub mod validate_params { .trigger_rule_name .clone() .expect("Trigger rule name is required"), + + trigger_role_name: aws_event_bridge_args + .trigger_role_name + .clone() + .expect("Trigger role name is required"), + + trigger_policy_name: aws_event_bridge_args + .trigger_policy_name + .clone() + .expect("Trigger policy name is required"), })) } else { Err("Only AWS Event Bridge is supported as of now".to_string()) @@ -831,6 +841,8 @@ pub mod validate_params { target_queue_name: Some(String::from("test")), cron_time: Some(String::from("12")), trigger_rule_name: Some(String::from("test")), + trigger_role_name: Some(String::from("test-role")), + trigger_policy_name: Some(String::from("test-policy")), }; let aws_config_args: AWSConfigCliArgs = AWSConfigCliArgs { aws: is_aws, diff --git a/crates/orchestrator/src/cron/event_bridge.rs b/crates/orchestrator/src/cron/event_bridge.rs index a9112976..112665f0 100644 --- a/crates/orchestrator/src/cron/event_bridge.rs +++ b/crates/orchestrator/src/cron/event_bridge.rs @@ -18,6 +18,8 @@ pub struct AWSEventBridgeValidatedArgs { pub target_queue_name: String, pub cron_time: Duration, pub trigger_rule_name: String, + pub trigger_role_name: String, + pub trigger_policy_name: String, } pub struct AWSEventBridge { @@ -27,6 +29,8 @@ pub struct AWSEventBridge { client: SchedulerClient, queue_client: SqsClient, iam_client: aws_sdk_iam::Client, + trigger_role_name: String, + trigger_policy_name: String, } impl AWSEventBridge { @@ -38,6 +42,8 @@ impl AWSEventBridge { client: aws_sdk_scheduler::Client::new(aws_config), queue_client: aws_sdk_sqs::Client::new(aws_config), iam_client: aws_sdk_iam::Client::new(aws_config), + trigger_role_name: params.trigger_role_name.clone(), + trigger_policy_name: params.trigger_policy_name.clone(), } } } @@ -59,7 +65,7 @@ impl Cron for AWSEventBridge { let queue_arn = queue_attributes.attributes().unwrap().get(&QueueAttributeName::QueueArn).unwrap(); // Create IAM role for EventBridge - let role_name = format!("worker-trigger-role-{}", uuid::Uuid::new_v4()); + let role_name = format!("{}-{}", self.trigger_role_name, uuid::Uuid::new_v4()); let assume_role_policy = r#"{ "Version": "2012-10-17", "Statement": [{ @@ -96,7 +102,7 @@ impl Cron for AWSEventBridge { queue_arn ); - let policy_name = format!("worker-trigger-policy-{}", uuid::Uuid::new_v4()); + let policy_name = format!("{}-{}", self.trigger_policy_name, uuid::Uuid::new_v4()); // Create and attach the policy let policy_resp = @@ -146,7 +152,7 @@ impl Cron for AWSEventBridge { } } -pub fn duration_to_rate_string(duration: Duration) -> String { +fn duration_to_rate_string(duration: Duration) -> String { let total_secs = duration.as_secs(); let total_mins = duration.as_secs() / 60; let total_hours = duration.as_secs() / 3600; diff --git a/crates/orchestrator/src/data_storage/aws_s3/mod.rs b/crates/orchestrator/src/data_storage/aws_s3/mod.rs index ba0d5958..5e7cba5c 100644 --- a/crates/orchestrator/src/data_storage/aws_s3/mod.rs +++ b/crates/orchestrator/src/data_storage/aws_s3/mod.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use aws_config::SdkConfig; +use aws_config::{Region, SdkConfig}; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::{BucketLocationConstraint, CreateBucketConfiguration}; use aws_sdk_s3::Client; @@ -19,6 +19,7 @@ pub struct AWSS3ValidatedArgs { pub struct AWSS3 { client: Client, bucket: String, + region: Region, } /// Implementation for AWS S3 client. Contains the function for : @@ -27,12 +28,13 @@ pub struct AWSS3 { impl AWSS3 { /// To init the struct with main settings pub async fn new_with_args(s3_config: &AWSS3ValidatedArgs, aws_config: &SdkConfig) -> Self { + let region = aws_config.region().expect("Missing region").clone(); // Building AWS S3 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)); let client = Client::from_conf(s3_config_builder.build()); - Self { client, bucket: s3_config.bucket_name.clone() } + Self { client, bucket: s3_config.bucket_name.clone(), region } } } @@ -80,11 +82,12 @@ impl DataStorage for AWSS3 { } async fn create_bucket(&self, bucket_name: &str) -> Result<()> { - let create_bucket_config = - Some(CreateBucketConfiguration::builder() - // TODO: assign region based on env - .location_constraint(BucketLocationConstraint::UsWest1) - .build()); + let region_string = self.region.to_string(); + let create_bucket_config = Some( + CreateBucketConfiguration::builder() + .location_constraint(BucketLocationConstraint::from(region_string.as_str())) + .build(), + ); self.client .create_bucket() diff --git a/crates/orchestrator/src/setup/mod.rs b/crates/orchestrator/src/setup/mod.rs index ab97ca29..286cfd93 100644 --- a/crates/orchestrator/src/setup/mod.rs +++ b/crates/orchestrator/src/setup/mod.rs @@ -44,8 +44,6 @@ pub async fn setup_cloud(setup_cmd: &SetupCmd) -> color_eyre::Result<()> { } println!("Queues setup completed ✅"); - sleep(Duration::from_secs(20)).await; - // Data Storage println!("Setting up data storage. ⏳"); let data_storage_params = setup_cmd.validate_storage_params().expect("Failed to validate storage params"); @@ -58,10 +56,23 @@ pub async fn setup_cloud(setup_cmd: &SetupCmd) -> color_eyre::Result<()> { } println!("Data storage setup completed ✅"); - sleep(Duration::from_secs(20)).await; + // Alerts + println!("Setting up alerts. ⏳"); + let alert_params = setup_cmd.validate_alert_params().expect("Failed to validate alert params"); + match alert_params { + AlertValidatedArgs::AWSSNS(aws_sns_params) => { + let aws_config = provider_config.get_aws_client_or_panic(); + let sns = Box::new(AWSSNS::new_with_args(&aws_sns_params, aws_config).await); + sns.setup().await? + } + } + + println!("Alerts setup completed ✅"); // Cron println!("Setting up cron. ⏳"); + // Sleeping for few seconds to let AWS index the newly created queues to be used for setting up cron + sleep(Duration::from_secs(60)).await; let cron_params = setup_cmd.validate_cron_params().expect("Failed to validate cron params"); match cron_params { CronValidatedArgs::AWSEventBridge(aws_event_bridge_params) => { @@ -72,20 +83,6 @@ pub async fn setup_cloud(setup_cmd: &SetupCmd) -> color_eyre::Result<()> { } println!("Cron setup completed ✅"); - sleep(Duration::from_secs(20)).await; - - // Alerts - println!("Setting up alerts. ⏳"); - let alert_params = setup_cmd.validate_alert_params().expect("Failed to validate alert params"); - match alert_params { - AlertValidatedArgs::AWSSNS(aws_sns_params) => { - let aws_config = provider_config.get_aws_client_or_panic(); - let sns = Box::new(AWSSNS::new_with_args(&aws_sns_params, aws_config).await); - sns.setup().await? - } - } - println!("Alerts setup completed ✅"); - Ok(()) } diff --git a/crates/orchestrator/src/workers/update_state.rs b/crates/orchestrator/src/workers/update_state.rs index 0e18bcaa..b6f28867 100644 --- a/crates/orchestrator/src/workers/update_state.rs +++ b/crates/orchestrator/src/workers/update_state.rs @@ -94,7 +94,7 @@ impl Worker for UpdateStateWorker { } } None => { - if blocks_to_process[0] != 0 && blocks_to_process[0] != 1 { + if blocks_to_process[0] != 0 { log::warn!("DA job for the first block is not yet completed. Returning safely..."); return Ok(()); } diff --git a/crates/prover-clients/atlantic-service/src/lib.rs b/crates/prover-clients/atlantic-service/src/lib.rs index 86c573b4..d10e11ba 100644 --- a/crates/prover-clients/atlantic-service/src/lib.rs +++ b/crates/prover-clients/atlantic-service/src/lib.rs @@ -69,7 +69,6 @@ impl ProverClient for AtlanticProverService { #[tracing::instrument(skip(self))] async fn get_task_status(&self, job_key: &str, fact: &str) -> Result { let res = self.atlantic_client.get_job_status(job_key).await?; - // TODO: match res.atlantic_query.status { AtlanticQueryStatus::InProgress => Ok(TaskStatus::Processing), AtlanticQueryStatus::Done => { @@ -84,10 +83,6 @@ impl ProverClient for AtlanticProverService { Ok(TaskStatus::Failed("Task failed while processing on Atlantic side".to_string())) } } - - // TODO: Commented the above code since, atlantic infra is not able - // to prove snos blocks currently so to run e2e tests returning Succeeded. - // Ok(TaskStatus::Succeeded) } } diff --git a/e2e-tests/tests.rs b/e2e-tests/tests.rs index 80800db5..6d10d7da 100644 --- a/e2e-tests/tests.rs +++ b/e2e-tests/tests.rs @@ -171,11 +171,14 @@ async fn test_orchestrator_workflow(#[case] l2_block_number: String) { println!("✅ Orchestrator setup completed."); - let trigger_rule_name = &get_env_var_or_panic("MADARA_ORCHESTRATOR_EVENT_BRIDGE_TRIGGER_RULE_NAME"); - let target_queue_name = &get_env_var_or_panic("MADARA_ORCHESTRATOR_EVENT_BRIDGE_TARGET_QUEUE_NAME"); + // let trigger_rule_name = + // &get_env_var_or_panic("MADARA_ORCHESTRATOR_EVENT_BRIDGE_TRIGGER_RULE_NAME"); + // let target_queue_name = + // &get_env_var_or_panic("MADARA_ORCHESTRATOR_EVENT_BRIDGE_TARGET_QUEUE_NAME"); // Setup eventbridge rules - create_eventbridge_rule(trigger_rule_name, target_queue_name).await.expect("Unable to create event bridge rule"); + // create_eventbridge_rule(trigger_rule_name, target_queue_name).await.expect("Unable to create + // event bridge rule"); // Run orchestrator let mut orchestrator = diff --git a/scripts/init_state.js b/scripts/init_state.js index 0c041972..a5cb3a09 100644 --- a/scripts/init_state.js +++ b/scripts/init_state.js @@ -852,4 +852,4 @@ async function main() { await setupMongoDb(block_number - 1); } -main(); +main(); \ No newline at end of file