def process(self, request): with self._lock, self._socket as sock: try: sock.sendall(request) except BrokenPipeError: # one extra attempt, then give up sock = self._socket.reset() sock.sendall(request) raw_response = b'' with Timeout(self.ipc_timeout) as timeout: while True: try: raw_response += sock.recv(BUFSIZE) except socket.timeout: timeout.sleep(0) continue if raw_response == b"": timeout.sleep(0) elif has_valid_json_rpc_ending(raw_response): try: json.loads(to_text(raw_response)) except JSONDecodeError: timeout.sleep(0) continue else: return raw_response else: timeout.sleep(0) continue return response
def test_txpool_content(web3_empty): web3 = web3_empty web3.miner.stop() with Timeout(60) as timeout: while web3.eth.hashrate or web3.eth.mining: timeout.sleep(random.random()) txn_1_hash = web3.eth.sendTransaction({ 'from': web3.eth.coinbase, 'to': '0xd3CdA913deB6f67967B99D67aCDFa1712C293601', 'value': 12345, }) txn_1 = web3.eth.getTransaction(txn_1_hash) txn_2_hash = web3.eth.sendTransaction({ 'from': web3.eth.coinbase, 'to': '0xd3CdA913deB6f67967B99D67aCDFa1712C293601', 'value': 54321, }) txn_2 = web3.eth.getTransaction(txn_2_hash) content = web3.txpool.content assert web3.eth.coinbase in content['pending'] pending_txns = content['pending'][web3.eth.coinbase] assert txn_1['nonce'] in pending_txns assert txn_2['nonce'] in pending_txns assert pending_txns[txn_1['nonce']][0]['hash'] == txn_1_hash assert pending_txns[txn_1['nonce']][0]['value'] == 12345 assert pending_txns[txn_2['nonce']][0]['hash'] == txn_2_hash assert pending_txns[txn_2['nonce']][0]['value'] == 54321
def test_async_filter_against_pending_transactions(web3_empty, wait_for_transaction, skip_if_testrpc ): web3 = web3_empty skip_if_testrpc(web3) seen_txns = [] txn_filter = web3.eth.filter("pending") txn_filter.watch(seen_txns.append) txn_1_hash = web3.eth.send_transaction({ 'from': web3.eth.coinbase, 'to': '0xd3CdA913deB6f67967B99D67aCDFa1712C293601', 'value': 12345, }) txn_2_hash = web3.eth.send_transaction({ 'from': web3.eth.coinbase, 'to': '0xd3CdA913deB6f67967B99D67aCDFa1712C293601', 'value': 54321, }) wait_for_transaction(web3, txn_1_hash) wait_for_transaction(web3, txn_2_hash) with Timeout(5) as timeout: while not seen_txns: timeout.sleep(random.random()) txn_filter.stop_watching(30) assert txn_1_hash in seen_txns assert txn_2_hash in seen_txns
def block_until_enough_confirmations(self, transaction_hash: str, timeout: float, confirmations: int) -> dict: receipt: TxReceipt = self.w3.eth.waitForTransactionReceipt( transaction_hash=transaction_hash, timeout=timeout, poll_latency=self.TRANSACTION_POLLING_TIME) preliminary_block_hash = Web3.toHex(receipt['blockHash']) tx_block_number = Web3.toInt(receipt['blockNumber']) self.log.info( f"Transaction {Web3.toHex(transaction_hash)} is preliminarily included in " f"block {preliminary_block_hash}") confirmations_timeout = self._calculate_confirmations_timeout( confirmations) confirmations_so_far = 0 with Timeout(seconds=confirmations_timeout, exception=self.NotEnoughConfirmations) as timeout_context: while confirmations_so_far < confirmations: timeout_context.sleep(self.BLOCK_CONFIRMATIONS_POLLING_TIME) self.check_transaction_is_on_chain(receipt=receipt) confirmations_so_far = self.block_number - tx_block_number self.log.info( f"We have {confirmations_so_far} confirmations. " f"Waiting for {confirmations - confirmations_so_far} more." ) return receipt
def test_miner_setExtra(web3_empty, wait_for_block): web3 = web3_empty initial_extra = decode_hex( web3.eth.getBlock(web3.eth.blockNumber)['extraData']) new_extra_data = b'-this-is-32-bytes-of-extra-data-' # sanity assert initial_extra != new_extra_data web3.geth.miner.setExtra(new_extra_data) with Timeout(60) as timeout: while True: extra_data = decode_hex( web3.eth.getBlock(web3.eth.blockNumber)['extraData']) if extra_data == new_extra_data: break timeout.sleep(random.random()) after_extra = decode_hex( web3.eth.getBlock(web3.eth.blockNumber)['extraData']) assert after_extra == new_extra_data
def wait_for_receipt(self, transaction_hash: str, timeout: float, confirmations: int = 0) -> TxReceipt: receipt: TxReceipt = None if confirmations: # If we're waiting for confirmations, we may as well let pass some time initially to make everything easier time.sleep(self.COOLING_TIME) # We'll keep trying to get receipts until there are enough confirmations or the timeout happens with Timeout(seconds=timeout, exception=self.TransactionTimeout) as timeout_context: while not receipt: try: receipt = self.block_until_enough_confirmations( transaction_hash=transaction_hash, timeout=timeout, confirmations=confirmations) except (self.ChainReorganizationDetected, self.NotEnoughConfirmations, TimeExhausted): timeout_context.sleep( self.BLOCK_CONFIRMATIONS_POLLING_TIME) continue else: # If not asking for confirmations, just use web3 and assume the returned receipt is final try: receipt = self.w3.eth.waitForTransactionReceipt( transaction_hash=transaction_hash, timeout=timeout, poll_latency=self.TRANSACTION_POLLING_TIME) except TimeExhausted: raise # TODO: #1504 - Handle transaction timeout return receipt
def wait(self, seconds: int) -> None: try: with Timeout(seconds) as timeout: while len(list(self.event_waiting.keys())): timeout.sleep(2) except Exception as e: echo(e, err=True) message = "NO EVENTS WERE TRIGGERED FOR: " + str( self.event_waiting) if len(self.event_unknown) > 0: message += "\n UNKOWN EVENTS: " + str(self.event_unknown) # FIXME Events triggered in an internal transaction # don't have the transactionHash we are looking for here # so we just check if the number of unknown events we find # is the same as the found events waiting_events = sum( [len(lst) for lst in self.event_waiting.values()]) if waiting_events == len(self.event_unknown): sandwitch_echo(message) else: raise Exception( message + " waiting_events " + str(waiting_events), " len(self.event_unknown) " + str(len(self.event_unknown)), )
def wait(self, seconds): try: with Timeout(seconds) as timeout: while len(list(self.event_waiting.keys())): timeout.sleep(2) except Exception as e: print(e) message = 'NO EVENTS WERE TRIGGERED FOR: ' + str(self.event_waiting) if len(self.event_unknown) > 0: message += '\n UNKOWN EVENTS: ' + str(self.event_unknown) # FIXME Events triggered in an internal transaction # don't have the transactionHash we are looking for here # so we just check if the number of unknown events we find # is the same as the found events waiting_events = 0 for ev in list(self.event_waiting.keys()): waiting_events += len(list(self.event_waiting[ev].keys())) if waiting_events == len(self.event_unknown): print('----------------------------------') print(message) print('----------------------------------') else: raise Exception(message + ' waiting_events ' + str(waiting_events), ' len(self.event_unkown) ' + str(len(self.event_unknown)))
def _wait_for_validation(_w3: Web3, _tx_dict: dict, _tmout: int = 120) -> dict: """ Wait contract's inclusion to a block :params Web3 _w3: Web3 instance :params dict _tx_dict: Transactions waiting for inclusion :params int: _tmout: Timeout for inclusion to a block in seconds :return: Receipts :rtype: dict """ receipts_list = {} for i in _tx_dict.keys(): receipts_list[i] = [_tx_dict[i], None] confirmations = len(list(_tx_dict)) with Timeout(_tmout) as tm: while(confirmations > 0): for i in _tx_dict.keys(): if receipts_list[i][1] is None: tx_reciept = _w3.eth.getTransactionReceipt(receipts_list[i][0]) if tx_reciept is not None: receipts_list[i][1] = tx_reciept confirmations -= 1 tm.sleep(random()) return receipts_list
def make_batch_request(self, text): request = text.encode('utf-8') with self._lock, self._socket as sock: try: sock.sendall(request) except BrokenPipeError: # one extra attempt, then give up sock = self._socket.reset() sock.sendall(request) raw_response = b"" with Timeout(self.timeout) as timeout: while True: try: raw_response += sock.recv(4096) except socket.timeout: timeout.sleep(0) continue if raw_response == b"": timeout.sleep(0) elif has_valid_json_rpc_ending(raw_response): try: response = json.loads(raw_response.decode('utf-8')) except JSONDecodeError: timeout.sleep(0) continue else: return response else: timeout.sleep(0) continue
def test_async_filter_against_log_events(web3_empty, emitter, wait_for_transaction, emitter_log_topics, emitter_event_ids): web3 = web3_empty seen_logs = [] txn_filter = web3.eth.filter({}) txn_filter.watch(seen_logs.append) txn_hashes = [] txn_hashes.append( emitter.functions.logNoArgs( emitter_event_ids.LogNoArguments).transact()) for txn_hash in txn_hashes: wait_for_transaction(web3, txn_hash) with Timeout(5) as timeout: while not seen_logs: timeout.sleep(random.random()) txn_filter.stop_watching(30) assert set(txn_hashes) == set(log['transactionHash'] for log in seen_logs)
def make_request(self, method: RPCEndpoint, params: Any) -> RPCResponse: self.logger.debug(f"Making request IPC. Path: {self.ipc_path}, Method: {method}") request = self.encode_rpc_request(method, params) with self._lock, self._socket as sock: try: sock.sendall(request) except BrokenPipeError: # one extra attempt, then give up sock = self._socket.reset() sock.sendall(request) raw_response = b"" with Timeout(self.timeout) as timeout: while True: try: raw_response += sock.recv(4096) except socket.timeout: timeout.sleep(0) continue if raw_response == b"": timeout.sleep(0) elif has_valid_json_rpc_ending(raw_response): try: response = self.decode_rpc_response(raw_response) except JSONDecodeError: timeout.sleep(0) continue else: return response else: timeout.sleep(0) continue
def test_sync_filter_against_pending_transactions(w3_empty, wait_for_transaction, skip_if_testrpc): w3 = w3_empty skip_if_testrpc(w3) txn_filter = w3.eth.filter("pending") txn_1_hash = w3.eth.send_transaction({ 'from': w3.eth.coinbase, 'to': '0xd3CdA913deB6f67967B99D67aCDFa1712C293601', 'value': 12345, }) txn_2_hash = w3.eth.send_transaction({ 'from': w3.eth.coinbase, 'to': '0xd3CdA913deB6f67967B99D67aCDFa1712C293601', 'value': 54321, }) wait_for_transaction(w3, txn_1_hash) wait_for_transaction(w3, txn_2_hash) with Timeout(5) as timeout: while not txn_filter.get_new_entries(): timeout.sleep(random.random()) seen_txns = txn_filter.get_new_entries() assert txn_1_hash in seen_txns assert txn_2_hash in seen_txns
def test_instantiate_existing_filter(web3, sleep_interval, wait_for_block, filter_id): with pytest.raises(TypeError): web3.eth.filter('latest', filter_id) with pytest.raises(TypeError): web3.eth.filter('latest', filter_id=filter_id) with pytest.raises(TypeError): web3.eth.filter(filter_params='latest', filter_id=filter_id) block_filter = web3.eth.filter(filter_id=filter_id) current_block = web3.eth.blockNumber wait_for_block(web3, current_block + 3) found_block_hashes = [] with Timeout(5) as timeout: while len(found_block_hashes) < 3: found_block_hashes.extend(block_filter.get_new_entries()) timeout.sleep(sleep_interval()) assert len(found_block_hashes) == 3 expected_block_hashes = [ web3.eth.get_block(n + 1).hash for n in range(current_block, current_block + 3) ] assert found_block_hashes == expected_block_hashes
def _wait_for_block(w3, block_number=1, timeout=None): if not timeout: timeout = (block_number - w3.eth.block_number) * 3 poll_delay_counter = PollDelayCounter() with Timeout(timeout) as timeout: while w3.eth.block_number < block_number: w3.manager.request_blocking("evm_mine", []) timeout.sleep(poll_delay_counter())
def wait_for_transaction_receipt(web3, txn_hash, timeout=120, poll_latency=0.1): with Timeout(timeout) as _timeout: while True: txn_receipt = web3.eth.getTransactionReceipt(txn_hash) if txn_receipt is not None: break _timeout.sleep(poll_latency) return txn_receipt
def _wait_for_transaction(web3, txn_hash, timeout=120): poll_delay_counter = PollDelayCounter() with Timeout(timeout) as timeout: while True: txn_receipt = web3.eth.getTransactionReceipt(txn_hash) if txn_receipt is not None: break time.sleep(poll_delay_counter()) timeout.check() return txn_receipt
def wait_for_transaction_receipt(web3, txn_hash, timeout=30, poll_latency=0.1): with Timeout(timeout) as _timeout: while True: try: txn_receipt = web3.fsn.getTransactionReceipt(txn_hash) except TransactionNotFound: txn_receipt = None if txn_receipt is not None and txn_receipt['blockHash'] is not None: break _timeout.sleep(poll_latency) return txn_receipt
def wait_for_transaction_receipt(web3: Web3, txid: HexBytes, timeout: int = 180) -> Optional[TxReceipt]: receipt = None with Timeout(timeout) as time: while not receipt or not receipt["blockNumber"]: # pylint: disable=E1136 try: receipt = web3.eth.get_transaction_receipt(txid) except TransactionNotFound: time.sleep(5) return receipt
def test_with_custom_exception_instance(): exc = ValueError("an instance of an excepiton") timeout = Timeout(0.01, exc) timeout.start() time.sleep(0.02) with pytest.raises(ValueError) as err: timeout.check() assert err.value is exc
def wait_for_transaction_receipt(web3, txn_hash, timeout=120, poll_latency=0.1): with Timeout(timeout) as _timeout: while True: txn_receipt = web3.eth.getTransactionReceipt(txn_hash) # FIXME: The check for a null `blockHash` is due to parity's # non-standard implementation of the JSON-RPC API and should # be removed once the formal spec for the JSON-RPC endpoints # has been finalized. if txn_receipt is not None and txn_receipt['blockHash'] is not None: break _timeout.sleep(poll_latency) return txn_receipt
def test_miner_stop(web3_empty): web3 = web3_empty assert web3.eth.mining assert web3.miner.hashrate web3.miner.stop() with Timeout(60) as timeout: while web3.eth.mining or web3.eth.hashrate: timeout.sleep(random.random()) timeout.check() assert not web3.eth.mining assert not web3.miner.hashrate
def test_miner_set_gas_price(web3_empty, wait_for_block): web3 = web3_empty initial_gas_price = web3.eth.gas_price # sanity check assert web3.eth.gas_price > 1000 web3.geth.miner.set_gas_price(initial_gas_price // 2) with Timeout(60) as timeout: while web3.eth.gas_price == initial_gas_price: timeout.sleep(random.random()) after_gas_price = web3.eth.gas_price assert after_gas_price < initial_gas_price
def test_miner_setGasPrice(web3_empty, wait_for_block): web3 = web3_empty initial_gas_price = web3.eth.gas_price assert web3.eth.gas_price > 1000 # sanity check with pytest.warns(DeprecationWarning): web3.geth.miner.setGasPrice(initial_gas_price // 2) with Timeout(60) as timeout: while web3.eth.gas_price == initial_gas_price: timeout.sleep(random.random()) after_gas_price = web3.eth.gas_price assert after_gas_price < initial_gas_price
def wait_for_transaction_receipt(web3: Web3, txid: str, timeout: int = 180 ) -> Optional[Dict[str, Any]]: receipt = None with Timeout(timeout) as time: while not receipt or not receipt["blockNumber"]: # pylint: disable=E1136 try: receipt = web3.eth.getTransactionReceipt(txid) except ValueError as ex: if str(ex).find("EmptyResponse") != -1: pass # Empty response from a Parity light client else: raise ex time.sleep(5) return receipt
def wait_for_transaction_receipt(web3: "Web3", txn_hash: _Hash32, timeout: float, poll_latency: float) -> TxReceipt: with Timeout(timeout) as _timeout: while True: try: txn_receipt = web3.eth.getTransactionReceipt(txn_hash) except TransactionNotFound: txn_receipt = None # FIXME: The check for a null `blockHash` is due to parity's # non-standard implementation of the JSON-RPC API and should # be removed once the formal spec for the JSON-RPC endpoints # has been finalized. if txn_receipt is not None and txn_receipt['blockHash'] is not None: break _timeout.sleep(poll_latency) return txn_receipt
def wait_for_transaction_to_be_validated( self, tx_hash: str, timeout: float = 120, poll_latency: float = 0.1 ) -> Optional[TxData]: with Timeout(timeout) as _timeout: while True: try: txn_data = self.get_transaction(tx_hash) except TransactionNotFound: txn_data = None if txn_data is not None and txn_data.get('transactionIndex') is not None: break _timeout.sleep(poll_latency) return txn_data
def wait_for_transaction_receipt( self, transaction_hash: _Hash32, timeout: float = 120, poll_latency: float = 0.1 ) -> TxReceipt: try: with Timeout(timeout) as _timeout: while True: try: tx_receipt = self._get_transaction_receipt(transaction_hash) except TransactionNotFound: tx_receipt = None if tx_receipt is not None: break _timeout.sleep(poll_latency) return tx_receipt except Timeout: raise TimeExhausted( f"Transaction {HexBytes(transaction_hash) !r} is not in the chain " f"after {timeout} seconds" )
def test_txpool_inspect(web3_empty): web3 = web3_empty web3.geth.miner.stop() with Timeout(60) as timeout: while web3.eth.hashrate or web3.eth.mining: timeout.sleep(random.random()) txn_1_hash = web3.eth.send_transaction({ 'from': web3.eth.coinbase, 'to': '0xd3CdA913deB6f67967B99D67aCDFa1712C293601', 'value': 12345, }) txn_1 = web3.eth.get_transaction(txn_1_hash) txn_2_hash = web3.eth.send_transaction({ 'from': web3.eth.coinbase, 'to': '0xd3CdA913deB6f67967B99D67aCDFa1712C293601', 'value': 54321, }) txn_2 = web3.eth.get_transaction(txn_2_hash) inspect_content = web3.geth.txpool.inspect assert web3.eth.coinbase in inspect_content['pending'] pending_txns = inspect_content['pending'][web3.eth.coinbase] assert txn_1['nonce'] in pending_txns assert txn_2['nonce'] in pending_txns txn_1_summary = pending_txns[txn_1['nonce']][0] txn_2_summary = pending_txns[txn_2['nonce']][0] assert '0xd3CdA913deB6f67967B99D67aCDFa1712C293601' in txn_1_summary assert '12345 wei' in txn_1_summary assert '0xd3CdA913deB6f67967B99D67aCDFa1712C293601' in txn_2_summary assert '54321 wei' in txn_2_summary
def test_sync_filter_against_latest_blocks(web3, sleep_interval, wait_for_block): if EthereumTesterProvider not in map(type, web3.providers): web3.providers = EthereumTesterProvider() txn_filter = web3.eth.filter("latest") current_block = web3.eth.blockNumber wait_for_block(web3, current_block + 3) found_block_hashes = [] with Timeout(5) as timeout: while len(found_block_hashes) < 3: found_block_hashes.extend(txn_filter.get_new_entries()) timeout.sleep(sleep_interval()) assert len(found_block_hashes) == 3 expected_block_hashes = [ web3.eth.getBlock(n + 1).hash for n in range(current_block, current_block + 3) ] assert found_block_hashes == expected_block_hashes