2020-05-25 23:41:42 +00:00
|
|
|
"""
|
|
|
|
This file is part of nucypher.
|
|
|
|
|
|
|
|
nucypher is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU Affero General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
nucypher is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU Affero General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
|
|
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
"""
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
from hexbytes import HexBytes
|
2020-06-05 00:04:43 +00:00
|
|
|
from web3.exceptions import TransactionNotFound
|
2020-05-25 23:41:42 +00:00
|
|
|
|
|
|
|
from tests.mock.interfaces import MockEthereumClient
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
def mock_ethereum_client(mocker):
|
|
|
|
web3_mock = mocker.Mock()
|
|
|
|
mock_client = MockEthereumClient(w3=web3_mock)
|
|
|
|
return mock_client
|
|
|
|
|
|
|
|
|
2020-06-05 00:04:43 +00:00
|
|
|
def test_check_transaction_is_on_chain(mocker, mock_ethereum_client):
|
2020-05-25 23:41:42 +00:00
|
|
|
|
|
|
|
# Mock data
|
|
|
|
block_number_of_my_tx = 42
|
|
|
|
my_tx_hash = HexBytes('0xFabadaAcabada')
|
|
|
|
|
|
|
|
receipt = {
|
|
|
|
'transactionHash': my_tx_hash,
|
|
|
|
'blockNumber': block_number_of_my_tx,
|
|
|
|
'blockHash': HexBytes('0xBebeCafe')
|
|
|
|
}
|
|
|
|
|
2020-06-05 00:04:43 +00:00
|
|
|
# Mocking Web3 and EthereumClient
|
|
|
|
web3_mock = mock_ethereum_client.w3
|
|
|
|
web3_mock.eth.getTransactionReceipt = mocker.Mock(return_value=receipt)
|
2020-05-25 23:41:42 +00:00
|
|
|
|
2020-06-05 00:04:43 +00:00
|
|
|
# Test with no chain reorganizations:
|
2020-05-25 23:41:42 +00:00
|
|
|
|
2020-06-05 00:04:43 +00:00
|
|
|
# While web3 keeps returning the same receipt that we initially had, all good
|
|
|
|
assert mock_ethereum_client.check_transaction_is_on_chain(receipt=receipt)
|
2020-05-25 23:41:42 +00:00
|
|
|
|
2020-06-05 00:04:43 +00:00
|
|
|
# Test with chain re-organizations:
|
2020-05-25 23:41:42 +00:00
|
|
|
|
2020-06-05 00:04:43 +00:00
|
|
|
# Let's assume that our TX ends up mined in a different block, and we receive a new receipt
|
|
|
|
new_receipt = {
|
|
|
|
'transactionHash': my_tx_hash,
|
|
|
|
'blockNumber': block_number_of_my_tx,
|
|
|
|
'blockHash': HexBytes('0xBebeCebada')
|
2020-05-25 23:41:42 +00:00
|
|
|
}
|
2020-06-05 00:04:43 +00:00
|
|
|
web3_mock.eth.getTransactionReceipt = mocker.Mock(return_value=new_receipt)
|
2020-05-25 23:41:42 +00:00
|
|
|
|
|
|
|
exception = mock_ethereum_client.ChainReorganizationDetected
|
2020-06-05 00:04:43 +00:00
|
|
|
message = exception(receipt=receipt).message
|
|
|
|
with pytest.raises(exception, match=message):
|
|
|
|
_ = mock_ethereum_client.check_transaction_is_on_chain(receipt=receipt)
|
|
|
|
|
|
|
|
# Another example: there has been a chain reorganization and our beloved TX is gone for good:
|
|
|
|
web3_mock.eth.getTransactionReceipt = mocker.Mock(side_effect=TransactionNotFound)
|
2020-05-25 23:41:42 +00:00
|
|
|
with pytest.raises(exception, match=message):
|
2020-06-05 00:04:43 +00:00
|
|
|
_ = mock_ethereum_client.check_transaction_is_on_chain(receipt=receipt)
|