Wait until the `transaction_hash` is mined, confirmed, handling reorgs. Consider the following reorg, where a transaction is mined at block B, but it is not mined in the canonical chain A-C-D: A -> B D *--> C --^ When the Ethereum node l
(self, transaction_sent: TransactionSent)
| 1477 | ) |
| 1478 | |
| 1479 | def poll_transaction(self, transaction_sent: TransactionSent) -> TransactionMined: |
| 1480 | """Wait until the `transaction_hash` is mined, confirmed, handling |
| 1481 | reorgs. |
| 1482 | |
| 1483 | Consider the following reorg, where a transaction is mined at block B, |
| 1484 | but it is not mined in the canonical chain A-C-D: |
| 1485 | |
| 1486 | A -> B D |
| 1487 | *--> C --^ |
| 1488 | |
| 1489 | When the Ethereum node looks at block B, from its perspective the |
| 1490 | transaction is mined and it has a receipt. After the reorg it does not |
| 1491 | have a receipt. This can happen on PoW and PoA based chains. |
| 1492 | |
| 1493 | Args: |
| 1494 | transaction_hash: Transaction hash that we are waiting for. |
| 1495 | """ |
| 1496 | transaction_hash_hex = encode_hex(transaction_sent.transaction_hash) |
| 1497 | |
| 1498 | while True: |
| 1499 | tx_receipt: Optional[TxReceipt] = None |
| 1500 | try: |
| 1501 | tx_receipt = self.web3.eth.getTransactionReceipt(transaction_hash_hex) |
| 1502 | except TransactionNotFound: |
| 1503 | pass |
| 1504 | |
| 1505 | # Parity (as of 2.5.7) always returns a receipt. When the |
| 1506 | # transaction is not mined in the canonical chain, the receipt will |
| 1507 | # not have meaningful values. Example of receipt for a transaction |
| 1508 | # that is not mined: |
| 1509 | # |
| 1510 | # blockHash: None |
| 1511 | # blockNumber: None |
| 1512 | # contractAddress: None |
| 1513 | # cumulativeGasUsed: The transaction's gas |
| 1514 | # from: None |
| 1515 | # gasUsed: The transaction's gas |
| 1516 | # logs: [] |
| 1517 | # logsBloom: Zero is hex |
| 1518 | # root: None |
| 1519 | # status: 1 |
| 1520 | # to: None |
| 1521 | # transactionHash: The transaction's hash |
| 1522 | # transactionIndex: 0 |
| 1523 | # |
| 1524 | # Geth only returns a receipt if the transaction was mined on the |
| 1525 | # canonical chain. https://github.com/raiden-network/raiden/issues/4529 |
| 1526 | is_transaction_mined = tx_receipt and tx_receipt.get("blockNumber") is not None |
| 1527 | |
| 1528 | if is_transaction_mined: |
| 1529 | assert tx_receipt is not None, MYPY_ANNOTATION |
| 1530 | confirmation_block = ( |
| 1531 | tx_receipt["blockNumber"] + self.default_block_num_confirmations |
| 1532 | ) |
| 1533 | block_number = self.block_number() |
| 1534 | |
| 1535 | is_transaction_confirmed = block_number >= confirmation_block |
| 1536 | if is_transaction_confirmed: |