mirror of
https://github.com/RoboSats/robosats.git
synced 2024-12-13 10:56:24 +00:00
Tight CLTV expiry dynamically
This commit is contained in:
parent
98e2da68d0
commit
8423896285
10
.env-sample
10
.env-sample
@ -77,9 +77,11 @@ MIN_TRADE = 20000
|
|||||||
MAX_TRADE = 3000000
|
MAX_TRADE = 3000000
|
||||||
MAX_TRADE_BONDLESS_TAKER = 50000
|
MAX_TRADE_BONDLESS_TAKER = 50000
|
||||||
|
|
||||||
# Expiration (CLTV_expiry) time for HODL invoices in HOURS // 7 min/block assumed
|
# For CLTV_expiry calculation
|
||||||
BOND_EXPIRY = 54
|
# Assume 8 min/block assumed
|
||||||
ESCROW_EXPIRY = 48
|
BLOCK_TIME = 8
|
||||||
|
# Safety multiplier in case of mining speed up (CLTV expiry will be times X larger than real time needs for locked bonds/escrow)
|
||||||
|
MAX_MINING_NETWORK_SPEEDUP_EXPECTED = 1.7
|
||||||
|
|
||||||
# Expiration time for locking collateral in SECONDS
|
# Expiration time for locking collateral in SECONDS
|
||||||
EXP_MAKER_BOND_INVOICE = 300
|
EXP_MAKER_BOND_INVOICE = 300
|
||||||
@ -123,7 +125,7 @@ MAX_SWAP_FEE = 0.1
|
|||||||
# Liquidity split point (LN/onchain) at which we use MAX_SWAP_FEE
|
# Liquidity split point (LN/onchain) at which we use MAX_SWAP_FEE
|
||||||
MAX_SWAP_POINT = 0
|
MAX_SWAP_POINT = 0
|
||||||
# Min amount allowed for Swap
|
# Min amount allowed for Swap
|
||||||
MIN_SWAP_AMOUNT = 50000
|
MIN_SWAP_AMOUNT = 10000
|
||||||
|
|
||||||
# Reward tip. Reward for every finished trade in the referral program (Satoshis)
|
# Reward tip. Reward for every finished trade in the referral program (Satoshis)
|
||||||
REWARD_TIP = 100
|
REWARD_TIP = 100
|
||||||
|
@ -160,7 +160,7 @@ class LNNode:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def gen_hold_invoice(cls, num_satoshis, description, invoice_expiry,
|
def gen_hold_invoice(cls, num_satoshis, description, invoice_expiry,
|
||||||
cltv_expiry_secs):
|
cltv_expiry_blocks):
|
||||||
"""Generates hold invoice"""
|
"""Generates hold invoice"""
|
||||||
|
|
||||||
hold_payment = {}
|
hold_payment = {}
|
||||||
@ -170,8 +170,6 @@ 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,
|
||||||
|
@ -27,13 +27,12 @@ MAX_TRADE = int(config("MAX_TRADE"))
|
|||||||
EXP_MAKER_BOND_INVOICE = int(config("EXP_MAKER_BOND_INVOICE"))
|
EXP_MAKER_BOND_INVOICE = int(config("EXP_MAKER_BOND_INVOICE"))
|
||||||
EXP_TAKER_BOND_INVOICE = int(config("EXP_TAKER_BOND_INVOICE"))
|
EXP_TAKER_BOND_INVOICE = int(config("EXP_TAKER_BOND_INVOICE"))
|
||||||
|
|
||||||
BOND_EXPIRY = int(config("BOND_EXPIRY"))
|
BLOCK_TIME = float(config("BLOCK_TIME"))
|
||||||
ESCROW_EXPIRY = int(config("ESCROW_EXPIRY"))
|
MAX_MINING_NETWORK_SPEEDUP_EXPECTED = float(config("MAX_MINING_NETWORK_SPEEDUP_EXPECTED"))
|
||||||
|
|
||||||
INVOICE_AND_ESCROW_DURATION = int(config("INVOICE_AND_ESCROW_DURATION"))
|
INVOICE_AND_ESCROW_DURATION = int(config("INVOICE_AND_ESCROW_DURATION"))
|
||||||
FIAT_EXCHANGE_DURATION = int(config("FIAT_EXCHANGE_DURATION"))
|
FIAT_EXCHANGE_DURATION = int(config("FIAT_EXCHANGE_DURATION"))
|
||||||
|
|
||||||
|
|
||||||
class Logics:
|
class Logics:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -987,6 +986,31 @@ class Logics:
|
|||||||
# send_message.delay(order.id,'order_published') # too spammy
|
# send_message.delay(order.id,'order_published') # too spammy
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def compute_cltv_expiry_blocks(order, invoice_concept):
|
||||||
|
''' Computes timelock CLTV expiry of the last hop in blocks for hodl invoices
|
||||||
|
|
||||||
|
invoice_concepts (str): maker_bond, taker_bond, trade_escrow
|
||||||
|
'''
|
||||||
|
# Every invoice_concept must be locked by at least the fiat exchange duration
|
||||||
|
cltv_expiry_secs = order.t_to_expire(Order.Status.CHA)
|
||||||
|
|
||||||
|
# Both fidelity bonds must also be locked for deposit_time (escrow duration or WFE status)
|
||||||
|
if invoice_concept in ["taker_bond", "maker_bond"]:
|
||||||
|
cltv_expiry_secs += order.t_to_expire(Order.Status.WFE)
|
||||||
|
|
||||||
|
# Maker bond must also be locked for the full public duration plus the taker bond locking time
|
||||||
|
if invoice_concept == "maker_bond":
|
||||||
|
cltv_expiry_secs += order.t_to_expire(Order.Status.PUB)
|
||||||
|
cltv_expiry_secs += order.t_to_expire(Order.Status.TAK)
|
||||||
|
|
||||||
|
# Add a safety marging by multiplying by the maxium expected mining network speed up
|
||||||
|
safe_cltv_expiry_secs = cltv_expiry_secs * MAX_MINING_NETWORK_SPEEDUP_EXPECTED
|
||||||
|
# Convert to blocks using assummed average block time (~8 mins/block)
|
||||||
|
cltv_expiry_blocks = int(safe_cltv_expiry_secs / (BLOCK_TIME * 60))
|
||||||
|
print(invoice_concept," cltv_expiry_hours:",cltv_expiry_secs/3600," cltv_expiry_blocks:",cltv_expiry_blocks)
|
||||||
|
|
||||||
|
return cltv_expiry_blocks
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_maker_bond_locked(cls, order):
|
def is_maker_bond_locked(cls, order):
|
||||||
if order.maker_bond.status == LNPayment.Status.LOCKED:
|
if order.maker_bond.status == LNPayment.Status.LOCKED:
|
||||||
@ -1031,7 +1055,7 @@ class Logics:
|
|||||||
bond_satoshis,
|
bond_satoshis,
|
||||||
description,
|
description,
|
||||||
invoice_expiry=order.t_to_expire(Order.Status.WFB),
|
invoice_expiry=order.t_to_expire(Order.Status.WFB),
|
||||||
cltv_expiry_secs=BOND_EXPIRY * 3600,
|
cltv_expiry_blocks=cls.compute_cltv_expiry_blocks(order, "maker_bond")
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(str(e))
|
print(str(e))
|
||||||
@ -1040,7 +1064,7 @@ class Logics:
|
|||||||
"bad_request":
|
"bad_request":
|
||||||
"The Lightning Network Daemon (LND) is down. Write in the Telegram group to make sure the staff is aware."
|
"The Lightning Network Daemon (LND) is down. Write in the Telegram group to make sure the staff is aware."
|
||||||
}
|
}
|
||||||
if "wallet locked" in str(e):
|
elif "wallet locked" in str(e):
|
||||||
return False, {
|
return False, {
|
||||||
"bad_request":
|
"bad_request":
|
||||||
"This is weird, RoboSats' lightning wallet is locked. Check in the Telegram group, maybe the staff has died."
|
"This is weird, RoboSats' lightning wallet is locked. Check in the Telegram group, maybe the staff has died."
|
||||||
@ -1147,7 +1171,7 @@ class Logics:
|
|||||||
bond_satoshis,
|
bond_satoshis,
|
||||||
description,
|
description,
|
||||||
invoice_expiry=order.t_to_expire(Order.Status.TAK),
|
invoice_expiry=order.t_to_expire(Order.Status.TAK),
|
||||||
cltv_expiry_secs=BOND_EXPIRY * 3600,
|
cltv_expiry_blocks=cls.compute_cltv_expiry_blocks(order, "taker_bond")
|
||||||
)
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -1235,7 +1259,7 @@ class Logics:
|
|||||||
escrow_satoshis,
|
escrow_satoshis,
|
||||||
description,
|
description,
|
||||||
invoice_expiry=order.t_to_expire(Order.Status.WF2),
|
invoice_expiry=order.t_to_expire(Order.Status.WF2),
|
||||||
cltv_expiry_secs=ESCROW_EXPIRY * 3600,
|
cltv_expiry_blocks=cls.compute_cltv_expiry_blocks(order, "trade_escrow")
|
||||||
)
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -1610,6 +1634,7 @@ class Logics:
|
|||||||
summary['mining_fee_sats'] = order.payout_tx.mining_fee_sats
|
summary['mining_fee_sats'] = order.payout_tx.mining_fee_sats
|
||||||
summary['swap_fee_sats'] = round(order.payout_tx.num_satoshis - order.payout_tx.mining_fee_sats - order.payout_tx.sent_satoshis)
|
summary['swap_fee_sats'] = round(order.payout_tx.num_satoshis - order.payout_tx.mining_fee_sats - order.payout_tx.sent_satoshis)
|
||||||
summary['swap_fee_percent'] = order.payout_tx.swap_fee_rate
|
summary['swap_fee_percent'] = order.payout_tx.swap_fee_rate
|
||||||
|
summary['trade_fee_sats'] = round(order.last_satoshis - summary['received_sats'] - summary['mining_fee_sats'] - summary['swap_fee_sats'])
|
||||||
else:
|
else:
|
||||||
summary['sent_sats'] = order.trade_escrow.num_satoshis
|
summary['sent_sats'] = order.trade_escrow.num_satoshis
|
||||||
summary['received_fiat'] = order.amount
|
summary['received_fiat'] = order.amount
|
||||||
|
Loading…
Reference in New Issue
Block a user