Skip to content

Commit

Permalink
Cairo v0.8.1.
Browse files Browse the repository at this point in the history
  • Loading branch information
liorgold2 committed Apr 5, 2022
1 parent 4e23351 commit b614d18
Show file tree
Hide file tree
Showing 128 changed files with 2,485 additions and 1,092 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
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.8.0.zip .
> docker cp ${container_id}:/app/cairo-lang-0.8.1.zip .
> docker rm -v ${container_id}
```

43 changes: 24 additions & 19 deletions src/demo/amm_demo/amm.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ struct AmmState:
end

func modify_account{range_check_ptr}(state : AmmState, account_id, diff_a, diff_b) -> (
state : AmmState, key):
state : AmmState, key
):
alloc_locals

# Define a reference to state.account_dict_end so that we
Expand Down Expand Up @@ -93,7 +94,8 @@ func swap{range_check_ptr}(state : AmmState, transaction : SwapTransaction*) ->

# Update the user's account.
let (state, key) = modify_account(
state=state, account_id=transaction.account_id, diff_a=-a, diff_b=b)
state=state, account_id=transaction.account_id, diff_a=-a, diff_b=b
)

# Here you should verify the user has signed on a message
# specifying that they would like to sell 'a' tokens of
Expand Down Expand Up @@ -128,7 +130,8 @@ func swap{range_check_ptr}(state : AmmState, transaction : SwapTransaction*) ->
end

func transaction_loop{range_check_ptr}(
state : AmmState, transactions : SwapTransaction**, n_transactions) -> (state : AmmState):
state : AmmState, transactions : SwapTransaction**, n_transactions
) -> (state : AmmState):
if n_transactions == 0:
return (state=state)
end
Expand All @@ -137,7 +140,8 @@ func transaction_loop{range_check_ptr}(
let (state) = swap(state=state, transaction=first_transaction)

return transaction_loop(
state=state, transactions=transactions + 1, n_transactions=n_transactions - 1)
state=state, transactions=transactions + 1, n_transactions=n_transactions - 1
)
end

# Returns a hash committing to the account's state using the
Expand All @@ -156,8 +160,8 @@ end
# hash_dict_start and hash_dict_end) after applying hash_account
# on prev_value and new_value and keeping the same key.
func hash_dict_values{pedersen_ptr : HashBuiltin*}(
dict_start : DictAccess*, dict_end : DictAccess*, hash_dict_start : DictAccess*) -> (
hash_dict_end : DictAccess*):
dict_start : DictAccess*, dict_end : DictAccess*, hash_dict_start : DictAccess*
) -> (hash_dict_end : DictAccess*):
if dict_start == dict_end:
return (hash_dict_end=hash_dict_start)
end
Expand All @@ -169,11 +173,11 @@ func hash_dict_values{pedersen_ptr : HashBuiltin*}(

# Add an entry to the output dict.
dict_update{dict_ptr=hash_dict_start}(
key=dict_start.key, prev_value=prev_hash, new_value=new_hash)
key=dict_start.key, prev_value=prev_hash, new_value=new_hash
)
return hash_dict_values(
dict_start=dict_start + DictAccess.SIZE,
dict_end=dict_end,
hash_dict_start=hash_dict_start)
dict_start=dict_start + DictAccess.SIZE, dict_end=dict_end, hash_dict_start=hash_dict_start
)
end

const LOG_N_ACCOUNTS = 10
Expand All @@ -182,12 +186,14 @@ const LOG_N_ACCOUNTS = 10
# Hint argument: initial_account_dict should be a dictionary
# from account_id to an address in memory of the Account struct.
func compute_merkle_roots{pedersen_ptr : HashBuiltin*, range_check_ptr}(state : AmmState) -> (
root_before, root_after):
root_before, root_after
):
alloc_locals

# Squash the account dictionary.
let (squashed_dict_start, squashed_dict_end) = dict_squash(
dict_accesses_start=state.account_dict_start, dict_accesses_end=state.account_dict_end)
dict_accesses_start=state.account_dict_start, dict_accesses_end=state.account_dict_end
)
local range_check_ptr = range_check_ptr

# Hash the dict values.
Expand All @@ -208,15 +214,13 @@ func compute_merkle_roots{pedersen_ptr : HashBuiltin*, range_check_ptr}(state :
%}
let (local hash_dict_start : DictAccess*) = dict_new()
let (hash_dict_end) = hash_dict_values(
dict_start=squashed_dict_start,
dict_end=squashed_dict_end,
hash_dict_start=hash_dict_start)
dict_start=squashed_dict_start, dict_end=squashed_dict_end, hash_dict_start=hash_dict_start
)

# Compute the two Merkle roots.
let (root_before, root_after) = small_merkle_tree_update{hash_ptr=pedersen_ptr}(
squashed_dict_start=hash_dict_start,
squashed_dict_end=hash_dict_end,
height=LOG_N_ACCOUNTS)
squashed_dict_start=hash_dict_start, squashed_dict_end=hash_dict_end, height=LOG_N_ACCOUNTS
)

return (root_before=root_before, root_after=root_after)
end
Expand Down Expand Up @@ -306,7 +310,8 @@ func main{output_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr}():
# Execute the transactions.
let (transactions, n_transactions) = get_transactions()
let (state : AmmState) = transaction_loop(
state=state, transactions=transactions, n_transactions=n_transactions)
state=state, transactions=transactions, n_transactions=n_transactions
)

# Output the AMM's balances after applying the batch.
assert output.token_a_after = state.token_a_balance
Expand Down
11 changes: 11 additions & 0 deletions src/services/everest/business_logic/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@ def __init__(self: TCarriedState, parent_state: Optional[TCarriedState]):

@property
def parent_state(self: TCarriedState) -> Optional[TCarriedState]:
"""
Meant for mypy to deduce the application-specific type of the parent state.
"""
return self._parent_state

@property
def non_optional_parent_state(self: TCarriedState) -> TCarriedState:
"""
Asserts that the parent state is not None and returns it.
"""
assert self._parent_state is not None, "Parent state expected to be initialized."
return self._parent_state

def __repr__(self) -> str:
Expand Down
8 changes: 8 additions & 0 deletions src/services/external_api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ python_lib(services_external_api_lib
LIBS
services_external_api_utils_lib
starkware_dataclasses_utils_lib
starkware_python_utils_lib
pip_aiohttp
${SERVICES_EXTERNAL_API_LIB_ADDITIONAL_LIBS}
)

python_lib(services_eth_gas_constants_lib
PREFIX services/external_api

FILES
eth_gas_constants.py
)
15 changes: 10 additions & 5 deletions src/services/external_api/base_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import aiohttp

from services.external_api.has_uri_prefix import HasUriPrefix
from starkware.python.object_utils import generic_object_repr
from starkware.starkware_utils.validated_dataclass import ValidatedDataclass

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -85,6 +86,9 @@ def __init__(
os.path.join(certificates_path, "server.crt")
)

def __repr__(self) -> str:
return generic_object_repr(obj=self)

async def _send_request(
self, send_method: str, uri: str, data: Optional[Union[str, Dict[str, Any]]] = None
) -> str:
Expand Down Expand Up @@ -125,16 +129,17 @@ async def _send_request(

logger.debug(f"{error_message}, retrying...")
except BadRequest as exception:
error_message = (
f"Got {type(exception).__name__} while trying to access {url}. "
f"Status code: {exception.status_code}; text: {exception.text}."
)
error_message = f"Got {type(exception).__name__} while trying to access {url}."

if limited_retries and (
n_retries_left == 0
or exception.status_code not in self.retry_config.retry_codes
):
logger.error(error_message, exc_info=True)
full_error_message = (
f"{error_message} "
f"Status code: {exception.status_code}; text: {exception.text}."
)
logger.error(full_error_message, exc_info=True)
raise

logger.debug(f"{error_message}, retrying...")
Expand Down
15 changes: 15 additions & 0 deletions src/services/external_api/eth_gas_constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Ethereum gas usage constants; for more details, see
# page 27 in https://ethereum.github.io/yellowpaper/paper.pdf.
GAS_PER_MEMORY_BYTE = 16
WORD_WIDTH = 32
GAS_PER_MEMORY_WORD = GAS_PER_MEMORY_BYTE * WORD_WIDTH
SHARP_ADDITIONAL_GAS_PER_MEMORY_WORD = 100 # This value is not accurate.
SHARP_GAS_PER_MEMORY_WORD = GAS_PER_MEMORY_WORD + SHARP_ADDITIONAL_GAS_PER_MEMORY_WORD
GAS_PER_ZERO_TO_NONZERO_STORAGE_SET = 20000
GAS_PER_COLD_STORAGE_ACCESS = 2100
GAS_PER_NONZERO_TO_INT_STORAGE_SET = 2900
GAS_PER_COUNTER_DECREASE = GAS_PER_COLD_STORAGE_ACCESS + GAS_PER_NONZERO_TO_INT_STORAGE_SET
GAS_PER_LOG = 375
GAS_PER_LOG_TOPIC = 375
GAS_PER_LOG_DATA_BYTE = 8
GAS_PER_LOG_DATA_WORD = GAS_PER_LOG_DATA_BYTE * WORD_WIDTH
2 changes: 1 addition & 1 deletion src/starkware/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
add_subdirectory(cairo)
add_subdirectory(contracts)
add_subdirectory(crypto)
add_subdirectory(eth)
add_subdirectory(python)
add_subdirectory(solidity)
add_subdirectory(starknet)
add_subdirectory(starkware_utils)
add_subdirectory(storage)
37 changes: 23 additions & 14 deletions src/starkware/cairo/bootloaders/bootloader/bootloader.cairo
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
%builtins output pedersen range_check ecdsa bitwise

from starkware.cairo.bootloaders.simple_bootloader.run_simple_bootloader import (
run_simple_bootloader)
run_simple_bootloader,
)
from starkware.cairo.cairo_verifier.objects import CairoVerifierOutput
from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.cairo_builtins import HashBuiltin
Expand All @@ -25,7 +26,7 @@ end
# Hint arguments:
# program_input - Contains the inputs for the bootloader.
func main{output_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr, ecdsa_ptr, bitwise_ptr}(
):
):
alloc_locals
local simple_bootloader_output_start : felt*
%{
Expand Down Expand Up @@ -84,7 +85,8 @@ func main{output_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr, ecds
%{ packed_outputs = bootloader_input.packed_outputs %}
with simple_bootloader_output_ptr, n_total_tasks:
parse_tasks{subtasks_output=simple_bootloader_output_ptr}(
bootloader_config=bootloader_config, n_subtasks=n_subtasks)
bootloader_config=bootloader_config, n_subtasks=n_subtasks
)
end

# Assert that parse_tasks used the entire output of the simple bootloader.
Expand All @@ -100,7 +102,9 @@ func main{output_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr, ecds
from starkware.cairo.bootloaders.bootloader.utils import compute_fact_topologies
from starkware.cairo.bootloaders.fact_topology import FactTopology
from starkware.cairo.bootloaders.simple_bootloader.utils import (
configure_fact_topologies, write_to_fact_topologies_file)
configure_fact_topologies,
write_to_fact_topologies_file,
)

# Compute the fact topologies of the plain packed outputs based on packed_outputs and
# fact_topologies of the inner tasks.
Expand Down Expand Up @@ -140,8 +144,8 @@ end
# subtasks_output - Contains direct subtasks outputs which is used for unpacking. This is an input
# to this function and is returned for validation purposes.
func parse_tasks{
output_ptr : felt*, pedersen_ptr : HashBuiltin*, n_total_tasks : felt,
subtasks_output : felt*}(bootloader_config : BootloaderConfig*, n_subtasks : felt):
output_ptr : felt*, pedersen_ptr : HashBuiltin*, n_total_tasks : felt, subtasks_output : felt*
}(bootloader_config : BootloaderConfig*, n_subtasks : felt):
if n_subtasks == 0:
return ()
end
Expand All @@ -159,7 +163,9 @@ func parse_tasks{

%{
from starkware.cairo.bootloaders.bootloader.objects import (
CompositePackedOutput, PlainPackedOutput)
CompositePackedOutput,
PlainPackedOutput,
)
%}

if nondet %{ isinstance(packed_output, PlainPackedOutput) %} != 0:
Expand All @@ -169,7 +175,8 @@ func parse_tasks{
# Handle composite packed task.
%{ assert isinstance(packed_output, CompositePackedOutput) %}
unpack_composite_packed_task{task_output=subtasks_output}(
bootloader_config=bootloader_config)
bootloader_config=bootloader_config
)
end

%{ vm_exit_scope() %}
Expand Down Expand Up @@ -203,8 +210,8 @@ end
# Hint arguments:
# packed_output - CompositePackedOutput object which uses for unpacking the task.
func unpack_composite_packed_task{
output_ptr : felt*, pedersen_ptr : HashBuiltin*, n_total_tasks : felt, task_output : felt*}(
bootloader_config : BootloaderConfig*):
output_ptr : felt*, pedersen_ptr : HashBuiltin*, n_total_tasks : felt, task_output : felt*
}(bootloader_config : BootloaderConfig*):
alloc_locals

# Guess the pre-image of subtasks_output_hash (subtasks_output_hash appears in task_output).
Expand All @@ -221,7 +228,8 @@ func unpack_composite_packed_task{
let (hash_state_ptr) = hash_update{hash_ptr=pedersen_ptr}(
hash_state_ptr=hash_state_ptr,
data_ptr=nested_subtasks_output,
data_length=nested_subtasks_output_len)
data_length=nested_subtasks_output_len,
)
let (subtasks_output_hash) = hash_finalize{hash_ptr=pedersen_ptr}(hash_state_ptr=hash_state_ptr)

# Verify task output header.
Expand All @@ -243,7 +251,8 @@ func unpack_composite_packed_task{
%{ packed_outputs = packed_output.subtasks %}
with nested_subtasks_output:
parse_tasks{subtasks_output=nested_subtasks_output}(
bootloader_config=bootloader_config, n_subtasks=n_subtasks)
bootloader_config=bootloader_config, n_subtasks=n_subtasks
)
end

# Assert that the entire subtask output was used.
Expand All @@ -262,8 +271,8 @@ end
# n_total_tasks - Number of PlainPackedOutput that were unpacked. This function increments this
# value by 1.
func unpack_plain_packed_task{
output_ptr : felt*, pedersen_ptr : HashBuiltin*, n_total_tasks : felt, task_output : felt*}(
bootloader_config : BootloaderConfig*):
output_ptr : felt*, pedersen_ptr : HashBuiltin*, n_total_tasks : felt, task_output : felt*
}(bootloader_config : BootloaderConfig*):
alloc_locals

# Parse task output header.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ end
# b. hash_chain(ProgramHeader || task.program.data) where ProgramHeader is defined below.
# The function returns a pointer to the updated builtin pointers after executing the task.
func execute_task{builtin_ptrs : BuiltinData*, self_range_check_ptr}(
builtin_encodings : BuiltinData*, builtin_instance_sizes : BuiltinData*):
builtin_encodings : BuiltinData*, builtin_instance_sizes : BuiltinData*
):
# Allocate memory for local variables.
alloc_locals

Expand Down Expand Up @@ -106,14 +107,20 @@ func execute_task{builtin_ptrs : BuiltinData*, self_range_check_ptr}(
all_encodings=builtin_encodings,
all_ptrs=&pre_execution_builtin_ptrs,
selected_encodings=builtin_list,
n_selected_builtins=n_builtins)
n_selected_builtins=n_builtins,
)

call_task:
%{
from starkware.cairo.bootloaders.simple_bootloader.objects import (
CairoPieTask, RunProgramTask, Task)
CairoPieTask,
RunProgramTask,
Task,
)
from starkware.cairo.bootloaders.simple_bootloader.utils import (
load_cairo_pie, prepare_output_runner)
load_cairo_pie,
prepare_output_runner,
)

assert isinstance(task, Task)
n_builtins = len(task.get_program().builtins)
Expand Down Expand Up @@ -175,7 +182,8 @@ func execute_task{builtin_ptrs : BuiltinData*, self_range_check_ptr}(
all_ptrs=&return_builtin_ptrs,
selected_encodings=builtin_list,
selected_ptrs=used_builtins_addr,
n_builtins=BuiltinData.SIZE)
n_builtins=BuiltinData.SIZE,
)
%{ vm_exit_scope() %}

# Assert that the correct number of builtins was selected.
Expand All @@ -187,7 +195,8 @@ func execute_task{builtin_ptrs : BuiltinData*, self_range_check_ptr}(
prev_builtin_ptrs=&pre_execution_builtin_ptrs,
new_builtin_ptrs=&return_builtin_ptrs,
builtin_instance_sizes=builtin_instance_sizes,
n_builtins=BuiltinData.SIZE)
n_builtins=BuiltinData.SIZE,
)

# Verify that [output_ptr] = return_builtin_ptrs.output - output_ptr.
# Output size should be 2 + the number of output slots that were consumed by the task.
Expand Down
Loading

0 comments on commit b614d18

Please sign in to comment.