mirror of
https://github.com/aljazceru/nutshell.git
synced 2025-12-20 18:44:20 +01:00
Mint: verify outputs first during mint (#379)
* verify outputs first during mint * verify outputs during melt as well
This commit is contained in:
@@ -302,6 +302,8 @@ class Ledger(LedgerVerification, LedgerSpendingConditions, LedgerLightning):
|
|||||||
logger.trace("called mint")
|
logger.trace("called mint")
|
||||||
amount_outputs = sum([b.amount for b in B_s])
|
amount_outputs = sum([b.amount for b in B_s])
|
||||||
|
|
||||||
|
await self._verify_outputs(B_s)
|
||||||
|
|
||||||
if settings.lightning:
|
if settings.lightning:
|
||||||
if not id:
|
if not id:
|
||||||
raise NotAllowedError("no id provided.")
|
raise NotAllowedError("no id provided.")
|
||||||
@@ -317,8 +319,6 @@ class Ledger(LedgerVerification, LedgerSpendingConditions, LedgerLightning):
|
|||||||
await self.crud.update_lightning_invoice(id=id, issued=True, db=self.db)
|
await self.crud.update_lightning_invoice(id=id, issued=True, db=self.db)
|
||||||
del self.locks[id]
|
del self.locks[id]
|
||||||
|
|
||||||
await self._verify_outputs(B_s)
|
|
||||||
|
|
||||||
promises = await self._generate_promises(B_s, keyset)
|
promises = await self._generate_promises(B_s, keyset)
|
||||||
logger.trace("generated promises")
|
logger.trace("generated promises")
|
||||||
return promises
|
return promises
|
||||||
@@ -368,6 +368,12 @@ class Ledger(LedgerVerification, LedgerSpendingConditions, LedgerLightning):
|
|||||||
f" {total_provided}, needed: {invoice_amount + reserve_fees_sat}"
|
f" {total_provided}, needed: {invoice_amount + reserve_fees_sat}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if outputs:
|
||||||
|
# verify the outputs. note: we don't verify inputs
|
||||||
|
# and outputs simultaneously with verify_inputs_and_outputs() as we do
|
||||||
|
# in split() because we do not expect the amounts to be equal here.
|
||||||
|
await self._verify_outputs(outputs)
|
||||||
|
|
||||||
# verify spending inputs and their spending conditions
|
# verify spending inputs and their spending conditions
|
||||||
await self.verify_inputs_and_outputs(proofs)
|
await self.verify_inputs_and_outputs(proofs)
|
||||||
|
|
||||||
|
|||||||
@@ -37,19 +37,19 @@ async def test_melt(wallet1: Wallet, ledger: Ledger):
|
|||||||
invoice = await wallet1.request_mint(64)
|
invoice = await wallet1.request_mint(64)
|
||||||
pay_if_regtest(invoice.bolt11)
|
pay_if_regtest(invoice.bolt11)
|
||||||
await wallet1.mint(64, id=invoice.id)
|
await wallet1.mint(64, id=invoice.id)
|
||||||
invoice = await wallet1.request_mint(64)
|
invoice2 = await wallet1.request_mint(64)
|
||||||
pay_if_regtest(invoice.bolt11)
|
pay_if_regtest(invoice2.bolt11)
|
||||||
await wallet1.mint(64, id=invoice.id)
|
await wallet1.mint(64, id=invoice2.id)
|
||||||
assert wallet1.balance == 128
|
assert wallet1.balance == 128
|
||||||
total_amount, fee_reserve_sat = await wallet1.get_pay_amount_with_fees(
|
total_amount, fee_reserve_sat = await wallet1.get_pay_amount_with_fees(
|
||||||
invoice.bolt11
|
invoice2.bolt11
|
||||||
)
|
)
|
||||||
mint_fees = await ledger.get_melt_fees(invoice.bolt11)
|
melt_fees = await ledger.get_melt_fees(invoice2.bolt11)
|
||||||
assert mint_fees == fee_reserve_sat
|
assert melt_fees == fee_reserve_sat
|
||||||
|
|
||||||
keep_proofs, send_proofs = await wallet1.split_to_send(wallet1.proofs, total_amount)
|
keep_proofs, send_proofs = await wallet1.split_to_send(wallet1.proofs, total_amount)
|
||||||
|
|
||||||
await ledger.melt(send_proofs, invoice.bolt11, outputs=None)
|
await ledger.melt(send_proofs, invoice2.bolt11, outputs=None)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@@ -176,6 +176,31 @@ async def test_mint_with_same_outputs_twice(wallet1: Wallet, ledger: Ledger):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_melt_with_same_outputs_twice(wallet1: Wallet, ledger: Ledger):
|
||||||
|
invoice = await wallet1.request_mint(130)
|
||||||
|
pay_if_regtest(invoice.bolt11)
|
||||||
|
await wallet1.mint(130, id=invoice.id)
|
||||||
|
|
||||||
|
output_amounts = [128]
|
||||||
|
secrets, rs, derivation_paths = await wallet1.generate_n_secrets(
|
||||||
|
len(output_amounts)
|
||||||
|
)
|
||||||
|
outputs, rs = wallet1._construct_outputs(output_amounts, secrets, rs)
|
||||||
|
|
||||||
|
# we use the outputs once for minting
|
||||||
|
invoice2 = await wallet1.request_mint(128)
|
||||||
|
pay_if_regtest(invoice2.bolt11)
|
||||||
|
await ledger.mint(outputs, id=invoice2.id)
|
||||||
|
|
||||||
|
# use the same outputs for melting
|
||||||
|
invoice3 = await wallet1.request_mint(128)
|
||||||
|
await assert_err(
|
||||||
|
ledger.melt(wallet1.proofs, invoice3.bolt11, outputs=outputs),
|
||||||
|
"outputs have already been signed before.",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_check_proof_state(wallet1: Wallet, ledger: Ledger):
|
async def test_check_proof_state(wallet1: Wallet, ledger: Ledger):
|
||||||
invoice = await wallet1.request_mint(64)
|
invoice = await wallet1.request_mint(64)
|
||||||
|
|||||||
Reference in New Issue
Block a user