Skip to content
This repository has been archived by the owner on Dec 15, 2023. It is now read-only.

Adapt to cairo-lang 0.9.0 #120

Merged
merged 10 commits into from
Jun 7, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ keywords = ["starknet", "cairo", "testnet", "local", "server"]
python = ">=3.7.2,<3.10"
Flask = {extras = ["async"], version = "~2.0.3"}
flask-cors = "~3.0.10"
cairo-lang = "0.8.2.1"
cairo-lang = "0.9.0"
dill = "~0.3.4"
meinheld = "~1.0.2"
Werkzeug = "~2.0.3"
crypto-cpp-py = "^1.0.4"
cloudpickle = "^2.1.0"
badurinantun marked this conversation as resolved.
Show resolved Hide resolved

[tool.poetry.dev-dependencies]
pylint = "~2.12.2"
Expand Down
26 changes: 13 additions & 13 deletions starknet_devnet/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
from starkware.solidity.utils import load_nearby_contract
from starkware.starknet.business_logic.state.objects import ContractState, ContractCarriedState
from starkware.starknet.public.abi import get_selector_from_name
from starkware.starknet.services.api.contract_definition import ContractDefinition
from starkware.starknet.services.api.gateway.contract_address import calculate_contract_address_from_hash
from starkware.starknet.services.api.contract_class import ContractClass
from starkware.starknet.core.os.contract_address.contract_address import calculate_contract_address_from_hash
from starkware.starknet.storage.starknet_storage import StorageLeaf
from starkware.starknet.testing.starknet import Starknet
from starkware.starknet.testing.contract import StarknetContract
Expand All @@ -18,11 +18,11 @@
class Account:
"""Account contract wrapper."""

DEFINITION: ContractDefinition = None # loaded lazily
CONTRACT_CLASS: ContractClass = None # loaded lazily
CONTRACT_PATH = "accounts_artifacts/OpenZeppelin/0.1.0/Account.cairo/Account"

# Precalculated to save time
# HASH = compute_contract_hash(contract_definition=Account.get_definition()))
# HASH = compute_class_hash(contract_class=Account.get_contract_class()))
HASH = 361479646297615797917493841430922492724680358320444679508058603177506550951
HASH_BYTES = to_bytes(HASH)

Expand All @@ -34,26 +34,26 @@ def __init__(self, private_key: int, public_key: int, initial_balance: int):
self.public_key = public_key
self.address = calculate_contract_address_from_hash(
salt=Account.SALT,
contract_hash=Account.HASH,
class_hash=Account.HASH,
constructor_calldata=[public_key],
caller_address=0
deployer_address=0
)
self.initial_balance = initial_balance

@classmethod
def get_definition(cls):
"""Returns contract definition via lazy loading."""
if not cls.DEFINITION:
cls.DEFINITION = ContractDefinition.load(load_nearby_contract(cls.CONTRACT_PATH))
return cls.DEFINITION
def get_contract_class(cls):
"""Returns contract class via lazy loading."""
if not cls.CONTRACT_CLASS:
cls.CONTRACT_CLASS = ContractClass.load(load_nearby_contract(cls.CONTRACT_PATH))
return cls.CONTRACT_CLASS

async def deploy(self, starknet: Starknet) -> StarknetContract:
"""Deploy this account."""
account_carried_state = starknet.state.state.contract_states[self.address]
account_state = account_carried_state.state
assert not account_state.initialized

starknet.state.state.contract_definitions[Account.HASH_BYTES] = Account.get_definition()
starknet.state.state.contract_definitions[Account.HASH_BYTES] = Account.get_contract_class()

