From 8f888d2aca4fc34051c617832ffb4af8f25cbe4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sa=C5=82aban?= Date: Mon, 7 Oct 2019 23:36:31 +0200 Subject: [PATCH] Optimize retrieval of master address --- monero/account.py | 2 +- monero/backends/jsonrpc.py | 9 ++- monero/backends/offline.py | 4 +- monero/exceptions.py | 6 ++ monero/wallet.py | 2 +- .../test_address-00-get_accounts.json | 18 ++++++ .../test_address-10-getaddress.json | 15 +++++ tests/test_jsonrpcwallet.py | 56 +++++-------------- 8 files changed, 65 insertions(+), 47 deletions(-) create mode 100644 tests/data/test_jsonrpcwallet/test_address-00-get_accounts.json create mode 100644 tests/data/test_jsonrpcwallet/test_address-10-getaddress.json diff --git a/monero/account.py b/monero/account.py index 607072d..10ced7c 100644 --- a/monero/account.py +++ b/monero/account.py @@ -49,7 +49,7 @@ class Account(object): :rtype: :class:`SubAddress ` """ - return self._backend.addresses(account=self.index)[0] + return self._backend.addresses(account=self.index, addr_indices=[0])[0] def addresses(self): """ diff --git a/monero/backends/jsonrpc.py b/monero/backends/jsonrpc.py index 9f4a6ae..f415b0e 100644 --- a/monero/backends/jsonrpc.py +++ b/monero/backends/jsonrpc.py @@ -162,8 +162,11 @@ class JSONRPCWallet(object): # doesn't return that detail here return Account(self, _account['account_index'], label=label), SubAddress(_account['address']) - def addresses(self, account=0): - _addresses = self.raw_request('getaddress', {'account_index': account}) + def addresses(self, account=0, addr_indices=None): + qdata = {'account_index': account} + if addr_indices: + qdata['address_index'] = addr_indices + _addresses = self.raw_request('getaddress', qdata) addresses = [None] * (max(map(operator.itemgetter('address_index'), _addresses['addresses'])) + 1) for _addr in _addresses['addresses']: addresses[_addr['address_index']] = address( @@ -412,6 +415,8 @@ _err2exc = { -5: exceptions.WrongPaymentId, -8: exceptions.TransactionNotFound, -9: exceptions.SignatureCheckFailed, + -14: exceptions.AccountIndexOutOfBound, + -15: exceptions.AddressIndexOutOfBound, -16: exceptions.TransactionNotPossible, -17: exceptions.NotEnoughMoney, -20: exceptions.AmountIsZero, diff --git a/monero/backends/offline.py b/monero/backends/offline.py index 06319d3..bf6aed4 100644 --- a/monero/backends/offline.py +++ b/monero/backends/offline.py @@ -40,8 +40,8 @@ class OfflineWallet(object): def new_account(self, label=None): raise WalletIsOffline() - def addresses(self, account=0): - if account == 0: + def addresses(self, account=0, addr_indices=None): + if account == 0 and (addr_indices == [0] or addr_indices is None): return [self._address] raise WalletIsOffline() # pragma: no cover (this should never happen) diff --git a/monero/exceptions.py b/monero/exceptions.py index 2b1bc4e..67a6da2 100644 --- a/monero/exceptions.py +++ b/monero/exceptions.py @@ -44,3 +44,9 @@ class WalletIsNotDeterministic(MoneroException): class GenericTransferError(AccountException): pass + +class AccountIndexOutOfBound(AccountException): + pass + +class AddressIndexOutOfBound(AccountException): + pass diff --git a/monero/wallet.py b/monero/wallet.py index d910769..0feb571 100644 --- a/monero/wallet.py +++ b/monero/wallet.py @@ -176,7 +176,7 @@ class Wallet(object): :rtype: :class:`Address ` """ - return self.accounts[0].addresses()[0] + return self.accounts[0].address() def addresses(self): """ diff --git a/tests/data/test_jsonrpcwallet/test_address-00-get_accounts.json b/tests/data/test_jsonrpcwallet/test_address-00-get_accounts.json new file mode 100644 index 0000000..9b33858 --- /dev/null +++ b/tests/data/test_jsonrpcwallet/test_address-00-get_accounts.json @@ -0,0 +1,18 @@ +{ + "id": 0, + "jsonrpc": "2.0", + "result": { + "subaddress_accounts": [ + { + "account_index": 0, + "balance": 21676544656446, + "base_address": "596ETuuDVZSNox73YLctrHaAv72fBboxy3atbEMnP3QtdnGFS9KWuHYGuy831SKWLUVCgrRfWLCxuCZ2fbVGh14X7mFrefy", + "label": "Primary account", + "tag": "", + "unlocked_balance": 21479383257259 + } + ], + "total_balance": 21676544656446, + "total_unlocked_balance": 21479383257259 + } +} diff --git a/tests/data/test_jsonrpcwallet/test_address-10-getaddress.json b/tests/data/test_jsonrpcwallet/test_address-10-getaddress.json new file mode 100644 index 0000000..60e3b11 --- /dev/null +++ b/tests/data/test_jsonrpcwallet/test_address-10-getaddress.json @@ -0,0 +1,15 @@ +{ + "id": 0, + "jsonrpc": "2.0", + "result": { + "address": "596ETuuDVZSNox73YLctrHaAv72fBboxy3atbEMnP3QtdnGFS9KWuHYGuy831SKWLUVCgrRfWLCxuCZ2fbVGh14X7mFrefy", + "addresses": [ + { + "address": "596ETuuDVZSNox73YLctrHaAv72fBboxy3atbEMnP3QtdnGFS9KWuHYGuy831SKWLUVCgrRfWLCxuCZ2fbVGh14X7mFrefy", + "address_index": 0, + "label": "Primary account", + "used": true + } + ] + } +} diff --git a/tests/test_jsonrpcwallet.py b/tests/test_jsonrpcwallet.py index 147aecd..87039fa 100644 --- a/tests/test_jsonrpcwallet.py +++ b/tests/test_jsonrpcwallet.py @@ -90,54 +90,28 @@ class JSONRPCWalletTestCase(JSONTestCase): self.assertIsInstance(balances[1], Decimal) self.assertEqual(locked, Decimal('224.916129245183')) - @patch('monero.backends.jsonrpc.requests.post') - def test_address(self, mock_post): - mock_post.return_value.status_code = 200 - mock_post.return_value.json.return_value = self.accounts_result + @responses.activate + def test_address(self): + responses.add(responses.POST, self.jsonrpc_url, + json=self._read('test_address-00-get_accounts.json'), + status=200) + responses.add(responses.POST, self.jsonrpc_url, + json=self._read('test_address-10-getaddress.json'), + status=200) + responses.add(responses.POST, self.jsonrpc_url, + json=self._read('test_address-10-getaddress.json'), + status=200) self.wallet = Wallet(JSONRPCWallet()) - mock_post.return_value.json.return_value = {'id': 0, - 'jsonrpc': '2.0', - 'result': {'address': '9vgV48wWAPTWik5QSUSoGYicdvvsbSNHrT9Arsx1XBTz6VrWPSgfmnUKSPZDMyX4Ms8R9TkhB4uFqK9s5LUBbV6YQN2Q9ag', - 'addresses': [{'address': '9vgV48wWAPTWik5QSUSoGYicdvvsbSNHrT9Arsx1XBTz6VrWPSgfmnUKSPZDMyX4Ms8R9TkhB4uFqK9s5LUBbV6YQN2Q9ag', - 'address_index': 0, - 'label': 'Primary account', - 'used': True}, - {'address': 'BbBjyYoYNNwFfL8RRVRTMiZUofBLpjRxdNnd5E4LyGcAK5CEsnL3gmE5QkrDRta7RPficGHcFdR6rUwWcjnwZVvCE3tLxhJ', - 'address_index': 1, - 'label': '', - 'used': True}, - {'address': 'BgzZVoJP6Vx5WP87r7NRCCRcFwiUha8uTgnjGGitHYTJEmRuz6Jq2oE9icDCGYMHXZcnR8T35Z8NoVXkfMnF9ikJNfcwwsy', - 'address_index': 2, - 'label': '(Untitled address)', - 'used': False}, - {'address': 'Bck7sYz1vvUghNNTR6rrpxfRDegswezggB9mWQkXgjwxKRTo1feiJopStdJAHtMJoSEdsYppWvQ6vbGbArWxP32xCG2TsVZ', - 'address_index': 3, - 'label': '(Untitled address)', - 'used': True}, - {'address': 'BYCcWM1gZHdCnh3Cb1KfWrAU1SjBWMV3KhUoeRy7V2Lw2F2hHeuzouP2NECBaTUgnyYAzEe8s5vpA7qmWYfjVfxeHoHWPnb', - 'address_index': 4, - 'label': '(Untitled address)', - 'used': False}, - {'address': 'BfJ5W7dZGaYih6J63YvhiDSKpVUUZbVrEhLRCY6L6TdnEfzJmwP6aUJZQQnzLQ2NMTKMAC8hiJsoiNC7jbEUZ8tmBoJcnN1', - 'address_index': 5, - 'label': '(Untitled address)', - 'used': True}, - {'address': 'BaJwiPYwnN6DV8yBeh4FjjCqRoPfdkWppSzVXTPBJo35fDyU8caxLchATGJg7TKB24Q8nM8P1iWSt4DMwec8Pg7bSbFDAir', - 'address_index': 6, - 'label': '(Untitled address)', - 'used': False}, - {'address': 'BbkS4mn6gcgUidn2znLa2J6eSBkbGjGX4doeDCKAzT2A3t1cjbquQGjhYgiMHiKTrY8ojk6Zjqi1ufvfuPwyKv4hNnMruro', - 'address_index': 7, - 'label': '(Untitled address)', - 'used': True}]}} waddr = self.wallet.address() a0addr = self.wallet.accounts[0].address() + self.assertEqual(len(responses.calls), 3) self.assertEqual(waddr, a0addr) + self.assertIsInstance(waddr, Address) self.assertEqual( waddr, - '9vgV48wWAPTWik5QSUSoGYicdvvsbSNHrT9Arsx1XBTz6VrWPSgfmnUKSPZDMyX4Ms8R9TkhB4uFqK9s5LUBbV6YQN2Q9ag') + '596ETuuDVZSNox73YLctrHaAv72fBboxy3atbEMnP3QtdnGFS9KWuHYGuy831SKWLUVCgrRfWLCxuCZ2fbVGh14X7mFrefy') + self.assertEqual(waddr.label, 'Primary account') self.assertEqual(a0addr.label, 'Primary account') - self.assertEqual(len(self.wallet.accounts[0].addresses()), 8) @responses.activate def test_account_creation(self):