Skip to content

Commit

Permalink
Cairo v0.10.2.
Browse files Browse the repository at this point in the history
  • Loading branch information
liorgold2 committed Nov 17, 2022
1 parent f951a66 commit 9889fbd
Show file tree
Hide file tree
Showing 11 changed files with 187 additions and 72 deletions.
2 changes: 1 addition & 1 deletion src/starkware/cairo/lang/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.10.2a0
0.10.2
2 changes: 1 addition & 1 deletion src/starkware/starknet/business_logic/execution/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ def get_sorted_l2_to_l1_messages(self) -> List[L2ToL1MessageInfo]:
@marshmallow_dataclass.dataclass(frozen=True)
class TransactionExecutionInfo(EverestTransactionExecutionInfo):
"""
Contains the information gathered by the execution of a transation. Main usages:
Contains the information gathered by the execution of a transaction. Main usages:
1. Supplies hints for the OS run on the corresponding transaction; e.g., internal call results.
2. Stores useful information for users; e.g., L2-to-L1 messages and emitted events.
"""
Expand Down
11 changes: 11 additions & 0 deletions src/starkware/starknet/business_logic/fact_state/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ python_lib(starknet_business_logic_fact_state_lib
LIBS
cairo_vm_lib
everest_business_logic_lib
starknet_business_logic_fact_state_utils_lib
starknet_business_logic_patricia_state_lib
starknet_business_logic_state_lib
starknet_definitions_lib
Expand Down Expand Up @@ -44,3 +45,13 @@ python_lib(starknet_business_logic_patricia_state_lib
starkware_utils_lib
pip_marshmallow_dataclass
)

python_lib(starknet_business_logic_fact_state_utils_lib
PREFIX starkware/starknet/business_logic/fact_state

FILES
utils.py

LIBS
starknet_business_logic_state_lib
)
59 changes: 37 additions & 22 deletions src/starkware/starknet/business_logic/fact_state/state.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
from dataclasses import field
from typing import Dict, Mapping, MutableMapping, Optional

import marshmallow_dataclass
Expand All @@ -16,15 +17,20 @@
ContractState,
)
from starkware.starknet.business_logic.fact_state.patricia_state import PatriciaStateReader
from starkware.starknet.business_logic.state.state import CachedState, StorageEntry
from starkware.starknet.business_logic.fact_state.utils import (
to_cached_state_storage_mapping,
to_state_diff_storage_mapping,
)
from starkware.starknet.business_logic.state.state import CachedState
from starkware.starknet.business_logic.state.state_api import StateReader
from starkware.starknet.business_logic.state.state_api_objects import BlockInfo
from starkware.starknet.definitions import fields
from starkware.starknet.definitions.general_config import StarknetGeneralConfig
from starkware.starknet.storage.starknet_storage import ContractStorageMapping, StorageLeaf
from starkware.starknet.storage.starknet_storage import StorageLeaf
from starkware.starkware_utils.commitment_tree.binary_fact_tree import BinaryFactDict
from starkware.starkware_utils.commitment_tree.patricia_tree.patricia_tree import PatriciaTree
from starkware.starkware_utils.config_base import Config
from starkware.storage.storage import FactFetchingContext
from starkware.storage.storage import DBObject, FactFetchingContext

logger = logging.getLogger(__name__)
state_objects_logger = logging.getLogger(f"{__name__}:state_objects_logger")
Expand Down Expand Up @@ -252,7 +258,9 @@ async def apply_state_updates(
ffc=ffc,
address_to_class_hash=state_cache._class_hash_writes,
address_to_nonce=state_cache._nonce_writes,
storage_updates=state_cache._storage_writes,
storage_updates=to_state_diff_storage_mapping(
storage_writes=state_cache._storage_writes
),
block_info=current_carried_state.state.block_info,
)

Expand All @@ -261,18 +269,11 @@ async def apply_updates(
ffc: FactFetchingContext,
address_to_class_hash: Mapping[int, bytes],
address_to_nonce: Mapping[int, int],
storage_updates: Mapping[StorageEntry, int],
storage_updates: Mapping[int, Mapping[int, int]],
block_info: BlockInfo,
) -> "SharedState":
address_to_storage_updates: Dict[int, ContractStorageMapping] = {}
for (address, key), value in storage_updates.items():
contract_storage_updates = address_to_storage_updates.setdefault(address, {})
contract_storage_updates[key] = StorageLeaf(value=value)

