Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement more libfuncs #3

Merged
merged 41 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
faa207d
progress
edg-l Aug 13, 2024
bb9da64
implement more libfuncs
edg-l Aug 14, 2024
2ed025d
progress
edg-l Aug 14, 2024
7697fad
progress
edg-l Aug 14, 2024
dd21f95
more libfuncs
edg-l Aug 14, 2024
b378a54
progress
edg-l Aug 16, 2024
b460614
progress
edg-l Aug 16, 2024
257fc8f
temp progress
edg-l Aug 16, 2024
7ccfcb6
progress
edg-l Aug 16, 2024
e3182e6
progress
edg-l Aug 16, 2024
c2f7da5
add makefile
edg-l Aug 19, 2024
18b4fcd
improve makefile
edg-l Aug 19, 2024
fce18da
gitignore json
edg-l Aug 19, 2024
adaa8fd
basic ci
edg-l Aug 19, 2024
fdaefe5
Merge remote-tracking branch 'origin/main' into progress
edg-l Aug 19, 2024
8e4589c
implement bool libfuncs
edg-l Aug 19, 2024
9bad2a7
fix ci
edg-l Aug 19, 2024
9ff8001
fix bool libfuncs
edg-l Aug 19, 2024
3363eb1
fix ci again
edg-l Aug 19, 2024
f5358b5
u128 from felt
edg-l Aug 19, 2024
d9c410a
fixes
edg-l Aug 19, 2024
c23c883
add contract execution result
edg-l Aug 19, 2024
21abd64
temp
edg-l Aug 20, 2024
8e85c06
add failing test
edg-l Aug 20, 2024
1abf41d
fix
edg-l Aug 20, 2024
ead1a15
implement more syscalls
edg-l Aug 20, 2024
7166e93
implement more syscalls
edg-l Aug 20, 2024
76f18bc
fix warns
edg-l Aug 20, 2024
a44627d
more libfuncs
edg-l Aug 20, 2024
839a92e
bytes31
edg-l Aug 20, 2024
c5dfb21
const libfuncs
edg-l Aug 20, 2024
c4706f2
fixes
edg-l Aug 21, 2024
b671b14
progress
edg-l Aug 22, 2024
d69c6dc
impl ec libfuncs
edg-l Aug 23, 2024
f4bf651
ec progress
edg-l Aug 23, 2024
ecae0eb
fix ec
edg-l Aug 23, 2024
e054744
impl call contract
edg-l Aug 23, 2024
f3ecce8
bitwise
edg-l Aug 26, 2024
d4cce3e
u16
edg-l Aug 26, 2024
f10b211
progress
edg-l Aug 26, 2024
89fb587
uint128 libfuncs
edg-l Aug 26, 2024
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
26 changes: 26 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Test

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

env:
CARGO_TERM_COLOR: always

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Retreive cached dependecies
uses: Swatinem/rust-cache@v2
- name: Deps
run: make deps
- name: Build
run: cargo build --all-features --verbose
- name: Run tests
run: make test
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,11 @@ Cargo.lock
*.pdb

# End of https://www.toptal.com/developers/gitignore/api/rust

cairo2/

corelib

*.tar

*.json
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ serde = { version = "1.0.204", features = ["derive"] }
serde_json = "1.0.121"
sha2 = { version = "0.10.8", features = ["compress"] }
smallvec = "1.13.2"
starknet-crypto = "0.7.1"
starknet-types-core = "0.1.2"
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
Expand Down
75 changes: 75 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
.PHONY: usage deps build check needs-cairo2 deps-macos build-cairo-2-compiler-macos decompress-cairo install-scarb clean

UNAME := $(shell uname)

CAIRO_2_VERSION=2.7.0
SCARB_VERSION = 2.7.0

needs-cairo2:
ifeq ($(wildcard ./cairo2/.),)
$(error You are missing the Starknet Cairo 1 compiler, please run 'make deps' to install the necessary dependencies.)
endif
./scripts/check-corelib-version.sh $(CAIRO_2_VERSION)

usage:
@echo "Usage:"
@echo " deps: Installs the necesarry dependencies."
@echo " build: Builds the cairo-native library and binaries."
@echo " check: Checks format and lints."
@echo " test: Runs all tests."
@echo " clean: Cleans the built artifacts."

build:
cargo build --release --all-features

check:
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings

test: needs-cairo2
cargo test --all-features

clean:
cargo clean

deps:
ifeq ($(UNAME), Linux)
deps: build-cairo-2-compiler install-scarb
endif
ifeq ($(UNAME), Darwin)
deps: deps-macos
endif
-rm -rf corelib
-ln -s cairo2/corelib corelib

