mirror of
https://github.com/Labelbase/Labelbase.git
synced 2026-08-13 12:33:23 +02:00
.
This commit is contained in:
parent
37b2a1b988
commit
b0b88a156a
10 changed files with 69 additions and 204 deletions
|
|
@ -38,7 +38,6 @@ def bg_runner(proxy_task, task=None, loop=None, *args, **kwargs):
|
|||
task = task_qs[0]
|
||||
if func is None:
|
||||
raise BackgroundTaskError("Function is None, can't execute!")
|
||||
print("bg_runner, loop {}".format(loop))
|
||||
kwargs['loop'] = loop
|
||||
func(*args, **kwargs)
|
||||
|
||||
|
|
@ -96,8 +95,6 @@ class Tasks(object):
|
|||
return _decorator
|
||||
|
||||
def run_task(self, task_name, loop, args=None, kwargs=None):
|
||||
print("run_task loop {}".format(loop))
|
||||
# task_name can be either the name of a task or a Task instance.
|
||||
if isinstance(task_name, Task):
|
||||
task = task_name
|
||||
task_name = task.task_name
|
||||
|
|
|
|||
|
|
@ -9,11 +9,10 @@ from finances.models import OutputStat, HistoricalPrice
|
|||
import logging
|
||||
logger = logging.getLogger('labelbase')
|
||||
|
||||
|
||||
async def interact(conn, server_info, method, utxo):
|
||||
try:
|
||||
await conn.connect(server_info, "s", use_tor=server_info.is_onion,
|
||||
disable_cert_verify=True, short_term=True)
|
||||
disable_cert_verify=True, short_term=True)
|
||||
txid, index = utxo.split(":")
|
||||
try:
|
||||
txn = await conn.RPC(method, txid, True)
|
||||
|
|
@ -43,10 +42,8 @@ async def interact_addr(conn, server_info, method, addr):
|
|||
hextx = await conn.RPC(method, addr)
|
||||
if hextx is not None:
|
||||
return hextx
|
||||
else:
|
||||
print("Failed to fetch transaction.")
|
||||
except ElectrumErrorResponse as ex:
|
||||
print(ex)
|
||||
logger.error(ex)
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
|
@ -58,167 +55,92 @@ def is_valid_output_ref(ref):
|
|||
return False
|
||||
|
||||
|
||||
def checkup_label(label_id, loop):
|
||||
def checkup_label(label_id, loop):
|
||||
if label_id and loop:
|
||||
try:
|
||||
elem = Label.objects.get(id=label_id)
|
||||
output = OutputStat.objects.filter(user=elem.labelbase.user,
|
||||
type_ref_hash=elem.type_ref_hash,
|
||||
network=elem.labelbase.network).last()
|
||||
if not output:
|
||||
output = OutputStat(user=elem.labelbase.user,
|
||||
type_ref_hash=elem.type_ref_hash,
|
||||
network=elem.labelbase.network, value=0)
|
||||
output = OutputStat.objects.filter(
|
||||
user=elem.labelbase.user,
|
||||
type_ref_hash=elem.type_ref_hash,
|
||||
network=elem.labelbase.network
|
||||
).last()
|
||||
|
||||
if elem.type == "output" and is_valid_output_ref(elem.ref) and \
|
||||
(output.spent is not True or output.confirmed_at_block_time == 0):
|
||||
if not output:
|
||||
output = OutputStat(
|
||||
user=elem.labelbase.user,
|
||||
type_ref_hash=elem.type_ref_hash,
|
||||
network=elem.labelbase.network,
|
||||
value=0,
|
||||
spent=None,
|
||||
confirmed_at_block_height=0,
|
||||
confirmed_at_block_time=0
|
||||
)
|
||||
logger.debug(f"Output before processing: {output.output_metrics_dict()}")
|
||||
|
||||
if elem.type == "output" and is_valid_output_ref(elem.ref) and (
|
||||
output.spent is not True or output.confirmed_at_block_time == 0
|
||||
):
|
||||
# Determine server info based on network
|
||||
if elem.labelbase.is_mainnet:
|
||||
electrum_hostname = elem.labelbase.user.profile.electrum_hostname or "electrum.emzy.de"
|
||||
electrum_hostname = elem.labelbase.user.profile.electrum_hostname or "fulcrum.sethforprivacy.com"
|
||||
electrum_ports = elem.labelbase.user.profile.electrum_ports or "s50002"
|
||||
elif elem.labelbase.is_testnet:
|
||||
electrum_hostname = elem.labelbase.user.profile.electrum_hostname_test or "testnet.qtornado.com"
|
||||
electrum_ports = elem.labelbase.user.profile.electrum_ports_test or "s51002"
|
||||
server_info = ServerInfo(electrum_hostname, electrum_hostname, ports=(electrum_ports))
|
||||
else:
|
||||
raise ValueError("Unknown network type.")
|
||||
|
||||
server_info = ServerInfo(electrum_hostname, electrum_hostname, ports=(electrum_ports))
|
||||
conn = StratumClient()
|
||||
utxo = elem.ref
|
||||
utxo_data = {}
|
||||
|
||||
# Fetch transaction details
|
||||
utxo_resp = loop.run_until_complete(interact(conn, server_info, "blockchain.transaction.get", utxo))
|
||||
|
||||
if utxo_resp:
|
||||
txid, index, address, value, blocktime, utxo_data = utxo_resp
|
||||
if utxo_data:
|
||||
#output.next_input_attributes = utxo_data
|
||||
output.set_next_input_attributes(utxo_data)
|
||||
logger.debug(f"Transaction {txid} fetched with blocktime {blocktime}")
|
||||
if blocktime:
|
||||
HistoricalPrice.get_or_create_from_api(None, timestamp=blocktime)
|
||||
output.confirmed_at_block_time = blocktime
|
||||
output.confirmed_at_block_height = txn.get('height', 0)
|
||||
|
||||
# Fetch all unspents for the address
|
||||
try:
|
||||
unspents = loop.run_until_complete(interact_addr(conn, server_info, "blockchain.address.listunspent", address))
|
||||
except:
|
||||
conn.last_error = None # reset error if needed
|
||||
conn.last_error = None
|
||||
unspents = loop.run_until_complete(interact_addr(conn, server_info, "blockchain.scripthash.listunspent", address))
|
||||
|
||||
utxo_value = 0
|
||||
utxo_height = 0
|
||||
logger.debug(f"Unspents for address {address}: {unspents}")
|
||||
|
||||
if unspents:
|
||||
for unspent in unspents:
|
||||
if unspent.get('tx_hash') == txid and \
|
||||
unspent.get('tx_pos') == int(index) and \
|
||||
unspent.get('height') > 0 and \
|
||||
unspent.get('value') > 0: # Output is confirmed, but not spent yet
|
||||
output.spent = False
|
||||
utxo_value = unspent.get('value')
|
||||
utxo_height = unspent.get('height')
|
||||
utxo_found = False
|
||||
for unspent in unspents:
|
||||
if unspent.get('tx_hash') == txid and unspent.get('tx_pos') == int(index):
|
||||
output.spent = False
|
||||
output.value = unspent.get('value', 0)
|
||||
output.confirmed_at_block_height = unspent.get('height', 0)
|
||||
utxo_found = True
|
||||
break
|
||||
|
||||
if not utxo_found:
|
||||
output.spent = True
|
||||
logger.warning(f"UTXO {txid}:{index} not found in unspent outputs.")
|
||||
else:
|
||||
logger.error(f"Failed to fetch transaction details for {utxo}")
|
||||
|
||||
output.network = elem.labelbase.network
|
||||
if utxo_height:
|
||||
output.confirmed_at_block_height = utxo_height
|
||||
if blocktime:
|
||||
output.confirmed_at_block_time = blocktime
|
||||
if utxo_value:
|
||||
output.value = utxo_value
|
||||
elif value:
|
||||
output.value = value
|
||||
break
|
||||
#
|
||||
elif conn.last_error:
|
||||
output.last_error = conn.last_error
|
||||
else:
|
||||
output.last_error = {}
|
||||
logger.warning(f"Unknown error occurred for UTXO {utxo}")
|
||||
output.last_error = {"error": "Unknown issue"}
|
||||
|
||||
logger.debug(f"Output after processing (before save): {output.output_metrics_dict()}")
|
||||
output.save()
|
||||
try:
|
||||
conn.close()
|
||||
except:
|
||||
pass
|
||||
output.refresh_from_db()
|
||||
logger.debug(f"Output after saving: {output.output_metrics_dict()}")
|
||||
conn.close()
|
||||
|
||||
except Exception as e:
|
||||
logger.error("Error processing label {}: {}".format(label_id, e))
|
||||
logger.error(f"Error processing label {label_id}: {e}")
|
||||
else:
|
||||
if not label_id:
|
||||
logger.error("Can't get label_id! {}".format(label_id))
|
||||
if not loop:
|
||||
logger.error("Can't get loop!")
|
||||
|
||||
|
||||
def checkup_label_buggy(label_id, loop):
|
||||
if label_id and loop:
|
||||
elem = Label.objects.get(id=label_id)
|
||||
output = OutputStat.objects.filter(user=elem.labelbase.user,
|
||||
type_ref_hash=elem.type_ref_hash,
|
||||
network=elem.labelbase.network).last()
|
||||
if not output:
|
||||
output = OutputStat(user=elem.labelbase.user,
|
||||
type_ref_hash=elem.type_ref_hash,
|
||||
network=elem.labelbase.network, value=0)
|
||||
#print("Using OutputStat id {}".format(output))
|
||||
#print("elem.type {} {} {} {}".format(elem.type, is_valid_output_ref(elem.ref), elem.ref, output.spent))
|
||||
if elem.type == "output" and is_valid_output_ref(elem.ref) and \
|
||||
(output.spent is not True or output.confirmed_at_block_time == 0):
|
||||
electrum_hostname = elem.labelbase.user.profile.electrum_hostname
|
||||
if not electrum_hostname:
|
||||
electrum_hostname = "electrum.emzy.de"
|
||||
electrum_ports = elem.labelbase.user.profile.electrum_ports
|
||||
if not electrum_ports:
|
||||
electrum_ports = "s50002"
|
||||
server_info = ServerInfo(electrum_hostname, electrum_hostname, ports=((electrum_ports)))
|
||||
conn = StratumClient()
|
||||
assert elem.type_ref_hash
|
||||
utxo = elem.ref
|
||||
tx_hash, tx_pos = elem.ref.split(":")
|
||||
utxo_resp = loop.run_until_complete(interact(conn, server_info, "blockchain.transaction.get", utxo))
|
||||
blocktime = 0
|
||||
if utxo_resp:
|
||||
txid, index, address, value, blocktime = utxo_resp
|
||||
if blocktime:
|
||||
#print("Found blocktime {} for label id {}.".format(blocktime, label_id))
|
||||
HistoricalPrice.get_or_create_from_api(None, timestamp=blocktime)
|
||||
try:
|
||||
unspents = loop.run_until_complete(interact_addr(conn, server_info, "blockchain.address.listunspent", address))
|
||||
except:
|
||||
conn.last_error = None # reset error if needed
|
||||
unspents = loop.run_until_complete(interact_addr(conn, server_info, "blockchain.scripthash.listunspent", address))
|
||||
unspent_utxo = False
|
||||
utxo_value = 0
|
||||
utxo_height = 0
|
||||
if unspents:
|
||||
for unspent in unspents:
|
||||
if unspent.get('tx_hash') == tx_hash and \
|
||||
unspent.get('tx_pos') == int(tx_pos) and \
|
||||
unspent.get('height') > 0 and \
|
||||
unspent.get('value') > 0:
|
||||
unspent_utxo = True
|
||||
utxo_value = unspent.get('value')
|
||||
utxo_height = unspent.get('height')
|
||||
break
|
||||
if output:
|
||||
output.network = elem.labelbase.network
|
||||
if utxo_height:
|
||||
output.confirmed_at_block_height = utxo_height
|
||||
if blocktime:
|
||||
output.confirmed_at_block_time = blocktime
|
||||
if utxo_value:
|
||||
output.value = utxo_value
|
||||
elif value: # take value from TX
|
||||
output.value = value
|
||||
if unspent_utxo:
|
||||
output.spent = False
|
||||
else:
|
||||
output.spent = True
|
||||
output.last_error = {}
|
||||
elif conn.last_error:
|
||||
# Damn...
|
||||
output.last_error = conn.last_error
|
||||
else:
|
||||
output.last_error = {}
|
||||
output.save()
|
||||
try:
|
||||
conn.close()
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
if not label_id:
|
||||
logger.error("Can't get label_id! {}".format(label_id))
|
||||
if not loop:
|
||||
logger.error("Can't get loop!")
|
||||
logger.error(f"Invalid input: label_id={label_id}, loop={loop}")
|
||||
|
|
|
|||
|
|
@ -11,9 +11,6 @@ from jsonfield import JSONField
|
|||
import json
|
||||
from django.contrib.auth.models import User
|
||||
from shared.encryption import get_fernet_key, cipher_suite
|
||||
|
||||
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger('labelbase')
|
||||
|
||||
|
|
@ -54,9 +51,11 @@ class OutputStat(models.Model):
|
|||
self.next_enc_input_attrs = encrypted_data.decode('utf-8')
|
||||
|
||||
def next_input_attributes(self):
|
||||
encrypted_data = self.next_enc_input_attrs.encode('utf-8')
|
||||
decrypted_data = cipher_suite.decrypt(encrypted_data)
|
||||
return json.loads(decrypted_data.decode('utf-8'))
|
||||
if self.next_enc_input_attrs:
|
||||
encrypted_data = self.next_enc_input_attrs.encode('utf-8')
|
||||
decrypted_data = cipher_suite.decrypt(encrypted_data)
|
||||
return json.loads(decrypted_data.decode('utf-8'))
|
||||
return json.loads("{}")
|
||||
|
||||
MAINNET = 'mainnet'
|
||||
TESTNET = 'testnet'
|
||||
|
|
@ -207,13 +206,11 @@ class OutputStat(models.Model):
|
|||
network=network).last()
|
||||
|
||||
if cached_data:
|
||||
print("found cached data {} for type_ref_hash {}, created {}".format(cached_data, type_ref_hash, created))
|
||||
return cached_data, False
|
||||
|
||||
def get_value_and_spent(txid, vout):
|
||||
mempool_api = MempoolAPI()
|
||||
res0 = mempool_api.get_transaction(txid)
|
||||
print("res0 {}".format(res0))
|
||||
vouts = res0.get("vout", [])
|
||||
if vouts:
|
||||
value = vouts[int(vout)].get("value", 0)
|
||||
|
|
@ -291,17 +288,18 @@ class HistoricalPrice(models.Model):
|
|||
mempool_endpoint = user.profile.mempool_endpoint
|
||||
else:
|
||||
mempool_endpoint = "https://mempool.space"
|
||||
url = f"{mempool_endpoints}/api/v1/historical-price?timestamp={timestamp}"
|
||||
url = f"{mempool_endpoint}/api/v1/historical-price?timestamp={timestamp}"
|
||||
response = requests.get(url)
|
||||
api_response = response.json()
|
||||
except Exception as ex:
|
||||
logger.error(ex, exc_info=True)
|
||||
try:
|
||||
from threadlocals.threadlocals import get_current_request
|
||||
request = get_current_request()
|
||||
if request:
|
||||
messages.error(request, "<strong>Connection Error:</strong> Could not connect to Mempool to retrieve historical price.")
|
||||
except Exception as ex2:
|
||||
logger.error(ex, exc_info=True)
|
||||
logger.error(ex2, exc_info=True)
|
||||
return None, None
|
||||
try:
|
||||
obj, created = cls.objects.get_or_create(timestamp=timestamp, defaults={
|
||||
|
|
|
|||
|
|
@ -833,7 +833,6 @@ class LabelUpdateView(UpdateView):
|
|||
return "label_derive_addresses.html"
|
||||
elif action == 'output-details':
|
||||
return "label_edit_output_details.html"
|
||||
|
||||
return "label_edit_update.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
from django.contrib.auth.models import User
|
||||
|
||||
from messages_extends.models import Message
|
||||
|
||||
|
||||
from messages_extends import constants
|
||||
"""
|
||||
DEBUG = 10
|
||||
|
|
@ -40,14 +37,3 @@ def notify_error_persistent(username, message):
|
|||
|
||||
def notify_error(username, message):
|
||||
notify_user(username, message, level=constants.ERROR)
|
||||
|
||||
|
||||
"""
|
||||
{% for message in messages %}
|
||||
<div class="alert {% if message.tags %} alert-{{ message.tags }} {% endif %}">
|
||||
{# close-href is used because href is used by bootstrap to closing other divs #}
|
||||
<a class="close" data-dismiss="alert"{% if message.pk %} close-href="{% url message_mark_read message.pk %}"{% endif %}>×</a>
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@
|
|||
<li class="nav-item ">
|
||||
<a class="nav-link" href="{% url "donate" %}"><span data-feather="heart" class="align-text-bottom"></span> Donate</a>
|
||||
<li>
|
||||
|
||||
|
||||
<li class="nav-item ">
|
||||
<a class="nav-link" href="https://labelbase.space/newsletter/"><span data-feather="mail" class="align-text-bottom"></span> Newsletter</a>
|
||||
<li>
|
||||
|
|
@ -608,13 +608,6 @@
|
|||
loadChat(false);
|
||||
{% endif %}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
<p class="fs-6 text-muted">
|
||||
<strong>Mainnet: </strong>
|
||||
<ul>
|
||||
<li>fulcrum.sethforprivacy.com / s50002</li>
|
||||
<li>electrum.emzy.de / s50002</li>
|
||||
<li>electrum.blockstream.info / s50002</li>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
{% load bootstrap %}
|
||||
{% load i18n %}
|
||||
|
||||
|
||||
{% block label_edit_content %}
|
||||
<!--
|
||||
{{ res_tx|safe }}
|
||||
|
|
@ -29,8 +28,5 @@
|
|||
|
||||
</pre>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -188,8 +188,6 @@ function getPopoverContent(index) {
|
|||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
var content = '<div class="popover-content">';
|
||||
content += '<div><strong>Label:</strong> ' + window.records[index].label + '</div>';
|
||||
content += '<div><strong>Output:</strong> ' + window.records[index].ref + '</div>';
|
||||
|
|
@ -204,9 +202,6 @@ function getPopoverContent(index) {
|
|||
content += '<div><strong>Performance:</strong> ' + window.records[index].performance + '%</div>';
|
||||
content += '<div><strong>Spent:</strong> ' + window.records[index].spent + '</div>';
|
||||
content += '<div><strong>Spendable:</strong> ' + window.records[index].spendable + '</div>';
|
||||
|
||||
|
||||
|
||||
content += '</div>';
|
||||
return content;
|
||||
}
|
||||
|
|
@ -294,25 +289,9 @@ NO LABELBASE
|
|||
<script>
|
||||
{% addtoblock "js" %}
|
||||
$(document).ready(function () {
|
||||
|
||||
|
||||
|
||||
$('[data-toggle="popover"]').popover()
|
||||
|
||||
|
||||
|
||||
});
|
||||
{% endaddtoblock %}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -49,13 +49,7 @@
|
|||
<p style="padding-top: 2.1em;">
|
||||
{% url 'registration' as reg_url %}
|
||||
<strong>First time here?</strong> Let's <a href="{{ reg_url }}">get started</a>.
|
||||
|
||||
</p>
|
||||
<p style="padding-top: .1em;">
|
||||
<strong>Having problems logging in?</strong> If your credentials are not functioning as expected, it is possible that your account is hosted our <a href="https://legacy.labelbase.space/">legacy system</a>.
|
||||
</p>
|
||||
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% block 'backup_tokens' %}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue