示例#1
0
    def mine(self,
             blocks: int = 1,
             timestamp: int = None,
             timedelta: int = None) -> int:
        """
        Increase the block height within the test RPC.

        Arguments
        ---------
        blocks : int
            Number of new blocks to be mined
        timestamp : int
            Timestamp of the final block being mined. If multiple blocks
            are mined, they will be placed at equal intervals starting
            at `chain.time()` and ending at `timestamp`.
        timedelta : int
            Timedelta for the final block to be mined. If given, the final
            block will have a timestamp of `chain.time() + timedelta`

        Returns
        -------
        int
            Current block height
        """
        if not isinstance(blocks, int):
            raise TypeError("`blocks` must be an integer value")

        if timedelta is not None and timestamp is not None:
            raise ValueError("Cannot use both `timestamp` and `timedelta`")

        if timedelta is not None:
            timestamp = self.time() + timedelta

        if timestamp is None:
            params: List = [[] for i in range(blocks)]
        elif blocks == 1:
            params = [[timestamp]]
        else:
            now = self.time()
            duration = (timestamp - now) / (blocks - 1)
            params = [[round(now + duration * i)] for i in range(blocks)]

        for i in range(blocks):
            rpc.Rpc().mine(*params[i])

        if timestamp is not None:
            self.sleep(0)

        self._redo_buffer.clear()
        self._current_id = rpc.Rpc().snapshot()
        return web3.eth.block_number
示例#2
0
    def sleep(self, seconds: int) -> None:
        """
        Increase the time within the test RPC.

        Arguments
        ---------
        seconds : int
            Number of seconds to increase the time by
        """
        if not isinstance(seconds, int):
            raise TypeError("seconds must be an integer value")
        self._time_offset = int(rpc.Rpc().sleep(seconds))

        if seconds:
            self._redo_buffer.clear()
            self._current_id = rpc.Rpc().snapshot()
示例#3
0
    def snapshot(self) -> None:
        """
        Take a snapshot of the current state of the EVM.

        This action clears the undo buffer.
        """
        self._undo_buffer.clear()
        self._redo_buffer.clear()
        self._snapshot_id = self._current_id = rpc.Rpc().snapshot()
示例#4
0
 def _add_to_undo_buffer(self, tx: Any, fn: Any, args: Tuple, kwargs: Dict) -> None:
     with self._undo_lock:
         tx._confirmed.wait()
         self._undo_buffer.append((self._current_id, fn, args, kwargs))
         if self._redo_buffer and (fn, args, kwargs) == self._redo_buffer[-1]:
             self._redo_buffer.pop()
         else:
             self._redo_buffer.clear()
         self._current_id = rpc.Rpc().snapshot()
示例#5
0
 def _add_to_undo_buffer(self, tx: Any, fn: Any, args: Tuple,
                         kwargs: Dict) -> None:
     with self._undo_lock:
         tx._confirmed.wait()
         self._undo_buffer.append((self._current_id, fn, args, kwargs))
         if self._redo_buffer and (fn, args,
                                   kwargs) == self._redo_buffer[-1]:
             self._redo_buffer.pop()
         else:
             self._redo_buffer.clear()
         self._current_id = rpc.Rpc().snapshot()
         # ensure the local time offset is correct, in case it was modified by the transaction
         self.sleep(0)
示例#6
0
 def _revert(self, id_: int) -> int:
     rpc_client = rpc.Rpc()
     if web3.isConnected() and not web3.eth.block_number and not self._time_offset:
         _notify_registry(0)
         return rpc_client.snapshot()
     rpc_client.revert(id_)
     id_ = rpc_client.snapshot()
     try:
         self.sleep(0)
     except NotImplementedError:
         pass
     _notify_registry()
     return id_
示例#7
0
    def reset(self) -> int:
        """
        Revert the EVM to the initial state when loaded.

        This action clears the undo buffer.

        Returns
        -------
        int
            Current block height
        """
        self._snapshot_id = None
        self._undo_buffer.clear()
        self._redo_buffer.clear()
        if self._reset_id is None:
            self._reset_id = self._current_id = rpc.Rpc().snapshot()
            _notify_registry(0)
        else:
            self._reset_id = self._current_id = self._revert(self._reset_id)
        return web3.eth.block_number