deps-macos: build-cairo-2-compiler-macos install-scarb-macos

cairo-repo-2-dir = cairo2
cairo-repo-2-dir-macos = cairo2-macos

build-cairo-2-compiler-macos: | $(cairo-repo-2-dir-macos)

$(cairo-repo-2-dir-macos): cairo-${CAIRO_2_VERSION}-macos.tar
$(MAKE) decompress-cairo SOURCE=$< TARGET=cairo2/

build-cairo-2-compiler: | $(cairo-repo-2-dir)

$(cairo-repo-2-dir): cairo-${CAIRO_2_VERSION}.tar
$(MAKE) decompress-cairo SOURCE=$< TARGET=cairo2/

decompress-cairo:
rm -rf $(TARGET) \
&& tar -xzvf $(SOURCE) \
&& mv cairo/ $(TARGET)

cairo-%-macos.tar:
curl -L -o "$@" "https://github.com/starkware-libs/cairo/releases/download/v$*/release-aarch64-apple-darwin.tar"

cairo-%.tar:
curl -L -o "$@" "https://github.com/starkware-libs/cairo/releases/download/v$*/release-x86_64-unknown-linux-musl.tar.gz"

install-scarb:
curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh| sh -s -- --no-modify-path --version $(SCARB_VERSION)

install-scarb-macos:
curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh| sh -s -- --version $(SCARB_VERSION)
10 changes: 10 additions & 0 deletions scripts/check-corelib-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash

# Script to check the corelib version matches.

_result=$(grep "version = \"$1\"" corelib/Scarb.toml)

if [ $? -ne 0 ]; then
echo "corelib version mismatch, please re-run 'make deps'"
exit 1
fi
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,
})
}
}
9 changes: 8 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 @@ -171,6 +171,13 @@ mod test {
trace.push(StateDump::new(statement_idx, state));
}

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
1 change: 1 addition & 0 deletions src/starknet/secp256k1_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub struct Secp256k1Point {
}

