def test_should_handle_duplicated_nonce_gaps_on_first_transaction(self, web3, datadir): # time.sleep(30) # given web3.eth.defaultAccount = web3.eth.accounts[3] some_account = web3.eth.accounts[3] some_gas_price = 150000000 # when with requests_mock.Mocker(real_http=True) as mock: self.mock_noncegapped_first_txs_in_parity_txqueue(mock, datadir, some_account) with captured_output() as (out, err): plunger = Plunger(args( f"--rpc-port 8545 --source parity_txqueue --override-with-zero-txs {some_account} --gas-price {some_gas_price}")) plunger.web3 = web3 # we need to set `web3` as it has `sendTransaction` mocked for nonce comparison plunger.main() # then assert re.match(f"""There are 2 pending transactions on unknown from {some_account}: TxHash Nonce ========================================================================== 0x72e7a42d3e1b0773f62cfa9ee2bc54ff904a908ac2a668678f9c4880fd046f7a 9 0x53050e62c81fbe440d97d703860096467089bd37b2ad4cc6c699acf217436a64 11 Sent replacement transaction with nonce=0, gas_price={some_gas_price}, tx_hash=0x[0-9a-f]{{64}}. Sent replacement transaction with nonce=1, gas_price={some_gas_price}, tx_hash=0x[0-9a-f]{{64}}. Waiting for the transactions to get mined... All pending transactions have been mined. """, out.getvalue(), re.MULTILINE) # and assert web3.eth.getTransactionCount(some_account) == 2
def test_chain(self, web3): # given some_account = web3.eth.accounts[0] plunger = Plunger(args(f"--rpc-port 8545 --source jsonrpc_getblock --list {some_account}")) # then assert plunger.chain() == "unknown"
def test_should_ignore_pending_transactions_if_their_nonce_is_already_used(self, web3, datadir): # given some_account = web3.eth.accounts[0] # and self.simulate_transactions(web3, 10) # when with requests_mock.Mocker(real_http=True) as mock: self.mock_3_pending_txs_on_jsonrpc(mock, datadir, some_account) with captured_output() as (out, err): Plunger(args(f"--rpc-port 8545 --source jsonrpc_getblock --list {some_account}")).main() with captured_output() as (json_out, err): Plunger(args(f"--rpc-port 8545 --source jsonrpc_getblock --json --list {some_account}")).main() # then assert out.getvalue() == f"""There is 1 pending transaction on unknown from {some_account}: TxHash Nonce ========================================================================== 0x124cb0887d0ea364b402fcc1369b7f9bf4d651bc77d2445aefbeab538dd3aab9 10 """ assert json.loads(json_out.getvalue()) == [ { 'hash': '0x124cb0887d0ea364b402fcc1369b7f9bf4d651bc77d2445aefbeab538dd3aab9', 'nonce': 10 } ]
def test_should_handle_transaction_sending_errors(self, port_number, datadir): with captured_output() as (out, err): # given web3 = Web3(TestRPCProvider("127.0.0.1", port_number)) web3.eth.defaultAccount = web3.eth.accounts[0] some_account = web3.eth.accounts[0] # and self.simulate_transactions(web3, 10) self.ensure_transactions_fail(web3, "Simulated transaction failure") # when with requests_mock.Mocker(real_http=True) as mock: self.mock_3_pending_txs_on_eterscan(mock, datadir, some_account) plunger = Plunger(args(f"--rpc-port {port_number} --source etherscan --override-with-zero-txs {some_account}")) plunger.web3 = web3 # we need to set `web3` as it has `sendTransaction` mocked for transaction failure simulation plunger.main() # then assert out.getvalue() == f"""There is 1 pending transaction on unknown from {some_account}: TxHash Nonce ========================================================================== 0x124cb0887d0ea364b402fcc1369b7f9bf4d651bc77d2445aefbeab538dd3aab9 10 Failed to send replacement transaction with nonce=10, gas_price=1. Error: Simulated transaction failure Waiting for the transactions to get mined... All pending transactions have been mined. """ # and assert web3.eth.getTransactionCount(some_account) == 11
def test_should_use_custom_gas_price_when_overriding_transactions(self, port_number, datadir): with captured_output() as (out, err): # given web3 = Web3(TestRPCProvider("127.0.0.1", port_number)) web3.eth.defaultAccount = web3.eth.accounts[0] some_account = web3.eth.accounts[0] some_gas_price = 150000000 # and self.simulate_transactions(web3, 10) self.ensure_transactions(web3, [10], some_gas_price) # when with requests_mock.Mocker(real_http=True) as mock: self.mock_3_pending_txs_on_eterscan(mock, datadir, some_account) plunger = Plunger(args(f"--rpc-port {port_number} --source etherscan --override-with-zero-txs --gas-price {some_gas_price} {some_account}")) plunger.web3 = web3 # we need to set `web3` as it has `sendTransaction` mocked for nonce comparison plunger.main() # then assert re.match(f"""There is 1 pending transaction on unknown from {some_account}: TxHash Nonce ========================================================================== 0x124cb0887d0ea364b402fcc1369b7f9bf4d651bc77d2445aefbeab538dd3aab9 10 Sent replacement transaction with nonce=10, gas_price={some_gas_price}, tx_hash=0x[0-9a-f]{{64}}. Waiting for the transactions to get mined... All pending transactions have been mined. """, out.getvalue(), re.MULTILINE) # and assert web3.eth.getTransactionCount(some_account) == 11
def test_wait_should_not_terminate_until_transactions_get_mined(self, port_number, datadir): with captured_output() as (out, err): # given web3 = Web3(TestRPCProvider("127.0.0.1", port_number)) some_account = web3.eth.accounts[0] # when with requests_mock.Mocker(real_http=True) as mock: self.mock_3_pending_txs_on_eterscan(mock, datadir, some_account) threading.Thread(target=lambda: Plunger(args(f"--rpc-port {port_number} --source etherscan --wait {some_account}")).main()).start() time.sleep(7) # then assert out.getvalue() == f"""There are 3 pending transactions on unknown from {some_account}: TxHash Nonce ========================================================================== 0x7bc44a24f93df200a3bd172a5a690bec50c215e7a84fa794bacfb61a211d6559 8 0x72e7a42d3e1b0773f62cfa9ee2bc54ff904a908ac2a668678f9c4880fd046f7a 9 0x124cb0887d0ea364b402fcc1369b7f9bf4d651bc77d2445aefbeab538dd3aab9 10 Waiting for the transactions to get mined... """ # when self.simulate_transactions(web3, 11) # and time.sleep(4) # then assert out.getvalue() == f"""There are 3 pending transactions on unknown from {some_account}:
def test_should_detect_0_pending_transactions_in_parity_txqueue(self, web3, datadir): # given some_account = web3.eth.accounts[0] # when with requests_mock.Mocker(real_http=True) as mock: self.mock_0_pending_txs_in_parity_txqueue(mock, datadir) with captured_output() as (out, err): Plunger(args(f"--rpc-port 8545 --source parity_txqueue --list {some_account}")).main() with captured_output() as (json_out, err): Plunger(args(f"--rpc-port 8545 --source parity_txqueue --json --list {some_account}")).main() # then assert out.getvalue() == f"There are no pending transactions on unknown from {some_account}\n" assert json.loads(json_out.getvalue()) == []
def test_should_complain_about_invalid_sources(self): # when with captured_output() as (out, err): with pytest.raises(SystemExit): Plunger(args("--source invalid_one,parity_txqueue --wait 0x0000011111222223333322222111110000099999")).main() # then assert "Unknown source(s): 'invalid_one'." in err.getvalue()
def test_should_complain_about_missing_source_when_only_address_specified(self): # when with captured_output() as (out, err): with pytest.raises(SystemExit): Plunger(args("0x0000011111222223333322222111110000099999")).main() # then assert "usage: plunger" in err.getvalue() assert "error: the following arguments are required: --source" in err.getvalue()
def test_should_print_usage_when_no_arguments(self): # when with captured_output() as (out, err): with pytest.raises(SystemExit): Plunger(args("")).main() # then assert "usage: plunger" in err.getvalue() assert "error: the following arguments are required: address" in err.getvalue()
def test_should_complain_about_missing_mode_when_only_address_and_source_specified(self): # when with captured_output() as (out, err): with pytest.raises(SystemExit): Plunger(args("--source parity_txqueue 0x0000011111222223333322222111110000099999")).main() # then assert "usage: plunger" in err.getvalue() assert "error: one of the arguments --list --wait --override-with-zero-txs is required" in err.getvalue()
def test_should_ignore_duplicates_when_using_two_sources(self, web3, datadir): # given some_account = web3.eth.accounts[0] # when with requests_mock.Mocker(real_http=True) as mock: self.mock_3_pending_txs_on_jsonrpc(mock, datadir, some_account) self.mock_3_pending_txs_in_parity_txqueue(mock, datadir, some_account) with captured_output() as (out, err): Plunger(args(f"--rpc-port 8545 --source jsonrpc_getblock,parity_txqueue --list {some_account}")).main() with captured_output() as (json_out, err): Plunger(args(f"--rpc-port 8545 --source jsonrpc_getblock,parity_txqueue --json --list {some_account}")).main() # then assert out.getvalue() == f"""There are 4 pending transactions on unknown from {some_account}: TxHash Nonce ========================================================================== 0x7bc44a24f93df200a3bd172a5a690bec50c215e7a84fa794bacfb61a211d6559 8 0x72e7a42d3e1b0773f62cfa9ee2bc54ff904a908ac2a668678f9c4880fd046f7a 9 0x124cb0887d0ea364b402fcc1369b7f9bf4d651bc77d2445aefbeab538dd3aab9 10 0x53050e62c81fbe440d97d703860096467089bd37b2ad4cc6c699acf217436a64 11 """ assert json.loads(json_out.getvalue()) == [ { 'hash': '0x7bc44a24f93df200a3bd172a5a690bec50c215e7a84fa794bacfb61a211d6559', 'nonce': 8 }, { 'hash': '0x72e7a42d3e1b0773f62cfa9ee2bc54ff904a908ac2a668678f9c4880fd046f7a', 'nonce': 9 }, { 'hash': '0x124cb0887d0ea364b402fcc1369b7f9bf4d651bc77d2445aefbeab538dd3aab9', 'nonce': 10 }, { 'hash': '0x53050e62c81fbe440d97d703860096467089bd37b2ad4cc6c699acf217436a64', 'nonce': 11 } ]
def test_should_override_parity_txqueue_transactions(self, web3, datadir): # given web3.eth.defaultAccount = web3.eth.accounts[0] some_account = web3.eth.accounts[0] some_gas_price = 150000000 # when with requests_mock.Mocker(real_http=True) as mock: self.mock_3_pending_txs_in_parity_txqueue(mock, datadir, some_account) with captured_output() as (out, err): # and self.simulate_transactions(web3, 9) self.ensure_transactions(web3, [9, 10, 11], some_gas_price) plunger = Plunger( args( f"--rpc-port 8545 --source parity_txqueue --override-with-zero-txs {some_account} --gas-price {some_gas_price}" )) plunger.web3 = web3 # we need to set `web3` as it has `sendTransaction` mocked for nonce comparison plunger.main() # then assert re.match( f"""There are 3 pending transactions on unknown from {some_account}: TxHash Nonce ========================================================================== 0x72e7a42d3e1b0773f62cfa9ee2bc54ff904a908ac2a668678f9c4880fd046f7a 9 0x124cb0887d0ea364b402fcc1369b7f9bf4d651bc77d2445aefbeab538dd3aab9 10 0x53050e62c81fbe440d97d703860096467089bd37b2ad4cc6c699acf217436a64 11 Sent replacement transaction with nonce=9, gas_price={some_gas_price}, tx_hash=0x[0-9a-f]{{64}}. Sent replacement transaction with nonce=10, gas_price={some_gas_price}, tx_hash=0x[0-9a-f]{{64}}. Sent replacement transaction with nonce=11, gas_price={some_gas_price}, tx_hash=0x[0-9a-f]{{64}}. Waiting for the transactions to get mined... All pending transactions have been mined. """, out.getvalue(), re.MULTILINE) # and assert web3.eth.getTransactionCount(some_account, "pending") == 12
def test_should_detect_3_pending_transactions_in_parity_txqueue(self, port_number, datadir): # given web3 = Web3(TestRPCProvider("127.0.0.1", port_number)) some_account = web3.eth.accounts[0] # when with requests_mock.Mocker(real_http=True) as mock: self.mock_3_pending_txs_in_parity_txqueue(mock, datadir, port_number, some_account) with captured_output() as (out, err): Plunger(args(f"--rpc-port {port_number} --source parity_txqueue --list {some_account}")).main() # then assert out.getvalue() == f"""There are 3 pending transactions on unknown from {some_account}:
def test_should_ignore_pending_transactions_if_their_nonce_is_already_used(self, port_number, datadir): # given web3 = Web3(TestRPCProvider("127.0.0.1", port_number)) some_account = web3.eth.accounts[0] # and self.simulate_transactions(web3, 10) # when with requests_mock.Mocker(real_http=True) as mock: self.mock_3_pending_txs_on_eterscan(mock, datadir, some_account) with captured_output() as (out, err): Plunger(args(f"--rpc-port {port_number} --source etherscan --list {some_account}")).main() # then assert out.getvalue() == f"""There is 1 pending transaction on unknown from {some_account}: