Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion crates/dry_hint_processor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ strum_macros.workspace = true
syscall_handler.workspace = true
tokio.workspace = true
tracing.workspace = true
types.workspace = true
types.workspace = true
serde_json.workspace = true
7 changes: 7 additions & 0 deletions crates/dry_hint_processor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use crate::syscall_handler::{injected_state, unconstrained};

pub struct CustomHintProcessor {
inputs: HDPDryRunInput,
output_preimage_path: std::path::PathBuf,
builtin_hint_proc: BuiltinHintProcessor,
cairo1_builtin_hint_proc: Cairo1HintProcessor,
hints: HashMap<String, HintImpl>,
Expand All @@ -44,13 +45,18 @@ impl CustomHintProcessor {
pub fn new(inputs: HDPDryRunInput) -> Self {
Self {
inputs,
output_preimage_path: std::path::PathBuf::from("dry_run_output_preimage.json"),
builtin_hint_proc: BuiltinHintProcessor::new_empty(),
cairo1_builtin_hint_proc: Cairo1HintProcessor::new(Default::default(), Default::default(), true),
hints: Self::hints(),
extensive_hints: Self::extensive_hints(),
}
}

pub fn set_output_preimage_path(&mut self, path: std::path::PathBuf) {
self.output_preimage_path = path;
}

#[rustfmt::skip]
fn hints() -> HashMap<String, HintImpl> {
let mut hints = hints();
Expand Down Expand Up @@ -91,6 +97,7 @@ impl HintProcessorLogic for CustomHintProcessor {
let res = match hint_code {
crate::input::HINT_INPUT => self.hint_input(vm, exec_scopes, hpd, constants),
crate::output::HINT_OUTPUT => self.hint_output(vm, exec_scopes, hpd, constants),
crate::output::HINT_SAVE_OUTPUT_PREIMAGE => self.hint_save_output_preimage(vm, exec_scopes, hpd, constants),
_ => Err(HintError::UnknownHint(hint_code.to_string().into_boxed_str())),
};

Expand Down
61 changes: 58 additions & 3 deletions crates/dry_hint_processor/src/output.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
use std::collections::HashMap;

use cairo_vm::{
hint_processor::builtin_hint_processor::{
builtin_hint_processor_definition::HintProcessorData, hint_utils::get_relocatable_from_var_name,
hint_processor::{
builtin_hint_processor::{
builtin_hint_processor_definition::HintProcessorData,
hint_utils::{get_integer_from_var_name, get_relocatable_from_var_name},
},
hint_processor_utils::felt_to_usize,
},
types::exec_scope::ExecutionScopes,
types::{exec_scope::ExecutionScopes, relocatable::MaybeRelocatable},
vm::{errors::hint_errors::HintError, vm_core::VirtualMachine},
Felt252,
};
use hints::vars;
use serde_json;

use super::CustomHintProcessor;

pub const HINT_OUTPUT: &str = "print(\"result\", [hex(ids.result.low), hex(ids.result.high)])";
pub const HINT_SAVE_OUTPUT_PREIMAGE: &str = "save_output_preimage(ids.retdata, ids.retdata_size)";

impl CustomHintProcessor {
pub fn hint_output(
Expand All @@ -33,4 +39,53 @@ impl CustomHintProcessor {
println!("result: {}, {}", result[0], result[1]);
Ok(())
}

pub fn hint_save_output_preimage(
&mut self,
vm: &mut VirtualMachine,
_exec_scopes: &mut ExecutionScopes,
hint_data: &HintProcessorData,
_constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
let retdata_ptr = get_relocatable_from_var_name("retdata", vm, &hint_data.ids_data, &hint_data.ap_tracking)?;
let retdata_size = get_integer_from_var_name("retdata_size", vm, &hint_data.ids_data, &hint_data.ap_tracking)?;
let len = felt_to_usize(&retdata_size)?;

let cells = vm.get_continuous_range(retdata_ptr, len)?;

let mut values: Vec<Felt252> = Vec::new();
if len > 0 {
// Relocatable pointer at retdata[0]
let ptr = match &cells[0] {
MaybeRelocatable::RelocatableValue(ptr) => *ptr,
_ => {
return Err(HintError::CustomHint(
"Expected relocatable pointer at retdata[0]".to_owned().into_boxed_str(),
));
}
};
let slice = vm.get_continuous_range(ptr, len).map_err(HintError::Memory)?;
for el in slice.into_iter() {
match el {
MaybeRelocatable::Int(f) => values.push(f),
MaybeRelocatable::RelocatableValue(_) => {
return Err(HintError::CustomHint(
"Unexpected relocatable inside output array".to_owned().into_boxed_str(),
));
}
}
}
}

// Write directly to file using the path stored in the hint processor
let json_bytes = serde_json::to_vec(&values)
.map_err(|e| HintError::CustomHint(format!("Failed to serialize output preimage: {}", e).into_boxed_str()))?;
std::fs::write(&self.output_preimage_path, json_bytes).map_err(|e| {
HintError::CustomHint(
format!("Failed to write output preimage to {}: {}", self.output_preimage_path.display(), e).into_boxed_str(),
)
})?;

Ok(())
}
}
12 changes: 12 additions & 0 deletions crates/dry_run/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ pub struct Args {
help = "Path where the output JSON will be written"
)]
pub output: PathBuf,
#[arg(
long = "output_preimage",
default_value = "dry_run_output_preimage.json",
help = "Path where the output preimage JSON will be written"
)]
pub output_preimage: PathBuf,
#[arg(
long = "print_output",
default_value_t = false,
Expand All @@ -62,6 +68,7 @@ pub struct Args {
pub fn run(
program_path: PathBuf,
input: HDPDryRunInput,
output_preimage_path: PathBuf,
) -> Result<
(
SyscallHandler<
Expand All @@ -86,6 +93,10 @@ pub fn run(
let program = Program::from_bytes(&program_file, Some(cairo_run_config.entrypoint))?;

let mut hint_processor = CustomHintProcessor::new(input);

// Set output preimage path in execution scopes before running (will be used by the hint)
hint_processor.set_output_preimage_path(output_preimage_path.clone());

let mut cairo_runner = cairo_run_program(&program, &cairo_run_config, &mut hint_processor).map_err(Box::new)?;
debug!("{:?}", cairo_runner.get_execution_resources());

Expand Down Expand Up @@ -139,6 +150,7 @@ pub async fn run_with_args(args: Args) -> Result<(), Error> {
params,
injected_state,
},
args.output_preimage.clone(),
)?;

if args.print_output {
Expand Down
20 changes: 20 additions & 0 deletions crates/types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ pub const OPTIMISM_MAINNET_CHAIN_ID: u128 = 0xa;
pub const OPTIMISM_TESTNET_CHAIN_ID: u128 = 0xaa37dc;
pub const STARKNET_MAINNET_CHAIN_ID: u128 = 0x534e5f4d41494e;
pub const STARKNET_TESTNET_CHAIN_ID: u128 = 0x534e5f5345504f4c4941;
pub const ARBITRUM_MAINNET_CHAIN_ID: u128 = 0xa4b1;
pub const ARBITRUM_TESTNET_CHAIN_ID: u128 = 0x66eee;
pub const BASE_MAINNET_CHAIN_ID: u128 = 0x2105;
pub const BASE_TESTNET_CHAIN_ID: u128 = 0x14a34;

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct ProofsData {
Expand Down Expand Up @@ -111,6 +115,10 @@ pub enum ChainIds {
StarknetSepolia,
OptimismMainnet,
OptimismSepolia,
ArbitrumMainnet,
ArbitrumSepolia,
BaseMainnet,
BaseSepolia,
}

impl fmt::Display for ChainIds {
Expand All @@ -122,6 +130,10 @@ impl fmt::Display for ChainIds {
ChainIds::StarknetSepolia => write!(f, "starknet-sepolia"),
ChainIds::OptimismMainnet => write!(f, "optimism-mainnet"),
ChainIds::OptimismSepolia => write!(f, "optimism-sepolia"),
ChainIds::ArbitrumMainnet => write!(f, "arbitrum-mainnet"),
ChainIds::ArbitrumSepolia => write!(f, "arbitrum-sepolia"),
ChainIds::BaseMainnet => write!(f, "base-mainnet"),
ChainIds::BaseSepolia => write!(f, "base-sepolia"),
}
}
}
Expand All @@ -137,6 +149,10 @@ impl FromStr for ChainIds {
"starknet-sepolia" | "starknet_sepolia" | "starknetsepolia" => Ok(Self::StarknetSepolia),
"optimism-mainnet" | "optimism_mainnet" | "optimismmainnet" => Ok(Self::OptimismMainnet),
"optimism-sepolia" | "optimism_sepolia" | "optimismsepolia" => Ok(Self::OptimismSepolia),
"arbitrum-mainnet" | "arbitrum_mainnet" | "arbitrummainnet" => Ok(Self::ArbitrumMainnet),
"arbitrum-sepolia" | "arbitrum_sepolia" | "arbitrumsepolia" => Ok(Self::ArbitrumSepolia),
"base-mainnet" | "base_mainnet" | "basemainnet" => Ok(Self::BaseMainnet),
"base-sepolia" | "base_sepolia" | "basesepolia" => Ok(Self::BaseSepolia),
_ => Err(format!("Invalid chain ID: {}", s)),
}
}
Expand All @@ -151,6 +167,10 @@ impl ChainIds {
STARKNET_TESTNET_CHAIN_ID => Some(Self::StarknetSepolia),
OPTIMISM_MAINNET_CHAIN_ID => Some(Self::OptimismMainnet),
OPTIMISM_TESTNET_CHAIN_ID => Some(Self::OptimismSepolia),
ARBITRUM_MAINNET_CHAIN_ID => Some(Self::ArbitrumMainnet),
ARBITRUM_TESTNET_CHAIN_ID => Some(Self::ArbitrumSepolia),
BASE_MAINNET_CHAIN_ID => Some(Self::BaseMainnet),
BASE_TESTNET_CHAIN_ID => Some(Self::BaseSepolia),
_ => None,
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/contract_bootloader/contract_dry_run.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ func main{
let (leafs: Uint256*) = alloc();
felt_array_to_uint256s(counter=retdata_size, retdata=retdata, leafs=leafs);

%{ save_output_preimage(ids.retdata, ids.retdata_size) %}

with keccak_ptr {
let output_root = compute_merkle_root(leafs, retdata_size);
}
Expand Down
56 changes: 56 additions & 0 deletions src/utils/chain_info.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,62 @@ func fetch_chain_info(chain_id: felt) -> (info: ChainInfo) {
);
}

// Arbitrum Mainnet
if (chain_id == 42161) {
return (
info=ChainInfo(
id=42161,
id_bytes_len=2,
encoded_id=0x82A4B1,
encoded_id_bytes_len=3,
byzantium=0,
layout=Layout.EVM,
),
);
}

// Arbitrum Sepolia
if (chain_id == 421614) {
return (
info=ChainInfo(
id=421614,
id_bytes_len=3,
encoded_id=0x83066EEE,
encoded_id_bytes_len=4,
byzantium=0,
layout=Layout.EVM,
),
);
}

// Base Mainnet
if (chain_id == 8453) {
return (
info=ChainInfo(
id=8453,
id_bytes_len=2,
encoded_id=0x822105,
encoded_id_bytes_len=3,
byzantium=0,
layout=Layout.EVM,
),
);
}

// Base Sepolia
if (chain_id == 84532) {
return (
info=ChainInfo(
id=84532,
id_bytes_len=3,
encoded_id=0x83014A34,
encoded_id_bytes_len=4,
byzantium=0,
layout=Layout.EVM,
),
);
}

// SN_MAIN
if (chain_id == 23448594291968334) {
return (
Expand Down
Loading