From bb6efeda03747bb3fc1e459938bc6c3a4d17b313 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Sun, 9 Oct 2022 22:35:54 +0200 Subject: [PATCH 1/4] coinselect --- cashu/wallet/wallet.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/cashu/wallet/wallet.py b/cashu/wallet/wallet.py index b00c982a..b7ec8bb3 100644 --- a/cashu/wallet/wallet.py +++ b/cashu/wallet/wallet.py @@ -388,24 +388,31 @@ async def serialize_proofs(proofs: List[Proof], hide_secrets=False): ).decode() return token - async def _get_spendable_proofs(self, proofs: List[Proof]): + async def _select_proofs_to_send(self, proofs: List[Proof], amount_to_send: int): """ Selects proofs that can be used with the current mint. Chooses: 1) Proofs that are not marked as reserved 2) Proofs that have a keyset id that is in self.keysets (active keysets of mint) - !!! optional for backwards compatibility with legacy clients """ + # select proofs that are in the active keysets of the mint proofs = [ p for p in proofs if p.id in self.keysets or not p.id ] # "or not p.id" is for backwards compatibility with proofs without a keyset id + # select proofs that are not reserved proofs = [p for p in proofs if not p.reserved] - return proofs + # select proofs based on amount to send + sorted_proofs = sorted(proofs, key=lambda p: p.amount) + send_proofs = [] + while sum_proofs(send_proofs) < amount_to_send: + send_proofs.append(sorted_proofs[len(send_proofs)]) + return send_proofs async def split_to_send(self, proofs: List[Proof], amount, scnd_secret: str = None): """Like self.split but only considers non-reserved tokens.""" if scnd_secret: logger.debug(f"Spending conditions: {scnd_secret}") - spendable_proofs = await self._get_spendable_proofs(proofs) + spendable_proofs = await self._select_proofs_to_send(proofs, amount) if sum_proofs(spendable_proofs) < amount: raise Exception("balance too low.") return await self.split( From 5d1a539b02757cf74ab61120496cc9c4fce54aa3 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Wed, 11 Jan 2023 03:36:49 +0100 Subject: [PATCH 2/4] mypy --- cashu/wallet/wallet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cashu/wallet/wallet.py b/cashu/wallet/wallet.py index b265d27b..731164f8 100644 --- a/cashu/wallet/wallet.py +++ b/cashu/wallet/wallet.py @@ -563,7 +563,7 @@ async def _select_proofs_to_send(self, proofs: List[Proof], amount_to_send: int) proofs = [p for p in proofs if not p.reserved] # select proofs based on amount to send sorted_proofs = sorted(proofs, key=lambda p: p.amount) - send_proofs = [] + send_proofs: List[Proof] = [] while sum_proofs(send_proofs) < amount_to_send: send_proofs.append(sorted_proofs[len(send_proofs)]) return send_proofs From db034a0e00b4df05fe4841ed4189cc822c7ef870 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Wed, 11 Jan 2023 03:41:11 +0100 Subject: [PATCH 3/4] fix tests --- cashu/wallet/wallet.py | 7 +++++-- tests/test_wallet.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/cashu/wallet/wallet.py b/cashu/wallet/wallet.py index 731164f8..b9a45f1a 100644 --- a/cashu/wallet/wallet.py +++ b/cashu/wallet/wallet.py @@ -561,6 +561,10 @@ async def _select_proofs_to_send(self, proofs: List[Proof], amount_to_send: int) ] # "or not p.id" is for backwards compatibility with proofs without a keyset id # select proofs that are not reserved proofs = [p for p in proofs if not p.reserved] + + if sum_proofs(proofs) < amount_to_send: + raise Exception("balance too low.") + # select proofs based on amount to send sorted_proofs = sorted(proofs, key=lambda p: p.amount) send_proofs: List[Proof] = [] @@ -598,8 +602,7 @@ async def split_to_send( if scnd_secret: logger.debug(f"Spending conditions: {scnd_secret}") spendable_proofs = await self._select_proofs_to_send(proofs, amount) - if sum_proofs(spendable_proofs) < amount: - raise Exception("balance too low.") + keep_proofs, send_proofs = await self.split( [p for p in spendable_proofs if not p.reserved], amount, scnd_secret ) diff --git a/tests/test_wallet.py b/tests/test_wallet.py index 493503f0..19177922 100644 --- a/tests/test_wallet.py +++ b/tests/test_wallet.py @@ -101,7 +101,7 @@ async def test_split_to_send(wallet1: Wallet): keep_proofs, spendable_proofs = await wallet1.split_to_send( wallet1.proofs, 32, set_reserved=True ) - get_spendable = await wallet1._get_spendable_proofs(wallet1.proofs) + get_spendable = await wallet1._select_proofs_to_send(wallet1.proofs, 32) assert keep_proofs == get_spendable assert sum_proofs(spendable_proofs) == 32 From e24ed990a190a5273a00b13ddfba38f58706357c Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Wed, 11 Jan 2023 03:43:53 +0100 Subject: [PATCH 4/4] comments --- cashu/wallet/wallet.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cashu/wallet/wallet.py b/cashu/wallet/wallet.py index b9a45f1a..cc313316 100644 --- a/cashu/wallet/wallet.py +++ b/cashu/wallet/wallet.py @@ -561,11 +561,11 @@ async def _select_proofs_to_send(self, proofs: List[Proof], amount_to_send: int) ] # "or not p.id" is for backwards compatibility with proofs without a keyset id # select proofs that are not reserved proofs = [p for p in proofs if not p.reserved] - + # check that enough spendable proofs exist if sum_proofs(proofs) < amount_to_send: raise Exception("balance too low.") - # select proofs based on amount to send + # coinselect based on amount to send sorted_proofs = sorted(proofs, key=lambda p: p.amount) send_proofs: List[Proof] = [] while sum_proofs(send_proofs) < amount_to_send: