mirror of
https://github.com/RoboSats/robosats.git
synced 2025-01-18 20:21:35 +00:00
Create Balance model and log task
This commit is contained in:
parent
4ac3618fd7
commit
f538d26355
18
.env-sample
18
.env-sample
@ -93,7 +93,7 @@ FIAT_EXCHANGE_DURATION = 24
|
|||||||
|
|
||||||
# ROUTING
|
# ROUTING
|
||||||
# Proportional routing fee limit (fraction of total payout: % / 100)
|
# Proportional routing fee limit (fraction of total payout: % / 100)
|
||||||
PROPORTIONAL_ROUTING_FEE_LIMIT = 0.0002
|
PROPORTIONAL_ROUTING_FEE_LIMIT = 0.001
|
||||||
# Base flat limit fee for routing in Sats (used only when proportional is lower than this)
|
# Base flat limit fee for routing in Sats (used only when proportional is lower than this)
|
||||||
MIN_FLAT_ROUTING_FEE_LIMIT = 10
|
MIN_FLAT_ROUTING_FEE_LIMIT = 10
|
||||||
MIN_FLAT_ROUTING_FEE_LIMIT_REWARD = 2
|
MIN_FLAT_ROUTING_FEE_LIMIT_REWARD = 2
|
||||||
@ -101,6 +101,22 @@ MIN_FLAT_ROUTING_FEE_LIMIT_REWARD = 2
|
|||||||
REWARDS_TIMEOUT_SECONDS = 60
|
REWARDS_TIMEOUT_SECONDS = 60
|
||||||
PAYOUT_TIMEOUT_SECONDS = 60
|
PAYOUT_TIMEOUT_SECONDS = 60
|
||||||
|
|
||||||
|
# REVERSE SUBMARINE SWAP PAYOUTS
|
||||||
|
# 4 parameters needed, min/max change and min/max balance points. E.g. If 25% or more of liquidity
|
||||||
|
# is onchain the fee for swap is 2% (minimum), if it is 12% fee is 6%, and for 0% fee is 10%.
|
||||||
|
# Minimum swap fee as fraction (2%)
|
||||||
|
MIN_SWAP_FEE = 0.02
|
||||||
|
# Liquidity split point (LN/onchain) at which we use MIN_SWAP_FEE
|
||||||
|
MIN_SWAP_POINT = 0.25
|
||||||
|
# Maximum swap fee as fraction (~10%)
|
||||||
|
MAX_SWAP_FEE = 0.1
|
||||||
|
# Liquidity split point (LN/onchain) at which we use MAX_SWAP_FEE
|
||||||
|
MAX_SWAP_POINT = 0
|
||||||
|
# Shape of fee to available liquidity curve. Only 'linear' implemented.
|
||||||
|
SWAP_FEE_ = 'linear'
|
||||||
|
# Min amount allowed for Swap
|
||||||
|
MIN_SWAP_AMOUNT = 800000
|
||||||
|
|
||||||
# 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
|
||||||
# Fraction rewarded to user from the slashed bond of a counterpart.
|
# Fraction rewarded to user from the slashed bond of a counterpart.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import grpc, os, hashlib, secrets
|
import grpc, os, hashlib, secrets, ring
|
||||||
from . import lightning_pb2 as lnrpc, lightning_pb2_grpc as lightningstub
|
from . import lightning_pb2 as lnrpc, lightning_pb2_grpc as lightningstub
|
||||||
from . import invoices_pb2 as invoicesrpc, invoices_pb2_grpc as invoicesstub
|
from . import invoices_pb2 as invoicesrpc, invoices_pb2_grpc as invoicesstub
|
||||||
from . import router_pb2 as routerrpc, router_pb2_grpc as routerstub
|
from . import router_pb2 as routerrpc, router_pb2_grpc as routerstub
|
||||||
@ -8,7 +8,6 @@ from base64 import b64decode
|
|||||||
|
|
||||||
from datetime import timedelta, datetime
|
from datetime import timedelta, datetime
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from api.models import LNPayment
|
from api.models import LNPayment
|
||||||
|
|
||||||
#######
|
#######
|
||||||
@ -67,6 +66,52 @@ class LNNode:
|
|||||||
MACAROON.hex())])
|
MACAROON.hex())])
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def estimate_fee(cls, amount_sats, target_conf=2, min_confs=1):
|
||||||
|
"""Returns estimated fee for onchain payouts"""
|
||||||
|
|
||||||
|
# We assume segwit. Use robosats donation address (shortcut so there is no need to have user input)
|
||||||
|
request = lnrpc.EstimateFeeRequest(AddrToAmount={'bc1q3cpp7ww92n6zp04hv40kd3eyy5avgughx6xqnx':amount_sats},
|
||||||
|
target_conf=target_conf,
|
||||||
|
min_confs=min_confs,
|
||||||
|
spend_unconfirmed=False)
|
||||||
|
|
||||||
|
response = cls.lightningstub.EstimateFee(request,
|
||||||
|
metadata=[("macaroon",
|
||||||
|
MACAROON.hex())])
|
||||||
|
|
||||||
|
return {'mining_fee_sats': response.fee_sat, 'mining_fee_rate': response.sat_per_vbyte}
|
||||||
|
|
||||||
|
wallet_balance_cache = {}
|
||||||
|
@ring.dict(wallet_balance_cache, expire=10) # keeps in cache for 10 seconds
|
||||||
|
@classmethod
|
||||||
|
def wallet_balance(cls):
|
||||||
|
"""Returns onchain balance"""
|
||||||
|
request = lnrpc.WalletBalanceRequest()
|
||||||
|
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}
|
||||||
|
|
||||||
|
channel_balance_cache = {}
|
||||||
|
@ring.dict(channel_balance_cache, expire=10) # keeps in cache for 10 seconds
|
||||||
|
@classmethod
|
||||||
|
def channel_balance(cls):
|
||||||
|
"""Returns channels balance"""
|
||||||
|
request = lnrpc.ChannelBalanceRequest()
|
||||||
|
response = cls.lightningstub.ChannelBalance(request,
|
||||||
|
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,
|
||||||
|
'unsettled_remote_balance': response.unsettled_remote_balance.sat}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def cancel_return_hold_invoice(cls, payment_hash):
|
def cancel_return_hold_invoice(cls, payment_hash):
|
||||||
"""Cancels or returns a hold invoice"""
|
"""Cancels or returns a hold invoice"""
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from control.models import AccountingDay, AccountingMonth, Dispute
|
from control.models import AccountingDay, AccountingMonth, BalanceLog
|
||||||
from import_export.admin import ImportExportModelAdmin
|
from import_export.admin import ImportExportModelAdmin
|
||||||
|
|
||||||
# Register your models here.
|
# Register your models here.
|
||||||
@ -51,3 +51,34 @@ class AccountingMonthAdmin(ImportExportModelAdmin):
|
|||||||
)
|
)
|
||||||
change_links = ["month"]
|
change_links = ["month"]
|
||||||
search_fields = ["month"]
|
search_fields = ["month"]
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(BalanceLog)
|
||||||
|
class BalanceLogAdmin(ImportExportModelAdmin):
|
||||||
|
|
||||||
|
list_display = (
|
||||||
|
"time",
|
||||||
|
"total",
|
||||||
|
"onchain_fraction",
|
||||||
|
"onchain_total",
|
||||||
|
"onchain_confirmed",
|
||||||
|
"onchain_unconfirmed",
|
||||||
|
"ln_local",
|
||||||
|
"ln_remote",
|
||||||
|
"ln_local_unsettled",
|
||||||
|
"ln_remote_unsettled",
|
||||||
|
)
|
||||||
|
readonly_fields = [
|
||||||
|
"time",
|
||||||
|
"total",
|
||||||
|
"onchain_fraction",
|
||||||
|
"onchain_total",
|
||||||
|
"onchain_confirmed",
|
||||||
|
"onchain_unconfirmed",
|
||||||
|
"ln_local",
|
||||||
|
"ln_remote",
|
||||||
|
"ln_local_unsettled",
|
||||||
|
"ln_remote_unsettled",
|
||||||
|
]
|
||||||
|
change_links = ["time"]
|
||||||
|
search_fields = ["time"]
|
@ -1,6 +1,8 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
|
from api.lightning.node import LNNode
|
||||||
|
|
||||||
class AccountingDay(models.Model):
|
class AccountingDay(models.Model):
|
||||||
day = models.DateTimeField(primary_key=True, auto_now=False, auto_now_add=False)
|
day = models.DateTimeField(primary_key=True, auto_now=False, auto_now_add=False)
|
||||||
|
|
||||||
@ -36,8 +38,6 @@ class AccountingDay(models.Model):
|
|||||||
# Rewards claimed on day
|
# Rewards claimed on day
|
||||||
rewards_claimed = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
|
rewards_claimed = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AccountingMonth(models.Model):
|
class AccountingMonth(models.Model):
|
||||||
month = models.DateTimeField(primary_key=True, auto_now=False, auto_now_add=False)
|
month = models.DateTimeField(primary_key=True, auto_now=False, auto_now_add=False)
|
||||||
|
|
||||||
@ -73,5 +73,19 @@ class AccountingMonth(models.Model):
|
|||||||
# Rewards claimed on day
|
# Rewards claimed on day
|
||||||
rewards_claimed = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
|
rewards_claimed = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=False, blank=False)
|
||||||
|
|
||||||
|
class BalanceLog(models.Model):
|
||||||
|
time = models.DateTimeField(primary_key=True, default=timezone.now)
|
||||||
|
|
||||||
|
# Every field is denominated in Sats
|
||||||
|
total = models.PositiveBigIntegerField(default=lambda : LNNode.wallet_balance()['total_balance'] + LNNode.channel_balance()['local_balance'])
|
||||||
|
onchain_fraction = models.DecimalField(max_digits=5, decimal_places=5, default=lambda : (LNNode.wallet_balance()['total_balance'] + LNNode.channel_balance()['local_balance']) / LNNode.wallet_balance()['total_balance'])
|
||||||
|
onchain_total = models.PositiveBigIntegerField(default=lambda : LNNode.wallet_balance()['total_balance'])
|
||||||
|
onchain_confirmed = models.PositiveBigIntegerField(default=lambda : LNNode.wallet_balance()['confirmed_balance'])
|
||||||
|
onchain_unconfirmed = models.PositiveBigIntegerField(default=lambda : LNNode.wallet_balance()['unconfirmed_balance'])
|
||||||
|
ln_local = models.PositiveBigIntegerField(default=lambda : LNNode.channel_balance()['local_balance'])
|
||||||
|
ln_remote = models.PositiveBigIntegerField(default=lambda : LNNode.channel_balance()['remote_balance'])
|
||||||
|
ln_local_unsettled = models.PositiveBigIntegerField(default=lambda : LNNode.channel_balance()['unsettled_local_balance'])
|
||||||
|
ln_remote_unsettled = models.PositiveBigIntegerField(default=lambda : LNNode.channel_balance()['unsettled_remote_balance'])
|
||||||
|
|
||||||
class Dispute(models.Model):
|
class Dispute(models.Model):
|
||||||
pass
|
pass
|
@ -1,10 +1,4 @@
|
|||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
from api.models import Order, LNPayment, Profile, MarketTick
|
|
||||||
from control.models import AccountingDay, AccountingMonth
|
|
||||||
from django.utils import timezone
|
|
||||||
from datetime import timedelta
|
|
||||||
from django.db.models import Sum
|
|
||||||
from decouple import config
|
|
||||||
|
|
||||||
@shared_task(name="do_accounting")
|
@shared_task(name="do_accounting")
|
||||||
def do_accounting():
|
def do_accounting():
|
||||||
@ -12,6 +6,13 @@ def do_accounting():
|
|||||||
Does all accounting from the beginning of time
|
Does all accounting from the beginning of time
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
from api.models import Order, LNPayment, Profile, MarketTick
|
||||||
|
from control.models import AccountingDay
|
||||||
|
from django.utils import timezone
|
||||||
|
from datetime import timedelta
|
||||||
|
from django.db.models import Sum
|
||||||
|
from decouple import config
|
||||||
|
|
||||||
all_payments = LNPayment.objects.all()
|
all_payments = LNPayment.objects.all()
|
||||||
all_ticks = MarketTick.objects.all()
|
all_ticks = MarketTick.objects.all()
|
||||||
today = timezone.now().date()
|
today = timezone.now().date()
|
||||||
@ -110,3 +111,14 @@ def do_accounting():
|
|||||||
day = day + timedelta(days=1)
|
day = day + timedelta(days=1)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@shared_task(name="compute_node_balance", ignore_result=True)
|
||||||
|
def compute_node_balance():
|
||||||
|
'''
|
||||||
|
Queries LND for channel and wallet balance
|
||||||
|
'''
|
||||||
|
from control.models import BalanceLog
|
||||||
|
|
||||||
|
BalanceLog.objects.create()
|
||||||
|
|
||||||
|
return
|
@ -55,6 +55,10 @@ app.conf.beat_schedule = {
|
|||||||
"task": "cache_external_market_prices",
|
"task": "cache_external_market_prices",
|
||||||
"schedule": timedelta(seconds=60),
|
"schedule": timedelta(seconds=60),
|
||||||
},
|
},
|
||||||
|
"compute-node-balance": { # Logs LND channel and wallet balance
|
||||||
|
"task":"compute_node_balance",
|
||||||
|
"schedule": timedelta(minutes=15),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
app.conf.timezone = "UTC"
|
app.conf.timezone = "UTC"
|
||||||
|
Loading…
Reference in New Issue
Block a user