From e20b1f54dd7e82934eb309bece9f75c733236be7 Mon Sep 17 00:00:00 2001 From: Felipe Selmo Date: Thu, 15 Jul 2021 15:30:27 -0600 Subject: [PATCH] Update eth-account version & add eip-1559 eth_signTransaction support Updated the eth-account version to the latest which includes eip-1559 support. Added integration tests and made minor tweaks to support eip-1559 params for eth_signTransaction --- newsfragments/2082.feature.rst | 1 + setup.py | 2 +- tests/integration/test_ethereum_tester.py | 8 +++ web3/_utils/method_formatters.py | 1 + web3/_utils/module_testing/eth_module.py | 62 +++++++++++++++++++++-- 5 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 newsfragments/2082.feature.rst diff --git a/newsfragments/2082.feature.rst b/newsfragments/2082.feature.rst new file mode 100644 index 0000000000..c1e028f246 --- /dev/null +++ b/newsfragments/2082.feature.rst @@ -0,0 +1 @@ +eth_signTransaction support for eip-1559 params 'maxFeePerGas' and 'maxPriorityFeePerGas' \ No newline at end of file diff --git a/setup.py b/setup.py index 0bfb6ea8d7..6e70ccc2f4 100644 --- a/setup.py +++ b/setup.py @@ -74,7 +74,7 @@ install_requires=[ "aiohttp>=3.7.4.post0,<4", "eth-abi>=2.0.0b6,<3.0.0", - "eth-account>=0.5.3,<0.6.0", + "eth-account>=0.5.5,<0.6.0", "eth-hash[pycryptodome]>=0.2.0,<1.0.0", "eth-typing>=2.0.0,<3.0.0", "eth-utils>=1.9.5,<2.0.0", diff --git a/tests/integration/test_ethereum_tester.py b/tests/integration/test_ethereum_tester.py index 80d80eb37a..7dac70280f 100644 --- a/tests/integration/test_ethereum_tester.py +++ b/tests/integration/test_ethereum_tester.py @@ -254,7 +254,15 @@ class TestEthereumTesterEthModule(EthModuleTest): EthModuleTest.test_eth_signTransaction_deprecated, ValueError ) + test_eth_sign_transaction_legacy = not_implemented( + EthModuleTest.test_eth_sign_transaction_legacy, + ValueError + ) test_eth_sign_transaction = not_implemented(EthModuleTest.test_eth_sign_transaction, ValueError) + test_eth_sign_transaction_hex_fees = not_implemented( + EthModuleTest.test_eth_sign_transaction_hex_fees, + ValueError + ) test_eth_sign_transaction_ens_names = not_implemented( EthModuleTest.test_eth_sign_transaction_ens_names, ValueError ) diff --git a/web3/_utils/method_formatters.py b/web3/_utils/method_formatters.py index e489b324e3..abbf21cd1b 100644 --- a/web3/_utils/method_formatters.py +++ b/web3/_utils/method_formatters.py @@ -411,6 +411,7 @@ def apply_list_to_array_formatter(formatter: Any) -> Callable[..., Any]: (is_length(2), estimate_gas_with_block_id), )), RPC.eth_sendTransaction: apply_formatter_at_index(transaction_param_formatter, 0), + RPC.eth_signTransaction: apply_formatter_at_index(transaction_param_formatter, 0), RPC.eth_getProof: apply_formatter_at_index(to_hex_if_integer, 2), # personal RPC.personal_importRawKey: apply_formatter_at_index( diff --git a/web3/_utils/module_testing/eth_module.py b/web3/_utils/module_testing/eth_module.py index d1eafb651e..c529533147 100644 --- a/web3/_utils/module_testing/eth_module.py +++ b/web3/_utils/module_testing/eth_module.py @@ -939,7 +939,11 @@ def test_invalid_eth_sign_typed_data( json.loads(invalid_typed_message) ) - def test_eth_sign_transaction(self, web3: "Web3", unlocked_account: ChecksumAddress) -> None: + def test_eth_sign_transaction_legacy( + self, + web3: "Web3", + unlocked_account: ChecksumAddress + ) -> None: txn_params: TxParams = { 'from': unlocked_account, 'to': unlocked_account, @@ -957,6 +961,56 @@ def test_eth_sign_transaction(self, web3: "Web3", unlocked_account: ChecksumAddr assert result['tx']['gasPrice'] == txn_params['gasPrice'] assert result['tx']['nonce'] == txn_params['nonce'] + def test_eth_sign_transaction( + self, + web3: "Web3", + unlocked_account: ChecksumAddress + ) -> None: + txn_params: TxParams = { + 'from': unlocked_account, + 'to': unlocked_account, + 'value': Wei(1), + 'gas': Wei(21000), + 'maxFeePerGas': web3.toWei(2, 'gwei'), + 'maxPriorityFeePerGas': web3.toWei(1, 'gwei'), + 'nonce': Nonce(0), + } + result = web3.eth.sign_transaction(txn_params) + signatory_account = web3.eth.account.recover_transaction(result['raw']) + assert unlocked_account == signatory_account + assert result['tx']['to'] == txn_params['to'] + assert result['tx']['value'] == txn_params['value'] + assert result['tx']['gas'] == txn_params['gas'] + assert result['tx']['maxFeePerGas'] == txn_params['maxFeePerGas'] + assert result['tx']['maxPriorityFeePerGas'] == txn_params['maxPriorityFeePerGas'] + assert result['tx']['nonce'] == txn_params['nonce'] + + def test_eth_sign_transaction_hex_fees( + self, + web3: "Web3", + unlocked_account: ChecksumAddress + ) -> None: + txn_params: TxParams = { + 'from': unlocked_account, + 'to': unlocked_account, + 'value': Wei(1), + 'gas': Wei(21000), + 'maxFeePerGas': hex(web3.toWei(2, 'gwei')), + 'maxPriorityFeePerGas': hex(web3.toWei(1, 'gwei')), + 'nonce': Nonce(0), + } + result = web3.eth.sign_transaction(txn_params) + signatory_account = web3.eth.account.recover_transaction(result['raw']) + assert unlocked_account == signatory_account + assert result['tx']['to'] == txn_params['to'] + assert result['tx']['value'] == txn_params['value'] + assert result['tx']['gas'] == txn_params['gas'] + assert result['tx']['maxFeePerGas'] == int(str(txn_params['maxFeePerGas']), 16) + assert result['tx']['maxPriorityFeePerGas'] == int( + str(txn_params['maxPriorityFeePerGas']), 16 + ) + assert result['tx']['nonce'] == txn_params['nonce'] + def test_eth_signTransaction_deprecated(self, web3: "Web3", unlocked_account: ChecksumAddress) -> None: @@ -988,7 +1042,8 @@ def test_eth_sign_transaction_ens_names( 'to': 'unlocked-account.eth', 'value': Wei(1), 'gas': Wei(21000), - 'gasPrice': web3.eth.gas_price, + 'maxFeePerGas': web3.toWei(2, 'gwei'), + 'maxPriorityFeePerGas': web3.toWei(1, 'gwei'), 'nonce': Nonce(0), } result = web3.eth.sign_transaction(txn_params) @@ -997,7 +1052,8 @@ def test_eth_sign_transaction_ens_names( assert result['tx']['to'] == unlocked_account assert result['tx']['value'] == txn_params['value'] assert result['tx']['gas'] == txn_params['gas'] - assert result['tx']['gasPrice'] == txn_params['gasPrice'] + assert result['tx']['maxFeePerGas'] == txn_params['maxFeePerGas'] + assert result['tx']['maxPriorityFeePerGas'] == txn_params['maxPriorityFeePerGas'] assert result['tx']['nonce'] == txn_params['nonce'] def test_eth_send_transaction_addr_checksum_required(