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

Bootloader #3

Merged
merged 7 commits into from
Apr 19, 2024
Merged
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 .cairofmtignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cairo/
11 changes: 7 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ members = [
"crates/delegator",
"crates/executor",
"crates/peer",
"crates/prover",
"crates/prover", "crates/runner",
]
exclude = []

Expand All @@ -28,18 +28,21 @@ futures-core = "0.3.30"
futures-util = "0.3.30"
hex = "0.4.3"
itertools = "0.12.1"
libp2p = { version = "0.53.2", features = ["tokio","gossipsub","kad","mdns","noise","macros","tcp","yamux","quic"]}
libp2p = { version = "0.53.2", features = ["secp256k1", "tokio","gossipsub","kad","mdns","noise","macros","tcp","yamux","quic"]}
libsecp256k1 = "0.7.1"
num-bigint = "0.4.4"
serde = "1.0.197"
serde_json = "1.0.115"
starknet = "0.10.0"
starknet = "0.9.0"
strum = { version = "0.26", features = ["derive"] }
tempfile = "3.10.1"
thiserror = "1.0.58"
tokio = { version = "1.36", features = ["full"] }
tokio-util = "0.7.10"
tracing = "0.1.37"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
cairo1-run = { git = "https://github.com/iosis-tech/cairo-vm", rev = "091e1b3acf62a6e6baa9784105ae1125231b29e7"}
zip-extensions = "0.6.2"


sharp-p2p-common = { path = "crates/common" }
sharp-p2p-delegator = { path = "crates/delegator" }
Expand Down
162 changes: 162 additions & 0 deletions cairo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock

# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

!/lang/compiler/lib/
Empty file added cairo/bootloader/__init__.py
Empty file.
55 changes: 55 additions & 0 deletions cairo/bootloader/hash_program.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import argparse
import json

from starkware.cairo.common.hash_chain import compute_hash_chain
from starkware.cairo.lang.compiler.program import Program, ProgramBase
from starkware.cairo.lang.version import __version__
from starkware.cairo.lang.vm.crypto import get_crypto_lib_context_manager, poseidon_hash_many
from starkware.python.utils import from_bytes


def compute_program_hash_chain(program: ProgramBase, use_poseidon: bool, bootloader_version=0):
"""
Computes a hash chain over a program, including the length of the data chain.
"""
builtin_list = [from_bytes(builtin.encode("ascii")) for builtin in program.builtins]
# The program header below is missing the data length, which is later added to the data_chain.
program_header = [bootloader_version, program.main, len(program.builtins)] + builtin_list
data_chain = program_header + program.data

if use_poseidon:
return poseidon_hash_many(data_chain)
return compute_hash_chain([len(data_chain)] + data_chain)


def main():
parser = argparse.ArgumentParser(description="A tool to compute the hash of a cairo program")
parser.add_argument("-v", "--version", action="version", version=f"%(prog)s {__version__}")
parser.add_argument(
"--program",
type=argparse.FileType("r"),
required=True,
help="The name of the program json file.",
)
parser.add_argument(
"--flavor",
type=str,
default="Release",
choices=["Debug", "Release", "RelWithDebInfo"],
help="Build flavor",
)
parser.add_argument(
"--use_poseidon",
type=bool,
default=False,
help="Use Poseidon hash.",
)
args = parser.parse_args()

with get_crypto_lib_context_manager(args.flavor):
program = Program.Schema().load(json.load(args.program))
print(hex(compute_program_hash_chain(program=program, use_poseidon=args.use_poseidon)))


if __name__ == "__main__":
main()
97 changes: 97 additions & 0 deletions cairo/bootloader/objects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import dataclasses
from abc import abstractmethod
from dataclasses import field
from typing import ClassVar, Dict, List, Optional, Type

import marshmallow
import marshmallow.fields as mfields
import marshmallow_dataclass
from marshmallow_oneofschema import OneOfSchema

from starkware.cairo.lang.compiler.program import Program, ProgramBase, StrippedProgram
from starkware.cairo.lang.vm.cairo_pie import CairoPie
from starkware.starkware_utils.marshmallow_dataclass_fields import additional_metadata
from starkware.starkware_utils.validated_dataclass import ValidatedMarshmallowDataclass


class TaskSpec(ValidatedMarshmallowDataclass):
"""
Contains task's specification.
"""

@abstractmethod
def load_task(self) -> "Task":
"""
Returns the corresponding task.
"""


class Task:
@abstractmethod
def get_program(self) -> ProgramBase:
"""
Returns the task's Cairo program.
"""


@marshmallow_dataclass.dataclass(frozen=True)
class RunProgramTask(TaskSpec, Task):
TYPE: ClassVar[str] = "RunProgramTask"
program: Program
program_input: dict
use_poseidon: bool

def get_program(self) -> Program:
return self.program

def load_task(self) -> "Task":
return self


@marshmallow_dataclass.dataclass(frozen=True)
class CairoPiePath(TaskSpec):
TYPE: ClassVar[str] = "CairoPiePath"
path: str
use_poseidon: bool

def load_task(self) -> "CairoPieTask":
"""
Loads the PIE to memory.
"""
return CairoPieTask(cairo_pie=CairoPie.from_file(self.path), use_poseidon=self.use_poseidon)


class TaskSchema(OneOfSchema):
"""
Schema for Task/CairoPiePath.
OneOfSchema adds a "type" field.
"""

type_schemas: Dict[str, Type[marshmallow.Schema]] = {
RunProgramTask.TYPE: RunProgramTask.Schema,
CairoPiePath.TYPE: CairoPiePath.Schema,
}

def get_obj_type(self, obj):
return obj.TYPE


@dataclasses.dataclass(frozen=True)
class CairoPieTask(Task):
cairo_pie: CairoPie
use_poseidon: bool

def get_program(self) -> StrippedProgram:
return self.cairo_pie.program


@marshmallow_dataclass.dataclass(frozen=True)
class SimpleBootloaderInput(ValidatedMarshmallowDataclass):
tasks: List[TaskSpec] = field(
metadata=additional_metadata(marshmallow_field=mfields.List(mfields.Nested(TaskSchema)))
)
fact_topologies_path: Optional[str]

# If true, the bootloader will put all the outputs in a single page, ignoring the
# tasks' fact topologies.
single_page: bool
Empty file.
11 changes: 11 additions & 0 deletions cairo/bootloader/recursive_with_poseidon/builtins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from starkware.cairo.lang.builtins.all_builtins import *

ALL_BUILTINS = BuiltinList(
[
OUTPUT_BUILTIN,
PEDERSEN_BUILTIN,
RANGE_CHECK_BUILTIN,
BITWISE_BUILTIN,
POSEIDON_BUILTIN,
]
)
Loading
Loading