Implement CLTV_expiries for each hold invoice duration. Invoice expiry matches status time to lock it.

This commit is contained in:
Reckless_Satoshi 2022-01-24 09:54:44 -08:00
parent 4d0c62734c
commit 51d65fd15e
No known key found for this signature in database
GPG Key ID: 9C4585B561315571
9 changed files with 33 additions and 20 deletions

View File

@ -28,7 +28,7 @@ RETRY_TIME = 5
MIN_TRADE = 10000 MIN_TRADE = 10000
MAX_TRADE = 500000 MAX_TRADE = 500000
# Expiration time for HODL invoices and returning collateral in HOURS # Expiration (CLTV_expiry) time for HODL invoices in HOURS // 7 min/block assumed
BOND_EXPIRY = 14 BOND_EXPIRY = 14
ESCROW_EXPIRY = 8 ESCROW_EXPIRY = 8

View File

@ -64,7 +64,7 @@ class LNNode():
return str(response)=="" # True if no response, false otherwise. return str(response)=="" # True if no response, false otherwise.
@classmethod @classmethod
def gen_hold_invoice(cls, num_satoshis, description, expiry): def gen_hold_invoice(cls, num_satoshis, description, invoice_expiry, cltv_expiry_secs):
'''Generates hold invoice''' '''Generates hold invoice'''
hold_payment = {} hold_payment = {}
@ -74,11 +74,15 @@ class LNNode():
# Its hash is used to generate the hold invoice # Its hash is used to generate the hold invoice
r_hash = hashlib.sha256(preimage).digest() r_hash = hashlib.sha256(preimage).digest()
# timelock expiry for the last hop, computed based on a 10 minutes block with 30% padding (~7 min block)
cltv_expiry_blocks = int(cltv_expiry_secs / (7*60))
request = invoicesrpc.AddHoldInvoiceRequest( request = invoicesrpc.AddHoldInvoiceRequest(
memo=description, memo=description,
value=num_satoshis, value=num_satoshis,
hash=r_hash, hash=r_hash,
expiry=expiry) expiry=invoice_expiry,
cltv_expiry=cltv_expiry_blocks,
)
response = cls.invoicesstub.AddHoldInvoice(request, metadata=[('macaroon', MACAROON.hex())]) response = cls.invoicesstub.AddHoldInvoice(request, metadata=[('macaroon', MACAROON.hex())])
hold_payment['invoice'] = response.payment_request hold_payment['invoice'] = response.payment_request

View File

