From 97b8b3b32a73218c96c4f43479ca0ece4a48d81d Mon Sep 17 00:00:00 2001 From: chris-belcher Date: Wed, 14 Apr 2021 15:48:31 +0100 Subject: [PATCH] Show fidelity bonds on orderbook watch html page Add two new pages for the orderbook watch html server. One displays each fidelity bond individually, the other shows calculations about how expensive a successful sybil attack would be against the current fidelity bonds in the orderbook. --- scripts/obwatch/ob-watcher.py | 368 +++++++++++++++++-- scripts/obwatch/orderbook.html | 2 + scripts/obwatch/sybil_attack_calculations.py | 81 ++++ 3 files changed, 423 insertions(+), 28 deletions(-) create mode 100755 scripts/obwatch/sybil_attack_calculations.py diff --git a/scripts/obwatch/ob-watcher.py b/scripts/obwatch/ob-watcher.py index b0cdc84..fe6cf7e 100755 --- a/scripts/obwatch/ob-watcher.py +++ b/scripts/obwatch/ob-watcher.py @@ -16,12 +16,18 @@ from future.moves.urllib.parse import parse_qs from decimal import Decimal from optparse import OptionParser from twisted.internet import reactor +from datetime import datetime if sys.version_info < (3, 7): print("ERROR: this script requires at least python 3.7") exit(1) from jmbase.support import EXIT_FAILURE +from jmbase import bintohex +from jmclient import FidelityBondMixin, get_interest_rate +from jmclient.fidelity_bond import FidelityBondProof + +import sybil_attack_calculations as sybil from jmbase import get_log log = get_log() @@ -86,31 +92,45 @@ def cjfee_display(cjfee, order, btc_unit, rel_unit): return str(Decimal(cjfee) * Decimal(rel_unit_to_factor[rel_unit])) + rel_unit -def satoshi_to_unit(sat, order, btc_unit, rel_unit): - power = unit_to_power[btc_unit] +def satoshi_to_unit_power(sat, power): return ("%." + str(power) + "f") % float( Decimal(sat) / Decimal(10 ** power)) +def satoshi_to_unit(sat, order, btc_unit, rel_unit): + return satoshi_to_unit_power(sat, unit_to_power[btc_unit]) def order_str(s, order, btc_unit, rel_unit): return str(s) -def create_table_heading(btc_unit, rel_unit): +def create_offerbook_table_heading(btc_unit, rel_unit): col = ' {1}\n' # .format(field,label) tableheading = '\n ' + ''.join( [ - col.format('ordertype', 'Type'), col.format( - 'counterparty', 'Counterparty'), + col.format('ordertype', 'Type'), + col.format('counterparty', 'Counterparty'), col.format('oid', 'Order ID'), - col.format('cjfee', 'Fee'), col.format( - 'txfee', 'Miner Fee Contribution / ' + btc_unit), - col.format( - 'minsize', 'Minimum Size / ' + btc_unit), col.format( - 'maxsize', 'Maximum Size / ' + btc_unit) + col.format('cjfee', 'Fee'), + col.format('txfee', 'Miner Fee Contribution / ' + btc_unit), + col.format('minsize', 'Minimum Size / ' + btc_unit), + col.format('maxsize', 'Maximum Size / ' + btc_unit), + col.format('bondvalue', 'Bond value / ' + btc_unit + '²') ]) + ' ' return tableheading +def create_bonds_table_heading(btc_unit): + tableheading = ('
' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + ) + return tableheading def create_choose_units_form(selected_btc, selected_rel): choose_units_form = ( @@ -128,6 +148,53 @@ def create_choose_units_form(selected_btc, selected_rel): '" + bondtable = "" + for (bond_data, utxo_data), bond_value, conf_time in zip( + fidelity_bond_data, fidelity_bond_values, bond_outpoint_conf_times): + + if bond_value == -1 or conf_time == -1 or utxo_data == None: + bond_value_str = "No data" + conf_time_str = "No data" + utxo_value_str = "No data" + else: + bond_value_str = satoshi_to_unit_power(bond_value, 2*unit_to_power[btc_unit]) + conf_time_str = str(datetime.utcfromtimestamp(conf_time)) + utxo_value_str = satoshi_to_unit(utxo_data["value"], None, btc_unit, 0) + bondtable += ("" + + elem(bond_data.maker_nick) + + elem(bintohex(bond_data.utxo[0]) + ":" + str(bond_data.utxo[1])) + + elem(bond_value_str) + + elem(datetime.utcfromtimestamp(bond_data.locktime).strftime("%Y-%m-%d")) + + elem(utxo_value_str) + + elem(conf_time_str) + + elem(str(bond_data.cert_expiry*RETARGET_INTERVAL)) + + elem(bintohex(btc.mk_freeze_script(bond_data.utxo_pub, + bond_data.locktime))) + + "" + ) + + heading2 = (str(len(fidelity_bond_data)) + " fidelity bonds found with " + + total_btc_committed_str + " " + btc_unit + + " total locked up") + choose_units_form = ( + '' + + '') + choose_units_form = choose_units_form.replace( + '
CounterpartyUTXOBond value / ' + btc_unit + '²LocktimeLocked coins / ' + btc_unit + 'Confirmation timeSignature expiry heightRedeem script
" + e + "
" + + decodescript_tip) + + def create_sybil_resistance_page(self, btc_unit): + if jm_single().bc_interface == None: + return "", "Calculations unavailable, requires configured bitcoin node." + + (fidelity_bond_data, fidelity_bond_values, bond_outpoint_conf_times) =\ + get_fidelity_bond_data(self.taker) + + choose_units_form = ( + '
' + + '
') + choose_units_form = choose_units_form.replace( + '