1
0

wallet: (regression) fix get_spendable_coins when "domain" arg is given

`get_spendable_coins` was ignoring the "domain" param, and returning utxos for the whole wallet
This commit is contained in:
SomberNight
2022-07-11 16:18:38 +02:00
parent 9ae0e5bffc
commit 2c73e7f854
2 changed files with 55 additions and 8 deletions

View File

@@ -2412,6 +2412,41 @@ class TestWalletSending(TestCaseForTestnet):
self.assertEqual('02000000000101ce010c0cab95cde544f713771916613a1a84c8787bbc95321854410b212aed9b0100000000fdffffff02cac00000000000001600147a65e09bb1da80abfc65d545388a2e61aab7c721eec100000000000016001405424089c64d39d9a498b6e1c8e646327431b240024730440220526eac6c56cba19842b67f6c9e45af113b1a2d44fb229335bdeaf08cb2cc164e0220087fba65619016fd3f62f6c8717070e48f94b45743b86d8e0517698d2b9c3afc012102d67eaa10463f5c786271feb9ae3456c27d35c3cf6c7d881617e915d1f32cb875c4951e00', self.assertEqual('02000000000101ce010c0cab95cde544f713771916613a1a84c8787bbc95321854410b212aed9b0100000000fdffffff02cac00000000000001600147a65e09bb1da80abfc65d545388a2e61aab7c721eec100000000000016001405424089c64d39d9a498b6e1c8e646327431b240024730440220526eac6c56cba19842b67f6c9e45af113b1a2d44fb229335bdeaf08cb2cc164e0220087fba65619016fd3f62f6c8717070e48f94b45743b86d8e0517698d2b9c3afc012102d67eaa10463f5c786271feb9ae3456c27d35c3cf6c7d881617e915d1f32cb875c4951e00',
str(tx_copy)) str(tx_copy))
@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
def test_get_spendable_coins(self, mock_save_db):
wallet = self.create_standard_wallet_from_seed('frost repair depend effort salon ring foam oak cancel receive save usage',
config=self.config)
# bootstrap wallet (incoming funding_tx1)
funding_tx1 = Transaction('01000000000102acd6459dec7c3c51048eb112630da756f5d4cb4752b8d39aa325407ae0885cba020000001716001455c7f5e0631d8e6f5f05dddb9f676cec48845532fdffffffd146691ef6a207b682b13da5f2388b1f0d2a2022c8cfb8dc27b65434ec9ec8f701000000171600147b3be8a7ceaf15f57d7df2a3d216bc3c259e3225fdffffff02a9875b000000000017a914ea5a99f83e71d1c1dfc5d0370e9755567fe4a141878096980000000000160014d4ca56fcbad98fb4dcafdc573a75d6a6fffb09b702483045022100dde1ba0c9a2862a65791b8d91295a6603207fb79635935a67890506c214dd96d022046c6616642ef5971103c1db07ac014e63fa3b0e15c5729eacdd3e77fcb7d2086012103a72410f185401bb5b10aaa30989c272b554dc6d53bda6da85a76f662723421af024730440220033d0be8f74e782fbcec2b396647c7715d2356076b442423f23552b617062312022063c95cafdc6d52ccf55c8ee0f9ceb0f57afb41ea9076eb74fe633f59c50c6377012103b96a4954d834fbcfb2bbf8cf7de7dc2b28bc3d661c1557d1fd1db1bfc123a94abb391400')
funding_txid1 = funding_tx1.txid()
self.assertEqual('52e669a20a26c8b3df5b41e5e6309b18bcde8e1ad7ea17a18f63b6dc6c8becc0', funding_txid1)
wallet.adb.receive_tx_callback(funding_txid1, funding_tx1, TX_HEIGHT_UNCONFIRMED)
# another incoming transaction (funding_tx2)
funding_tx2 = Transaction('01000000000101c0ec8b6cdcb6638fa117ead71a8edebc189b30e6e5415bdfb3c8260aa269e6520000000017160014ba9ca815474a674ff1efb3fc82cf0f3460de8c57fdffffff0230390f000000000017a9148b59abaca8215c0d4b18cbbf715550aa2b50c85b87404b4c000000000016001483c3bc7234f17a209cc5dcce14903b54ee4dab9002473044022038a05f7d38bcf810dfebb39f1feda5cc187da4cf5d6e56986957ddcccedc75d302203ab67ccf15431b4e2aeeab1582b9a5a7821e7ac4be8ebf512505dbfdc7e094fd0121032168234e0ba465b8cedc10173ea9391725c0f6d9fa517641af87926626a5144abd391400')
funding_txid2 = funding_tx2.txid()
self.assertEqual('c36a6e1cd54df108e69574f70bc9b88dc13beddc70cfad9feb7f8f6593255d4a', funding_txid2)
wallet.adb.receive_tx_callback(funding_txid2, funding_tx2, TX_HEIGHT_UNCONFIRMED)
self.assertEqual((0, 15_000_000, 0), wallet.get_balance())
self.assertEqual(
{'c36a6e1cd54df108e69574f70bc9b88dc13beddc70cfad9feb7f8f6593255d4a:1',
'52e669a20a26c8b3df5b41e5e6309b18bcde8e1ad7ea17a18f63b6dc6c8becc0:1'},
{txi.prevout.to_str() for txi in wallet.get_spendable_coins()})
self.assertEqual(
{'52e669a20a26c8b3df5b41e5e6309b18bcde8e1ad7ea17a18f63b6dc6c8becc0:1'},
{txi.prevout.to_str() for txi in wallet.get_spendable_coins(["tb1q6n99dl96mx8mfh90m3tn5awk5mllkzdh25dw7z"])})
# test freezing an address
wallet.set_frozen_state_of_addresses(["tb1q6n99dl96mx8mfh90m3tn5awk5mllkzdh25dw7z"], freeze=True)
self.assertEqual(
{'c36a6e1cd54df108e69574f70bc9b88dc13beddc70cfad9feb7f8f6593255d4a:1'},
{txi.prevout.to_str() for txi in wallet.get_spendable_coins()})
wallet.set_frozen_state_of_addresses(["tb1q6n99dl96mx8mfh90m3tn5awk5mllkzdh25dw7z"], freeze=False)
self.assertEqual(
{'c36a6e1cd54df108e69574f70bc9b88dc13beddc70cfad9feb7f8f6593255d4a:1',
'52e669a20a26c8b3df5b41e5e6309b18bcde8e1ad7ea17a18f63b6dc6c8becc0:1'},
{txi.prevout.to_str() for txi in wallet.get_spendable_coins()})
class TestWalletOfflineSigning(TestCaseForTestnet): class TestWalletOfflineSigning(TestCaseForTestnet):