impl Secp256k1Point {
#[allow(unused)]
pub(crate) fn into_value(self) -> Value {
Value::Struct(vec![
Value::U256(self.x.lo, self.x.hi),
Expand Down
1 change: 1 addition & 0 deletions src/starknet/secp256r1_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub struct Secp256r1Point {
}

impl Secp256r1Point {
#[allow(unused)]
pub(crate) fn into_value(self) -> Value {
Value::Struct(vec![
Value::U256(self.x.lo, self.x.hi),
Expand Down
1 change: 1 addition & 0 deletions src/starknet/u256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub struct U256 {
}

impl U256 {
#[allow(unused)]
pub(crate) fn into_value(self) -> Value {
Value::Struct(vec![Value::U128(self.lo), Value::U128(self.hi)])
}
Expand Down
23 changes: 12 additions & 11 deletions src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub enum Value {
Struct(Vec<Self>),
U128(u128),
U256(u128, u128),
U16(u16),
U32(u32),
U64(u64),
U8(u8),
Expand Down Expand Up @@ -99,29 +100,29 @@ impl Value {

// To do:
CoreTypeConcrete::Coupon(_) => todo!(),
CoreTypeConcrete::Bitwise(_) => todo!(),
CoreTypeConcrete::Box(_) => todo!(),
CoreTypeConcrete::Bitwise(_) => matches!(self, Self::Unit),
CoreTypeConcrete::Box(info) => self.is(registry, &info.ty),
CoreTypeConcrete::Circuit(_) => todo!(),
CoreTypeConcrete::Const(_) => todo!(),
CoreTypeConcrete::EcOp(_) => todo!(),
CoreTypeConcrete::EcPoint(_) => todo!(),
CoreTypeConcrete::EcState(_) => todo!(),
CoreTypeConcrete::BuiltinCosts(_) => todo!(),
CoreTypeConcrete::Uint16(_) => todo!(),
CoreTypeConcrete::Uint64(_) => todo!(),
CoreTypeConcrete::Uint128(_) => todo!(),
CoreTypeConcrete::Uint128MulGuarantee(_) => todo!(),
CoreTypeConcrete::BuiltinCosts(_) => matches!(self, Self::Unit),
CoreTypeConcrete::Uint16(_) => matches!(self, Self::U16(_)),
CoreTypeConcrete::Uint64(_) => matches!(self, Self::U64(_)),
CoreTypeConcrete::Uint128(_) => matches!(self, Self::U128(_)),
CoreTypeConcrete::Uint128MulGuarantee(_) => matches!(self, Self::Unit),
CoreTypeConcrete::Sint16(_) => todo!(),
CoreTypeConcrete::Sint32(_) => todo!(),
CoreTypeConcrete::Sint64(_) => todo!(),
CoreTypeConcrete::Sint128(_) => todo!(),
CoreTypeConcrete::Nullable(_) => todo!(),
CoreTypeConcrete::RangeCheck96(_) => todo!(),
CoreTypeConcrete::Nullable(info) => self.is(registry, &info.ty),
CoreTypeConcrete::RangeCheck96(_) => matches!(self, Self::Unit),
CoreTypeConcrete::Uninitialized(_) => todo!(),
CoreTypeConcrete::Felt252DictEntry(_) => todo!(),
CoreTypeConcrete::SquashedFelt252Dict(_) => todo!(),
CoreTypeConcrete::Pedersen(_) => todo!(),
CoreTypeConcrete::Poseidon(_) => todo!(),
CoreTypeConcrete::Pedersen(_) => matches!(self, Self::Unit),
CoreTypeConcrete::Poseidon(_) => matches!(self, Self::Unit),
CoreTypeConcrete::Span(_) => todo!(),
CoreTypeConcrete::StarkNet(inner) => match inner {
StarkNetTypeConcrete::ClassHash(_)
Expand Down
17 changes: 11 additions & 6 deletions src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use tracing::debug;

mod ap_tracking;
mod array;
mod bool;
mod bounded_int;
mod r#box;
mod branch_align;
Expand All @@ -35,16 +36,20 @@ mod function_call;
mod gas;
mod jump;
mod mem;
mod pedersen;
mod poseidon;
mod snapshot_take;
mod starknet;
mod r#struct;
mod u128;
edg-l marked this conversation as resolved.
Show resolved Hide resolved
mod uint32;
mod uint64;
mod uint8;

pub struct VirtualMachine<S: StarknetSyscallHandler = StubSyscallHandler> {
program: Arc<Program>,
registry: ProgramRegistry<CoreType, CoreLibfunc>,
syscall_handler: S,
pub syscall_handler: S,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally this shouldn't be pub. Instead we'd just assign it once then leave it assigned.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ill fix this on another pr

frames: Vec<SierraFrame>,
}

Expand Down Expand Up @@ -269,7 +274,7 @@ fn eval<'a>(
self::ap_tracking::eval(registry, selector, args)
}
CoreConcreteLibfunc::Array(selector) => self::array::eval(registry, selector, args),
CoreConcreteLibfunc::Bool(_) => todo!(),
CoreConcreteLibfunc::Bool(selector) => self::bool::eval(registry, selector, args),
CoreConcreteLibfunc::BoundedInt(selector) => {
self::bounded_int::eval(registry, selector, args)
}
Expand Down Expand Up @@ -297,8 +302,8 @@ fn eval<'a>(
CoreConcreteLibfunc::Gas(selector) => self::gas::eval(registry, selector, args),
CoreConcreteLibfunc::Mem(selector) => self::mem::eval(registry, selector, args),
CoreConcreteLibfunc::Nullable(_) => todo!(),
CoreConcreteLibfunc::Pedersen(_) => todo!(),
CoreConcreteLibfunc::Poseidon(_) => todo!(),
CoreConcreteLibfunc::Pedersen(selector) => self::pedersen::eval(registry, selector, args),
CoreConcreteLibfunc::Poseidon(selector) => self::poseidon::eval(registry, selector, args),
CoreConcreteLibfunc::Sint128(_) => todo!(),
CoreConcreteLibfunc::Sint16(_) => todo!(),
CoreConcreteLibfunc::Sint32(_) => todo!(),
Expand All @@ -309,12 +314,12 @@ fn eval<'a>(
self::starknet::eval(registry, selector, args, syscall_handler)
}
CoreConcreteLibfunc::Struct(selector) => self::r#struct::eval(registry, selector, args),
CoreConcreteLibfunc::Uint128(_) => todo!(),
CoreConcreteLibfunc::Uint128(selector) => self::u128::eval(registry, selector, args),
CoreConcreteLibfunc::Uint16(_) => todo!(),
CoreConcreteLibfunc::Uint256(_) => todo!(),
CoreConcreteLibfunc::Uint32(selector) => self::uint32::eval(registry, selector, args),
CoreConcreteLibfunc::Uint512(_) => todo!(),
CoreConcreteLibfunc::Uint64(_) => todo!(),
CoreConcreteLibfunc::Uint64(selector) => self::uint64::eval(registry, selector, args),
CoreConcreteLibfunc::Uint8(selector) => self::uint8::eval(registry, selector, args),
CoreConcreteLibfunc::UnconditionalJump(info) => self::jump::eval(registry, info, args),
CoreConcreteLibfunc::UnwrapNonZero(_) => todo!(),
Expand Down
Loading