diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 1cd7236..1b877f4 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -11,7 +11,8 @@ "customizations": { "vscode": { "extensions": [ - "1YiB.rust-bundle" + "1YiB.rust-bundle", + "vadimcn.vscode-lldb" ] } }, diff --git a/.github/docker/Dockerfile.prover b/.github/docker/Dockerfile.prover new file mode 100644 index 0000000..112927d --- /dev/null +++ b/.github/docker/Dockerfile.prover @@ -0,0 +1,18 @@ +# Declare the build argument before any FROM instructions +ARG PROVER_TAG + +# Use the build argument in the FROM instruction and name the stage with the version reference +FROM risczero/risc0-groth16-prover:${PROVER_TAG} AS prover + +# Start a new stage from scratch +FROM scratch +ARG PROVER_TAG +# Set the working directory +WORKDIR /${PROVER_TAG} + +# Copy files from the 'prover' stage +COPY --from=prover /app/stark_verify stark/prover.sh +COPY --from=prover /app/stark_verify stark/stark_verify +COPY --from=prover /app/stark_verify.dat stark/stark_verify.dat +COPY --from=prover /app/stark_verify_final.zkey stark/stark_verify_final.zkey +COPY --from=prover /usr/local/sbin/rapidsnark stark/rapidsnark diff --git a/.github/workflows/s3-prover-sync.yml b/.github/workflows/s3-prover-sync.yml new file mode 100644 index 0000000..12d030f --- /dev/null +++ b/.github/workflows/s3-prover-sync.yml @@ -0,0 +1,32 @@ +name: Sync Prover to S3 +on: + push: + tags: + - "*" + workflow_dispatch: +# Allow one concurrent deployment +env: + S3_BUCKET_NAME: "risc0-prover-us-east-1-041119533185" + AWS_REGION: "us-east-1" + PROVER_TAG: "v2024-05-17.1" +concurrency: + group: "sync-prover-to-s3-${{ env.PROVER_TAG }}" + cancel-in-progress: true +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + audience: sts.amazonaws.com.cn + aws-region: us-east-1 + role-to-assume: arn:aws:iam::041119533185:role/GithubBonsolCI + - name: Build Prover Artifact + run: | + docker build --progress=plain -f .github/docker/Dockerfile.prover -o risc0-groth16-prover . --build-arg PROVER_TAG=${PROVER_TAG} + - name: Sync S3 Bucket + run: | + aws s3 sync ./risc0-groth16-prover/ s3://${S3_BUCKET_NAME} --region ${{ env.AWS_REGION }} diff --git a/bin/install_prover.sh b/bin/install_prover.sh new file mode 100755 index 0000000..442a7f7 --- /dev/null +++ b/bin/install_prover.sh @@ -0,0 +1,94 @@ +#!/usr/bin/env bash + +set -e + +DEFAULT_PROVER_PROVIDER_URL="http://risc0-prover-us-east-1-041119533185.s3-website-us-east-1.amazonaws.com" +DEFAULT_INSTALL_PREFIX="/opt/risc0-prover" +DEFAULT_JOB_TIMEOUT=3600 +DEFAULT_VERSION="v2024-05-17.1" + +function parse_arguments() { + # Initialize variables with default values + PROVER_PROVIDER_URL="${DEFAULT_PROVER_PROVIDER_URL}" + INSTALL_PREFIX="${DEFAULT_INSTALL_PREFIX}" + JOB_TIMEOUT="${DEFAULT_JOB_TIMEOUT}" + PROVER_VERSION="${DEFAULT_VERSION}" + + # Loop through all arguments + while [[ "$#" -gt 0 ]]; do + case "$1" in + --help) + echo "Usage: $0 [--prefix ] [--prover-provider-url ]" + echo "Options:" + echo " --prefix Specify the install location." + echo " Default: $DEFAULT_INSTALL_PREFIX" + echo " --prover-provider-url URL of the prover provider to install." + echo " Default: $DEFAULT_PROVER_PROVIDER_URL" + echo " --job-timeout Timeout for the job in seconds." + echo " Default: $DEFAULT_JOB_TIMEOUT" + exit 0 + ;; + --prefix) + shift + if [[ -z "$1" ]]; then + echo "Error: --prefix requires a non-empty argument." + exit 1 + fi + INSTALL_PREFIX="$1" + ;; + --prover-provider-url) + shift + if [[ -z "$1" ]]; then + echo "Error: --prover-provider-url requires a non-empty argument." + exit 1 + fi + PROVER_PROVIDER_URL="$1" + ;; + --job-timeout) + shift + if [[ -z "$1" ]]; then + echo "Error: --job-timeout requires a non-empty argument." + exit 1 + fi + JOB_TIMEOUT="$1" + ;; + --version) + shift + if [[ -z "$1" ]]; then + echo "Error: --version requires a non-empty argument." + exit 1 + fi + PROVER_VERSION="$1" + ;; + *) + echo "Error: Unknown option '$1'" + echo "Use --help to see the usage." + exit 1 + ;; + esac + shift + done + + # Output the parsed values for confirmation + echo "PROVER_PROVIDER_URL is set to '$PROVER_PROVIDER_URL'" + echo "INSTALL_PREFIX is set to '$INSTALL_PREFIX'" + echo "JOB_TIMEOUT is set to '$JOB_TIMEOUT'" +} + +if [ ! -x $(which curl) ]; then + echo "Error: curl is required to download risc0-prover." + exit 1 +fi + +parse_arguments "$@" + +mkdir -p "${INSTALL_PREFIX}"/stark + +for stark_tech in stark/rapidsnark stark/stark_verify stark/stark_verify_final.zkey stark/stark_verify.dat; do + if [ ! -f "${INSTALL_PREFIX}/${stark_tech}" ]; then + echo "Downloading ${stark_tech} from ${PROVER_PROVIDER_URL}/${PROVER_VERSION}" + curl --max-time ${JOB_TIMEOUT} -o "${INSTALL_PREFIX}/${stark_tech}" "$PROVER_PROVIDER_URL/${PROVER_VERSION}/${stark_tech}" + else + echo "${INSTALL_PREFIX}$${stark_tech} already exists. Skipping download." + fi +done \ No newline at end of file diff --git a/node/src/ingest/mod.rs b/node/src/ingest/mod.rs index 4b5ce6e..c2f17d9 100644 --- a/node/src/ingest/mod.rs +++ b/node/src/ingest/mod.rs @@ -1,35 +1,29 @@ mod dragon; mod rpc; + use anyhow::Result; pub use {dragon::GrpcIngester, rpc::RpcIngester}; -use { - solana_sdk::pubkey::Pubkey, - std::{ - error::Error, - fmt::{self, Display, Formatter}, - }, - tokio::sync::mpsc::UnboundedReceiver, -}; - use crate::types::BonsolInstruction; +use solana_sdk::pubkey::Pubkey; +use tokio::sync::mpsc::UnboundedReceiver; + pub type TxChannel = UnboundedReceiver>; -#[derive(Debug)] + +#[derive(Debug, thiserror::Error)] pub enum IngestErrorType { + #[error("RPC Error")] RpcError, + #[error("I/O Error")] IoError, } -#[derive(Debug)] + +#[derive(Debug, thiserror::Error)] +#[error("IngestError: {code} - {message}")] pub struct IngestError { pub code: IngestErrorType, pub message: String, } -impl Display for IngestError { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "IngestError: {:?} - {:?}", self.code, self.message) - } -} -impl Error for IngestError {} pub type IngesterResult = Result<(), IngestError>; pub trait Ingester { @@ -37,3 +31,32 @@ pub trait Ingester { fn stop(&mut self) -> Result<()>; } + +#[cfg(test)] +mod test { + + #[test] + fn test_ingest_error_type_display() { + let rpc_error = super::IngestErrorType::RpcError; + let io_error = super::IngestErrorType::IoError; + + assert_eq!(rpc_error.to_string(), "RPC Error"); + assert_eq!(io_error.to_string(), "I/O Error"); + } + + #[test] + fn test_ingest_error_display() { + let rpc_error = super::IngestError { + code: super::IngestErrorType::RpcError, + message: "RPC failed".to_string(), + }; + + let io_error = super::IngestError { + code: super::IngestErrorType::IoError, + message: "I/O failed".to_string(), + }; + + assert_eq!(rpc_error.to_string(), "IngestError: RPC Error - RPC failed"); + assert_eq!(io_error.to_string(), "IngestError: I/O Error - I/O failed"); + } +}