From 4ac87b94ed4d5b0ab0a77ca7a2e590fd17f730ab Mon Sep 17 00:00:00 2001 From: Ben Hauser Date: Tue, 17 Nov 2020 19:56:08 +0400 Subject: [PATCH 1/3] fix: get nonce using getTransactionCount (in case sender is not Account) --- brownie/network/transaction.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/brownie/network/transaction.py b/brownie/network/transaction.py index 1644144e4..5c5dfafe0 100644 --- a/brownie/network/transaction.py +++ b/brownie/network/transaction.py @@ -310,10 +310,12 @@ def wait(self, required_confs: int) -> None: tx: Dict = web3.eth.getTransaction(self.txid) break except TransactionNotFound: - if self.sender.nonce > self.nonce: # type: ignore - self.status = Status(-2) - print("This transaction was replaced.") - return + if self.nonce is not None: + sender_nonce = web3.eth.getTransactionCount(str(self.sender)) + if sender_nonce > self.nonce: + self.status = Status(-2) + print("This transaction was replaced.") + return time.sleep(1) self._await_confirmation(tx, required_confs) @@ -343,10 +345,13 @@ def _await_transaction(self, required_confs: int, is_blocking: bool) -> None: # if sender was not explicitly set, this transaction was # not broadcasted locally and so likely doesn't exist raise - if self.nonce is not None and self.sender.nonce > self.nonce: - self.status = Status(-2) - return + if self.nonce is not None: + sender_nonce = web3.eth.getTransactionCount(str(self.sender)) + if sender_nonce > self.nonce: + self.status = Status(-2) + return time.sleep(1) + self._set_from_tx(tx) if not self._silent: @@ -378,10 +383,11 @@ def _await_confirmation(self, tx: Dict, required_confs: int = 1) -> None: # await first confirmation while True: # if sender nonce is greater than tx nonce, the tx should be confirmed - expect_confirmed = bool(self.sender.nonce > self.nonce) # type: ignore + sender_nonce = web3.eth.getTransactionCount(str(self.sender)) + expect_confirmed = bool(sender_nonce > self.nonce) # type: ignore try: receipt = web3.eth.waitForTransactionReceipt( - HexBytes(self.txid), timeout=30, poll_latency=1 + HexBytes(self.txid), timeout=15, poll_latency=1 ) break except TimeExhausted: From 27f80e8dd003a9a7f62df0238c7c2970254bb997 Mon Sep 17 00:00:00 2001 From: Ben Hauser Date: Sat, 21 Nov 2020 18:58:25 +0400 Subject: [PATCH 2/3] fix: await confirmation on non-blocking calls when tx has already confirmed --- brownie/network/transaction.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/brownie/network/transaction.py b/brownie/network/transaction.py index 5c5dfafe0..0d48a2ed9 100644 --- a/brownie/network/transaction.py +++ b/brownie/network/transaction.py @@ -361,12 +361,13 @@ def _await_transaction(self, required_confs: int, is_blocking: bool) -> None: f" Nonce: {color('bright blue')}{self.nonce}{color}" ) - # await confirmation of tx in a separate thread which is blocking if required_confs > 0 + # await confirmation of tx in a separate thread which is blocking if + # required_confs > 0 or tx has already confirmed (`blockNumber` != None) confirm_thread = threading.Thread( target=self._await_confirmation, args=(tx, required_confs), daemon=True ) confirm_thread.start() - if is_blocking and required_confs > 0: + if is_blocking and (required_confs > 0 or tx["blockNumber"]): confirm_thread.join() def _await_confirmation(self, tx: Dict, required_confs: int = 1) -> None: From 0c907447cd5b5e18f6909f2569b35a402e017842 Mon Sep 17 00:00:00 2001 From: Ben Hauser Date: Sat, 21 Nov 2020 18:59:40 +0400 Subject: [PATCH 3/3] test: chain.get_transaction on mainnet with unknown tx's --- tests/network/state/test_get_transaction.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/network/state/test_get_transaction.py b/tests/network/state/test_get_transaction.py index 08fe6caaa..0f38c42c8 100644 --- a/tests/network/state/test_get_transaction.py +++ b/tests/network/state/test_get_transaction.py @@ -19,3 +19,17 @@ def test_not_in_history(accounts, chain, history): def test_unknown_tx(accounts, chain, history): with pytest.raises(TransactionNotFound): chain.get_transaction("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") + + +def test_external_tx(network, chain): + network.connect("mainnet") + + tx = chain.get_transaction("0x1e0e3df9daa09d009185a1d009b905a9264e296f2d9c8cf6e8a2d0723df249a3") + assert tx.status == 1 + + +def test_external_tx_reverted(network, chain): + network.connect("mainnet") + + tx = chain.get_transaction("0x7c913d12a7692889c364913b7909806de05692abc9312b718f16f444e4a6b94b") + assert tx.status == 0