diff --git a/WORKSPACE b/WORKSPACE index 3057b22f..549bd262 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -60,7 +60,7 @@ http_archive( "//src/starkware/starknet/compiler/v1:BUILD." + CAIRO_COMPILER_ARCHIVE, ), strip_prefix = "cairo", - url = "https://github.com/starkware-libs/cairo/releases/download/v2.7.0-rc.1/release-x86_64-unknown-linux-musl.tar.gz", + url = "https://github.com/starkware-libs/cairo/releases/download/v2.7.0/release-x86_64-unknown-linux-musl.tar.gz", ) http_archive( diff --git a/scripts/requirements-gen.txt b/scripts/requirements-gen.txt index 143ff45d..49dad344 100644 --- a/scripts/requirements-gen.txt +++ b/scripts/requirements-gen.txt @@ -7,7 +7,7 @@ fastecdsa frozendict gprof2dot lark -marshmallow-dataclass>=7.1.0 +marshmallow-dataclass==8.6.1 marshmallow-enum marshmallow-oneofschema marshmallow>=3.2.1 diff --git a/src/starkware/cairo/bootloaders/bootloader/supported_verifier_hashes.json b/src/starkware/cairo/bootloaders/bootloader/supported_verifier_hashes.json new file mode 100644 index 00000000..6609231b --- /dev/null +++ b/src/starkware/cairo/bootloaders/bootloader/supported_verifier_hashes.json @@ -0,0 +1,16 @@ +[ + "0x1000a7b3fbe5305ae59f9298ce57619cf9914d810ba876a2c30fc6145904ce2", + "0x32daa3bd81bfc6aba263401761e78ae4a21b63161d6fc74bd4482b11fbdac6", + "0x268e762c9153438f6a9203036739502104708b2f100987927fae7d563e027fb", + "0x7c37f4bb5e5f73b62939127cf3669f3cc5a96eb0fd0f30d5642bce1ce1c9895", + "0x29fa47f641f1d0112ca6c42bc10f31b3539d688a7f8008e750eae1c6dd7e7a", + "0x193641eb151b0f41674641089952e60bc3aded26e3cf42793655c562b8c3aa0", + "0x14c11937eeaf285502dec0e2db494708679fa51c4229f4cad2682344eae6935", + "0x10d4339b5fb9134112e8c8d21b2b800414f2aebbf595dc2a1e1db0ad7c1f11d", + "0x4d817d698a34fa79d97cccf5ba2707861a94b766d749b0dd47203018a43a112", + "0x2a258bceea610b1008bd183365df7809688034a927fabcaff85ff63bb956f09", + "0x672ad4caa2ed1d0c3b4954b32eaf51d867203a66920d8ee6b7455b3989f6a86", + "0x2824b7ddb10287dd935d6e67fb846f32fec9bacb34fea4d2246dce395d4b580", + "0x4f25ecc7f3184b4b5fe3bb34e6d553c1e477ff07c3efa64c433815fbdfb51a8", + "0x7fb130c1bf059a1fa742f84877872ced1b0cb2c0f3b5d1fd63435946c4b11fd" +] diff --git a/src/starkware/cairo/common/cairo_sha256/sha256_utils.cairo b/src/starkware/cairo/common/cairo_sha256/sha256_utils.cairo index 43f0189c..00588e61 100644 --- a/src/starkware/cairo/common/cairo_sha256/sha256_utils.cairo +++ b/src/starkware/cairo/common/cairo_sha256/sha256_utils.cairo @@ -480,7 +480,7 @@ func finalize_sha256{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}( sha2_compress_function, ) - number_of_missing_blocks = -ids.n % ids.BATCH_SIZE + number_of_missing_blocks = (-ids.n) % ids.BATCH_SIZE assert 0 <= number_of_missing_blocks < 20 _sha256_input_chunk_size_felts = ids.SHA256_INPUT_CHUNK_SIZE_FELTS assert 0 <= _sha256_input_chunk_size_felts < 100 @@ -488,7 +488,7 @@ func finalize_sha256{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}( message = [0] * _sha256_input_chunk_size_felts w = compute_message_schedule(message) output = sha2_compress_function(IV, w) - padding = (message + IV + output) * (number_of_missing_blocks) + padding = (message + IV + output) * number_of_missing_blocks segments.write_arg(ids.sha256_ptr_end, padding) %} diff --git a/src/starkware/cairo/common/ec.cairo b/src/starkware/cairo/common/ec.cairo index 02a587a1..7e89405e 100644 --- a/src/starkware/cairo/common/ec.cairo +++ b/src/starkware/cairo/common/ec.cairo @@ -137,6 +137,7 @@ func ec_op{ec_op_ptr: EcOpBuiltin*}(p: EcPoint, m: felt, q: EcPoint) -> (r: EcPo seed = b"".join(map(to_bytes, [ids.p.x, ids.p.y, ids.m, ids.q.x, ids.q.y])) ids.s.x, ids.s.y = random_ec_point(FIELD_PRIME, ALPHA, BETA, seed) %} + assert_on_curve(s); let p_plus_s: EcPoint = ec_add(p, s); assert ec_op_ptr.p = p_plus_s; @@ -217,6 +218,7 @@ func chained_ec_op{ec_op_ptr: EcOpBuiltin*}(p: EcPoint, m: felt*, q: EcPoint*, l ) ids.s.x, ids.s.y = random_ec_point(FIELD_PRIME, ALPHA, BETA, seed) %} + assert_on_curve(s); let p_plus_s: EcPoint = ec_add(p, s); let r_plus_s: EcPoint = _chained_ec_op_inner(p=p_plus_s, m=m, q=q, len=len); let r: EcPoint = ec_add(r_plus_s, EcPoint(x=s.x, y=-s.y)); diff --git a/src/starkware/cairo/lang/VERSION b/src/starkware/cairo/lang/VERSION index 2702fce1..9beb74d4 100644 --- a/src/starkware/cairo/lang/VERSION +++ b/src/starkware/cairo/lang/VERSION @@ -1 +1 @@ -0.13.2a0 +0.13.2 diff --git a/src/starkware/cairo/lang/builtins/modulo/mod_builtin_runner.py b/src/starkware/cairo/lang/builtins/modulo/mod_builtin_runner.py index 5c1eba98..9729b520 100644 --- a/src/starkware/cairo/lang/builtins/modulo/mod_builtin_runner.py +++ b/src/starkware/cairo/lang/builtins/modulo/mod_builtin_runner.py @@ -129,13 +129,6 @@ def initialize_segments(self, runner): def finalize_segments(self, runner): super().finalize_segments(runner) - def get_additional_data(self): - assert self.zero_value is not None, "Uninitialized self.zero_value." - return [list(RelocatableValue.to_tuple(self.zero_value))] - - def extend_additional_data(self, data, relocate_callback, data_is_trusted=True): - self.zero_value = relocate_callback(RelocatableValue.from_tuple(data[0])) - # The structure of the values in the returned dictionary is of the form: # {keys = INPUT_NAMES, "batch": {index_in_batch: {keys = MEMORY_VAR_NAMES}}}. def air_private_input(self, runner) -> Dict[str, Any]: diff --git a/src/starkware/cairo/lang/ide/vscode-cairo/README.md b/src/starkware/cairo/lang/ide/vscode-cairo/README.md index 081f8930..70bf3f2f 100644 --- a/src/starkware/cairo/lang/ide/vscode-cairo/README.md +++ b/src/starkware/cairo/lang/ide/vscode-cairo/README.md @@ -1,4 +1,9 @@ -# Installation +# CairoZero for Visual Studio Code + +This extension provides support for the older version of Cairo, known as CairoZero. For the new language, install the [Cairo 1.0](https://marketplace.visualstudio.com/items?itemName=starkware.cairo1) extension. +Note that the CairoZero compiler and extension are no longer maintained. This extension should only be used by projects that still rely on CairoZero code. + +## Installation From the directory of this file, run: ``` @@ -8,7 +13,7 @@ vsce package code --install-extension cairo*.vsix ``` -# Configuration +## Configuration If you have `cairo-format` installed globally (available in PATH), the value of `cairo.cairoFormatPath` should be `cairo-format` (the default). @@ -19,7 +24,7 @@ set the value of `cairo.cairoFormatPath` to ${workspaceFolder}/src/starkware/cairo/lang/scripts/cairo-format ``` -# Run the extension (for development) +## Run the extension (for development) 1. Open VSCode in the directory of the extension. 2. Run: diff --git a/src/starkware/cairo/lang/ide/vscode-cairo/syntaxes/cairo.tmLanguage.json b/src/starkware/cairo/lang/ide/vscode-cairo/syntaxes/cairo.tmLanguage.json index de288c07..cb5f015f 100644 --- a/src/starkware/cairo/lang/ide/vscode-cairo/syntaxes/cairo.tmLanguage.json +++ b/src/starkware/cairo/lang/ide/vscode-cairo/syntaxes/cairo.tmLanguage.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", - "name": "Cairo", + "name": "CairoZero", "patterns": [ { "name": "meta.control.if", @@ -13,11 +13,11 @@ "name": "entity.name.condition" } }, - "contentName": "source.cairo", + "contentName": "source.cairo0", "end": "\\}", "patterns": [ { - "include": "source.cairo" + "include": "source.cairo0" } ], "endCaptures": { @@ -37,11 +37,11 @@ "name": "entity.name.identifiers" } }, - "contentName": "source.cairo", + "contentName": "source.cairo0", "end": "\\}", "patterns": [ { - "include": "source.cairo" + "include": "source.cairo0" } ], "endCaptures": { @@ -61,11 +61,11 @@ "name": "entity.name.function" } }, - "contentName": "source.cairo", + "contentName": "source.cairo0", "end": "\\}", "patterns": [ { - "include": "source.cairo" + "include": "source.cairo0" } ], "endCaptures": { @@ -113,11 +113,11 @@ "name": "entity.name.function" } }, - "contentName": "source.cairo", + "contentName": "source.cairo0", "end": "\\}", "patterns": [ { - "include": "source.cairo" + "include": "source.cairo0" } ], "endCaptures": { @@ -137,11 +137,11 @@ "name": "entity.name.function" } }, - "contentName": "source.cairo", + "contentName": "source.cairo0", "end": "\\}", "patterns": [ { - "include": "source.cairo" + "include": "source.cairo0" } ], "endCaptures": { @@ -191,5 +191,5 @@ ] } ], - "scopeName": "source.cairo" + "scopeName": "source.cairo0" } diff --git a/src/starkware/starknet/business_logic/fact_state/contract_state_objects.py b/src/starkware/starknet/business_logic/fact_state/contract_state_objects.py index ac8fb54c..921b4283 100644 --- a/src/starkware/starknet/business_logic/fact_state/contract_state_objects.py +++ b/src/starkware/starknet/business_logic/fact_state/contract_state_objects.py @@ -138,9 +138,14 @@ async def update( nonce=nonce, ) - async def fetch_witnesses(self, ffc: FactFetchingContext, updates: Mapping[int, int]): + async def fetch_storage_witnesses( + self, ffc: FactFetchingContext, updates: Mapping[int, int], get_leaves: bool + ): await self.storage_commitment_tree.fetch_witnesses( - ffc=ffc, sorted_leaf_indices=sorted(updates.keys()), fact_cls=StorageLeaf + ffc=ffc, + sorted_leaf_indices=sorted(updates.keys()), + fact_cls=StorageLeaf if get_leaves else None, + empty_leaf=StorageLeaf.empty(), ) diff --git a/src/starkware/starknet/business_logic/fact_state/state.py b/src/starkware/starknet/business_logic/fact_state/state.py index ee5c1ca8..9d01c0e6 100644 --- a/src/starkware/starknet/business_logic/fact_state/state.py +++ b/src/starkware/starknet/business_logic/fact_state/state.py @@ -224,10 +224,7 @@ async def empty(cls, ffc: FactFetchingContext, general_config: Config) -> "Share return cls( contract_states=empty_contract_states, contract_classes=empty_contract_classes, - block_info=BlockInfo.empty( - sequencer_address=general_config.sequencer_address, - use_kzg_da=general_config.use_kzg_da, - ), + block_info=BlockInfo.empty(sequencer_address=general_config.sequencer_address), ) async def get_contract_class_tree( @@ -388,7 +385,12 @@ async def apply_updates( block_info=block_info, ) - async def fetch_witnesses(self, cached_ffc: FactFetchingContext, state_diff: "StateDiff"): + async def fetch_all_witnesses( + self, + cached_ffc: FactFetchingContext, + state_diff: "StateDiff", + get_leaves: bool, + ): """ Fetches the necessary witnesses from storage to update the state with the provided diff. """ @@ -400,34 +402,42 @@ async def fetch_witnesses(self, cached_ffc: FactFetchingContext, state_diff: "St accessed_addresses = ( address_to_class_hash.keys() | address_to_nonce.keys() | storage_updates.keys() ) - current_contract_states = await self.contract_states.get_leaves( - ffc=cached_ffc, indices=accessed_addresses, fact_cls=ContractState + + # Fetch global tree's witnesses. + contract_states = await self.contract_states.fetch_witnesses( + ffc=cached_ffc, + sorted_leaf_indices=sorted(accessed_addresses), + fact_cls=ContractState, + empty_leaf=await ContractState.empty( + storage_commitment_tree_height=constants.CONTRACT_STATES_COMMITMENT_TREE_HEIGHT, + ffc=cached_ffc, + ), + ) + + # Fetch classes tree's witnesses. + classes_tree_awaitable = ( + [ + self.contract_classes.fetch_witnesses( + ffc=cached_ffc, + sorted_leaf_indices=sorted(class_hash_to_compiled_class_hash.keys()), + fact_cls=ContractClassLeaf if get_leaves else None, + empty_leaf=ContractClassLeaf.empty(), + ) + ] + if self.contract_classes is not None + else [] ) await gather_in_chunks( awaitables=[ - current_contract_states[address].fetch_witnesses(ffc=cached_ffc, updates=updates) + contract_states[address].fetch_storage_witnesses( + ffc=cached_ffc, updates=updates, get_leaves=get_leaves + ) for address, updates in storage_updates.items() ] + + classes_tree_awaitable ) - # Fetch global tree's witnesses. - await self.contract_states.fetch_witnesses( - ffc=cached_ffc, sorted_leaf_indices=sorted(accessed_addresses), fact_cls=ContractState - ) - - # Fetch classes tree's witnesses. - if self.contract_classes is not None: - await self.contract_classes.fetch_witnesses( - ffc=cached_ffc, - sorted_leaf_indices=sorted(class_hash_to_compiled_class_hash.keys()), - fact_cls=ContractClassLeaf, - ) - else: - assert ( - len(class_hash_to_compiled_class_hash) == 0 - ), "contract_classes must be concrete before fetch." - @marshmallow_dataclass.dataclass(frozen=True) class StateDiff(EverestStateDiff, DBObject): @@ -445,6 +455,7 @@ class StateDiff(EverestStateDiff, DBObject): declared_classes: Mapping[int, int] = field( metadata=fields.state_diff_declared_classes_metadata ) + # The block after this StateDiff is applied. block_info: BlockInfo @marshmallow.pre_load diff --git a/src/starkware/starknet/business_logic/state/state_api_objects.py b/src/starkware/starknet/business_logic/state/state_api_objects.py index fec9ebea..f142868a 100644 --- a/src/starkware/starknet/business_logic/state/state_api_objects.py +++ b/src/starkware/starknet/business_logic/state/state_api_objects.py @@ -105,7 +105,7 @@ def rename_old_gas_price_fields( return rename_old_gas_price_fields(data=data) @classmethod - def empty(cls, sequencer_address: Optional[int], use_kzg_da: bool) -> "BlockInfo": + def empty(cls, sequencer_address: Optional[int]) -> "BlockInfo": """ Returns an empty BlockInfo object; i.e., the one before the first in the chain. """ @@ -117,7 +117,7 @@ def empty(cls, sequencer_address: Optional[int], use_kzg_da: bool) -> "BlockInfo l1_data_gas_price=ResourcePrice(price_in_wei=1, price_in_fri=1), sequencer_address=sequencer_address, starknet_version=STARKNET_VERSION, - use_kzg_da=use_kzg_da, + use_kzg_da=True, # Value is ignored for an empty block. ) @classmethod diff --git a/src/starkware/starknet/common/new_syscalls.cairo b/src/starkware/starknet/common/new_syscalls.cairo index 9fbb4c09..40a395ce 100644 --- a/src/starkware/starknet/common/new_syscalls.cairo +++ b/src/starkware/starknet/common/new_syscalls.cairo @@ -1,4 +1,5 @@ from starkware.cairo.common.cairo_secp.ec import EcPoint +from starkware.cairo.common.sha256_state import Sha256Input, Sha256State from starkware.cairo.common.uint256 import Uint256 // Syscall selectors. @@ -169,8 +170,8 @@ struct KeccakRequest { } struct Sha256ProcessBlockRequest { - state_ptr: felt*, - input_start: felt*, + state_ptr: Sha256State*, + input_start: Sha256Input*, } struct SecpAddRequest { @@ -262,7 +263,7 @@ struct KeccakResponse { } struct Sha256ProcessBlockResponse { - state_ptr: felt*, + state_ptr: Sha256State*, } struct SecpGetXyResponse { diff --git a/src/starkware/starknet/compiler/external_wrapper.py b/src/starkware/starknet/compiler/external_wrapper.py index b1496cc3..699dc7d0 100644 --- a/src/starkware/starknet/compiler/external_wrapper.py +++ b/src/starkware/starknet/compiler/external_wrapper.py @@ -45,7 +45,7 @@ ) from starkware.starknet.definitions import constants from starkware.starknet.public.abi import DEFAULT_ENTRY_POINT_NAME, DEFAULT_L1_ENTRY_POINT_NAME -from starkware.starknet.services.api.contract_class.contract_class import SUPPORTED_BUILTINS +from starkware.starknet.services.api.contract_class.contract_class import CAIRO0_SUPPORTED_BUILTINS RAW_INPUT_DECORATOR = "raw_input" RAW_OUTPUT_DECORATOR = "raw_output" @@ -67,7 +67,7 @@ WRAPPER_SCOPE = ScopedName.from_string("__wrappers__") BUILTIN_PTR_TO_BUILTIN = { - f"{builtin_name}_ptr": builtin_name for builtin_name in SUPPORTED_BUILTINS + f"{builtin_name}_ptr": builtin_name for builtin_name in CAIRO0_SUPPORTED_BUILTINS } @@ -330,9 +330,12 @@ def validate_raw_output_signature(self, elm: CodeElementFunction): def get_collected_builtins(self): """ - Returns the builtins collected from the external functions, ordered by SUPPORTED_BUILTINS. + Returns the builtins collected from the external functions, ordered by + CAIRO0_SUPPORTED_BUILTINS. """ - return [builtin for builtin in SUPPORTED_BUILTINS if builtin in self.collected_builtins] + return [ + builtin for builtin in CAIRO0_SUPPORTED_BUILTINS if builtin in self.collected_builtins + ] class PreExternalWrapperStage(Stage): diff --git a/src/starkware/starknet/compiler/external_wrapper_test.py b/src/starkware/starknet/compiler/external_wrapper_test.py index a6ba313f..cd2c083d 100644 --- a/src/starkware/starknet/compiler/external_wrapper_test.py +++ b/src/starkware/starknet/compiler/external_wrapper_test.py @@ -97,7 +97,7 @@ def test_wrapper_with_return_values(builtins_directive: bool): """ Tests that the external wrapper works with return values. In addition, also tests that the builtins are collected correctly and reordered according to - SUPPORTED_BUILTINS. + CAIRO0_SUPPORTED_BUILTINS. """ program = preprocess_str( f""" diff --git a/src/starkware/starknet/compiler/starknet_preprocessor.py b/src/starkware/starknet/compiler/starknet_preprocessor.py index 907f0b90..0f2af178 100644 --- a/src/starkware/starknet/compiler/starknet_preprocessor.py +++ b/src/starkware/starknet/compiler/starknet_preprocessor.py @@ -33,7 +33,7 @@ struct_definition_to_abi_entry, ) from starkware.starknet.security.secure_hints import HintsWhitelist, InsecureHintError -from starkware.starknet.services.api.contract_class.contract_class import SUPPORTED_BUILTINS +from starkware.starknet.services.api.contract_class.contract_class import CAIRO0_SUPPORTED_BUILTINS from starkware.starkware_utils.subsequence import is_subsequence @@ -65,9 +65,9 @@ def visit_BuiltinsDirective(self, directive: BuiltinsDirective): super().visit_BuiltinsDirective(directive) assert self.builtins is not None - if not is_subsequence(self.builtins, SUPPORTED_BUILTINS): + if not is_subsequence(self.builtins, CAIRO0_SUPPORTED_BUILTINS): raise PreprocessorError( - f"{self.builtins} is not a subsequence of {SUPPORTED_BUILTINS}.", + f"{self.builtins} is not a subsequence of {CAIRO0_SUPPORTED_BUILTINS}.", location=directive.location, ) diff --git a/src/starkware/starknet/compiler/starknet_preprocessor_test.py b/src/starkware/starknet/compiler/starknet_preprocessor_test.py index 19ec01af..4e206154 100644 --- a/src/starkware/starknet/compiler/starknet_preprocessor_test.py +++ b/src/starkware/starknet/compiler/starknet_preprocessor_test.py @@ -1,5 +1,7 @@ +import pytest + from starkware.starknet.compiler.test_utils import preprocess_str, verify_exception -from starkware.starknet.services.api.contract_class.contract_class import SUPPORTED_BUILTINS +from starkware.starknet.services.api.contract_class.contract_class import CAIRO0_SUPPORTED_BUILTINS def test_builtin_directive_after_external(): @@ -20,15 +22,19 @@ def test_builtin_directive_after_external(): ) -def test_storage_in_builtin_directive(): +@pytest.mark.parametrize( + "builtin", + ["segment_arena", "range_check96", "add_mod", "mul_mod"], +) +def test_unsupported_builtins_in_builtin_directive(builtin: str): verify_exception( - """ -%builtins storage + f""" +%builtins {builtin} """, f""" -file:?:?: ['storage'] is not a subsequence of {SUPPORTED_BUILTINS}. -%builtins storage -^***************^ +file:?:?: ['{builtin}'] is not a subsequence of {CAIRO0_SUPPORTED_BUILTINS}. +%builtins {builtin} +^********{len(builtin) * "*"}^ """, ) @@ -39,7 +45,7 @@ def test_output_in_builtin_directive(): %builtins output range_check """, f""" -file:?:?: ['output', 'range_check'] is not a subsequence of {SUPPORTED_BUILTINS}. +file:?:?: ['output', 'range_check'] is not a subsequence of {CAIRO0_SUPPORTED_BUILTINS}. %builtins output range_check ^**************************^ """, diff --git a/src/starkware/starknet/compiler/v1/mainnet_libfuncs.json b/src/starkware/starknet/compiler/v1/mainnet_libfuncs.json index cfe1fbfa..b6ec4ea6 100644 --- a/src/starkware/starknet/compiler/v1/mainnet_libfuncs.json +++ b/src/starkware/starknet/compiler/v1/mainnet_libfuncs.json @@ -88,7 +88,6 @@ "i128_const", "i128_diff", "i128_eq", - "i128_is_zero", "i128_overflowing_add_impl", "i128_overflowing_sub_impl", "i128_to_felt252", @@ -96,7 +95,6 @@ "i16_const", "i16_diff", "i16_eq", - "i16_is_zero", "i16_overflowing_add_impl", "i16_overflowing_sub_impl", "i16_to_felt252", @@ -105,7 +103,6 @@ "i32_const", "i32_diff", "i32_eq", - "i32_is_zero", "i32_overflowing_add_impl", "i32_overflowing_sub_impl", "i32_to_felt252", @@ -114,7 +111,6 @@ "i64_const", "i64_diff", "i64_eq", - "i64_is_zero", "i64_overflowing_add_impl", "i64_overflowing_sub_impl", "i64_to_felt252", @@ -123,7 +119,6 @@ "i8_const", "i8_diff", "i8_eq", - "i8_is_zero", "i8_overflowing_add_impl", "i8_overflowing_sub_impl", "i8_to_felt252", diff --git a/src/starkware/starknet/compiler/v1/testnet_libfuncs.json b/src/starkware/starknet/compiler/v1/testnet_libfuncs.json index cfe1fbfa..b6ec4ea6 100644 --- a/src/starkware/starknet/compiler/v1/testnet_libfuncs.json +++ b/src/starkware/starknet/compiler/v1/testnet_libfuncs.json @@ -88,7 +88,6 @@ "i128_const", "i128_diff", "i128_eq", - "i128_is_zero", "i128_overflowing_add_impl", "i128_overflowing_sub_impl", "i128_to_felt252", @@ -96,7 +95,6 @@ "i16_const", "i16_diff", "i16_eq", - "i16_is_zero", "i16_overflowing_add_impl", "i16_overflowing_sub_impl", "i16_to_felt252", @@ -105,7 +103,6 @@ "i32_const", "i32_diff", "i32_eq", - "i32_is_zero", "i32_overflowing_add_impl", "i32_overflowing_sub_impl", "i32_to_felt252", @@ -114,7 +111,6 @@ "i64_const", "i64_diff", "i64_eq", - "i64_is_zero", "i64_overflowing_add_impl", "i64_overflowing_sub_impl", "i64_to_felt252", @@ -123,7 +119,6 @@ "i8_const", "i8_diff", "i8_eq", - "i8_is_zero", "i8_overflowing_add_impl", "i8_overflowing_sub_impl", "i8_to_felt252", diff --git a/src/starkware/starknet/core/os/execution/execute_syscalls.cairo b/src/starkware/starknet/core/os/execution/execute_syscalls.cairo index f9cdb72a..dcacf355 100644 --- a/src/starkware/starknet/core/os/execution/execute_syscalls.cairo +++ b/src/starkware/starknet/core/os/execution/execute_syscalls.cairo @@ -963,7 +963,7 @@ func execute_keccak{ let selectable_builtins = &builtin_ptrs.selectable; let non_selectable_builtins = &builtin_ptrs.non_selectable; let bitwise_ptr = selectable_builtins.bitwise; - let keccak_ptr = builtin_ptrs.non_selectable.keccak; + let keccak_ptr = non_selectable_builtins.keccak; with bitwise_ptr, keccak_ptr { let (res) = keccak_padded_input(inputs=input_start, n_blocks=q); } @@ -1020,14 +1020,14 @@ func execute_sha256_process_block{ local sha256_ptr: Sha256ProcessBlock* = builtin_ptrs.non_selectable.sha256; - let input = cast(sha256_ptr, Sha256Input*); - assert [input] = [cast(request.input_start, Sha256Input*)]; + let input: Sha256Input* = &sha256_ptr.input; + assert [input] = [request.input_start]; - let state = cast(sha256_ptr + Sha256Input.SIZE, Sha256State*); - assert [state] = [cast(request.state_ptr, Sha256State*)]; + let state: Sha256State* = &sha256_ptr.in_state; + assert [state] = [request.state_ptr]; - let res = sha256_ptr + Sha256Input.SIZE + Sha256State.SIZE; - let sha256_ptr = sha256_ptr + Sha256ProcessBlock.SIZE; + let res: Sha256State* = &sha256_ptr.out_state; + let sha256_ptr = &sha256_ptr[1]; assert [cast(syscall_ptr, Sha256ProcessBlockResponse*)] = Sha256ProcessBlockResponse( state_ptr=res diff --git a/src/starkware/starknet/core/os/execution/execute_transactions.cairo b/src/starkware/starknet/core/os/execution/execute_transactions.cairo index 694cdf95..30683252 100644 --- a/src/starkware/starknet/core/os/execution/execute_transactions.cairo +++ b/src/starkware/starknet/core/os/execution/execute_transactions.cairo @@ -191,8 +191,20 @@ func execute_transactions{ let mul_mod_ptr = selectable_builtins.mul_mod; let keccak_ptr = builtin_ptrs.non_selectable.keccak; - // finalize the sha256 segment. - finalize_sha256(sha256_ptr_start, builtin_ptrs.non_selectable.sha256); + // Fill holes in the rc96 segment. + %{ + rc96_ptr = ids.range_check96_ptr + segment_size = rc96_ptr.offset + base = rc96_ptr - segment_size + + for i in range(segment_size): + memory.setdefault(base + i, 0) + %} + + // Finalize the sha256 segment. + finalize_sha256( + sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=builtin_ptrs.non_selectable.sha256 + ); return (reserved_range_checks_end=reserved_range_checks_end); } @@ -420,6 +432,10 @@ func execute_invoke_function_transaction{ nondet %{ 0 if tx.version < 3 else tx.fee_data_availability_mode %} ), ); + if (common_tx_fields.version != 0) { + assert tx_execution_info.selector = EXECUTE_ENTRY_POINT_SELECTOR; + } + local account_deployment_data_size = ( nondet %{ 0 if tx.version < 3 else len(tx.account_deployment_data) %} ); diff --git a/src/starkware/starknet/core/os/program_hash.json b/src/starkware/starknet/core/os/program_hash.json index f8d11b48..24138e6c 100644 --- a/src/starkware/starknet/core/os/program_hash.json +++ b/src/starkware/starknet/core/os/program_hash.json @@ -1,3 +1,3 @@ { - "program_hash": "0x1d83cded627b9239355cc5b4ad5c37979058c5c6423cf2107fa8e16933875eb" + "program_hash": "0x1f17730cc039dfbe74f54513b55e005648862439a3c1bc1e8e1c8ebfe198064" } diff --git a/src/starkware/starknet/core/os/transaction_hash/transaction_hash.cairo b/src/starkware/starknet/core/os/transaction_hash/transaction_hash.cairo index 01fe99a6..1976dcac 100644 --- a/src/starkware/starknet/core/os/transaction_hash/transaction_hash.cairo +++ b/src/starkware/starknet/core/os/transaction_hash/transaction_hash.cairo @@ -185,7 +185,6 @@ func compute_invoke_transaction_hash{ tempvar additional_data_size = 0; tempvar additional_data = cast(0, felt*); } else { - assert execution_context.execution_info.selector = EXECUTE_ENTRY_POINT_SELECTOR; tempvar entry_point_selector_field = 0; tempvar additional_data_size = 1; tempvar additional_data = &common_fields.nonce; diff --git a/src/starkware/starknet/definitions/general_config.py b/src/starkware/starknet/definitions/general_config.py index a1d44181..cc8fa344 100644 --- a/src/starkware/starknet/definitions/general_config.py +++ b/src/starkware/starknet/definitions/general_config.py @@ -173,14 +173,6 @@ class StarknetGeneralConfig(EverestGeneralConfig): default=DEFAULT_ENFORCE_L1_FEE, ) - use_kzg_da: bool = field( - metadata=additional_metadata( - marshmallow_field=RequiredBoolean(), - description="Enabler for using KZG commitment scheme in created blocks.", - ), - default=DEFAULT_USE_KZG_DA, - ) - @property def chain_id(self) -> StarknetChainId: return StarknetChainId(self.starknet_os_config.chain_id) diff --git a/src/starkware/starknet/definitions/general_config.yml b/src/starkware/starknet/definitions/general_config.yml index 52adb126..8d94f060 100644 --- a/src/starkware/starknet/definitions/general_config.yml +++ b/src/starkware/starknet/definitions/general_config.yml @@ -13,5 +13,4 @@ starknet_os_config: chain_id: 1536727068981429685321 deprecated_fee_token_address: '0x4201b1ca8320dd248a9c18aeae742db64b0ea0f6f1f5a4c72ddb6b725e16316' fee_token_address: '0x3c0178a04b4d297c884e366bb0a2ec0f682188ba604d71955134a203d4f2adc' -use_kzg_da: true validate_max_n_steps: 1000000 diff --git a/src/starkware/starknet/definitions/versioned_constants.json b/src/starkware/starknet/definitions/versioned_constants.json index 5e62bccb..e362db48 100644 --- a/src/starkware/starknet/definitions/versioned_constants.json +++ b/src/starkware/starknet/definitions/versioned_constants.json @@ -548,6 +548,7 @@ } } }, + "segment_arena_cells": false, "tx_event_limits": { "max_data_length": 300, "max_keys_length": 50, diff --git a/src/starkware/starknet/services/api/contract_class/contract_class.py b/src/starkware/starknet/services/api/contract_class/contract_class.py index 2b688869..e236f25c 100644 --- a/src/starkware/starknet/services/api/contract_class/contract_class.py +++ b/src/starkware/starknet/services/api/contract_class/contract_class.py @@ -28,8 +28,8 @@ ValidatedMarshmallowDataclass, ) -# An ordered list of the supported builtins. -SUPPORTED_BUILTINS = [ +# An ordered list of the supported builtins in Cairo 1. +CAIRO1_SUPPORTED_BUILTINS = [ "pedersen", "range_check", "ecdsa", @@ -42,17 +42,28 @@ "mul_mod", ] +# An ordered list of the supported builtins in Cairo 0. +CAIRO0_SUPPORTED_BUILTINS = [ + "pedersen", + "range_check", + "ecdsa", + "bitwise", + "ec_op", + "poseidon", +] + # Utilites. -def validate_builtins(builtins: Optional[List[str]]): +def validate_builtins(builtins: Optional[List[str]], is_cairo1: bool): if builtins is None: return + supported_builtins = CAIRO1_SUPPORTED_BUILTINS if is_cairo1 else CAIRO0_SUPPORTED_BUILTINS stark_assert( - is_subsequence(builtins, SUPPORTED_BUILTINS), + is_subsequence(builtins, supported_builtins), code=StarknetErrorCode.INVALID_CONTRACT_CLASS, - message=f"{builtins} is not a subsequence of {SUPPORTED_BUILTINS}.", + message=f"{builtins} is not a subsequence of {supported_builtins}.", ) @@ -137,6 +148,13 @@ def get_bytecode(self) -> List[int]: Returns the "bytecode" attribute of the compiled class. """ + @property + @abstractmethod + def is_cairo1(self) -> bool: + """ + Retruns whether the class was compiled from Cairo 1. + """ + def __post_init__(self): super().__post_init__() @@ -164,10 +182,10 @@ def __post_init__(self): ) def validate(self): - validate_builtins(builtins=self.get_builtins()) + validate_builtins(builtins=self.get_builtins(), is_cairo1=self.is_cairo1) for entry_points in self.entry_points_by_type.values(): for entry_point in entry_points: - validate_builtins(builtins=entry_point.builtins) + validate_builtins(builtins=entry_point.builtins, is_cairo1=self.is_cairo1) stark_assert( self.get_prime() == DEFAULT_PRIME, @@ -213,6 +231,10 @@ class CompiledClass(CompiledClassBase): metadata=dict(marshmallow_field=mfields.String(required=False, load_default=None)) ) + @property + def is_cairo1(self) -> bool: + return True + def get_builtins(self) -> List[str]: return [] @@ -327,6 +349,10 @@ class DeprecatedCompiledClass(CompiledClassBase): program: Program abi: Optional[AbiType] = None + @property + def is_cairo1(self) -> bool: + return False + def get_builtins(self) -> List[str]: return self.program.builtins diff --git a/src/starkware/starknet/testing/state.py b/src/starkware/starknet/testing/state.py index 6137dfd5..943b3f5d 100644 --- a/src/starkware/starknet/testing/state.py +++ b/src/starkware/starknet/testing/state.py @@ -98,10 +98,7 @@ async def empty(cls, general_config: Optional[StarknetGeneralConfig] = None) -> contract_class_storage=ffc.storage, ) state = CachedState( - block_info=BlockInfo.empty( - sequencer_address=general_config.sequencer_address, - use_kzg_da=general_config.use_kzg_da, - ), + block_info=BlockInfo.empty(sequencer_address=general_config.sequencer_address), state_reader=state_reader, compiled_class_cache={}, ) diff --git a/src/starkware/starkware_utils/commitment_tree/patricia_tree/fast_patricia_update.py b/src/starkware/starkware_utils/commitment_tree/patricia_tree/fast_patricia_update.py index 34d4ce36..4e9157f6 100644 --- a/src/starkware/starkware_utils/commitment_tree/patricia_tree/fast_patricia_update.py +++ b/src/starkware/starkware_utils/commitment_tree/patricia_tree/fast_patricia_update.py @@ -72,7 +72,8 @@ class TreeContext: # Updated nodes, grouped and ordered by dependency. nodes_by_dependency_layers: List[List[IndexedNode]] ffc: FactFetchingContext - leaf_db_keys: List[bytes] + # Maps a modified leaf (full) index to its DB key. + modified_leaves_to_db_keys: Dict[int, bytes] @classmethod def create( @@ -84,7 +85,7 @@ def create( prefetched_nodes={}, nodes_by_dependency_layers=[], ffc=ffc, - leaf_db_keys=[], + modified_leaves_to_db_keys={}, ) def get_node_height(self, index: int) -> int: @@ -107,18 +108,20 @@ class SubTree: def set_leaf(self, context: TreeContext, leaf_fact_cls: Optional[Type[TLeafFact]]): """ Assumes the subtree represents a leaf; creates a corresponding Node object and sets it. + If `leaf_fact_cls` is not None, the DB key of the leaf is added to the tree context. """ - if leaf_fact_cls is not None: - db_key = leaf_fact_cls.db_key(suffix=self.root_hash) - context.leaf_db_keys.append(db_key) - if len(self.leaf_indices) == 0: # Leaf sibiling. value = self.root_hash else: + # Modified leaf. (leaf_index,) = self.leaf_indices assert self.index == leaf_index value = context.leaves[leaf_index] + if leaf_fact_cls is not None: + context.modified_leaves_to_db_keys[leaf_index] = leaf_fact_cls.db_key( + suffix=self.root_hash + ) context.prefetched_nodes[self.index] = ( EMPTY_NODE if value == EmptyNodeFact.EMPTY_NODE_HASH else Node.from_value(value=value) diff --git a/src/starkware/starkware_utils/commitment_tree/patricia_tree/patricia_tree.py b/src/starkware/starkware_utils/commitment_tree/patricia_tree/patricia_tree.py index 62a5ef0e..9df35032 100644 --- a/src/starkware/starkware_utils/commitment_tree/patricia_tree/patricia_tree.py +++ b/src/starkware/starkware_utils/commitment_tree/patricia_tree/patricia_tree.py @@ -3,6 +3,7 @@ import marshmallow_dataclass +from starkware.python.utils_stub_module import safe_zip from starkware.starkware_utils.commitment_tree.binary_fact_tree import ( BinaryFactDict, BinaryFactTree, @@ -124,15 +125,25 @@ async def get_diff_between_patricia_trees( return await self_node.get_diff_between_trees(other=other_node, ffc=ffc, fact_cls=fact_cls) async def fetch_witnesses( - self, ffc: FactFetchingContext, sorted_leaf_indices: List[int], fact_cls: Type[TLeafFact] - ): + self, + ffc: FactFetchingContext, + sorted_leaf_indices: List[int], + fact_cls: Optional[Type[TLeafFact]], + empty_leaf: TLeafFact, + ) -> Dict[int, TLeafFact]: """ Fetches the necessary witnesses from storage to update the tree at the provided leaf - indices. + indices. This function is meant to be called with an underlying CachedStorage, filling the + cache with the witnesses. If fact_cls is given, the witnesses include the leaves + (modified and siblings) and this function returns the previous leaves at the given indices. + Otherwise, empty leaves are returned. """ + assert empty_leaf.is_empty + leaves = {index: empty_leaf for index in sorted_leaf_indices} + if self.root == EmptyNodeFact.EMPTY_NODE_HASH: - # Nothing to fetch. - return + # Nothing to fetch and all leaves are empty. + return leaves leaf_layer_prefix = 1 << self.height sorted_leaf_full_indices = [leaf_layer_prefix | index for index in sorted_leaf_indices] @@ -145,5 +156,19 @@ async def fetch_witnesses( context=tree_context, leaf_fact_cls=fact_cls, ) - # Populate the cache and ignore. - await ffc.storage.mget_or_fail(tree_context.leaf_db_keys) + # Get the facts of the modified leaves. + modified_leaves_facts = await ffc.storage.mget_or_fail( + list(tree_context.modified_leaves_to_db_keys.values()) + ) + + # Override non-empty leaves. + if fact_cls is not None: + leaves.update( + { + leaf_index ^ leaf_layer_prefix: fact_cls.deserialize(leaf_fact) + for leaf_index, leaf_fact in safe_zip( + tree_context.modified_leaves_to_db_keys.keys(), modified_leaves_facts + ) + } + ) + return leaves diff --git a/src/starkware/starkware_utils/marshmallow_dataclass_fields.py b/src/starkware/starkware_utils/marshmallow_dataclass_fields.py index 7d9ae019..0b45a605 100644 --- a/src/starkware/starkware_utils/marshmallow_dataclass_fields.py +++ b/src/starkware/starkware_utils/marshmallow_dataclass_fields.py @@ -3,7 +3,7 @@ import re from abc import ABC, abstractmethod from enum import Enum -from typing import Any, Callable, Dict, Optional, Type +from typing import Any, Callable, Dict, Optional, Tuple, Type import marshmallow import marshmallow.exceptions @@ -13,7 +13,7 @@ from marshmallow.base import FieldABC from mypy_extensions import KwArg, VarArg -from starkware.python.utils import from_bytes +from starkware.python.utils import from_bytes, to_bytes from starkware.starkware_utils.custom_raising_dict import CustomRaisingDict, CustomRaisingFrozenDict FieldMetadata = Dict[str, Any] @@ -187,6 +187,68 @@ def _deserialize(self, value, attr, data, **kwargs): return bytes.fromhex(value) +class BytesAsIntTuple(mfields.Field): + """ + A field that behaves like bytes, but serializes to a tuple of ints. + """ + + default_error_messages = {"invalid": 'Expected a tuple of ints, got: "{input}".'} + + def _serialize(self, value, attr, obj, **kwargs) -> Optional[Tuple[int, ...]]: + if value is None: + return None + assert isinstance(value, bytes) + return tuple(value) + + def _deserialize(self, value, attr, data, **kwargs) -> bytes: + if not isinstance(value, tuple): + raise self.make_error("invalid", input=value) + + return bytes(value) + + +class IntAsBytesIntTuple(mfields.Field): + """ + A field that behaves like an int, but serializes using BytesAsIntTuple over the byte + representation of self. + """ + + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.bytes_as_int_tuple = BytesAsIntTuple(**kwargs) + + def _serialize(self, value, attr, obj, **kwargs) -> Optional[Tuple[int, ...]]: + return self.bytes_as_int_tuple._serialize( + to_bytes(value, byte_order="big"), attr, obj, **kwargs + ) + + def _deserialize(self, value, attr, data, **kwargs) -> int: + return int.from_bytes( + self.bytes_as_int_tuple._deserialize(value, attr, data, **kwargs), byteorder="big" + ) + + +class DictAsList(mfields.Dict): + """ + A field that behaves like a dict, but serializes to a list of 2 element tuples. + """ + + default_error_messages = {"invalid": 'Expected a list of length 2 tuples, got: "{input}".'} + + def _serialize(self, value, attr, obj, **kwargs): + serialized = super()._serialize(value, attr, obj, **kwargs) + if serialized is None: + return None + + return [(k, v) for k, v in serialized.items()] + + def _deserialize(self, value, attr, data, **kwargs): + if not isinstance(value, list) or any(len(elem) != 2 for elem in value): + raise self.make_error("invalid", input=value) + + return super()._deserialize({elem[0]: elem[1] for elem in value}, attr, data, **kwargs) + + class BytesAsBase64Str(mfields.Field): """ A field that behaves like bytes, but serializes to base64. diff --git a/src/starkware/storage/BUILD b/src/starkware/storage/BUILD index 01445eb1..2ad4e8fb 100644 --- a/src/starkware/storage/BUILD +++ b/src/starkware/storage/BUILD @@ -1,12 +1,13 @@ load("//bazel_utils:python.bzl", "pytest_test") load("//bazel_utils/python:defs.bzl", "requirement") +package(default_visibility = ["//visibility:public"]) + py_library( name = "starkware_storage_metric_lib", srcs = [ "metrics.py", ], - visibility = ["//visibility:public"], deps = [requirement("prometheus_client")], ) @@ -15,19 +16,15 @@ py_library( srcs = [ "test_utils.py", ], - visibility = ["//visibility:public"], deps = [":starkware_abstract_storage_lib"], ) -package(default_visibility = ["//visibility:public"]) - py_library( name = "starkware_abstract_storage_lib", srcs = [ "__init__.py", "storage.py", ], - visibility = ["//visibility:public"], deps = [ "//src/starkware/python:starkware_python_utils_lib", "//src/starkware/starkware_utils:starkware_config_utils_lib", @@ -41,7 +38,6 @@ py_library( srcs = [ "dict_storage.py", ], - visibility = ["//visibility:public"], deps = [ ":starkware_abstract_storage_lib", ":starkware_storage_metric_lib", @@ -55,7 +51,6 @@ py_library( srcs = [ "imm_storage.py", ], - visibility = ["//visibility:public"], deps = [":starkware_abstract_storage_lib"], ) @@ -64,7 +59,6 @@ pytest_test( srcs = [ "storage_test.py", ], - visibility = ["//visibility:public"], deps = [ ":starkware_abstract_storage_lib", ":starkware_dict_storage_lib", @@ -79,7 +73,6 @@ py_library( "gated_storage.py", "names.py", ], - visibility = ["//visibility:public"], deps = [ ":starkware_abstract_storage_lib", "//src/starkware/starkware_utils/time:starkware_utils_time_lib", @@ -91,7 +84,6 @@ py_library( srcs = [ "storage_utils.py", ], - visibility = ["//visibility:public"], deps = [ ":starkware_abstract_storage_lib", "//src/starkware/python:starkware_python_utils_lib", @@ -104,7 +96,6 @@ pytest_test( srcs = [ "gated_storage_test.py", ], - visibility = ["//visibility:public"], deps = [ ":starkware_storage_lib", ":starkware_storage_test_utils_lib",