mirror of
https://github.com/RoboSats/robosats.git
synced 2024-12-27 14:22:58 +03:00
Implement CLTV_expiries for each hold invoice duration. Invoice expiry matches status time to lock it.
This commit is contained in:
parent
4d0c62734c
commit
51d65fd15e
@ -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
|
||||||
|
|
||||||
|
@ -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 = {}
|
||||||
@ -73,12 +73,16 @@ 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
|
||||||
|
@ -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,
|
||||||
|
@ -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))
|
||||||
|
@ -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))
|
@ -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>
|
||||||
@ -98,7 +98,7 @@ export default class InfoDialog extends Component {
|
|||||||
forever. This is true for both, locked bonds and trading escrows. However,
|
forever. This is true for both, locked bonds and trading escrows. However,
|
||||||
there is a small window between the seller confirms FIAT RECEIVED and the moment
|
there is a small window between the seller confirms FIAT RECEIVED and the moment
|
||||||
the buyer receives the satoshis when the funds could be permanentely lost if
|
the buyer receives the satoshis when the funds could be permanentely lost if
|
||||||
<i>RoboSats</i> disappears. This window is about 1 second long. Make sure to have enough
|
<i> RoboSats</i> disappears. This window is about 1 second long. Make sure to have enough
|
||||||
inbound liquidity to avoid routing failures. If you have any problem, reach out
|
inbound liquidity to avoid routing failures. If you have any problem, reach out
|
||||||
trough the <i>RoboSats</i> public channels.
|
trough the <i>RoboSats</i> public channels.
|
||||||
</p>
|
</p>
|
||||||
|
@ -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'
|
||||||
@ -87,7 +87,7 @@ export default class OrderPage extends Component {
|
|||||||
delay: this.setDelay(newStateVars.status),
|
delay: this.setDelay(newStateVars.status),
|
||||||
currencyCode: this.getCurrencyCode(newStateVars.currency),
|
currencyCode: this.getCurrencyCode(newStateVars.currency),
|
||||||
};
|
};
|
||||||
|
|
||||||
var completeStateVars = Object.assign({}, newStateVars, otherStateVars);
|
var completeStateVars = Object.assign({}, newStateVars, otherStateVars);
|
||||||
this.setState(completeStateVars);
|
this.setState(completeStateVars);
|
||||||
}
|
}
|
||||||
|
@ -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">
|
||||||
@ -665,7 +665,7 @@ handleRatingChange=(e)=>{
|
|||||||
showRoutingFailed(){
|
showRoutingFailed(){
|
||||||
|
|
||||||
// TODO If it has failed 3 times, ask for a new invoice.
|
// TODO If it has failed 3 times, ask for a new invoice.
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<Grid container spacing={1}>
|
<Grid container spacing={1}>
|
||||||
<Grid item xs={12} align="center">
|
<Grid item xs={12} align="center">
|
||||||
|
Loading…
Reference in New Issue
Block a user