Skip to content

Commit f9a3729

Browse files
committed
Add unified backend trait and polymorphic command dispatch
The changes introduce a new Backend trait that provides a common interface for Cairo and EVM proof system implementations, along with a factory pattern for creating backend instances. Command dispatching is updated to use this new abstraction.
1 parent f827d14 commit f9a3729

File tree

2 files changed

+100
-14
lines changed

2 files changed

+100
-14
lines changed

crates/bargo-core/src/backend.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//! Backend trait and factory for polymorphic proof system backends
2+
//!
3+
//! This module provides a unified interface for different proof system backends
4+
//! (Cairo/Starknet and EVM/Ethereum), allowing them to be used interchangeably
5+
//! through trait objects or concrete types.
6+
7+
use color_eyre::Result;
8+
9+
use crate::config::Config;
10+
11+
/// Trait for polymorphic backend implementations (Cairo, EVM, etc.)
12+
///
13+
/// This trait provides a unified interface for different proof system backends,
14+
/// allowing them to be used interchangeably through dynamic dispatch.
15+
pub trait Backend {
16+
/// Generate verifier contract and setup project structure
17+
fn generate(&self, cfg: &Config) -> Result<()>;
18+
19+
/// Generate proof using the backend's proof system
20+
fn prove(&self, cfg: &Config) -> Result<()>;
21+
22+
/// Verify a generated proof
23+
fn verify(&self, cfg: &Config) -> Result<()>;
24+
25+
/// Generate calldata for proof verification
26+
fn calldata(&self, cfg: &Config) -> Result<()>;
27+
28+
/// Deploy verifier contract to specified network
29+
///
30+
/// Note: Implementation varies by backend:
31+
/// - Cairo: Two-step process (declare contract to get class_hash, then deploy instance)
32+
/// - EVM: Single-step process (deploy contract directly to network)
33+
fn deploy(&self, cfg: &Config, network: Option<&str>) -> Result<()>;
34+
35+
/// Verify proof on-chain using deployed verifier
36+
fn verify_onchain(&self, cfg: &Config, address: Option<&str>) -> Result<()>;
37+
}
38+
39+
/// Backend type identifier for factory function
40+
#[derive(Debug, Clone, Copy)]
41+
pub enum BackendKind {
42+
/// Cairo/Starknet backend
43+
Cairo,
44+
/// EVM/Ethereum backend
45+
Evm,
46+
}
47+
48+
/// Factory function to create appropriate backend implementation
49+
///
50+
/// This function creates concrete backend implementations based on the backend kind,
51+
/// returning a boxed trait object that can be used polymorphically.
52+
///
53+
/// # Arguments
54+
/// * `backend_kind` - The backend kind (Cairo or EVM)
55+
///
56+
/// # Returns
57+
/// * `Box<dyn Backend>` - Boxed backend implementation
58+
///
59+
/// # Example
60+
/// ```ignore
61+
/// let backend = backend_for(BackendKind::Cairo);
62+
/// backend.generate(&config)?;
63+
/// ```
64+
pub fn backend_for(backend_kind: BackendKind) -> Box<dyn Backend> {
65+
use crate::commands::{cairo, evm};
66+
67+
match backend_kind {
68+
BackendKind::Cairo => Box::new(cairo::backend::CairoBackend::new()),
69+
BackendKind::Evm => Box::new(evm::backend::EvmBackend::new()),
70+
}
71+
}

crates/bargo-core/src/lib.rs

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@ use tracing::{info, warn};
55
mod backends;
66
mod util;
77

8+
pub mod backend;
89
pub mod cli;
910
pub mod commands;
1011
pub mod config;
1112

13+
use backend::{BackendKind, backend_for};
14+
1215
pub use cli::Cli;
1316
pub use config::Config;
1417

