Fix invoice payouts. Add onchain summary to accounting days.

This commit is contained in:
Reckless_Satoshi 2022-06-16 15:45:36 -07:00
parent 5c87c5ad85
commit 43b85d79d4
No known key found for this signature in database
GPG Key ID: 9C4585B561315571
9 changed files with 32 additions and 79 deletions

View File

@ -93,7 +93,7 @@ class LNNode:
response = cls.lightningstub.WalletBalance(request,
metadata=[("macaroon",
MACAROON.hex())])
print(response)
return {'total_balance': response.total_balance,
'confirmed_balance': response.confirmed_balance,
'unconfirmed_balance': response.unconfirmed_balance}
@ -108,7 +108,7 @@ class LNNode:
metadata=[("macaroon",
MACAROON.hex())])
print(response)
return {'local_balance': response.local_balance.sat,
'remote_balance': response.remote_balance.sat,
'unsettled_local_balance': response.unsettled_local_balance.sat,
@ -208,22 +208,17 @@ class LNNode:
metadata=[("macaroon",
MACAROON.hex())
])
print("status here")
print(response.state)
# TODO ERROR HANDLING
# Will fail if 'unable to locate invoice'. Happens if invoice expiry
# time has passed (but these are 15% padded at the moment). Should catch it
# and report back that the invoice has expired (better robustness)
if response.state == 0: # OPEN
print("STATUS: OPEN")
pass
if response.state == 1: # SETTLED
pass
if response.state == 2: # CANCELLED
pass
if response.state == 3: # ACCEPTED (LOCKED)
print("STATUS: ACCEPTED")
lnpayment.expiry_height = response.htlcs[0].expiry_height
lnpayment.status = LNPayment.Status.LOCKED
lnpayment.save()
@ -254,7 +249,6 @@ class LNNode:
try:
payreq_decoded = cls.decode_payreq(invoice)
print(payreq_decoded)
except:
payout["context"] = {
"bad_invoice": "Does not look like a valid lightning invoice"

View File

@ -725,7 +725,7 @@ class Logics:
concept=LNPayment.Concepts.PAYBUYER,
type=LNPayment.Types.NORM,
sender=User.objects.get(username=ESCROW_USERNAME),
order_paid=
order_paid_LN=
order, # In case this user has other payouts, update the one related to this order.
receiver=user,
# if there is a LNPayment matching these above, it updates that one with defaults below.

View File

@ -87,7 +87,7 @@ def follow_send_payment(hash):
timeout_seconds=timeout_seconds,
)
order = lnpayment.order_paid
order = lnpayment.order_paid_LN
try:
for response in LNNode.routerstub.SendPaymentV2(request,
metadata=[

View File

@ -1,5 +1,5 @@
from django.contrib import admin
from control.models import AccountingDay, AccountingMonth, BalanceLog
from control.models import AccountingDay, BalanceLog
from import_export.admin import ImportExportModelAdmin
# Register your models here.
@ -17,6 +17,7 @@ class AccountingDayAdmin(ImportExportModelAdmin):
"inflow",
"outflow",
"routing_fees",
"mining_fees",
"cashflow",
"outstanding_earned_rewards",
"outstanding_pending_disputes",
@ -28,31 +29,6 @@ class AccountingDayAdmin(ImportExportModelAdmin):
change_links = ["day"]
search_fields = ["day"]
@admin.register(AccountingMonth)
class AccountingMonthAdmin(ImportExportModelAdmin):
list_display = (
"month",
"contracted",
"num_contracts",
"net_settled",
"net_paid",
"net_balance",
"inflow",
"outflow",
"routing_fees",
"cashflow",
"outstanding_earned_rewards",
"outstanding_pending_disputes",
"lifetime_rewards_claimed",
"outstanding_earned_rewards",
"pending_disputes",
"rewards_claimed",
)
change_links = ["month"]
search_fields = ["month"]
@admin.register(BalanceLog)
class BalanceLogAdmin(ImportExportModelAdmin):

View File

@ -23,6 +23,8 @@ class AccountingDay(models.Model):
outflow = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
# Total cost in routing fees
routing_fees = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
# Total cost in minig fees
mining_fees = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
# Total inflows minus outflows and routing fees
cashflow = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
# Balance on earned rewards (referral rewards, slashed bonds and solved disputes)
@ -38,41 +40,6 @@ class AccountingDay(models.Model):
# Rewards claimed on day
rewards_claimed = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
class AccountingMonth(models.Model):
month = models.DateTimeField(primary_key=True, auto_now=False, auto_now_add=False)
# Every field is denominated in Sats with (3 decimals for millisats)
# Total volume contracted
contracted = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
# Number of contracts
num_contracts = models.BigIntegerField(default=0, null=False, blank=False)
# Net volume of trading invoices settled (excludes disputes)
net_settled = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
# Net volume of trading invoices paid (excludes rewards and disputes)
net_paid = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
# Sum of net settled and net paid
net_balance = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
# Total volume of invoices settled
inflow = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
# Total volume of invoices paid
outflow = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
# Total cost in routing fees
routing_fees = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
# Total inflows minus outflows and routing fees
cashflow = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
# Balance on earned rewards (referral rewards, slashed bonds and solved disputes)
outstanding_earned_rewards = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
# Balance on pending disputes (not resolved yet)
outstanding_pending_disputes = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
# Rewards claimed lifetime
lifetime_rewards_claimed = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
# Balance change from last day on earned rewards (referral rewards, slashed bonds and solved disputes)
earned_rewards = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
# Balance change on pending disputes (not resolved yet)
pending_disputes = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
# Rewards claimed on day
rewards_claimed = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
class BalanceLog(models.Model):
def get_total():

View File

@ -6,7 +6,7 @@ def do_accounting():
Does all accounting from the beginning of time
'''
from api.models import Order, LNPayment, Profile, MarketTick
from api.models import Order, LNPayment, OnchainPayment, Profile, MarketTick
from control.models import AccountingDay
from django.utils import timezone
from datetime import timedelta
@ -36,14 +36,16 @@ def do_accounting():
result = {}
while day <= today:
day_payments = all_payments.filter(created_at__gte=day,created_at__lte=day+timedelta(days=1))
day_onchain_payments = OnchainPayment.objects.filter(created_at__gte=day,created_at__lte=day+timedelta(days=1))
day_ticks = all_ticks.filter(timestamp__gte=day,timestamp__lte=day+timedelta(days=1))
# Coarse accounting based on LNpayment objects
# Coarse accounting based on LNpayment and OnchainPayment objects
contracted = day_ticks.aggregate(Sum('volume'))['volume__sum']
num_contracts = day_ticks.count()
inflow = day_payments.filter(type=LNPayment.Types.HOLD,status=LNPayment.Status.SETLED).aggregate(Sum('num_satoshis'))['num_satoshis__sum']
outflow = day_payments.filter(type=LNPayment.Types.NORM,status=LNPayment.Status.SUCCED).aggregate(Sum('num_satoshis'))['num_satoshis__sum']
outflow = day_payments.filter(type=LNPayment.Types.NORM,status=LNPayment.Status.SUCCED).aggregate(Sum('num_satoshis'))['num_satoshis__sum'] + day_onchain_payments.filter(status__in=[OnchainPayment.Status.MEMPO,OnchainPayment.Status.CONFI]).aggregate(Sum('sent_satoshis'))['sent_satoshis__sum']
routing_fees = day_payments.filter(type=LNPayment.Types.NORM,status=LNPayment.Status.SUCCED).aggregate(Sum('fee'))['fee__sum']
mining_fees = day_onchain_payments.filter(status__in=[OnchainPayment.Status.MEMPO,OnchainPayment.Status.CONFI]).aggregate(Sum('mining_fee_sats'))['mining_fee_sats__sum']
rewards_claimed = day_payments.filter(type=LNPayment.Types.NORM,concept=LNPayment.Concepts.WITHREWA,status=LNPayment.Status.SUCCED).aggregate(Sum('num_satoshis'))['num_satoshis__sum']
contracted = 0 if contracted == None else contracted
@ -59,6 +61,7 @@ def do_accounting():
inflow = inflow,
outflow = outflow,
routing_fees = routing_fees,
mining_fees = mining_fees,
cashflow = inflow - outflow - routing_fees,
rewards_claimed = rewards_claimed,
)
@ -70,10 +73,21 @@ def do_accounting():
payouts_paid = 0
routing_cost = 0
for payout in payouts:
escrows_settled += payout.order_paid.trade_escrow.num_satoshis
escrows_settled += payout.order_paid_LN.trade_escrow.num_satoshis
payouts_paid += payout.num_satoshis
routing_cost += payout.fee
# Same for orders that use onchain payments.
payouts_tx = day_onchain_payments.filter(status__in=[OnchainPayment.Status.MEMPO,OnchainPayment.Status.CONFI])
escrows_settled = 0
payouts_tx_paid = 0
mining_cost = 0
for payout_tx in payouts_tx:
escrows_settled += payout_tx.order_paid_TX.trade_escrow.num_satoshis
payouts_tx_paid += payout_tx.sent_satoshis
mining_cost += payout_tx.fee
# account for those orders where bonds were lost
# + Settled bonds / bond_split
bonds_settled = day_payments.filter(type=LNPayment.Types.HOLD,concept__in=[LNPayment.Concepts.TAKEBOND,LNPayment.Concepts.MAKEBOND], status=LNPayment.Status.SETLED)
@ -117,8 +131,8 @@ def compute_node_balance():
'''
Queries LND for channel and wallet balance
'''
from control.models import BalanceLog
from control.models import BalanceLog
BalanceLog.objects.create()
return

View File

@ -936,7 +936,7 @@ class TradeBox extends Component {
<Grid container spacing={1}>
<Grid item xs={12} align="center">
<Typography variant="subtitle1">
<b>{t("Your invoice looks good!")}</b> {" " + this.stepXofY()}
<b>{t("Your info looks good!")}</b> {" " + this.stepXofY()}
</Typography>
</Grid>
<Grid item xs={12} align="center">

View File

@ -181,6 +181,7 @@
"You do not have previous orders":"You do not have previous orders",
"Join RoboSats' Subreddit":"Join RoboSats' Subreddit",
"RoboSats in Reddit":"RoboSats in Reddit",
"Current onchain payout fee":"Current onchain payout fee",
"ORDER PAGE - OrderPage.js": "Order details page",
"Order Box":"Order Box",
@ -316,7 +317,7 @@
"Submit an invoice for {{amountSats}} Sats":"Submit an invoice for {{amountSats}} Sats",
"The taker is committed! Before letting you send {{amountFiat}} {{currencyCode}}, we want to make sure you are able to receive the BTC. Please provide a valid invoice for {{amountSats}} Satoshis.":"The taker is committed! Before letting you send {{amountFiat}} {{currencyCode}}, we want to make sure you are able to receive the BTC. Please provide a valid invoice for {{amountSats}} Satoshis.",
"Payout Lightning Invoice":"Payout Lightning Invoice",
"Your invoice looks good!":"Your invoice looks good!",
"Your info looks good!":"Your info looks good!",
"We are waiting for the seller to lock the trade amount.":"We are waiting for the seller to lock the trade amount.",
"Just hang on for a moment. If the seller does not deposit, you will get your bond back automatically. In addition, you will receive a compensation (check the rewards in your profile).":"Just hang on for a moment. If the seller does not deposit, you will get your bond back automatically. In addition, you will receive a compensation (check the rewards in your profile).",
"The trade collateral is locked!":"The trade collateral is locked!",

View File

@ -181,6 +181,7 @@
"You do not have previous orders":"No tienes órdenes previas",
"Join RoboSats' Subreddit":"Únete al subreddit de RoboSats",
"RoboSats in Reddit":"RoboSats en Reddit",
"Current onchain payout fee":"Coste por envio onchain actual",
"ORDER PAGE - OrderPage.js": "Order details page",
"Order Box": "Orden",