@ -500,7 +500,10 @@ class Logics():
description = f"RoboSats - Publishing '{str(order)}' - This is a maker bond, it will freeze in your wallet temporarily and automatically return. It will be charged if you cheat or cancel." description = f"RoboSats - Publishing '{str(order)}' - This is a maker bond, it will freeze in your wallet temporarily and automatically return. It will be charged if you cheat or cancel."
# Gen hold Invoice # Gen hold Invoice
hold_payment = LNNode.gen_hold_invoice(bond_satoshis, description, BOND_EXPIRY*3600) hold_payment = LNNode.gen_hold_invoice(bond_satoshis,
description,
invoice_expiry=Order.t_to_expire[Order.Status.WFB],
cltv_expiry_secs=BOND_EXPIRY*3600)
order.maker_bond = LNPayment.objects.create( order.maker_bond = LNPayment.objects.create(
concept = LNPayment.Concepts.MAKEBOND, concept = LNPayment.Concepts.MAKEBOND,
@ -577,7 +580,10 @@ class Logics():
+ " - This is a taker bond, it will freeze in your wallet temporarily and automatically return. It will be charged if you cheat or cancel.") + " - This is a taker bond, it will freeze in your wallet temporarily and automatically return. It will be charged if you cheat or cancel.")
# Gen hold Invoice # Gen hold Invoice
hold_payment = LNNode.gen_hold_invoice(bond_satoshis, description, BOND_EXPIRY*3600) hold_payment = LNNode.gen_hold_invoice(bond_satoshis,
description,
invoice_expiry=Order.t_to_expire[Order.Status.TAK],
cltv_expiry_secs=BOND_EXPIRY*3600)
order.taker_bond = LNPayment.objects.create( order.taker_bond = LNPayment.objects.create(
concept = LNPayment.Concepts.TAKEBOND, concept = LNPayment.Concepts.TAKEBOND,
@ -640,7 +646,10 @@ class Logics():
description = f"RoboSats - Escrow amount for '{str(order)}' - The escrow will be released to the buyer once you confirm you received the fiat. It will automatically return if buyer does not confirm the payment." description = f"RoboSats - Escrow amount for '{str(order)}' - The escrow will be released to the buyer once you confirm you received the fiat. It will automatically return if buyer does not confirm the payment."
# Gen hold Invoice # Gen hold Invoice
hold_payment = LNNode.gen_hold_invoice(escrow_satoshis, description, ESCROW_EXPIRY*3600) hold_payment = LNNode.gen_hold_invoice(escrow_satoshis,
description,
invoice_expiry=Order.t_to_expire[Order.Status.WF2],
cltv_expiry_secs=ESCROW_EXPIRY*3600)
order.trade_escrow = LNPayment.objects.create( order.trade_escrow = LNPayment.objects.create(
concept = LNPayment.Concepts.TRESCROW, concept = LNPayment.Concepts.TRESCROW,

View File

@ -62,4 +62,4 @@ class Command(BaseCommand):
if 'database is locked' in str(e): if 'database is locked' in str(e):
self.stdout.write('database is locked') self.stdout.write('database is locked')
self.stdout.write(e) self.stdout.write(str(e))

View File

@ -62,8 +62,8 @@ class Command(BaseCommand):
hold_lnpayment.status = lnd_state_to_lnpayment_status[response.state] hold_lnpayment.status = lnd_state_to_lnpayment_status[response.state]
except Exception as e: except Exception as e:
# If it fails at finding the invoice it has been canceled. # If it fails at finding the invoice: it has been canceled.
# On RoboSats DB we make a distinction between cancelled and returned (LND does not) # In RoboSats DB we make a distinction between cancelled and returned (LND does not)
if 'unable to locate invoice' in str(e): if 'unable to locate invoice' in str(e):
self.stdout.write(str(e)) self.stdout.write(str(e))
hold_lnpayment.status = LNPayment.Status.CANCEL hold_lnpayment.status = LNPayment.Status.CANCEL
@ -140,4 +140,4 @@ class Command(BaseCommand):
if 'database is locked' in str(e): if 'database is locked' in str(e):
self.stdout.write('database is locked') self.stdout.write('database is locked')
self.stdout.write(e) self.stdout.write(str(e))

View File

@ -79,10 +79,10 @@ export default class InfoDialog extends Component {
In addition, disputes are solved by the <i>RoboSats</i> staff. In addition, disputes are solved by the <i>RoboSats</i> staff.
</p> </p>
<p> Trust requirements are minimal, however there is still one way <i>RoboSats</i> <p> To be totally clear. Trust requirements are minimized. However, there is still
could run away with your satoshis: by not releasing one way <i>RoboSats </i> could run away with your satoshis: by not releasing
the satoshis to the buyer. It could be argued that such move is not on <i>RoboSats</i> the satoshis to the buyer. It could be argued that such move is not in <i>RoboSats' </i>
interest as it would damage the reputation for a small payout. as it would damage the reputation for a small payout.
However, you should hesitate and only trade small quantities at a However, you should hesitate and only trade small quantities at a
time. For large amounts use an onchain escrow service such as <i>Bisq</i> time. For large amounts use an onchain escrow service such as <i>Bisq</i>
</p> </p>

View File

@ -52,7 +52,7 @@ export default class OrderPage extends Component {
// Refresh delays according to Order status // Refresh delays according to Order status
this.statusToDelay = { this.statusToDelay = {
"0": 2000, //'Waiting for maker bond' "0": 2000, //'Waiting for maker bond'
"1": 15000, //'Public' "1": 45000, //'Public'
"2": 9999999, //'Deleted' "2": 9999999, //'Deleted'
"3": 2000, //'Waiting for taker bond' "3": 2000, //'Waiting for taker bond'
"4": 9999999, //'Cancelled' "4": 9999999, //'Cancelled'

View File

@ -147,7 +147,7 @@ export default class TradeBox extends Component {
<Grid container spacing={1}> <Grid container spacing={1}>
<Grid item xs={12} align="center"> <Grid item xs={12} align="center">
<Typography component="body2" variant="body2"> <Typography component="body2" variant="body2">
Robosats show commitment to their peers Robots show commitment to their peers
</Typography> </Typography>
</Grid> </Grid>
<Grid item xs={12} align="center"> <Grid item xs={12} align="center">