View File

@@ -40,7 +40,7 @@ from functools import partial
from collections import defaultdict from collections import defaultdict
from numbers import Number from numbers import Number
from decimal import Decimal from decimal import Decimal
from typing import TYPE_CHECKING, List, Optional, Tuple, Union, NamedTuple, Sequence, Dict, Any, Set from typing import TYPE_CHECKING, List, Optional, Tuple, Union, NamedTuple, Sequence, Dict, Any, Set, Iterable
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
import itertools import itertools
import threading import threading
@@ -830,19 +830,31 @@ class Abstract_Wallet(ABC, Logger, EventListener):
def get_addr_balance(self, address): def get_addr_balance(self, address):
return self.adb.get_balance([address]) return self.adb.get_balance([address])
def get_utxos(self, **kwargs): def get_utxos(
domain = self.get_addresses() self,
domain: Optional[Iterable[str]] = None,
**kwargs,
):
if domain is None:
domain = self.get_addresses()
return self.adb.get_utxos(domain=domain, **kwargs) return self.adb.get_utxos(domain=domain, **kwargs)
def get_spendable_coins(self, domain, *, nonlocal_only=False) -> Sequence[PartialTxInput]: def get_spendable_coins(
self,
domain: Optional[Iterable[str]] = None,
*,
nonlocal_only: bool = False,
) -> Sequence[PartialTxInput]:
confirmed_only = self.config.get('confirmed_only', False) confirmed_only = self.config.get('confirmed_only', False)
with self._freeze_lock: with self._freeze_lock:
frozen_addresses = self._frozen_addresses.copy() frozen_addresses = self._frozen_addresses.copy()
utxos = self.get_utxos( utxos = self.get_utxos(
excluded_addresses=frozen_addresses, domain=domain,
mature_only=True, excluded_addresses=frozen_addresses,
confirmed_funding_only=confirmed_only, mature_only=True,
nonlocal_only=nonlocal_only) confirmed_funding_only=confirmed_only,
nonlocal_only=nonlocal_only,
)
utxos = [utxo for utxo in utxos if not self.is_frozen_coin(utxo)] utxos = [utxo for utxo in utxos if not self.is_frozen_coin(utxo)]
return utxos return utxos