diff --git a/Dockerfile b/Dockerfile index 01c66ff3..f130a57f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ RUN ./docker_common_deps.sh RUN curl https://binaries.soliditylang.org/linux-amd64/solc-linux-amd64-v0.6.12+commit.27d51765 -o /usr/local/bin/solc-0.6.12 RUN echo 'f6cb519b01dabc61cab4c184a3db11aa591d18151e362fcae850e42cffdfb09a /usr/local/bin/solc-0.6.12' | sha256sum --check RUN chmod +x /usr/local/bin/solc-0.6.12 -RUN npm install -g --unsafe-perm ganache@7.4.3 vsce@1.87.1 +RUN npm install -g --unsafe-perm ganache@7.9.0 vsce@1.87.1 COPY . /app RUN chown -R starkware:starkware /app diff --git a/WORKSPACE b/WORKSPACE index b50429b2..c54e67b5 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -33,6 +33,14 @@ http_file( ], ) +http_file( + name = "solc-0.8.24", + downloaded_file_path = "solc-0.8.24", + executable = True, + sha256 = "fb03a29a517452b9f12bcf459ef37d0a543765bb3bbc911e70a87d6a37c30d5f", + urls = ["https://binaries.soliditylang.org/linux-amd64/solc-linux-amd64-v0.8.24+commit.e11b9ed9"], +) + http_archive( name = "rules_python", patch_args = ["-p1"], @@ -52,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.6.0-rc.0/release-x86_64-unknown-linux-musl.tar.gz", + url = "https://github.com/starkware-libs/cairo/releases/download/v2.6.0/release-x86_64-unknown-linux-musl.tar.gz", ) http_archive( diff --git a/bazel_utils/BUILD b/bazel_utils/BUILD index 61ff2e99..efda4392 100644 --- a/bazel_utils/BUILD +++ b/bazel_utils/BUILD @@ -20,6 +20,11 @@ sh_binary( srcs = ["@solc-0.6.12//file"], ) +sh_binary( + name = "solc-0.8.24", + srcs = ["@solc-0.8.24//file"], +) + py_library( name = "default_extract_artifacts_lib", srcs = [ diff --git a/package.json b/package.json index 86cf3446..01f90da8 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "private": true, "description": "", "dependencies": { - "ganache": "7.4.4" + "ganache": "7.9.0" }, "devDependencies": {}, "author": "", diff --git a/src/starkware/cairo/common/find_element.cairo b/src/starkware/cairo/common/find_element.cairo index c7cf8852..c598b0d6 100644 --- a/src/starkware/cairo/common/find_element.cairo +++ b/src/starkware/cairo/common/find_element.cairo @@ -1,4 +1,4 @@ -from starkware.cairo.common.math import assert_le, assert_le_felt, assert_nn_le +from starkware.cairo.common.math import assert_le, assert_le_felt, assert_lt_felt, assert_nn_le const FIND_ELEMENT_RANGE_CHECK_USAGE = 2; @@ -67,7 +67,7 @@ func find_element{range_check_ptr}(array_ptr: felt*, elm_size, n_elms, key) -> ( // Given an array sorted by its first field, returns the pointer to the first element in the array // whose first field is at least key. If no such item exists, returns a pointer to the end of the // array. -// Prover assumption: all the keys (the first field in each item) are in [0, RANGE_CHECK_BOUND). +// Assumption: the array is sorted as unsigned numbers. func search_sorted_lower{range_check_ptr}(array_ptr: felt*, elm_size, n_elms, key) -> ( elm_ptr: felt* ) { @@ -105,7 +105,7 @@ func search_sorted_lower{range_check_ptr}(array_ptr: felt*, elm_size, n_elms, ke } if (index != 0) { - assert_le_felt(a=[elm_ptr - elm_size] + 1, b=key); + assert_lt_felt(a=[elm_ptr - elm_size], b=key); } return (elm_ptr=elm_ptr); @@ -114,7 +114,7 @@ func search_sorted_lower{range_check_ptr}(array_ptr: felt*, elm_size, n_elms, ke // Given an array sorted by its first field, returns the pointer to the first element in the array // whose first field is exactly key. If no such item exists, returns an undefined pointer, // and success=0. -// Prover assumption: all the keys (the first field in each item) are in [0, RANGE_CHECK_BOUND). +// Assumption: the array is sorted as unsigned numbers. func search_sorted{range_check_ptr}(array_ptr: felt*, elm_size, n_elms, key) -> ( elm_ptr: felt*, success: felt ) { diff --git a/src/starkware/cairo/lang/VERSION b/src/starkware/cairo/lang/VERSION index 77661707..c317a918 100644 --- a/src/starkware/cairo/lang/VERSION +++ b/src/starkware/cairo/lang/VERSION @@ -1 +1 @@ -0.13.1a0 +0.13.1 diff --git a/src/starkware/cairo/lang/vm/cairo_pie.py b/src/starkware/cairo/lang/vm/cairo_pie.py index 26e381b4..443709fe 100644 --- a/src/starkware/cairo/lang/vm/cairo_pie.py +++ b/src/starkware/cairo/lang/vm/cairo_pie.py @@ -420,22 +420,15 @@ def verify_zip_format(cls, zf: zipfile.ZipFile): ), "Invalid list of inner files in the CairoPIE zip." # Make sure the file sizes are reasonable. - file_size = lambda name: inner_files[name].file_size if name in inner_files else 0 - assert ( - file_size(cls.METADATA_FILENAME) < cls.MAX_SIZE - ), f"Invalid file size for {cls.METADATA_FILENAME}." - assert ( - file_size(cls.MEMORY_FILENAME) < cls.MAX_SIZE - ), f"Invalid file size for {cls.MEMORY_FILENAME}." - assert ( - file_size(cls.ADDITIONAL_DATA_FILENAME) < cls.MAX_SIZE - ), f"Invalid file size for {cls.ADDITIONAL_DATA_FILENAME}." - assert ( - file_size(cls.EXECUTION_RESOURCES_FILENAME) < 10000 - ), f"Invalid file size for {cls.EXECUTION_RESOURCES_FILENAME}." - assert ( - file_size(cls.VERSION_FILENAME) < 10000 - ), f"Invalid file size for {cls.VERSION_FILENAME}." + for name, limit in ( + (cls.METADATA_FILENAME, cls.MAX_SIZE), + (cls.MEMORY_FILENAME, cls.MAX_SIZE), + (cls.ADDITIONAL_DATA_FILENAME, cls.MAX_SIZE), + (cls.EXECUTION_RESOURCES_FILENAME, 10000), + (cls.VERSION_FILENAME, 10000), + ): + size = inner_files[name].file_size if name in inner_files else 0 + assert size < limit, f"Invalid file size {size} for {name}; limit is {limit}." def get_segment(self, segment_info: SegmentInfo): return self.memory.get_range( diff --git a/src/starkware/cairo/sharp/client_lib.py b/src/starkware/cairo/sharp/client_lib.py index b4d92b8e..346b7eaf 100644 --- a/src/starkware/cairo/sharp/client_lib.py +++ b/src/starkware/cairo/sharp/client_lib.py @@ -12,11 +12,11 @@ class ClientLib: This is a slim wrapper around the SHARP API. """ - def __init__(self, service_url: str): + def __init__(self, url: str): """ service_url is the SHARP url. """ - self.service_url = service_url + self.url = url def add_job(self, cairo_pie: CairoPie) -> str: """ @@ -48,13 +48,12 @@ def _send(self, action: str, payload: dict) -> dict: action: the action to be sent to the SHARP. payload: action specific parameters. """ - data = { "action": action, "request": payload, } http = urllib3.PoolManager() res = http.request( - method="POST", url=self.service_url, body=json.dumps(data).encode("utf-8") + method="POST", url=f"{self.url}{action}", body=json.dumps(data).encode("utf-8") ) return json.loads(res.data.decode("utf-8")) diff --git a/src/starkware/cairo/sharp/client_lib_test.py b/src/starkware/cairo/sharp/client_lib_test.py index 6c762c46..ad952b88 100644 --- a/src/starkware/cairo/sharp/client_lib_test.py +++ b/src/starkware/cairo/sharp/client_lib_test.py @@ -23,8 +23,10 @@ class Response: data: bytes +EXPECTED_URL = "https://some_url/" + + def test_add_job(monkeypatch: MonkeyPatch): - expected_url = "some url" expected_data = { "action": "add_job", "request": {"cairo_pie": base64.b64encode(MockCairoPie().serialize()).decode("ascii")}, @@ -34,20 +36,19 @@ def test_add_job(monkeypatch: MonkeyPatch): # A mock function enforcing expected scenario. def check_expected(_, method: str, url: str, body: str): assert method == "POST" - assert url == expected_url + assert url == EXPECTED_URL + expected_data["action"] assert json.loads(body) == expected_data return Response(json.dumps({"cairo_job_key": expected_res}).encode("utf-8")) monkeypatch.setattr(PoolManager, "request", check_expected) # Test the scenario. - client = ClientLib(expected_url) + client = ClientLib(url=EXPECTED_URL) res = client.add_job(MockCairoPie()) assert res == expected_res def test_get_status(monkeypatch: MonkeyPatch): - expected_url = "some url" expected_id = "some id" expected_data = {"action": "get_status", "request": {"cairo_job_key": expected_id}} expected_res = "the status" @@ -55,14 +56,14 @@ def test_get_status(monkeypatch: MonkeyPatch): # A mock function enforcing expected scenario. def check_expected(_, method: str, url: str, body: str): assert method == "POST" - assert url == expected_url + assert url == EXPECTED_URL + expected_data["action"] assert json.loads(body) == expected_data return Response(json.dumps({"status": expected_res}).encode("utf-8")) monkeypatch.setattr(PoolManager, "request", check_expected) # Test the scenario. - client = ClientLib(expected_url) + client = ClientLib(url=EXPECTED_URL) res = client.get_status(expected_id) assert res == expected_res @@ -76,7 +77,7 @@ def check_expected(_, method: str, url: str, body: str): monkeypatch.setattr(PoolManager, "request", check_expected) # Test the scenario. - client = ClientLib("") + client = ClientLib(url=EXPECTED_URL) with pytest.raises(AssertionError, match="Error when sending job to SHARP:"): client.add_job(MockCairoPie()) diff --git a/src/starkware/cairo/sharp/config.json b/src/starkware/cairo/sharp/config.json index e53811d5..925a54d3 100644 --- a/src/starkware/cairo/sharp/config.json +++ b/src/starkware/cairo/sharp/config.json @@ -1,5 +1,5 @@ { - "prover_url": "https://testnet.provingservice.io", + "url": "https://testnet.provingservice.io/", "verifier_address": "0x07ec0D28e50322Eb0C159B9090ecF3aeA8346DFe", "steps_limit": 1000000 } diff --git a/src/starkware/cairo/sharp/sharp_client.py b/src/starkware/cairo/sharp/sharp_client.py index 4f356516..636e30b1 100755 --- a/src/starkware/cairo/sharp/sharp_client.py +++ b/src/starkware/cairo/sharp/sharp_client.py @@ -78,9 +78,11 @@ def run_program(self, program: Program, program_input_path: Optional[str]) -> Ca self.cairo_run_path, "--layout=all_solidity", f"--program={program_file.name}", - f"--program_input={program_input_path}" - if program_input_path is not None - else None, + ( + f"--program_input={program_input_path}" + if program_input_path is not None + else None + ), f"--cairo_pie_output={cairo_pie_file.name}", ], ) @@ -152,7 +154,7 @@ def init_client(bin_dir: str, node_rpc_url: Optional[str] = None) -> SharpClient # Initialize the SharpClient. client = SharpClient( - service_client=ClientLib(config["prover_url"]), + service_client=ClientLib(url=config["url"]), contract_client=FactChecker( fact_registry_address=config["verifier_address"], node_rpc_url=node_rpc_url if node_rpc_url is not None else "", @@ -167,9 +169,10 @@ def init_client(bin_dir: str, node_rpc_url: Optional[str] = None) -> SharpClient def submit(args, command_args): parser = argparse.ArgumentParser( - description="Submits a Cairo job to SHARP. " - "You can provide (1) the source code and the program input OR (2) the compiled program and " - "the program input OR (3) the Cairo PIE." + description=( + "Submits a Cairo job to SHARP. You can provide (1) the source code and the program " + "input OR (2) the compiled program and the program input OR (3) the Cairo PIE." + ) ) parser.add_argument( @@ -242,7 +245,10 @@ def is_verified(args, command_args): ) parser.add_argument("fact", type=str, help="The fact to verify if registered.") parser.add_argument( - "--node_url", required=True, type=str, help="URL for a Sepolia Ethereum node RPC API." + "--node_url", + required=True, + type=str, + help="URL for a Sepolia Ethereum node RPC API.", ) parser.parse_args(command_args, namespace=args) @@ -266,8 +272,10 @@ def main(): "--bin_dir", type=str, default="", - help="The path to a directory that contains the cairo-compile and cairo-run scripts. " - "If not specified, files are assumed to be in the system's PATH.", + help=( + "The path to a directory that contains the cairo-compile and cairo-run scripts. " + "If not specified, files are assumed to be in the system's PATH." + ), ) parser.add_argument( "--flavor", diff --git a/src/starkware/solidity/components/BUILD b/src/starkware/solidity/components/BUILD index 8dae9781..ccf187e9 100644 --- a/src/starkware/solidity/components/BUILD +++ b/src/starkware/solidity/components/BUILD @@ -4,6 +4,16 @@ package(default_visibility = ["//visibility:public"]) exports_files(glob(["*.sol"])) +sol_library( + name = "governance_sol", + srcs = [ + "Governance.sol", + ], + deps = [ + "//src/starkware/solidity/interfaces:governance_interface_sol", + ], +) + sol_library( name = "governance_contract_sol", srcs = [ @@ -21,13 +31,21 @@ sol_library( name = "solidity_contracts_components_sol", srcs = [ "FactRegistry.sol", - "GovernedFinalizable.sol", "OnchainDataFactTreeEncoder.sol", ], deps = [ - "//src/starkware/solidity/interfaces:governance_interface_sol", "//src/starkware/solidity/interfaces:solidity_contracts_interfaces_sol", "//src/starkware/solidity/libraries:common_library_sol", - "//src/starkware/solidity/libraries:named_storage_sol", + ], +) + +sol_library( + name = "governed_finalizable_sol", + srcs = [ + "GovernedFinalizable.sol", + ], + deps = [ + "//src/starkware/solidity/interfaces:governance_interface_sol", + "//src/starkware/solidity/libraries:named_storage8_sol", ], ) diff --git a/src/starkware/solidity/components/Governance.sol b/src/starkware/solidity/components/Governance.sol index 913303f0..247a5e26 100644 --- a/src/starkware/solidity/components/Governance.sol +++ b/src/starkware/solidity/components/Governance.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity >=0.6.12; import "../interfaces/MGovernance.sol"; diff --git a/src/starkware/solidity/components/GovernedFinalizable.sol b/src/starkware/solidity/components/GovernedFinalizable.sol index 79d0804c..6450e8d6 100644 --- a/src/starkware/solidity/components/GovernedFinalizable.sol +++ b/src/starkware/solidity/components/GovernedFinalizable.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity ^0.8.0; import "starkware/solidity/interfaces/MGovernance.sol"; -import "starkware/solidity/libraries/NamedStorage.sol"; +import "starkware/solidity/libraries/NamedStorage8.sol"; /** A Governor controlled finalizable contract. diff --git a/src/starkware/solidity/components/OnchainDataFactTreeEncoder.sol b/src/starkware/solidity/components/OnchainDataFactTreeEncoder.sol index c2dd382e..031e0f88 100644 --- a/src/starkware/solidity/components/OnchainDataFactTreeEncoder.sol +++ b/src/starkware/solidity/components/OnchainDataFactTreeEncoder.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity >=0.6.12; library OnchainDataFactTreeEncoder { struct DataAvailabilityFact { diff --git a/src/starkware/solidity/components/Operator.sol b/src/starkware/solidity/components/Operator.sol index 7880d89d..03eeac28 100644 --- a/src/starkware/solidity/components/Operator.sol +++ b/src/starkware/solidity/components/Operator.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity >=0.6.12; import "../interfaces/MOperator.sol"; import "../interfaces/MGovernance.sol"; diff --git a/src/starkware/solidity/interfaces/BlockDirectCall.sol b/src/starkware/solidity/interfaces/BlockDirectCall.sol index 4f5860a9..716654e3 100644 --- a/src/starkware/solidity/interfaces/BlockDirectCall.sol +++ b/src/starkware/solidity/interfaces/BlockDirectCall.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity >=0.6.12; /* This contract provides means to block direct call of an external function. diff --git a/src/starkware/solidity/interfaces/ContractInitializer.sol b/src/starkware/solidity/interfaces/ContractInitializer.sol index ec01f988..aae74be3 100644 --- a/src/starkware/solidity/interfaces/ContractInitializer.sol +++ b/src/starkware/solidity/interfaces/ContractInitializer.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity >=0.6.12; /** Interface for contract initialization. diff --git a/src/starkware/solidity/interfaces/IFactRegistry.sol b/src/starkware/solidity/interfaces/IFactRegistry.sol index 94537e6a..0fe03ce5 100644 --- a/src/starkware/solidity/interfaces/IFactRegistry.sol +++ b/src/starkware/solidity/interfaces/IFactRegistry.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity >=0.6.12; /* The Fact Registry design pattern is a way to separate cryptographic verification from the diff --git a/src/starkware/solidity/interfaces/Identity.sol b/src/starkware/solidity/interfaces/Identity.sol index d540c8d6..71a44732 100644 --- a/src/starkware/solidity/interfaces/Identity.sol +++ b/src/starkware/solidity/interfaces/Identity.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity >=0.6.12; interface Identity { /* diff --git a/src/starkware/solidity/interfaces/MGovernance.sol b/src/starkware/solidity/interfaces/MGovernance.sol index 33b3a5ab..4e282559 100644 --- a/src/starkware/solidity/interfaces/MGovernance.sol +++ b/src/starkware/solidity/interfaces/MGovernance.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity >=0.6.12; abstract contract MGovernance { function _isGovernor(address user) internal view virtual returns (bool); diff --git a/src/starkware/solidity/interfaces/MOperator.sol b/src/starkware/solidity/interfaces/MOperator.sol index 17f2c832..5a7cf96d 100644 --- a/src/starkware/solidity/interfaces/MOperator.sol +++ b/src/starkware/solidity/interfaces/MOperator.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity >=0.6.12; import "./MGovernance.sol"; diff --git a/src/starkware/solidity/interfaces/ProxySupport.sol b/src/starkware/solidity/interfaces/ProxySupport.sol index a2d049ab..71f2713e 100644 --- a/src/starkware/solidity/interfaces/ProxySupport.sol +++ b/src/starkware/solidity/interfaces/ProxySupport.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity >=0.6.12; import "../components/Governance.sol"; import "../libraries/Addresses.sol"; diff --git a/src/starkware/solidity/libraries/Addresses.sol b/src/starkware/solidity/libraries/Addresses.sol index 76c185fc..f033a608 100644 --- a/src/starkware/solidity/libraries/Addresses.sol +++ b/src/starkware/solidity/libraries/Addresses.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity >=0.6.12; /* Common Utility Libraries. diff --git a/src/starkware/solidity/libraries/BUILD b/src/starkware/solidity/libraries/BUILD index 828830a1..62c494fb 100644 --- a/src/starkware/solidity/libraries/BUILD +++ b/src/starkware/solidity/libraries/BUILD @@ -13,6 +13,15 @@ sol_library( deps = [], ) +sol_library( + name = "named_storage8_sol", + srcs = [ + "NamedStorage8.sol", + ], + visibility = ["//visibility:public"], + deps = [], +) + sol_library( name = "common_library_sol", srcs = [ diff --git a/src/starkware/solidity/libraries/NamedStorage8.sol b/src/starkware/solidity/libraries/NamedStorage8.sol new file mode 100644 index 00000000..3fa1967a --- /dev/null +++ b/src/starkware/solidity/libraries/NamedStorage8.sol @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: Apache-2.0. +pragma solidity ^0.8.0; + +/* + Library to provide basic storage, in storage location out of the low linear address space. + + New types of storage variables should be added here upon need. +*/ +library NamedStorage { + function bytes32ToUint256Mapping(string memory tag_) + internal + pure + returns (mapping(bytes32 => uint256) storage randomVariable) + { + bytes32 location = keccak256(abi.encodePacked(tag_)); + assembly { + randomVariable.slot := location + } + } + + function bytes32ToAddressMapping(string memory tag_) + internal + pure + returns (mapping(bytes32 => address) storage randomVariable) + { + bytes32 location = keccak256(abi.encodePacked(tag_)); + assembly { + randomVariable.slot := location + } + } + + function uintToAddressMapping(string memory tag_) + internal + pure + returns (mapping(uint256 => address) storage randomVariable) + { + bytes32 location = keccak256(abi.encodePacked(tag_)); + assembly { + randomVariable.slot := location + } + } + + function addressToAddressMapping(string memory tag_) + internal + pure + returns (mapping(address => address) storage randomVariable) + { + bytes32 location = keccak256(abi.encodePacked(tag_)); + assembly { + randomVariable.slot := location + } + } + + function addressToBoolMapping(string memory tag_) + internal + pure + returns (mapping(address => bool) storage randomVariable) + { + bytes32 location = keccak256(abi.encodePacked(tag_)); + assembly { + randomVariable.slot := location + } + } + + function getUintValue(string memory tag_) internal view returns (uint256 retVal) { + bytes32 slot = keccak256(abi.encodePacked(tag_)); + assembly { + retVal := sload(slot) + } + } + + function setUintValue(string memory tag_, uint256 value) internal { + bytes32 slot = keccak256(abi.encodePacked(tag_)); + assembly { + sstore(slot, value) + } + } + + function setUintValueOnce(string memory tag_, uint256 value) internal { + require(getUintValue(tag_) == 0, "ALREADY_SET"); + setUintValue(tag_, value); + } + + function getAddressValue(string memory tag_) internal view returns (address retVal) { + bytes32 slot = keccak256(abi.encodePacked(tag_)); + assembly { + retVal := sload(slot) + } + } + + function setAddressValue(string memory tag_, address value) internal { + bytes32 slot = keccak256(abi.encodePacked(tag_)); + assembly { + sstore(slot, value) + } + } + + function setAddressValueOnce(string memory tag_, address value) internal { + require(getAddressValue(tag_) == address(0x0), "ALREADY_SET"); + setAddressValue(tag_, value); + } + + function getBoolValue(string memory tag_) internal view returns (bool retVal) { + bytes32 slot = keccak256(abi.encodePacked(tag_)); + assembly { + retVal := sload(slot) + } + } + + function setBoolValue(string memory tag_, bool value) internal { + bytes32 slot = keccak256(abi.encodePacked(tag_)); + assembly { + sstore(slot, value) + } + } +} diff --git a/src/starkware/starknet/business_logic/transaction/deprecated_objects.py b/src/starkware/starknet/business_logic/transaction/deprecated_objects.py index d4fff2b7..d754c3e5 100644 --- a/src/starkware/starknet/business_logic/transaction/deprecated_objects.py +++ b/src/starkware/starknet/business_logic/transaction/deprecated_objects.py @@ -330,9 +330,7 @@ def charge_fee( return None, 0 actual_fee = calculate_tx_fee( - l1_gas_price=state.block_info.l1_gas_price.price_in_wei, - general_config=general_config, - resources=resources, + l1_gas_price=state.block_info.l1_gas_price.price_in_wei, resources=resources ) fee_transfer_info = execute_fee_transfer( general_config=general_config, @@ -379,9 +377,7 @@ def _apply_specific_sequential_changes( self._handle_nonce(state=state) return self.charge_fee( - state=state, - general_config=general_config, - resources=actual_resources, + state=state, resources=actual_resources, general_config=general_config ) @@ -1539,7 +1535,6 @@ def _apply_specific_concurrent_changes( if self.paid_fee_on_l1 is not None: required_fee = calculate_tx_fee( l1_gas_price=state.block_info.l1_gas_price.price_in_wei, - general_config=general_config, resources=actual_resources, ) # For now, assert only that any amount of fee was paid. diff --git a/src/starkware/starknet/business_logic/transaction/fee.py b/src/starkware/starknet/business_logic/transaction/fee.py index e58297b8..923b07c0 100644 --- a/src/starkware/starknet/business_logic/transaction/fee.py +++ b/src/starkware/starknet/business_logic/transaction/fee.py @@ -1,4 +1,5 @@ import math +from typing import Mapping from starkware.starknet.business_logic.execution.deprecated_objects import ExecutionResourcesManager from starkware.starknet.business_logic.execution.execute_entry_point import ExecuteEntryPoint @@ -9,7 +10,7 @@ ) from starkware.starknet.business_logic.state.state_api import SyncState from starkware.starknet.business_logic.utils import extract_l1_gas_and_cairo_usage -from starkware.starknet.definitions.constants import GasCost +from starkware.starknet.definitions.constants import VERSIONED_CONSTANTS, GasCost from starkware.starknet.definitions.error_codes import StarknetErrorCode from starkware.starknet.definitions.general_config import StarknetGeneralConfig from starkware.starknet.public import abi as starknet_abi @@ -59,7 +60,7 @@ def execute_fee_transfer( def calculate_l1_gas_by_cairo_usage( - general_config: StarknetGeneralConfig, + cairo_resource_fee_weights: Mapping[str, float], cairo_resource_usage: ResourcesMapping, ) -> float: """ @@ -67,7 +68,6 @@ def calculate_l1_gas_by_cairo_usage( I.e., returns the heaviest Cairo resource weight (in terms of L1 gas), as the size of a proof is determined similarly - by the (normalized) largest segment. """ - cairo_resource_fee_weights = general_config.cairo_resource_fee_weights cairo_resource_names = set(cairo_resource_usage.keys()) assert cairo_resource_names.issubset( cairo_resource_fee_weights.keys() @@ -82,9 +82,7 @@ def calculate_l1_gas_by_cairo_usage( return cairo_l1_gas_usage -def calculate_tx_fee( - resources: ResourcesMapping, l1_gas_price: int, general_config: StarknetGeneralConfig -) -> int: +def calculate_tx_fee(resources: ResourcesMapping, l1_gas_price: int) -> int: """ Calculates the fee of a transaction given its execution resources. We add the l1_gas_usage (which may include, for example, the direct cost of L2-to-L1 @@ -92,7 +90,7 @@ def calculate_tx_fee( """ l1_gas_usage, cairo_resource_usage = extract_l1_gas_and_cairo_usage(resources=resources) l1_gas_by_cairo_usage = calculate_l1_gas_by_cairo_usage( - general_config=general_config, + cairo_resource_fee_weights=VERSIONED_CONSTANTS.cairo_resource_fee_weights, cairo_resource_usage=cairo_resource_usage, ) total_l1_gas_usage = l1_gas_usage + l1_gas_by_cairo_usage diff --git a/src/starkware/starknet/compiler/v1/mainnet_libfuncs.json b/src/starkware/starknet/compiler/v1/mainnet_libfuncs.json index 27907da5..699214e7 100644 --- a/src/starkware/starknet/compiler/v1/mainnet_libfuncs.json +++ b/src/starkware/starknet/compiler/v1/mainnet_libfuncs.json @@ -26,6 +26,7 @@ "class_hash_to_felt252", "class_hash_try_from_felt252", "const_as_box", + "const_as_immediate", "contract_address_const", "contract_address_to_felt252", "contract_address_try_from_felt252", diff --git a/src/starkware/starknet/compiler/v1/testnet_libfuncs.json b/src/starkware/starknet/compiler/v1/testnet_libfuncs.json index 27907da5..699214e7 100644 --- a/src/starkware/starknet/compiler/v1/testnet_libfuncs.json +++ b/src/starkware/starknet/compiler/v1/testnet_libfuncs.json @@ -26,6 +26,7 @@ "class_hash_to_felt252", "class_hash_try_from_felt252", "const_as_box", + "const_as_immediate", "contract_address_const", "contract_address_to_felt252", "contract_address_try_from_felt252", diff --git a/src/starkware/starknet/core/os/block_context.cairo b/src/starkware/starknet/core/os/block_context.cairo index 31499e32..4386fb7b 100644 --- a/src/starkware/starknet/core/os/block_context.cairo +++ b/src/starkware/starknet/core/os/block_context.cairo @@ -3,6 +3,10 @@ from starkware.cairo.common.math import unsigned_div_rem from starkware.cairo.common.registers import get_fp_and_pc from starkware.starknet.common.new_syscalls import BlockInfo from starkware.starknet.core.os.builtins import BuiltinParams, get_builtin_params +from starkware.starknet.core.os.constants import ( + VALIDATE_BLOCK_NUMBER_ROUNDING, + VALIDATE_TIMESTAMP_ROUNDING, +) from starkware.starknet.core.os.contract_class.compiled_class import ( CompiledClassFact, load_compiled_class_facts, @@ -13,10 +17,6 @@ from starkware.starknet.core.os.contract_class.deprecated_compiled_class import ) from starkware.starknet.core.os.os_config.os_config import StarknetOsConfig -// Round down the block number and timestamp when queried inside `__validate__`. -const VALIDATE_BLOCK_NUMBER_ROUNDING = 100; -const VALIDATE_TIMESTAMP_ROUNDING = 3600; - // Represents information that is the same throughout the block. struct BlockContext { // Parameters for select_builtins. diff --git a/src/starkware/starknet/core/os/constants.cairo b/src/starkware/starknet/core/os/constants.cairo index 87316e77..db7bd6d1 100644 --- a/src/starkware/starknet/core/os/constants.cairo +++ b/src/starkware/starknet/core/os/constants.cairo @@ -1,3 +1,5 @@ +// Autogenerated file. + // An entry point offset that indicates that nothing needs to be done. // Used to implement an empty constructor. const NOP_ENTRY_POINT_OFFSET = -1; @@ -127,3 +129,7 @@ const L1_GAS = 'L1_GAS'; const L2_GAS = 'L2_GAS'; const L1_GAS_INDEX = 0; const L2_GAS_INDEX = 1; + +// Round down the block number and timestamp when queried inside `__validate__`. +const VALIDATE_BLOCK_NUMBER_ROUNDING = 100; +const VALIDATE_TIMESTAMP_ROUNDING = 3600; diff --git a/src/starkware/starknet/core/os/program_hash.json b/src/starkware/starknet/core/os/program_hash.json index 9d283e0a..c9c514c8 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": "0xa15c784d92588218d2e810337baf6e0d9bcf90c63e7b2ce830774da0c2940b" + "program_hash": "0x3e060e1f35eb3a968ab349767e3aeff9fa5d74f82230aeccab73345ac11282" } diff --git a/src/starkware/starknet/definitions/BUILD b/src/starkware/starknet/definitions/BUILD index 27fa9ac4..f0f900cb 100644 --- a/src/starkware/starknet/definitions/BUILD +++ b/src/starkware/starknet/definitions/BUILD @@ -50,12 +50,9 @@ py_library( ":starknet_definitions_lib", "//src/services/everest/definitions:everest_general_config_lib", "//src/starkware/cairo/lang:cairo_instances_lib", - "//src/starkware/cairo/lang/builtins:cairo_all_builtins_lib", "//src/starkware/python:starkware_python_utils_lib", "//src/starkware/starkware_utils:starkware_config_utils_lib", - "//src/starkware/starkware_utils:starkware_dataclasses_field_utils_lib", "//src/starkware/starkware_utils:starkware_dataclasses_utils_lib", - requirement("marshmallow"), requirement("marshmallow_dataclass"), ], ) diff --git a/src/starkware/starknet/definitions/constants.py b/src/starkware/starknet/definitions/constants.py index 9a59c6cf..19e6f233 100644 --- a/src/starkware/starknet/definitions/constants.py +++ b/src/starkware/starknet/definitions/constants.py @@ -126,9 +126,6 @@ LOG_MSG_TO_L1_ENCODED_DATA_SIZE = (L2_TO_L1_MSG_HEADER_SIZE + 1) - LOG_MSG_TO_L1_N_TOPICS CONSUMED_MSG_TO_L2_ENCODED_DATA_SIZE = (L1_TO_L2_MSG_HEADER_SIZE + 1) - CONSUMED_MSG_TO_L2_N_TOPICS -# The (empirical) L1 gas cost of each Cairo step. -N_STEPS_FEE_WEIGHT = 0.005 - # Expected return values of a 'validate' entry point. VALIDATE_RETDATA = [from_bytes(b"VALID")] @@ -227,6 +224,8 @@ class ThinVersionedConstants: cairo_resource_fee_weights: Dict[str, float] + l2_resource_gas_costs: Dict[str, int] + @classmethod def create(cls): versioned_constants_json = json.load(cls.VERSIONED_CONSTANTS_PATH.open()) @@ -240,6 +239,7 @@ def create(cls): "max_contract_bytecode_size" ], cairo_resource_fee_weights=versioned_constants_json["vm_resource_fee_cost"], + l2_resource_gas_costs=versioned_constants_json["l2_resource_gas_costs"], ) diff --git a/src/starkware/starknet/definitions/error_codes.py b/src/starkware/starknet/definitions/error_codes.py index 925c917b..920ff7c9 100644 --- a/src/starkware/starknet/definitions/error_codes.py +++ b/src/starkware/starknet/definitions/error_codes.py @@ -84,6 +84,7 @@ class StarknetErrorCode(ErrorCode): UNINITIALIZED_CONTRACT = auto() UNSUPPORTED_TRANSACTION_VERSION = auto() # Native blockifier errors. + PY_CONTRACT_CLASS_ERROR = auto() PY_NATIVE_BLOCKIFIER_INPUT_ERROR = auto() PY_PROGRAM_ERROR = auto() PY_PYO3_ERROR = auto() @@ -171,6 +172,7 @@ def from_raw_code(cls, code: str) -> "StarknetErrorCode": StarknetErrorCode.DEPRECATED_TRANSACTION_VERSION, StarknetErrorCode.DUPLICATED_TRANSACTION, StarknetErrorCode.SENDER_ADDRESS_IS_BLOCKED, + StarknetErrorCode.UNSUPPORTED_TRANSACTION_VERSION, # Signature validation errors. StarkErrorCode.INVALID_SIGNATURE, # External deploy loading errors. @@ -208,7 +210,6 @@ def from_raw_code(cls, code: str) -> "StarknetErrorCode": StarknetErrorCode.OUT_OF_RANGE_CONTRACT_STORAGE_KEY, StarknetErrorCode.OUT_OF_RANGE_TRANSACTION_HASH, StarknetErrorCode.OUT_OF_RANGE_TRANSACTION_ID, - StarknetErrorCode.UNSUPPORTED_TRANSACTION_VERSION, # Deprecation errors. StarknetErrorCode.DEPRECATED_ENDPOINT, ] diff --git a/src/starkware/starknet/definitions/general_config.py b/src/starkware/starknet/definitions/general_config.py index 5cb0362e..ae4f60f7 100644 --- a/src/starkware/starknet/definitions/general_config.py +++ b/src/starkware/starknet/definitions/general_config.py @@ -1,20 +1,15 @@ -import copy import os from dataclasses import field -from typing import Any, Dict -import marshmallow.fields as mfields import marshmallow_dataclass from services.everest.definitions.general_config import EverestGeneralConfig -from starkware.cairo.lang.builtins.all_builtins import ALL_BUILTINS, OUTPUT_BUILTIN, with_suffix from starkware.cairo.lang.instances import starknet_instance, starknet_with_keccak_instance from starkware.python.utils import from_bytes from starkware.starknet.definitions import fields from starkware.starknet.definitions.chain_ids import StarknetChainId from starkware.starknet.definitions.constants import VERSIONED_CONSTANTS from starkware.starkware_utils.config_base import Config, load_config -from starkware.starkware_utils.field_validators import validate_dict, validate_non_negative from starkware.starkware_utils.marshmallow_dataclass_fields import ( RequiredBoolean, additional_metadata, @@ -61,7 +56,7 @@ value=default_general_config["sequencer_address"], ) DEFAULT_ENFORCE_L1_FEE = True -DEFAULT_USE_KZG_DA = False +DEFAULT_USE_KZG_DA = True # Given in units of wei. DEFAULT_DEPRECATED_L1_GAS_PRICE = 10**11 @@ -71,7 +66,7 @@ DEFAULT_MIN_FRI_L1_GAS_PRICE = 10**6 DEFAULT_MAX_FRI_L1_GAS_PRICE = 10**18 DEFAULT_MIN_FRI_L1_DATA_GAS_PRICE = 10**5 -DEFAULT_MAX_FRI_L1_DATA_GAS_PRICE = 10**10 +DEFAULT_MAX_FRI_L1_DATA_GAS_PRICE = 10**17 # Configuration schema definition. @@ -164,23 +159,6 @@ class StarknetGeneralConfig(EverestGeneralConfig): default=DEFAULT_SEQUENCER_ADDRESS, ) - cairo_resource_fee_weights: Dict[str, float] = field( - metadata=additional_metadata( - marshmallow_field=mfields.Dict( - keys=mfields.String, - values=mfields.Float, - validate=validate_dict( - "Cairo resource fee weights", value_validator=validate_non_negative - ), - ), - description=( - "A mapping from a Cairo resource to its coefficient in this transaction " - "fee calculation." - ), - ), - default_factory=lambda: VERSIONED_CONSTANTS.cairo_resource_fee_weights, - ) - enforce_l1_handler_fee: bool = field( metadata=additional_metadata( marshmallow_field=RequiredBoolean(), description="Enabler for L1 fee enforcement." @@ -231,36 +209,3 @@ def min_fri_l1_data_gas_price(self) -> int: @property def max_fri_l1_data_gas_price(self) -> int: return self.gas_price_bounds.max_fri_l1_data_gas_price - - -def build_general_config(raw_general_config: Dict[str, Any]) -> StarknetGeneralConfig: - """ - Updates the fee weights and builds the general config. - """ - raw_general_config = copy.deepcopy(raw_general_config) - cairo_resource_fee_weights: Dict[str, float] = raw_general_config["cairo_resource_fee_weights"] - assert cairo_resource_fee_weights.keys() == { - N_STEPS_RESOURCE - }, f"Only {N_STEPS_RESOURCE} weight should be given." - - n_steps_weight = cairo_resource_fee_weights[N_STEPS_RESOURCE] - - # Zero all entries. - cairo_resource_fee_weights.update( - {resource: 0.0 for resource in [N_STEPS_RESOURCE] + ALL_BUILTINS.with_suffix()} - ) - - # Update relevant entries. - cairo_resource_fee_weights.update( - { - N_STEPS_RESOURCE: n_steps_weight, - # All other weights are deduced from n_steps. - **{ - with_suffix(name): n_steps_weight * instance_def.ratio - for name, instance_def in STARKNET_LAYOUT_INSTANCE.builtins.items() - if name != OUTPUT_BUILTIN - }, - } - ) - - return StarknetGeneralConfig.load(data=raw_general_config) diff --git a/src/starkware/starknet/definitions/general_config.yml b/src/starkware/starknet/definitions/general_config.yml index ff14a275..0e92e474 100644 --- a/src/starkware/starknet/definitions/general_config.yml +++ b/src/starkware/starknet/definitions/general_config.yml @@ -1,13 +1,11 @@ -cairo_resource_fee_weights: - n_steps: 0.0025 constant_gas_price: false default_eth_price_in_fri: 1000000000000000000000 enforce_l1_handler_fee: true gas_price_bounds: - max_fri_l1_data_gas_price: 10000000000 + max_fri_l1_data_gas_price: 10000000000000 max_fri_l1_gas_price: 100000000000000 min_fri_l1_data_gas_price: 10 - min_fri_l1_gas_price: 100000000000 + min_fri_l1_gas_price: 30000000000 min_wei_l1_data_gas_price: 100000 min_wei_l1_gas_price: 10000000000 invoke_tx_max_n_steps: 1000000 @@ -16,5 +14,5 @@ starknet_os_config: chain_id: 1536727068981429685321 deprecated_fee_token_address: "0x3c9310766d2309bb2d7b2934fee57f5ae8bd2c4cbb4199c88f2230ed1d5f0df" fee_token_address: "0x17cbe4265c239101e83ffcd371cb5631101d389b088d962cd222062d9cfddab" -use_kzg_da: false +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 60b8a844..4a15e922 100644 --- a/src/starkware/starknet/definitions/versioned_constants.json +++ b/src/starkware/starknet/definitions/versioned_constants.json @@ -1,14 +1,19 @@ { + "tx_event_limits": { + "max_data_length": 300, + "max_keys_length": 50, + "max_n_emitted_events": 1000 + }, "gateway": { "max_calldata_length": 4000, - "max_contract_bytecode_size": 61440 + "max_contract_bytecode_size": 81920 }, + "invoke_tx_max_n_steps": 4000000, "l2_resource_gas_costs": { "milligas_per_data_felt": 128, "event_key_factor": 2, "milligas_per_code_byte": 875 }, - "invoke_tx_max_n_steps": 4000000, "max_recursion_depth": 50, "os_constants": { "nop_entry_point_offset": -1, @@ -152,294 +157,292 @@ "l1_gas": "L1_GAS", "l2_gas": "L2_GAS", "l1_gas_index": 0, - "l2_gas_index": 1 + "l2_gas_index": 1, + "validate_rounding_consts": { + "validate_block_number_rounding": 100, + "validate_timestamp_rounding": 3600 + } }, "os_resources": { "execute_syscalls": { "call_contract": { + "n_steps": 760, "builtin_instance_counter": { "range_check_builtin": 20 }, - "n_memory_holes": 0, - "n_steps": 760 + "n_memory_holes": 0 }, "delegate_call": { + "n_steps": 713, "builtin_instance_counter": { "range_check_builtin": 19 }, - "n_memory_holes": 0, - "n_steps": 713 + "n_memory_holes": 0 }, "delegate_l1_handler": { + "n_steps": 692, "builtin_instance_counter": { "range_check_builtin": 15 }, - "n_memory_holes": 0, - "n_steps": 692 + "n_memory_holes": 0 }, "deploy": { + "n_steps": 1012, "builtin_instance_counter": { "pedersen_builtin": 7, "range_check_builtin": 19 }, - "n_memory_holes": 0, - "n_steps": 1012 + "n_memory_holes": 0 }, "emit_event": { + "n_steps": 61, "builtin_instance_counter": { "range_check_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 61 + "n_memory_holes": 0 }, "get_block_hash": { + "n_steps": 104, "builtin_instance_counter": { "range_check_builtin": 2 }, - "n_memory_holes": 0, - "n_steps": 104 + "n_memory_holes": 0 }, "get_block_number": { + "n_steps": 40, "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 40 + "n_memory_holes": 0 }, "get_block_timestamp": { + "n_steps": 38, "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 38 + "n_memory_holes": 0 }, "get_caller_address": { + "n_steps": 64, "builtin_instance_counter": { "range_check_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 64 + "n_memory_holes": 0 }, "get_contract_address": { + "n_steps": 64, "builtin_instance_counter": { "range_check_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 64 + "n_memory_holes": 0 }, "get_execution_info": { + "n_steps": 64, "builtin_instance_counter": { "range_check_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 64 + "n_memory_holes": 0 }, "get_sequencer_address": { + "n_steps": 34, "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 34 + "n_memory_holes": 0 }, "get_tx_info": { + "n_steps": 64, "builtin_instance_counter": { "range_check_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 64 + "n_memory_holes": 0 }, "get_tx_signature": { + "n_steps": 44, "builtin_instance_counter": {}, - "n_memory_holes": 0, - "n_steps": 44 + "n_memory_holes": 0 }, "keccak": { + "n_steps": 381, "builtin_instance_counter": { "bitwise_builtin": 6, "keccak_builtin": 1, "range_check_builtin": 56 }, - "n_memory_holes": 0, - "n_steps": 381 + "n_memory_holes": 0 }, "library_call": { + "n_steps": 751, "builtin_instance_counter": { "range_check_builtin": 20 }, - "n_memory_holes": 0, - "n_steps": 751 + "n_memory_holes": 0 }, "library_call_l1_handler": { + "n_steps": 659, "builtin_instance_counter": { "range_check_builtin": 15 }, - "n_memory_holes": 0, - "n_steps": 659 + "n_memory_holes": 0 }, "replace_class": { + "n_steps": 98, "builtin_instance_counter": { "range_check_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 98 + "n_memory_holes": 0 }, "secp256k1_add": { + "n_steps": 408, "builtin_instance_counter": { "range_check_builtin": 29 }, - "n_memory_holes": 0, - "n_steps": 408 + "n_memory_holes": 0 }, "secp256k1_get_point_from_x": { + "n_steps": 393, "builtin_instance_counter": { "range_check_builtin": 30 }, - "n_memory_holes": 0, - "n_steps": 393 + "n_memory_holes": 0 }, "secp256k1_get_xy": { + "n_steps": 205, "builtin_instance_counter": { "range_check_builtin": 11 }, - "n_memory_holes": 0, - "n_steps": 205 + "n_memory_holes": 0 }, "secp256k1_mul": { + "n_steps": 76503, "builtin_instance_counter": { "range_check_builtin": 7045 }, - "n_memory_holes": 0, - "n_steps": 76503 + "n_memory_holes": 0 }, "secp256k1_new": { + "n_steps": 459, "builtin_instance_counter": { "range_check_builtin": 35 }, - "n_memory_holes": 0, - "n_steps": 459 + "n_memory_holes": 0 }, "secp256r1_add": { + "n_steps": 591, "builtin_instance_counter": { "range_check_builtin": 57 }, - "n_memory_holes": 0, - "n_steps": 591 + "n_memory_holes": 0 }, "secp256r1_get_point_from_x": { + "n_steps": 512, "builtin_instance_counter": { "range_check_builtin": 44 }, - "n_memory_holes": 0, - "n_steps": 512 + "n_memory_holes": 0 }, "secp256r1_get_xy": { + "n_steps": 207, "builtin_instance_counter": { "range_check_builtin": 11 }, - "n_memory_holes": 0, - "n_steps": 207 + "n_memory_holes": 0 }, "secp256r1_mul": { + "n_steps": 125342, "builtin_instance_counter": { "range_check_builtin": 13961 }, - "n_memory_holes": 0, - "n_steps": 125342 + "n_memory_holes": 0 }, "secp256r1_new": { + "n_steps": 578, "builtin_instance_counter": { "range_check_builtin": 49 }, - "n_memory_holes": 0, - "n_steps": 578 + "n_memory_holes": 0 }, "send_message_to_l1": { + "n_steps": 139, "builtin_instance_counter": { "range_check_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 139 + "n_memory_holes": 0 }, "storage_read": { + "n_steps": 87, "builtin_instance_counter": { "range_check_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 87 + "n_memory_holes": 0 }, "storage_write": { + "n_steps": 89, "builtin_instance_counter": { "range_check_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 89 + "n_memory_holes": 0 } }, "execute_txs_inner": { "DECLARE": { "constant": { + "n_steps": 2839, "builtin_instance_counter": { "pedersen_builtin": 16, "range_check_builtin": 63 }, - "n_memory_holes": 0, - "n_steps": 2839 + "n_memory_holes": 0 }, "calldata_factor": { - "builtin_instance_counter": { - "pedersen_builtin": 0, - "range_check_builtin": 0 - }, - "n_memory_holes": 0, - "n_steps": 0 + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 } }, "DEPLOY_ACCOUNT": { "constant": { + "n_steps": 3792, "builtin_instance_counter": { "pedersen_builtin": 23, "range_check_builtin": 83 }, - "n_memory_holes": 0, - "n_steps": 3792 + "n_memory_holes": 0 }, "calldata_factor": { + "n_steps": 21, "builtin_instance_counter": { - "pedersen_builtin": 2, - "range_check_builtin": 0 + "pedersen_builtin": 2 }, - "n_memory_holes": 0, - "n_steps": 21 + "n_memory_holes": 0 } }, "INVOKE_FUNCTION": { "constant": { + "n_steps": 3546, "builtin_instance_counter": { "pedersen_builtin": 14, "range_check_builtin": 80 }, - "n_memory_holes": 0, - "n_steps": 3546 + "n_memory_holes": 0 }, "calldata_factor": { + "n_steps": 8, "builtin_instance_counter": { - "pedersen_builtin": 1, - "range_check_builtin": 0 + "pedersen_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 8 + "n_memory_holes": 0 } }, "L1_HANDLER": { "constant": { + "n_steps": 1146, "builtin_instance_counter": { "pedersen_builtin": 11, "range_check_builtin": 17 }, - "n_memory_holes": 0, - "n_steps": 1146 + "n_memory_holes": 0 }, "calldata_factor": { + "n_steps": 13, "builtin_instance_counter": { - "pedersen_builtin": 1, - "range_check_builtin": 0 + "pedersen_builtin": 1 }, - "n_memory_holes": 0, - "n_steps": 13 + "n_memory_holes": 0 } }, "DEPLOY": { 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 e635edfe..34ad58d2 100644 --- a/src/starkware/starknet/services/api/contract_class/contract_class.py +++ b/src/starkware/starknet/services/api/contract_class/contract_class.py @@ -1,4 +1,5 @@ import dataclasses +import json import re from abc import abstractmethod from dataclasses import field @@ -218,6 +219,9 @@ def get_prime(self) -> int: def get_bytecode(self) -> List[int]: return self.bytecode + def get_bytecode_size(self) -> int: + return len(self.get_bytecode()) + @marshmallow.decorators.pre_load def parse_pythonic_hints(self, data: Dict[str, Any], many: bool, **kwargs) -> Dict[str, Any]: """ @@ -329,6 +333,12 @@ def get_prime(self) -> int: def get_bytecode(self) -> List[int]: return self.program.data + def get_bytecode_size(self) -> int: + return len(self.get_bytecode()) + + def get_abi_size(self) -> int: + return len(json.dumps(self.abi)) if self.abi is not None else 0 + @marshmallow.decorators.post_dump def remove_none_builtins(self, data: Dict[str, Any], many: bool, **kwargs) -> Dict[str, Any]: """ diff --git a/src/starkware/starknet/services/utils/sequencer_api_utils.py b/src/starkware/starknet/services/utils/sequencer_api_utils.py index 9eb955f9..97cd6194 100644 --- a/src/starkware/starknet/services/utils/sequencer_api_utils.py +++ b/src/starkware/starknet/services/utils/sequencer_api_utils.py @@ -89,9 +89,7 @@ def charge_fee( Overrides the charge fee method. Only calculates the actual fee and does not charge any fee. """ actual_fee = calculate_tx_fee( - l1_gas_price=state.block_info.l1_gas_price.price_in_wei, - resources=resources, - general_config=general_config, + l1_gas_price=state.block_info.l1_gas_price.price_in_wei, resources=resources ) return None, actual_fee diff --git a/src/starkware/starknet/solidity/BUILD b/src/starkware/starknet/solidity/BUILD index f685f71b..d518ff5f 100644 --- a/src/starkware/starknet/solidity/BUILD +++ b/src/starkware/starknet/solidity/BUILD @@ -3,14 +3,22 @@ load("//bazel_utils:solidity.bzl", "sol_contract", "sol_library") sol_library( name = "starknet_messaging_sol", srcs = [ - "IStarknetMessaging.sol", - "IStarknetMessagingEvents.sol", "StarknetMessaging.sol", ], visibility = ["//visibility:public"], deps = [ - "//src/starkware/solidity/libraries:named_storage_sol", + ":starknet_messaging_interface_sol", + "//src/starkware/solidity/libraries:named_storage8_sol", + ], +) + +sol_library( + name = "starknet_messaging_interface_sol", + srcs = [ + "IStarknetMessaging.sol", + "IStarknetMessagingEvents.sol", ], + visibility = ["//visibility:public"], ) sol_library( @@ -27,21 +35,28 @@ sol_library( sol_library( name = "starknet_core_sol", srcs = [ - "BlobHashGetter.sol", "Output.sol", "Starknet.sol", + "StarknetGovernance.sol", "StarknetOperator.sol", "StarknetState.sol", + "//src/starkware/solidity/components:Governance.sol", + "//src/starkware/solidity/components:GovernedFinalizable.sol", + "//src/starkware/solidity/components:OnchainDataFactTreeEncoder.sol", + "//src/starkware/solidity/components:Operator.sol", + "//src/starkware/solidity/interfaces:BlockDirectCall.sol", + "//src/starkware/solidity/interfaces:ContractInitializer.sol", + "//src/starkware/solidity/interfaces:IFactRegistry.sol", + "//src/starkware/solidity/interfaces:Identity.sol", + "//src/starkware/solidity/interfaces:MGovernance.sol", + "//src/starkware/solidity/interfaces:MOperator.sol", + "//src/starkware/solidity/interfaces:ProxySupport.sol", ], visibility = ["//visibility:public"], deps = [ - "starknet_governance_sol", - "starknet_messaging_sol", - "//src/starkware/solidity/components:governance_contract_sol", - "//src/starkware/solidity/components:solidity_contracts_components_sol", - "//src/starkware/solidity/interfaces:solidity_contract_initializer_sol", - "//src/starkware/solidity/interfaces:solidity_contracts_interfaces_sol", - "//src/starkware/solidity/libraries:named_storage_sol", + ":starknet_messaging_sol", + "//src/starkware/solidity/libraries:common_library_sol", + "//src/starkware/solidity/libraries:named_storage8_sol", ], ) @@ -50,6 +65,8 @@ sol_contract( contracts = [ "Starknet.json", ], + evm_version = "cancun", + solc_exe = "//bazel_utils:solc-0.8.24", deps = [ "starknet_core_sol", ], diff --git a/src/starkware/starknet/solidity/BlobHashGetter.sol b/src/starkware/starknet/solidity/BlobHashGetter.sol deleted file mode 100644 index c80e079a..00000000 --- a/src/starkware/starknet/solidity/BlobHashGetter.sol +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; - -/** - A factory for creating contracts from EVM bytecode. -*/ -contract ContractFactory { - constructor(bytes memory code) public { - uint256 size = code.length; - assembly { - return(add(code, 0x20), size) - } - } -} - -library BlobHashGetter { - // The bytescode for retrieving the blob hash. - // See https://github.com/ethstorage/eip4844-blob-hash-getter/blob/main/README.md for a detailed - // explanation. - bytes internal constant CODE = hex"6000354960005260206000F3"; - - // Storage slot to hold the deployed hash getter address. - // Web3.keccak(text="BLOB_HASH_GETTER_CONTRACT_SLOT"). - bytes32 internal constant BLOB_HASH_GETTER_CONTRACT_SLOT = - 0xd599dde24be23990034c1ef263a0e367ed5609a1c3122cb48d78c560328abb89; - - /** - Deploys the bytecode that retrieves the hash of a blob, using the DATAHASH (0x49) opcode. - The deployed code accepts blob index as 32-byte input, and outputs blob hash as 32 bytes. - */ - function deploy() internal returns (address) { - address getter = address(new ContractFactory(CODE)); - assembly { - sstore(BLOB_HASH_GETTER_CONTRACT_SLOT, getter) - } - return getter; - } - - /** - Accepts a blob index and returns its versioned hash. - Deploys the hash getter code if it wasn't deployed yet. - */ - function getBlobHash(uint256 idx) internal returns (bytes32) { - address getter; - assembly { - getter := sload(BLOB_HASH_GETTER_CONTRACT_SLOT) - } - if (getter == address(0x0)) { - getter = deploy(); - } - - bool success; - bytes32 blobHash; - assembly { - mstore(0x0, idx) - - success := staticcall(gas(), getter, 0x0, 0x0, 0x20, 0x20) - - blobHash := mload(0x20) - } - - require(success, "GET_BLOB_HASH_FAILED"); - return blobHash; - } -} diff --git a/src/starkware/starknet/solidity/IStarknetMessaging.sol b/src/starkware/starknet/solidity/IStarknetMessaging.sol index 41a62b58..ec41e58b 100644 --- a/src/starkware/starknet/solidity/IStarknetMessaging.sol +++ b/src/starkware/starknet/solidity/IStarknetMessaging.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity >=0.6.12; import "./IStarknetMessagingEvents.sol"; diff --git a/src/starkware/starknet/solidity/IStarknetMessagingEvents.sol b/src/starkware/starknet/solidity/IStarknetMessagingEvents.sol index 9e7c841e..fa91c7a5 100644 --- a/src/starkware/starknet/solidity/IStarknetMessagingEvents.sol +++ b/src/starkware/starknet/solidity/IStarknetMessagingEvents.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity >=0.6.12; interface IStarknetMessagingEvents { // This event needs to be compatible with the one defined in Output.sol. diff --git a/src/starkware/starknet/solidity/Output.sol b/src/starkware/starknet/solidity/Output.sol index c682ef90..3f01ef72 100644 --- a/src/starkware/starknet/solidity/Output.sol +++ b/src/starkware/starknet/solidity/Output.sol @@ -1,5 +1,7 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity ^0.8.0; + +import "./IStarknetMessagingEvents.sol"; library CommitmentTreeUpdateOutput { /** @@ -46,18 +48,6 @@ library StarknetOutput { uint256 constant MESSAGE_TO_L2_PAYLOAD_SIZE_OFFSET = 4; uint256 constant MESSAGE_TO_L2_PREFIX_SIZE = 5; - // An event that is raised when a message is sent from L2 to L1. - event LogMessageToL1(uint256 indexed fromAddress, address indexed toAddress, uint256[] payload); - - // An event that is raised when a message from L1 to L2 is consumed. - event ConsumedMessageToL2( - address indexed fromAddress, - uint256 indexed toAddress, - uint256 indexed selector, - uint256[] payload, - uint256 nonce - ); - /** Returns the offset of the messages segment in the output_data. */ @@ -114,11 +104,11 @@ library StarknetOutput { abi.encodePacked(programOutputSlice[offset:endOffset]) ); - emit LogMessageToL1( + emit IStarknetMessagingEvents.LogMessageToL1( // from= programOutputSlice[offset + MESSAGE_TO_L1_FROM_ADDRESS_OFFSET], // to= - address(programOutputSlice[offset + MESSAGE_TO_L1_TO_ADDRESS_OFFSET]), + address(uint160(programOutputSlice[offset + MESSAGE_TO_L1_TO_ADDRESS_OFFSET])), // payload= (uint256[])(programOutputSlice[offset + MESSAGE_TO_L1_PREFIX_SIZE:endOffset]) ); @@ -139,9 +129,11 @@ library StarknetOutput { uint256[] memory messageSlice = (uint256[])( programOutputSlice[offset + MESSAGE_TO_L2_PREFIX_SIZE:endOffset] ); - emit ConsumedMessageToL2( + emit IStarknetMessagingEvents.ConsumedMessageToL2( // from= - address(programOutputSlice[offset + MESSAGE_TO_L2_FROM_ADDRESS_OFFSET]), + address( + uint160(programOutputSlice[offset + MESSAGE_TO_L2_FROM_ADDRESS_OFFSET]) + ), // to= programOutputSlice[offset + MESSAGE_TO_L2_TO_ADDRESS_OFFSET], // selector= diff --git a/src/starkware/starknet/solidity/Starknet.sol b/src/starkware/starknet/solidity/Starknet.sol index 436a3206..6be08c21 100644 --- a/src/starkware/starknet/solidity/Starknet.sol +++ b/src/starkware/starknet/solidity/Starknet.sol @@ -1,8 +1,6 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; -pragma experimental ABIEncoderV2; +pragma solidity ^0.8.24; -import "./BlobHashGetter.sol"; import "./Output.sol"; import "./StarknetGovernance.sol"; import "./StarknetMessaging.sol"; @@ -14,7 +12,7 @@ import "starkware/solidity/interfaces/ContractInitializer.sol"; import "starkware/solidity/interfaces/Identity.sol"; import "starkware/solidity/interfaces/IFactRegistry.sol"; import "starkware/solidity/interfaces/ProxySupport.sol"; -import "starkware/solidity/libraries/NamedStorage.sol"; +import "starkware/solidity/libraries/NamedStorage8.sol"; contract Starknet is Identity, @@ -115,7 +113,7 @@ contract Starknet is function state() internal pure returns (StarknetState.State storage stateStruct) { bytes32 location = keccak256(abi.encodePacked(STATE_STRUCT_TAG)); assembly { - stateStruct_slot := location + stateStruct.slot := location } } @@ -158,7 +156,7 @@ contract Starknet is require(kzgSegment.length == StarknetOutput.KZG_SEGMENT_SIZE, "INVALID_KZG_SEGMENT_SIZE"); require(kzgProof.length == PROOF_BYTES_LENGTH, "INVALID_KZG_PROOF_SIZE"); - bytes32 blobHash = BlobHashGetter.getBlobHash( + bytes32 blobHash = blobhash( // blobIndex= 0 ); @@ -252,7 +250,7 @@ contract Starknet is Returns a string that identifies the contract. */ function identify() external pure override returns (string memory) { - return "StarkWare_Starknet_2023_7"; + return "StarkWare_Starknet_2024_8"; } /** diff --git a/src/starkware/starknet/solidity/StarknetGovernance.sol b/src/starkware/starknet/solidity/StarknetGovernance.sol index 8d4749d9..9e807197 100644 --- a/src/starkware/starknet/solidity/StarknetGovernance.sol +++ b/src/starkware/starknet/solidity/StarknetGovernance.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity ^0.8.0; import "starkware/solidity/components/Governance.sol"; @@ -12,7 +12,7 @@ contract StarknetGovernance is Governance { function getGovernanceInfo() internal view override returns (GovernanceInfoStruct storage gub) { bytes32 location = keccak256(abi.encodePacked(STARKNET_GOVERNANCE_INFO_TAG)); assembly { - gub_slot := location + gub.slot := location } } diff --git a/src/starkware/starknet/solidity/StarknetMessaging.sol b/src/starkware/starknet/solidity/StarknetMessaging.sol index eb4766bd..ebf353a7 100644 --- a/src/starkware/starknet/solidity/StarknetMessaging.sol +++ b/src/starkware/starknet/solidity/StarknetMessaging.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity ^0.8.0; import "./IStarknetMessaging.sol"; -import "starkware/solidity/libraries/NamedStorage.sol"; +import "starkware/solidity/libraries/NamedStorage8.sol"; /** Implements sending messages to L2 by adding them to a pipe and consuming messages from L2 by @@ -94,7 +94,7 @@ contract StarknetMessaging is IStarknetMessaging { return keccak256( abi.encodePacked( - uint256(msg.sender), + uint256(uint160(msg.sender)), toAddress, nonce, selector, @@ -135,7 +135,7 @@ contract StarknetMessaging is IStarknetMessaging { returns (bytes32) { bytes32 msgHash = keccak256( - abi.encodePacked(fromAddress, uint256(msg.sender), payload.length, payload) + abi.encodePacked(fromAddress, uint256(uint160(msg.sender)), payload.length, payload) ); require(l2ToL1Messages()[msgHash] > 0, "INVALID_MESSAGE_TO_CONSUME"); diff --git a/src/starkware/starknet/solidity/StarknetOperator.sol b/src/starkware/starknet/solidity/StarknetOperator.sol index 169ebba0..3ad59aab 100644 --- a/src/starkware/starknet/solidity/StarknetOperator.sol +++ b/src/starkware/starknet/solidity/StarknetOperator.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity ^0.8.0; import "starkware/solidity/components/Operator.sol"; -import "starkware/solidity/libraries/NamedStorage.sol"; +import "starkware/solidity/libraries/NamedStorage8.sol"; abstract contract StarknetOperator is Operator { string constant OPERATORS_MAPPING_TAG = "STARKNET_1.0_ROLES_OPERATORS_MAPPING_TAG"; diff --git a/src/starkware/starknet/solidity/StarknetState.sol b/src/starkware/starknet/solidity/StarknetState.sol index 981a0f94..44c78311 100644 --- a/src/starkware/starknet/solidity/StarknetState.sol +++ b/src/starkware/starknet/solidity/StarknetState.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity ^0.8.0; import "./Output.sol"; diff --git a/src/starkware/starknet/testing/BUILD b/src/starkware/starknet/testing/BUILD index 130c00ca..d39ff37e 100644 --- a/src/starkware/starknet/testing/BUILD +++ b/src/starkware/starknet/testing/BUILD @@ -19,6 +19,7 @@ sol_contract( contracts = [ "MockStarknetMessaging.json", ], + solc_exe = "//bazel_utils:solc-0.8.24", deps = [ "starknet_mock_messaging_sol", ], diff --git a/src/starkware/starknet/testing/MockStarknetMessaging.sol b/src/starkware/starknet/testing/MockStarknetMessaging.sol index e4e4afc7..e63073f7 100644 --- a/src/starkware/starknet/testing/MockStarknetMessaging.sol +++ b/src/starkware/starknet/testing/MockStarknetMessaging.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0. -pragma solidity ^0.6.12; +pragma solidity ^0.8.0; import "starkware/starknet/solidity/StarknetMessaging.sol"; diff --git a/src/starkware/starkware_utils/validated_dataclass.py b/src/starkware/starkware_utils/validated_dataclass.py index ce1ba57a..d955412b 100644 --- a/src/starkware/starkware_utils/validated_dataclass.py +++ b/src/starkware/starkware_utils/validated_dataclass.py @@ -9,6 +9,7 @@ import marshmallow_dataclass import typeguard +from starkware.starkware_utils.error_handling import StarkErrorCode, stark_assert from starkware.starkware_utils.serializable_dataclass import SerializableMarshmallowDataclass from starkware.starkware_utils.validated_fields import Field, ValidatedField @@ -20,9 +21,13 @@ def rename_old_field_in_pre_load( data: Dict[str, Any], old_field_name: str, new_field_name: str ) -> Dict[str, Any]: if old_field_name in data: - assert new_field_name not in data, ( - f"Error while renaming {old_field_name} to {new_field_name}. " - "It is unexpected to have both fields in the data." + stark_assert( + new_field_name not in data, + code=StarkErrorCode.MALFORMED_REQUEST, + message=( + f"Error while renaming {old_field_name} to {new_field_name}. " + "It is unexpected to have both fields in the data." + ), ) data[new_field_name] = data.pop(old_field_name) return data diff --git a/src/starkware/storage/storage.py b/src/starkware/storage/storage.py index 3f37a378..e192f8b2 100644 --- a/src/starkware/storage/storage.py +++ b/src/starkware/storage/storage.py @@ -176,6 +176,12 @@ async def set_file(self, file: str, key: bytes): Upload file to large storage. """ + @abstractmethod + async def set_large_file(self, file: str, key: bytes): + """ + Upload file to large storage. + """ + def escape(self, key: bytes) -> str: return codecs.escape_encode(key)[0].decode("ascii") # type: ignore