Skip to content

Commit

Permalink
add contract execution result
Browse files Browse the repository at this point in the history
  • Loading branch information
edg-l committed Aug 19, 2024
1 parent d9c410a commit c23c883
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 1 deletion.
71 changes: 71 additions & 0 deletions src/dump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::value::Value;
use cairo_lang_sierra::{ids::VarId, program::StatementIdx};
use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
use serde::{ser::SerializeMap, Serialize};
use starknet_crypto::Felt;
use std::collections::BTreeMap;

#[derive(Clone, Debug, Default, Serialize)]
Expand Down Expand Up @@ -51,3 +52,73 @@ impl Serialize for StateDump {
s.end()
}
}

#[derive(Debug, Clone)]
pub struct ContractExecutionResult {
pub remaining_gas: u128,
pub failure_flag: bool,
pub return_values: Vec<Felt>,
pub error_msg: Option<String>,
}

impl ContractExecutionResult {
pub fn from_trace(trace: &ProgramTrace) -> Option<Self> {
let last = trace.states.last()?;

let mut remaining_gas = None;
let mut error_msg = None;
let mut failure_flag = false;
let mut return_values = Vec::new();

for value in last.items.values() {
match value {
Value::U128(gas) => remaining_gas = Some(*gas),
Value::Enum {
self_ty: _,
index,
payload,
} => {
failure_flag = (*index) != 0;

if let Value::Struct(inner) = &**payload {
if !failure_flag {
if let Value::Struct(inner) = &inner[0] {
if let Value::Array { ty: _, data } = &inner[0] {
for value in data.iter() {
if let Value::Felt(x) = value {
return_values.push(*x);
}
}
}
}
} else if let Value::Array { ty: _, data } = &inner[1] {
let mut error_felt_vec = Vec::new();
for value in data.iter() {
if let Value::Felt(x) = value {
error_felt_vec.push(*x);
}
}
let bytes_err: Vec<_> = error_felt_vec
.iter()
.flat_map(|felt| felt.to_bytes_be().to_vec())
// remove null chars
.filter(|b| *b != 0)
.collect();
let str_error = String::from_utf8(bytes_err).unwrap().to_owned();
error_msg = Some(str_error);
}
}
}
Value::Unit => {}
_ => None?,
}
}

Some(Self {
remaining_gas: remaining_gas.unwrap_or(0),
return_values,
error_msg,
failure_flag,
})
}
}
7 changes: 6 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ mod test {
use cairo_lang_compiler::CompilerConfig;
use cairo_lang_sierra::program::{GenFunction, Program, StatementIdx};
use cairo_lang_starknet::compile::compile_path;
use sierra_emu::{ProgramTrace, StateDump, VirtualMachine};
use sierra_emu::{ContractExecutionResult, ProgramTrace, StateDump, VirtualMachine};

#[test]
fn test_contract() {
Expand Down Expand Up @@ -173,6 +173,11 @@ mod test {

assert!(!vm.syscall_handler.storage.is_empty());

let result = ContractExecutionResult::from_trace(&trace).unwrap();
assert!(!result.failure_flag);
assert_eq!(result.return_values.len(), 0);
assert_eq!(result.error_msg, None);

// let trace_str = serde_json::to_string_pretty(&trace).unwrap();
// std::fs::write("contract_trace.json", trace_str).unwrap();
}
Expand Down

0 comments on commit c23c883

Please sign in to comment.