Skip to content

Commit

Permalink
Cairo v0.12.0a0 (pre).
Browse files Browse the repository at this point in the history
  • Loading branch information
liorgold2 committed Jun 28, 2023
1 parent 361fe32 commit 3a32740
Show file tree
Hide file tree
Showing 126 changed files with 10,580 additions and 5,562 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
FROM ciimage/python:3.9
RUN sed -i -e 's|http://archive\.ubuntu\.com/ubuntu/|mirror://mirrors.ubuntu.com/mirrors.txt|' /etc/apt/sources.list

COPY ./docker_common_deps.sh /app/
WORKDIR /app/
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ We recommend starting from [Setting up the environment](https://cairo-lang.org/d
# Installation instructions

You should be able to download the python package zip file directly from
[github](https://github.com/starkware-libs/cairo-lang/releases/tag/v0.11.2)
[github](https://github.com/starkware-libs/cairo-lang/releases/tag/v0.12.0)
and install it using ``pip``.
See [Setting up the environment](https://cairo-lang.org/docs/quickstart.html).

Expand Down Expand Up @@ -54,7 +54,7 @@ Once the docker image is built, you can fetch the python package zip file using:

```bash
> container_id=$(docker create cairo)
> docker cp ${container_id}:/app/cairo-lang-0.11.2.zip .
> docker cp ${container_id}:/app/cairo-lang-0.12.0.zip .
> docker rm -v ${container_id}
```

6 changes: 3 additions & 3 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ http_archive(
)

http_archive(
name = "cairo-compiler-archive-1.1.0",
name = "cairo-compiler-archive-2.0.0",
build_file = get_from_cairo_lang(
"//src/starkware/starknet/compiler/v1:BUILD.cairo-compiler-archive-1.1.0",
"//src/starkware/starknet/compiler/v1:BUILD.cairo-compiler-archive",
),
strip_prefix = "cairo",
url = "https://github.com/starkware-libs/cairo/releases/download/v1.1.0/release-x86_64-unknown-linux-musl.tar.gz",
url = "https://github.com/starkware-libs/cairo/releases/download/v2.0.0-rc5/release-x86_64-unknown-linux-musl.tar.gz",
)

http_archive(
Expand Down
30 changes: 26 additions & 4 deletions bazel_utils/python.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,45 @@ def pytest_test(
Calls pytest.
"""

if "timeout" not in kwargs:
kwargs["timeout"] = "eternal"
# Set the test timeout to 'eternal' if it isn't already set.
timeout = kwargs.pop("timeout", "eternal")

(pypy_test if is_pypy else cpython_test)(
test_and_debug_targets(
name = name,
srcs = [
"//bazel_utils:pytest_wrapper.py",
] + srcs,
main = "//bazel_utils:pytest_wrapper.py",
# Args passed to the tests using parser.addoption() need to be sent after the tested
# files so pytest recognizes them.
args = ["$(location :%s)" % x for x in srcs] + ["--color=yes"] + args,
args = [
"$(location :%s)" % x
for x in srcs
] + ["--color=yes", "--junitxml=$$XML_OUTPUT_FILE"] + args,
python_version = "PY3",
srcs_version = "PY3",
deps = deps + [requirement("pytest"), "//:starkware"],
data = data,
timeout = timeout,
legacy_create_init = legacy_create_init,
is_pypy = is_pypy,
**kwargs
)

def test_and_debug_targets(name, srcs, timeout, is_pypy, **kwargs):
"""
Creates both a test target and a binary target with the same content, for debugging purposes.
"""
(pypy_test if is_pypy else cpython_test)(
name = name,
srcs = srcs,
timeout = timeout,
**kwargs
)

(pypy_binary if is_pypy else cpython_binary)(
name = name + "-debug",
srcs = srcs,
**kwargs
)

Expand Down
16 changes: 16 additions & 0 deletions src/services/utils/http_status_code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from enum import Enum


class HttpStatusCode(Enum):
"""
See HTTP status codes in Wikipedia: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes.
"""

# Success.
OK = 200

# Client Errors.
BAD_REQUEST = 400

# Server Errors.
INTERNAL_SERVER_ERROR = 500
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"program_hash": "0x4be98ab4e3f3d142b0323d537a98b1f3c9886e142c83d9c2125a718cbac41d4"
"program_hash": "0x271bc26265915a6fb21e99388451ef7491c5ec3229546381a7e2b581ecb699a"
}
24 changes: 21 additions & 3 deletions src/starkware/cairo/common/structs.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List, MutableMapping, NamedTuple, Optional
from typing import List, MutableMapping, NamedTuple, Optional, Union

from starkware.cairo.lang.compiler.ast.cairo_types import (
CairoType,
Expand All @@ -17,6 +17,7 @@
)
from starkware.cairo.lang.compiler.program import Program
from starkware.cairo.lang.compiler.scoped_name import ScopedName
from starkware.cairo.lang.vm.relocatable import MaybeRelocatable
from starkware.python.utils import WriteOnceDict


Expand Down Expand Up @@ -151,6 +152,17 @@ def structs(self):
"""
return CairoStructProxy(self, ScopedName())

def from_type_and_ptr(
self, cairo_type: CairoType, memory, addr
) -> Union[NamedTuple, MaybeRelocatable]:
if isinstance(cairo_type, TypeStruct):
return CairoStructProxy(factory=self, path=cairo_type.scope).from_ptr(memory, addr)

assert isinstance(
cairo_type, (TypeFelt, TypeCodeoffset, TypePointer)
), f"Unsupported Cairo type {cairo_type}."
return memory[addr]


class CairoStructProxy:
"""
Expand Down Expand Up @@ -184,7 +196,13 @@ def from_ptr(self, memory, addr):
namedtuple instance.
"""
named_tuple = self.build()

return named_tuple(
**{name: memory[addr + index] for index, name in enumerate(named_tuple._fields)}
**{
name: self.factory.from_type_and_ptr(
member_def.cairo_type,
memory=memory,
addr=addr + member_def.offset,
)
for name, member_def in self.struct_definition_.members.items()
}
)
41 changes: 40 additions & 1 deletion src/starkware/cairo/common/uint256.cairo
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
from starkware.cairo.common.bitwise import bitwise_and, bitwise_or, bitwise_xor
from starkware.cairo.common.cairo_builtins import BitwiseBuiltin
from starkware.cairo.common.math import assert_in_range, assert_le, assert_nn_le, assert_not_zero
from starkware.cairo.common.math import (
assert_in_range,
assert_le,
assert_nn_le,
assert_not_zero,
split_felt,
)
from starkware.cairo.common.math_cmp import is_le
from starkware.cairo.common.pow import pow
from starkware.cairo.common.registers import get_ap, get_fp_and_pc
Expand All @@ -25,6 +31,39 @@ func uint256_check{range_check_ptr}(a: Uint256) {
return ();
}

// Converters.

// Converts a Uint256 value in the range [0, PRIME) to a felt. Fails if value is out of range.
func uint256_to_felt{range_check_ptr}(value: Uint256) -> felt {
// The maximal accepted value is PRIME - 1 = -1 = 2**251 + 17 * 2**192 =
// SHIFT * (2**123 + 17*2**64).
// Denote HIGH_PART = -1 / SHIFT.
// If value.low = 0 then value is valid only if value.high <= HIGH_PART.
// Otherwise, value is valid if value.high <= HIGH_PART - 1.

const HIGH_PART = (-1) / SHIFT;
// Derive the upper bound based on value.low.
if (value.low == 0) {
tempvar high_part_max_value = HIGH_PART;
} else {
tempvar high_part_max_value = HIGH_PART - 1;
}

with_attr error_message("OUT_OF_RANGE_UINT256_VALUE") {
// Assert value.high <= high_part_max_value.
assert [range_check_ptr] = high_part_max_value - value.high;
let range_check_ptr = range_check_ptr + 1;
}
// Express the value as felt.
return value.high * SHIFT + value.low;
}

// Converts a felt to a uint256.
func felt_to_uint256{range_check_ptr}(value: felt) -> Uint256 {
let (high, low) = split_felt(value=value);
return (Uint256(low=low, high=high));
}

// Arithmetics.

// Adds two integers. Returns the result as a 256-bit integer and the (1-bit) carry.
Expand Down
1 change: 1 addition & 0 deletions src/starkware/cairo/lang/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ py_library(
] + CAIRO_INSTANCES_LIB_ADDITIONAL_FILES,
visibility = ["//visibility:public"],
deps = [
"//src/starkware/cairo/lang/builtins:cairo_all_builtins_lib",
"//src/starkware/cairo/lang/builtins:cairo_run_builtins_lib",
],
)
Expand Down
2 changes: 1 addition & 1 deletion src/starkware/cairo/lang/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.11.2
0.12.0a0
1 change: 1 addition & 0 deletions src/starkware/cairo/lang/builtins/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package(default_visibility = ["//visibility:public"])
py_library(
name = "cairo_run_builtins_lib",
srcs = [
"instance_def.py",
"//src/starkware/cairo/lang/builtins/bitwise:bitwise_builtin_runner.py",
"//src/starkware/cairo/lang/builtins/bitwise:instance_def.py",
"//src/starkware/cairo/lang/builtins/ec:ec_op_builtin_runner.py",
Expand Down
3 changes: 3 additions & 0 deletions src/starkware/cairo/lang/builtins/all_builtins.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,6 @@ def with_suffix(self):
POSEIDON_BUILTIN,
]
)


SUPPORTED_DYNAMIC_BUILTINS = ALL_BUILTINS.except_for(KECCAK_BUILTIN)
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,7 @@ def air_private_input(self, runner) -> Dict[str, Any]:
return {"bitwise": sorted(res.values(), key=lambda item: item["index"])}

def get_used_diluted_check_units(self, diluted_spacing: int, diluted_n_bits: int) -> int:
total_n_bits = self.bitwise_builtin.total_n_bits

partition = [
i + j
for i in range(0, total_n_bits, diluted_spacing * diluted_n_bits)
for j in range(diluted_spacing)
if i + j < total_n_bits
]
num_trimmed = len(
[
1
for shift in partition
if shift + diluted_spacing * (diluted_n_bits - 1) + 1 > total_n_bits
]
return self.bitwise_builtin.get_diluted_units_per_builtin(
diluted_spacing=diluted_spacing,
diluted_n_bits=diluted_n_bits,
)
return 4 * len(partition) + num_trimmed
38 changes: 29 additions & 9 deletions src/starkware/cairo/lang/builtins/bitwise/instance_def.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,45 @@
import dataclasses
from typing import Optional

from starkware.cairo.lang.builtins.instance_def import BuiltinInstanceDef

# Each bitwise operation consists of 5 cells (two inputs and three outputs - and, or, xor).
CELLS_PER_BITWISE = 5
HEIGHT = 64
INPUT_CELLS_PER_BITWISE = 2


@dataclasses.dataclass
class BitwiseInstanceDef:
# Defines the ratio between the number of steps to the number of bitwise instances.
# For every ratio steps, we have one instance.
# None means dynamic ratio.
ratio: Optional[int]

class BitwiseInstanceDef(BuiltinInstanceDef):
# The number of bits in a single field element that are supported by the bitwise builtin.
total_n_bits: int

@property
def cells_per_builtin(self):
def cells_per_builtin(self) -> int:
return CELLS_PER_BITWISE

@property
def range_check_units_per_builtin(self):
def range_check_units_per_builtin(self) -> int:
return 0

@property
def invocation_height(self) -> int:
return HEIGHT

def get_diluted_units_per_builtin(self, diluted_spacing: int, diluted_n_bits: int) -> int:
"""
Calculates the number of diluted check units used by one bitwise builtin.
"""
partition = [
i + j
for i in range(0, self.total_n_bits, diluted_spacing * diluted_n_bits)
for j in range(diluted_spacing)
if i + j < self.total_n_bits
]
num_trimmed = len(
[
1
for shift in partition
if shift + diluted_spacing * (diluted_n_bits - 1) + 1 > self.total_n_bits
]
)
return 4 * len(partition) + num_trimmed
20 changes: 12 additions & 8 deletions src/starkware/cairo/lang/builtins/ec/instance_def.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
import dataclasses
from typing import Optional

from starkware.cairo.lang.builtins.instance_def import BuiltinInstanceDef

# Each EC operation P + m * Q = R contains 7 cells: P_x, P_y, Q_x, Q_y, m, R_x, R_y.
CELLS_PER_EC_OP = 7
INPUT_CELLS_PER_EC_OP = 5


@dataclasses.dataclass
class EcOpInstanceDef:
# Defines the ratio between the number of steps to the number of EC op instances.
# For every ratio steps, we have one instance.
# None means dynamic ratio.
ratio: Optional[int]

class EcOpInstanceDef(BuiltinInstanceDef):
# Size of coefficient.
scalar_height: int
scalar_bits: int
# The upper bound on the multiplication scalar, m. If None, the upper bound is 2^scalar_bits.
scalar_limit: Optional[int] = None

@property
def cells_per_builtin(self):
def cells_per_builtin(self) -> int:
return CELLS_PER_EC_OP

@property
def range_check_units_per_builtin(self):
def range_check_units_per_builtin(self) -> int:
return 0

@property
def invocation_height(self) -> int:
return self.scalar_height

def get_diluted_units_per_builtin(self, diluted_spacing: int, diluted_n_bits: int) -> int:
return 0
20 changes: 12 additions & 8 deletions src/starkware/cairo/lang/builtins/hash/instance_def.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import dataclasses
from typing import Optional

from starkware.cairo.lang.builtins.instance_def import BuiltinInstanceDef

# Each hash consists of 3 cells (two inputs and one output).
CELLS_PER_HASH = 3
INPUT_CELLS_PER_HASH = 2


@dataclasses.dataclass
class PedersenInstanceDef:
# Defines the ratio between the number of steps to the number of pedersen instances.
# For every ratio steps, we have one instance.
# None means dynamic ratio.
ratio: Optional[int]

class PedersenInstanceDef(BuiltinInstanceDef):
# Split to this many different components - for optimization.
repetitions: int

Expand All @@ -25,9 +22,16 @@ class PedersenInstanceDef:
hash_limit: Optional[int] = None

@property
def cells_per_builtin(self):
def cells_per_builtin(self) -> int:
return CELLS_PER_HASH

@property
def range_check_units_per_builtin(self):
def range_check_units_per_builtin(self) -> int:
return 0

@property
def invocation_height(self) -> int:
return self.element_height * self.n_inputs

def get_diluted_units_per_builtin(self, diluted_spacing: int, diluted_n_bits: int) -> int:
return 0
Loading

0 comments on commit 3a32740

Please sign in to comment.