accessed_addresses = (
set(address_to_class_hash.keys())
| set(address_to_nonce.keys())
| {address for address, _ in storage_updates.keys()}
address_to_class_hash.keys() | address_to_nonce.keys() | storage_updates.keys()
)
current_contract_states = await self.contract_states.get_leaves(
ffc=ffc, indices=accessed_addresses, fact_cls=ContractState
Expand All @@ -283,7 +284,10 @@ async def apply_updates(
awaitables=(
current_contract_states[address].update(
ffc=ffc,
updates=address_to_storage_updates.get(address, {}),
updates={
key: StorageLeaf(value=value)
for key, value in storage_updates.get(address, {}).items()
},
nonce=address_to_nonce.get(address, None),
class_hash=address_to_class_hash.get(address, None),
)
Expand All @@ -300,14 +304,18 @@ async def apply_updates(


@marshmallow_dataclass.dataclass(frozen=True)
class StateDiff(EverestStateDiff):
class StateDiff(EverestStateDiff, DBObject):
"""
Holds uncommitted changes induced on StarkNet contracts.
"""

address_to_class_hash: Mapping[int, bytes]
address_to_nonce: Mapping[int, int]
storage_updates: Mapping[StorageEntry, int]
address_to_class_hash: Mapping[int, bytes] = field(
metadata=fields.address_to_class_hash_metadata
)
address_to_nonce: Mapping[int, int] = field(metadata=fields.address_to_nonce_metadata)
storage_updates: Mapping[int, Mapping[int, int]] = field(
metadata=fields.storage_updates_metadata
)
block_info: BlockInfo

@classmethod
Expand All @@ -328,24 +336,31 @@ def from_cached_state(cls, cached_state: CachedState) -> "StateDiff":
return cls(
address_to_class_hash=state_cache._class_hash_writes,
address_to_nonce=state_cache._nonce_writes,
storage_updates=state_cache._storage_writes,
storage_updates=to_state_diff_storage_mapping(
storage_writes=state_cache._storage_writes
),
block_info=cached_state.block_info,
)

def to_cached_state(self, state_reader: StateReader) -> CachedState:
cached_state = CachedState(block_info=self.block_info, state_reader=state_reader)
cached_state.cache.update_writes(
cached_state.cache.set_initial_values(
address_to_class_hash=self.address_to_class_hash,
address_to_nonce=self.address_to_nonce,
storage_updates=self.storage_updates,
storage_updates=to_cached_state_storage_mapping(storage_updates=self.storage_updates),
)

return cached_state

def squash(self, other: "StateDiff") -> "StateDiff":
address_to_class_hash = {**self.address_to_class_hash, **other.address_to_class_hash}
address_to_nonce = {**self.address_to_nonce, **other.address_to_nonce}
storage_updates = {**self.storage_updates, **other.storage_updates}
storage_updates: Dict[int, Dict[int, int]] = {}
for address in self.storage_updates.keys() | other.storage_updates.keys():
storage_updates[address] = {
**self.storage_updates.get(address, {}),
**other.storage_updates.get(address, {}),
}
self.block_info.validate_legal_progress(next_block_info=other.block_info)

return StateDiff(
Expand Down
35 changes: 35 additions & 0 deletions src/starkware/starknet/business_logic/fact_state/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from typing import Dict, Mapping

from starkware.starknet.business_logic.state.state import StorageEntry


def to_cached_state_storage_mapping(
storage_updates: Mapping[int, Mapping[int, int]]
) -> Mapping[StorageEntry, int]:
"""
Converts StateDiff storage mapping (addresses map to a key-value mapping) to CachedState
storage mapping (Tuple of address and key map to the associated value).
"""
storage_writes: Dict[StorageEntry, int] = {}
for address, contract_storage in storage_updates.items():
for key, value in contract_storage.items():
storage_writes[(address, key)] = value

return storage_writes


def to_state_diff_storage_mapping(
storage_writes: Mapping[StorageEntry, int]
) -> Mapping[int, Mapping[int, int]]:
"""
Converts CachedState storage mapping to StateDiff storage mapping.
See to_cached_state_storage_mapping documentation.
"""
storage_updates: Dict[int, Dict[int, int]] = {}
for (address, key), value in storage_writes.items():
if address in storage_updates:
storage_updates[address][key] = value
else:
storage_updates[address] = {key: value}

return storage_updates
17 changes: 17 additions & 0 deletions src/starkware/starknet/business_logic/state/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,23 @@ def update_writes(
self._nonce_writes.update(address_to_nonce)
self._storage_writes.update(storage_updates)

def set_initial_values(
self,
address_to_class_hash: Mapping[int, bytes],
address_to_nonce: Mapping[int, int],
storage_updates: Mapping[Tuple[int, int], int],
):
mappings: Tuple[Mapping, ...] = (
self.address_to_class_hash,
self.address_to_nonce,
self.storage_view,
)
assert all(len(mapping) == 0 for mapping in mappings), "Cache already initialized."

self._class_hash_writes.update(address_to_class_hash)
self._nonce_writes.update(address_to_nonce)
self._storage_writes.update(storage_updates)

def get_accessed_contract_addresses(self) -> Set[int]:
return {
*self.address_to_class_hash.keys(),
Expand Down
72 changes: 35 additions & 37 deletions src/starkware/starknet/business_logic/transaction/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import logging
from abc import abstractmethod
from dataclasses import field
from typing import Any, ClassVar, Dict, List, Optional, Tuple, Type
from typing import Any, ClassVar, Dict, List, Optional, Type

import marshmallow
import marshmallow_dataclass
Expand All @@ -25,7 +25,10 @@
from starkware.starknet.business_logic.state.state_api import SyncState
from starkware.starknet.business_logic.state.state_api_objects import BlockInfo
from starkware.starknet.business_logic.transaction.fee import calculate_tx_fee, execute_fee_transfer
from starkware.starknet.business_logic.transaction.state_objects import InternalStateTransaction
from starkware.starknet.business_logic.transaction.state_objects import (
FeeInfo,
InternalStateTransaction,
)
from starkware.starknet.business_logic.utils import (
calculate_tx_resources,
preprocess_invoke_function_fields,
Expand Down Expand Up @@ -178,15 +181,6 @@ async def apply_state_updates(
assert isinstance(tx_execution_info, TransactionExecutionInfo)
return tx_execution_info

@abstractmethod
def _apply_specific_sequential_changes(
self,
state: SyncState,
general_config: StarknetGeneralConfig,
concurrent_execution_info: TransactionExecutionInfo,
) -> TransactionExecutionInfo:
pass


class SyntheticTransaction(InternalStateTransaction):
"""
Expand Down Expand Up @@ -216,24 +210,33 @@ class InitializeBlockInfo(SyntheticTransaction):
block_info: BlockInfo
tx_type: ClassVar[TransactionType] = TransactionType.INITIALIZE_BLOCK_INFO

def _apply_specific_sequential_changes(
self,
state: SyncState,
general_config: StarknetGeneralConfig,
concurrent_execution_info: TransactionExecutionInfo,
) -> Optional[TransactionExecutionInfo]:
def sync_apply_state_updates(self, state: StateProxy, general_config: Config) -> None:
# Downcast arguments to application-specific types.
assert isinstance(state, SyncState)

# Validate progress is legal.
state.block_info.validate_legal_progress(next_block_info=self.block_info)

# Update entire block-related information.
state.update_block_info(block_info=self.block_info)

return None

def _apply_specific_sequential_changes(
self,
state: SyncState,
general_config: StarknetGeneralConfig,
actual_resources: ResourcesMapping,
) -> FeeInfo:
raise NotImplementedError(
f"_apply_specific_sequential_changes is not implemented for {type(self).__name__}."
)

def _apply_specific_concurrent_changes(
self, state: UpdatesTrackerState, general_config: StarknetGeneralConfig
) -> TransactionExecutionInfo:
return TransactionExecutionInfo.empty()
raise NotImplementedError(
f"_apply_specific_concurrent_changes is not implemented for {type(self).__name__}."
)

def get_state_selector(self, general_config: Config) -> StateSelector:
return StateSelector.empty()
Expand Down Expand Up @@ -335,7 +338,7 @@ def get_execution_context(self, n_steps: int) -> TransactionExecutionContext:

def charge_fee(
self, state: SyncState, resources: ResourcesMapping, general_config: StarknetGeneralConfig
) -> Tuple[Optional[CallInfo], int]:
) -> FeeInfo:
"""
Calculates and charges the actual fee.
"""
Expand Down Expand Up @@ -382,21 +385,14 @@ def _apply_specific_sequential_changes(
self,
state: SyncState,
general_config: StarknetGeneralConfig,
concurrent_execution_info: TransactionExecutionInfo,
) -> TransactionExecutionInfo:
actual_resources: ResourcesMapping,
) -> FeeInfo:
self._handle_nonce(state=state)

# Handle fee.
fee_transfer_info, actual_fee = self.charge_fee(
return self.charge_fee(
state=state,
general_config=general_config,
resources=concurrent_execution_info.actual_resources,
)

return TransactionExecutionInfo.from_concurrent_stage_execution_info(
concurrent_execution_info=concurrent_execution_info,
fee_transfer_info=fee_transfer_info,
actual_fee=actual_fee,
resources=actual_resources,
)


Expand Down Expand Up @@ -945,9 +941,10 @@ def _apply_specific_sequential_changes(
self,
state: SyncState,
general_config: StarknetGeneralConfig,
concurrent_execution_info: TransactionExecutionInfo,
) -> TransactionExecutionInfo:
return concurrent_execution_info
actual_resources: ResourcesMapping,
) -> FeeInfo:
fee_transfer_info, actual_fee = None, 0
return fee_transfer_info, actual_fee

def handle_empty_constructor(self, state: UpdatesTrackerState) -> TransactionExecutionInfo:
stark_assert(
Expand Down Expand Up @@ -1462,9 +1459,10 @@ def _apply_specific_sequential_changes(
self,
state: SyncState,
general_config: StarknetGeneralConfig,
concurrent_execution_info: TransactionExecutionInfo,
) -> TransactionExecutionInfo:
return concurrent_execution_info
actual_resources: ResourcesMapping,
) -> FeeInfo:
fee_transfer_info, actual_fee = None, 0
return fee_transfer_info, actual_fee

def get_execution_context(self, n_steps: int) -> TransactionExecutionContext:
return TransactionExecutionContext.create(
Expand Down
Loading

0 comments on commit 9889fbd

Please sign in to comment.