Skip to content

Commit

Permalink
Expose timestamp
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielSchiavini committed May 15, 2024
1 parent e12f051 commit 93dd6ea
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 7 deletions.
2 changes: 1 addition & 1 deletion boa_zksync/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ def source_code(self):
def __call__(self, *args, **kwargs):
env = self.contract.env
balance_before = env.get_balance(env.eoa)
env.set_balance(env.eoa, 10**20)
env.set_code(self.contract.address, self._override_bytecode)
env.set_balance(env.eoa, 10**20)
try:
return super().__call__(*args, **kwargs)
finally:
Expand Down
43 changes: 38 additions & 5 deletions boa_zksync/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from functools import cached_property
from hashlib import sha256
from pathlib import Path
from typing import Any, Iterable, Optional
from typing import Any, Iterable, Optional, Type
from unittest.mock import MagicMock

from boa.contracts.abi.abi_contract import ABIContract, ABIContractFactory
Expand Down Expand Up @@ -37,10 +37,7 @@ def __init__(self, rpc: str | RPC, *args, **kwargs):
self.evm = None # not used in zkSync
self.eoa = self.generate_address("eoa")
self.last_receipt: dict | None = None

@property
def vm(self):
return MagicMock() # todo: vyper base contract is calling vm directly
self._vm = None

@cached_property
def create(self):
Expand All @@ -50,7 +47,15 @@ def create(self):
if func.full_signature == "create(bytes32,bytes32,bytes)"
)

@property
def vm(self):
if self._vm is None:
# todo: vyper base contract calls this property
self._vm = MagicMock(state=_RPCState(self._rpc))
return self._vm

def _reset_fork(self, block_identifier="latest"):
self._vm = None
if isinstance(self._rpc, EraTestNode) and (inner_rpc := self._rpc.inner_rpc):
del self._rpc # close the old rpc
self._rpc = inner_rpc
Expand All @@ -77,6 +82,7 @@ def fork_rpc(
self.sha3_trace: dict = {}
self.sstore_trace: dict = {}
self._rpc = EraTestNode(rpc, block_identifier)
self._reset_vm()

def register_contract(self, address, obj):
addr = Address(address)
Expand Down Expand Up @@ -249,3 +255,30 @@ def _hash_code(bytecode: bytes) -> bytes:
assert bytecode_size < 2**16, "Bytecode length must be less than 2^16"
bytecode_hash = sha256(bytecode).digest()
return b"\x01\00" + bytecode_size.to_bytes(2, byteorder="big") + bytecode_hash[4:]


class _RPCProperty:
def __init__(self, getter, setter):
self.getter = getter
self.setter = setter

def __set_name__(self, owner: Type["_RPCState"], name: str) -> None:
... # python descriptor protocol

def __get__(self, state: "_RPCState", owner):
if state is None:
return self # static call
return self.getter(state.rpc)

def __set__(self, state: "_RPCState", value):
self.setter(state.rpc, value)


class _RPCState:
timestamp = _RPCProperty(
lambda rpc: to_int(rpc.fetch("eth_getBlockByNumber", ["latest", False])["timestamp"]),
lambda rpc, value: rpc.fetch("evm_setNextBlockTimestamp", [value]),
)

def __init__(self, rpc):
self.rpc = rpc
1 change: 0 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

@pytest.fixture(scope="module")
def zksync_env(account):
boa.interpret.disable_cache() # todo: remove this when api is stable
old_env = boa.env
boa_zksync.set_zksync_test_env()
boa.env.add_account(account, force_eoa=True)
Expand Down
19 changes: 19 additions & 0 deletions tests/test_deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,22 @@ def transfer(_to : address, _value : uint256) -> bool:
to = boa.env.generate_address()
contract.transfer(to, 10)
assert [str(e) for e in contract.get_logs()] == [f"Transfer(sender={boa.env.eoa}, receiver={to}, value=10)"]


def test_time(zksync_env):
code = """
@external
@view
def get_time() -> uint256:
return block.timestamp
"""
# TODO: For some reason the RPC vs the VM timestamp is off by 1
contract = boa.loads(code)
env_timestamp = boa.env.vm.state.timestamp
assert contract.get_time() == env_timestamp + 1
boa.env.vm.state.timestamp = 1234567890
assert contract.get_time() == 1234567890 + 1

# sanity check
block = boa.env._rpc.fetch("eth_getBlockByNumber", ["latest", False])
assert int(block["timestamp"], 16) == env_timestamp

0 comments on commit 93dd6ea

Please sign in to comment.