newly_deployed_account_state = await ContractState.create(
contract_hash=Account.HASH_BYTES,
Expand All @@ -78,7 +78,7 @@ async def deploy(self, starknet: Starknet) -> StarknetContract:

return StarknetContract(
state=starknet.state,
abi=Account.get_definition().abi,
abi=Account.get_contract_class().abi,
contract_address=self.address,
deploy_execution_info=None
)
2 changes: 1 addition & 1 deletion starknet_devnet/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from typing import Dict

from starkware.starknet.testing.state import StarknetState
from starkware.starknet.services.api.feeder_gateway.block_hash import calculate_block_hash
from starkware.starknet.core.os.block_hash.block_hash import calculate_block_hash
from starkware.starknet.services.api.feeder_gateway.response_objects import StarknetBlock, BlockStatus
from starkware.starknet.services.api.feeder_gateway.response_objects import BlockStateUpdate

Expand Down
2 changes: 1 addition & 1 deletion starknet_devnet/blueprints/feeder_gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def get_code():
@feeder_gateway.route("/get_full_contract", methods=["GET"])
def get_full_contract():
"""
Returns the contract definition of the contract whose contractAddress is provided.
Returns the contract class of the contract whose contractAddress is provided.
"""
_check_block_hash(request.args)

Expand Down
50 changes: 5 additions & 45 deletions starknet_devnet/contract_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,62 +5,22 @@
from dataclasses import dataclass
from typing import List

from starkware.starknet.services.api.contract_definition import ContractDefinition
from starkware.starknet.services.api.contract_class import ContractClass
from starkware.starknet.testing.contract import StarknetContract
from starkware.starknet.utils.api_utils import cast_to_felts
from starkware.starknet.business_logic.internal_transaction import InternalInvokeFunction
from starkware.starknet.business_logic.execution.execute_entry_point import ExecuteEntryPoint
from starkware.starknet.business_logic.execution.objects import (
TransactionExecutionContext,
TransactionExecutionInfo,
)
from starkware.starknet.testing.state import StarknetState

async def call_internal_tx(starknet_state: StarknetState, internal_tx: InternalInvokeFunction):
"""
Executes an internal transaction.
"""
with starknet_state.state.copy_and_apply() as state_copy:
tx_execution_context = TransactionExecutionContext.create(
account_contract_address=internal_tx.contract_address,
transaction_hash=internal_tx.hash_value,
signature=internal_tx.signature,
max_fee=internal_tx.max_fee,
n_steps=starknet_state.general_config.invoke_tx_max_n_steps,
version=internal_tx.version,
)
call = ExecuteEntryPoint(
contract_address=internal_tx.contract_address,
code_address=internal_tx.code_address,
entry_point_selector=internal_tx.entry_point_selector,
entry_point_type=internal_tx.entry_point_type,
calldata=internal_tx.calldata,
caller_address=internal_tx.caller_address,
)
call_info = await call.execute(
state=state_copy,
general_config=starknet_state.general_config,
tx_execution_context=tx_execution_context
)
fee_transfer_info = None
actual_fee = 0

return TransactionExecutionInfo(
call_info=call_info, fee_transfer_info=fee_transfer_info, actual_fee=actual_fee
)

@dataclass
class ContractWrapper:
"""
Wraps a StarknetContract, storing its types and code for later use.
"""
def __init__(self, contract: StarknetContract, contract_definition: ContractDefinition):
def __init__(self, contract: StarknetContract, contract_class: ContractClass):
self.contract: StarknetContract = contract
self.contract_definition = contract_definition.remove_debug_info().dump()
self.contract_class = contract_class.remove_debug_info().dump()

self.code: dict = {
"abi": contract_definition.abi,
"bytecode": self.contract_definition["program"]["data"]
"abi": contract_class.abi,
"bytecode": self.contract_class["program"]["data"]
}

# pylint: disable=too-many-arguments
Expand Down
2 changes: 1 addition & 1 deletion starknet_devnet/contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,4 @@ def get_full_contract(self, address: int) -> ContractWrapper:
Get the contract wrapper by address.
"""
contract = self.get_by_address(address)
return contract.contract_definition
return contract.contract_class
2 changes: 1 addition & 1 deletion starknet_devnet/dump.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import multiprocessing

import dill as pickle
import cloudpickle as pickle

from .util import DumpOn

Expand Down
22 changes: 11 additions & 11 deletions starknet_devnet/fee_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""

from starkware.solidity.utils import load_nearby_contract
from starkware.starknet.services.api.contract_definition import ContractDefinition
from starkware.starknet.services.api.contract_class import ContractClass
from starkware.starknet.business_logic.state.objects import ContractState, ContractCarriedState
from starkware.starknet.testing.contract import StarknetContract
from starkware.starknet.testing.starknet import Starknet
Expand All @@ -14,10 +14,10 @@
class FeeToken:
"""Wrapper of token for charging fees."""

DEFINITION: ContractDefinition = None # loaded lazily
CONTRACT_CLASS: ContractClass = None # loaded lazily

# Precalcuated to save time
# HASH = to_bytes(compute_contract_hash(contract_definition=FeeToken.get_definition()))
# HASH = to_bytes(compute_class_hash(contract_class=FeeToken.get_contract_class()))
HASH = 375899817338126263298463755162657787890597705735749339531748983767835688120
HASH_BYTES = to_bytes(HASH)

Expand All @@ -26,7 +26,7 @@ class FeeToken:
CONSTRUCTOR_CALLDATA = []

# Precalculated to save time
# ADDRESS = calculate_contract_address_from_hash(salt=SALT, contract_hash=HASH,
# ADDRESS = calculate_contract_address_from_hash(salt=SALT, class_hash=HASH,
# constructor_calldata=CONSTRUCTOR_CALLDATA,
# caller_address=0
# )
Expand All @@ -35,11 +35,11 @@ class FeeToken:
contract: StarknetContract = None

@classmethod
def get_definition(cls):
"""Returns contract definition via lazy loading."""
if not cls.DEFINITION:
cls.DEFINITION = ContractDefinition.load(load_nearby_contract("ERC20"))
return cls.DEFINITION
def get_contract_class(cls):
"""Returns contract class via lazy loading."""
if not cls.CONTRACT_CLASS:
cls.CONTRACT_CLASS = ContractClass.load(load_nearby_contract("ERC20"))
return cls.CONTRACT_CLASS

@classmethod
async def deploy(cls, starknet: Starknet):
Expand All @@ -49,7 +49,7 @@ async def deploy(cls, starknet: Starknet):
fee_token_state = fee_token_carried_state.state
assert not fee_token_state.initialized

starknet.state.state.contract_definitions[cls.HASH_BYTES] = cls.get_definition()
starknet.state.state.contract_definitions[cls.HASH_BYTES] = cls.get_contract_class()
newly_deployed_fee_token_state = await ContractState.create(
contract_hash=cls.HASH_BYTES,
storage_commitment_tree=fee_token_state.storage_commitment_tree
Expand All @@ -66,7 +66,7 @@ async def deploy(cls, starknet: Starknet):

cls.contract = StarknetContract(
state=starknet.state,
abi=cls.get_definition().abi,
abi=cls.get_contract_class().abi,
contract_address=cls.ADDRESS,
deploy_execution_info=None
)
Expand Down
2 changes: 1 addition & 1 deletion starknet_devnet/origin.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def get_code(self, contract_address: int) -> dict:
raise NotImplementedError

def get_full_contract(self, contract_address: int) -> dict:
"""Returns the contract definition"""
"""Returns the contract class"""
raise NotImplementedError

def get_storage_at(self, contract_address: int, key: int) -> str:
Expand Down
6 changes: 3 additions & 3 deletions starknet_devnet/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
"""

import sys
import meinheld
import dill as pickle
from pickle import UnpicklingError

from flask import Flask
from flask_cors import CORS
import meinheld

from starkware.starkware_utils.error_handling import StarkException
from .blueprints.base import base
Expand Down Expand Up @@ -50,7 +50,7 @@ def load_dumped(args):
if args.load_path:
try:
state.load(args.load_path)
except (FileNotFoundError, pickle.UnpicklingError):
except (FileNotFoundError, UnpicklingError):
sys.exit(f"Error: Cannot load from {args.load_path}. Make sure the file exists and contains a Devnet dump.")

def enable_lite_mode(args):
Expand Down
Loading