From e8e0630dbc9c6bc7af5657266537154905175e0c Mon Sep 17 00:00:00 2001 From: Alice Date: Mon, 12 Oct 2026 18:50:33 +0700 Subject: [PATCH 1/2] fix: normalize address in sim_fundAccount sim_fundAccount returned a success-looking result hash but silently credited nothing when passed a lowercase address (e.g. from MetaMask). Ethereum JSON-RPC addresses are case-insensitive, so normalize to checksum format before the lookup. Closes #1788 --- backend/protocol_rpc/endpoints.py | 4 +++ tests/unit/test_simulator_sessions.py | 38 +++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/backend/protocol_rpc/endpoints.py b/backend/protocol_rpc/endpoints.py index c150d4830..576448099 100644 --- a/backend/protocol_rpc/endpoints.py +++ b/backend/protocol_rpc/endpoints.py @@ -394,6 +394,10 @@ def fund_account( if not accounts_manager.is_valid_address(account_address): raise InvalidAddressError(account_address) + from eth_utils import to_checksum_address + + account_address = to_checksum_address(account_address) + import secrets nonce = transactions_processor.get_transaction_count(None) diff --git a/tests/unit/test_simulator_sessions.py b/tests/unit/test_simulator_sessions.py index cae1d6203..62a32eaca 100644 --- a/tests/unit/test_simulator_sessions.py +++ b/tests/unit/test_simulator_sessions.py @@ -460,3 +460,41 @@ def transactions_processor_factory(s): new_status=TransactionStatus.FINALIZED, update_current_status_changes=True, ) + + +def test_fund_account_normalizes_lowercase_address(monkeypatch): + session = object() + accounts_manager_instance = MagicMock() + accounts_manager_instance.is_valid_address.return_value = True + + transactions_processor_instance = MagicMock() + transactions_processor_instance.get_transaction_count.return_value = 5 + transactions_processor_instance.insert_transaction.return_value = None + + def mock_token_hex(n): + return "def" if n == 32 else "xxx" + + monkeypatch.setattr("secrets.token_hex", mock_token_hex) + + monkeypatch.setattr( + endpoints, + "AccountsManager", + lambda s: accounts_manager_instance if s is session else None, + ) + monkeypatch.setattr( + endpoints, + "TransactionsProcessor", + lambda s: transactions_processor_instance if s is session else None, + ) + + lowercase = "0x" + "ab" * 20 + result = endpoints.fund_account(session, lowercase, 100) + + assert result == "0xdef" + checksummed = "0x" + "AB" * 20 + transactions_processor_instance.insert_transaction.assert_called_once_with( + None, checksummed, None, 100, 0, 5, False, 0, None, "0xdef" + ) + accounts_manager_instance.credit_tx_value_once.assert_called_once_with( + "0xdef", checksummed, 100 + ) From 5d724aa0979c5fc9bf028f0d507ad20146d055b1 Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Wed, 21 Oct 2026 10:23:20 -0500 Subject: [PATCH 2/2] test: fix checksum expectation and session mock in fund_account normalization test The expected address was not a valid EIP-55 checksum, so the test never passed. fund_account now commits the session (#1760), which object() cannot do. --- tests/unit/test_simulator_sessions.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/unit/test_simulator_sessions.py b/tests/unit/test_simulator_sessions.py index 675db874a..7a3f9bebd 100644 --- a/tests/unit/test_simulator_sessions.py +++ b/tests/unit/test_simulator_sessions.py @@ -1117,7 +1117,7 @@ def transactions_processor_factory(s): def test_fund_account_normalizes_lowercase_address(monkeypatch): - session = object() + session = MagicMock() accounts_manager_instance = MagicMock() accounts_manager_instance.is_valid_address.return_value = True @@ -1145,10 +1145,11 @@ def mock_token_hex(n): result = endpoints.fund_account(session, lowercase, 100) assert result == "0xdef" - checksummed = "0x" + "AB" * 20 + checksummed = "0xABaBaBaBABabABabAbAbABAbABabababaBaBABaB" transactions_processor_instance.insert_transaction.assert_called_once_with( None, checksummed, None, 100, 0, 5, False, 0, None, "0xdef" ) accounts_manager_instance.credit_tx_value_once.assert_called_once_with( "0xdef", checksummed, 100 ) + session.commit.assert_called_once()