diff --git a/Cargo.lock b/Cargo.lock index b878c6f..92d5d33 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -285,6 +285,17 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "async-trait" +version = "0.1.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.32", +] + [[package]] name = "auto_impl" version = "1.1.0" @@ -429,6 +440,7 @@ version = "0.1.0" dependencies = [ "alloy-primitives", "anyhow", + "async-trait", "cannon-mipsevm", "clap", "flate2", diff --git a/bin/Cargo.toml b/bin/Cargo.toml index c3ab49a..11a85ad 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -17,6 +17,7 @@ serde_json = "1.0.107" alloy-primitives = "0.3.3" tokio = { version = "1.32.0", features = ["macros"] } flate2 = "1.0.27" +async-trait = "0.1.73" # Local cannon-mipsevm = { path = "../crates/mipsevm" } diff --git a/bin/src/cannon.rs b/bin/src/cannon.rs index 493a09e..9e03e9f 100644 --- a/bin/src/cannon.rs +++ b/bin/src/cannon.rs @@ -19,7 +19,8 @@ struct Args { subcommand: subcommands::CannonSubcommand, } -fn main() -> Result<()> { +#[tokio::main] +async fn main() -> Result<()> { // Parse the command arguments let Args { v, subcommand } = Args::parse(); @@ -27,7 +28,7 @@ fn main() -> Result<()> { init_tracing_subscriber(v)?; tracing::debug!(target: "cannon-cli", "Dispatching subcommand"); - subcommand.dispatch()?; + subcommand.dispatch().await?; Ok(()) } diff --git a/bin/src/compressor.rs b/bin/src/compressor.rs index ce02414..aafc0cd 100644 --- a/bin/src/compressor.rs +++ b/bin/src/compressor.rs @@ -2,7 +2,7 @@ use anyhow::Result; use flate2::{bufread::GzDecoder, write::GzEncoder, Compression}; -use std::io::{Cursor, Read, Write}; +use std::io::{Read, Write}; /// Compresses a byte slice using gzip. pub(crate) fn compress_bytes(bytes: &[u8]) -> Result> { @@ -13,11 +13,10 @@ pub(crate) fn compress_bytes(bytes: &[u8]) -> Result> { /// Decompresses a byte slice using gzip. pub(crate) fn decompress_bytes(compressed_bytes: &[u8]) -> Result> { - let cursor = Cursor::new(compressed_bytes); - let mut decoder = GzDecoder::new(cursor); + let mut decoder = GzDecoder::new(compressed_bytes); - // Give our decompressed buffer the same capacity as the compressed buffer. It'll still - // reallocate, but less. + // Give our decompressed buffer the same capacity as the compressed buffer to reduce + // reallocations up to the compressed buffer's size. let mut decompressed_bytes = Vec::with_capacity(compressed_bytes.len()); decoder.read_to_end(&mut decompressed_bytes)?; diff --git a/bin/src/subcommands/load_elf.rs b/bin/src/subcommands/load_elf.rs index bf35e59..93fc22a 100644 --- a/bin/src/subcommands/load_elf.rs +++ b/bin/src/subcommands/load_elf.rs @@ -4,6 +4,7 @@ use crate::compressor::compress_bytes; use super::CannonSubcommandDispatcher; use anyhow::Result; +use async_trait::async_trait; use cannon_mipsevm::{load_elf, patch_go, patch_stack}; use clap::{builder::PossibleValue, Args, ValueEnum}; use std::{fs, path::PathBuf}; @@ -45,8 +46,9 @@ impl ValueEnum for PatchKind { } } +#[async_trait] impl CannonSubcommandDispatcher for LoadElfArgs { - fn dispatch(&self) -> Result<()> { + async fn dispatch(&self) -> Result<()> { tracing::info!(target: "cannon-cli::load-elf", "Loading ELF file @ {}", self.path.display()); let elf_raw = fs::read(&self.path)?; let mut state = load_elf(&elf_raw)?; diff --git a/bin/src/subcommands/mod.rs b/bin/src/subcommands/mod.rs index 5f42f15..68ff111 100644 --- a/bin/src/subcommands/mod.rs +++ b/bin/src/subcommands/mod.rs @@ -1,15 +1,17 @@ //! Subcommands for the `cannon` binary use anyhow::Result; +use async_trait::async_trait; use clap::Subcommand; mod load_elf; mod run; mod witness; +#[async_trait] pub(crate) trait CannonSubcommandDispatcher { /// Dispatches the subcommand - fn dispatch(&self) -> Result<()>; + async fn dispatch(&self) -> Result<()>; } /// The subcommands for the `cannon` binary @@ -20,13 +22,14 @@ pub(crate) enum CannonSubcommand { LoadElf(load_elf::LoadElfArgs), } +#[async_trait] impl CannonSubcommandDispatcher for CannonSubcommand { /// TODO(clabby): Dynamic dispatch on Box - fn dispatch(&self) -> Result<()> { + async fn dispatch(&self) -> Result<()> { match self { - CannonSubcommand::Run(args) => args.dispatch(), - CannonSubcommand::Witness(args) => args.dispatch(), - CannonSubcommand::LoadElf(args) => args.dispatch(), + CannonSubcommand::Run(args) => args.dispatch().await, + CannonSubcommand::Witness(args) => args.dispatch().await, + CannonSubcommand::LoadElf(args) => args.dispatch().await, } } } diff --git a/bin/src/subcommands/run.rs b/bin/src/subcommands/run.rs index 2dcef59..3188ce3 100644 --- a/bin/src/subcommands/run.rs +++ b/bin/src/subcommands/run.rs @@ -2,6 +2,7 @@ use super::CannonSubcommandDispatcher; use anyhow::Result; +use async_trait::async_trait; use clap::Args; /// Command line arguments for `cannon run` @@ -50,8 +51,9 @@ pub(crate) struct RunArgs { l2_endpoint: String, } +#[async_trait] impl CannonSubcommandDispatcher for RunArgs { - fn dispatch(&self) -> Result<()> { + async fn dispatch(&self) -> Result<()> { todo!() } } diff --git a/bin/src/subcommands/witness.rs b/bin/src/subcommands/witness.rs index 3b0e396..e6e6fc2 100644 --- a/bin/src/subcommands/witness.rs +++ b/bin/src/subcommands/witness.rs @@ -4,6 +4,7 @@ use super::CannonSubcommandDispatcher; use crate::compressor::decompress_bytes; use alloy_primitives::B256; use anyhow::Result; +use async_trait::async_trait; use cannon_mipsevm::{State, StateWitnessHasher}; use clap::Args; use std::{fs, path::PathBuf}; @@ -21,8 +22,9 @@ pub(crate) struct WitnessArgs { output: Option, } +#[async_trait] impl CannonSubcommandDispatcher for WitnessArgs { - fn dispatch(&self) -> Result<()> { + async fn dispatch(&self) -> Result<()> { tracing::info!(target: "cannon-cli::witness", "Loading state JSON dump from {}", self.input.display()); let state_raw = fs::read(&self.input)?;