@@ -70,81 +73,93 @@ fn dispatch(cli: &Cli, cfg: &Config) -> Result<()> {
7073
if !cfg.quiet {
7174
print_banner("cairo gen");
7275
}
73-
commands::cairo::run_gen(cfg)
76+
let backend = backend_for(BackendKind::Cairo);
77+
backend.generate(cfg)
7478
}
7579
CairoCommands::Prove => {
7680
if !cfg.quiet {
7781
print_banner("cairo prove");
7882
}
79-
commands::cairo::run_prove(cfg)
83+
let backend = backend_for(BackendKind::Cairo);
84+
backend.prove(cfg)
8085
}
8186
CairoCommands::Verify => {
8287
if !cfg.quiet {
8388
print_banner("cairo verify");
8489
}
85-
commands::cairo::run_verify(cfg)
90+
let backend = backend_for(BackendKind::Cairo);
91+
backend.verify(cfg)
8692
}
8793
CairoCommands::Calldata => {
8894
if !cfg.quiet {
8995
print_banner("cairo calldata");
9096
}
91-
commands::cairo::run_calldata(cfg)
97+
let backend = backend_for(BackendKind::Cairo);
98+
backend.calldata(cfg)
9299
}
93100
CairoCommands::Declare { network } => {
94101
if !cfg.quiet {
95102
print_banner("cairo declare");
96103
}
97104
commands::cairo::run_declare(cfg, network)
98105
}
99-
CairoCommands::Deploy { class_hash } => {
106+
CairoCommands::Deploy { class_hash: _ } => {
100107
if !cfg.quiet {
101108
print_banner("cairo deploy");
102109
}
103-
commands::cairo::run_deploy(cfg, class_hash.as_deref())
110+
let backend = backend_for(BackendKind::Cairo);
111+
backend.deploy(cfg, None)
104112
}
105113
CairoCommands::VerifyOnchain { address } => {
106114
if !cfg.quiet {
107115
print_banner("cairo verify-onchain");
108116
}
109-
commands::cairo::run_verify_onchain(cfg, address.as_deref())
117+
let backend = backend_for(BackendKind::Cairo);
118+
backend.verify_onchain(cfg, address.as_deref())
110119
}
111120
},
112121
Commands::Evm { command } => match command {
113122
EvmCommands::Gen => {
114123
if !cfg.quiet {
115124
print_banner("evm gen");
116125
}
117-
commands::evm::run_gen(cfg)
126+
let backend = backend_for(BackendKind::Evm);
127+
backend.generate(cfg)
118128
}
119129
EvmCommands::Prove => {
120130
if !cfg.quiet {
121131
print_banner("evm prove");
122132
}
123-
commands::evm::run_prove(cfg)
133+
let backend = backend_for(BackendKind::Evm);
134+
backend.prove(cfg)
124135
}
125136
EvmCommands::Verify => {
126137
if !cfg.quiet {
127138
print_banner("evm verify");
128139
}
129-
commands::evm::run_verify(cfg)
140+
let backend = backend_for(BackendKind::Evm);
141+
backend.verify(cfg)
130142
}
131143
EvmCommands::Deploy { network } => {
132144
if !cfg.quiet {
133145
print_banner("evm deploy");
134146
}
135-
commands::evm::run_deploy(cfg, network)
147+
let backend = backend_for(BackendKind::Evm);
148+
backend.deploy(cfg, Some(network))
136149
}
137150
EvmCommands::Calldata => {
138151
if !cfg.quiet {
139152
print_banner("evm calldata");
140153
}
141-
commands::evm::run_calldata(cfg)
154+
let backend = backend_for(BackendKind::Evm);
155+
backend.calldata(cfg)
142156
}
143157
EvmCommands::VerifyOnchain => {
144158
if !cfg.quiet {
145159
print_banner("evm verify-onchain");
146160
}
147-
commands::evm::run_verify_onchain(cfg)
161+
let backend = backend_for(BackendKind::Evm);
162+
backend.verify_onchain(cfg, None)
148163
}
149164
},
150165
Commands::Doctor => {
@@ -157,7 +172,7 @@ fn dispatch(cli: &Cli, cfg: &Config) -> Result<()> {
157172
}
158173

159174
fn setup_logging(verbose: bool, quiet: bool) -> Result<()> {
160-
use tracing_subscriber::{fmt, EnvFilter};
175+
use tracing_subscriber::{EnvFilter, fmt};
161176

162177
if quiet {
163178
let subscriber = fmt()

0 commit comments

Comments
 (0)