Repository: raspiblitz/raspiblitz

Issue:
Add reindex Bitcoin chainstate to the Repair menu
There is also delete transaction index in the repair menu - but not the "reindex chainstate" like offered by the `/config-scripts/network.reindex.sh` script. Add this and make the progress info as part of the background task.

Improve that script, add status/progress info and make it part of the repair menu.

Cross reference: #3016 & https://github.com/rootzoll/raspiblitz/issues/3178#issuecomment-1381166928


Discussion:

Resolving patch:
diff --git a/home.admin/config.scripts/blitz.check-invoice-wrap.py b/home.admin/config.scripts/blitz.check-invoice-wrap.py
new file mode 100644
--- /dev/null
+++ b/home.admin/config.scripts/blitz.check-invoice-wrap.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+# adapted from: https://github.com/lnproxy/lnproxy-cli/blob/fe18d16e42b58f635b94c7da59a34d5e092e4d56/check-wrap.py
+# Parses payment hashes and amounts in bolt11 invoices to check lnproxy
+# Can skip most bolt11 checks since both the user's wallet and lnproxy will do that
+
+from decimal import Decimal
+
+CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
+units = {
+	'p': 10**12,
+	'n': 10**9,
+	'u': 10**6,
+	'm': 10**3,
+}
+
+def parse(invoice):
+	invoice = invoice.lower()
+	pos = invoice.rfind('1')
+	amount = invoice[4:pos]
+	if amount == '':
+		amount = Decimal(0)
+	else:
+		amount = Decimal(amount[:-1]) / units[amount[-1]]
+	data = invoice[pos+1+7:]
+	i = 0
+	while i < len(data):
+		if data[i] == 'p' and data[i+1:i+1+2] == 'p5':
+			payment_hash = data[i+1+2:i+1+2+52]
+			break
+		else:
+			i += 3 + CHARSET.find(data[i+1]) * 32 + CHARSET.find(data[i+1+1])
+	return (amount, payment_hash)
+
+from sys import stderr, argv
+try:
+	if len(argv) != 3:
+		raise Exception("Incorrect number of arguments")
+
+	amt1, hash1 = parse(argv[1])
+	amt2, hash2 = parse(argv[2])
+
+	if hash1 != hash2:
+		print(f"Payment hashes do not match!", file=stderr)
+		exit(3)
+
+	if amt1 != Decimal(0):
+		print(f"Hashes match, routing fee is {(amt2-amt1)*10**8:0,.0f} sat ({(amt2-amt1)/amt1*100:0.2f}%)")
+	else:
+		print(f"Hashes match")
+
+except Exception as err:
+	print('Error:', err)
+	print(f"usage: {argv[0]} <original invoice> <wrapped invoice>", file=stderr)
+	exit(2)
diff --git a/home.admin/config.scripts/blitz.subscriptions.ip2tor.py b/home.admin/config.scripts/blitz.subscriptions.ip2tor.py
--- a/home.admin/config.scripts/blitz.subscriptions.ip2tor.py
+++ b/home.admin/config.scripts/blitz.subscriptions.ip2tor.py
@@ -595,37 +595,68 @@ def menuMakeSubscription(blitzServiceName, torAddress, torPort):
     torTarget = "{0}:{1}".format(torAddress, torPort)
 
     ############################
-    # PHASE 1: Enter Shop URL
+    # PHASE 1: Choose Shop URL
 
-    # see if user had before entered another shop of preference
-    shopurl = DEFAULT_SHOPURL
-    try:
-        subscriptions = toml.load(SUBSCRIPTIONS_FILE)
-        shopurl = subscriptions['shop_ip2tor']
-        print("# using last shop url set in subscriptions.toml")
-    except Exception as e:
-        print("# using default shop url")
+    shopurl = ""
+    while True:
 
-    # remove https:// from shop url (to keep it short)
-    if shopurl.find("://") > 0:
-        shopurl = shopurl[shopurl.find("://") + 3:]
+        # see if user had before entered another shop of preference
+        lastusedShop = ""
+        try:
+            subscriptions = toml.load(SUBSCRIPTIONS_FILE)
+            lastusedShop = subscriptions['shop_ip2tor']
+            print("# using last shop url set in subscriptions.toml")
+        except Exception as e:
+            print("# using default shop url")
 
-    while True:
+        # set choices of shops
+        choices = []
 
-        # input shop url
+        # remove https:// from shop url (to keep it short)
+        if lastusedShop.find("://") > 0: lastusedShop = lastusedShop[lastusedShop.find("://") + 3:]
+
+        # IP2TOR.COM Shop
+        choice_url_ip2torcom="ip2tor.com"
+        choices.append(("A", "ip2tor.com Shop"))
+        if lastusedShop == choice_url_ip2torcom: lastusedShop="" 
+
+        # FULMO Shop
+        choice_url_fulmo="fulmo7x6yvgz6zs2b2ptduvzwevxmizhq23klkenslt5drxx2physlqd.onion"
+        choices.append(("B", "Fulmo Shop"))
+        if lastusedShop == choice_url_fulmo: lastusedShop="" 
+
+        # add before option if different from static options
+        if len(lastusedShop) > 0: choices.append(("Y", lastusedShop))
+    
+        # enter own shop address option
+        choices.append(("X", "Enter a new Shop URL"))
+
+        # select dialog
         d = Dialog(dialog="dialog", autowidgetsize=True)
-        d.set_background_title("Select IP2TOR Bridge Shop (communication secured thru TOR)")
-        code, text = d.inputbox(
-            "Enter Address of the IP2TOR Shop (OR JUST PRESS OK):",
-            height=10, width=72, init=shopurl,
-            title="Shop Address")
+        d.set_background_title("IP2TOR - Select Shop")
+        code, selected = d.menu(
+            "\nChoose your IP2Tor provider/shop:",
+            choices=choices, width=75, height=10, title="Select IP2Tor Shop")
 
         # if user canceled
         if code != d.OK:
             sys.exit(0)
 
-        # get host list from shop
-        shopurl = text
+        if selected == "A" : shopurl=choice_url_ip2torcom
+        if selected == "B" : shopurl=choice_url_fulmo
+        if selected == "Y" : shopurl=lastusedShop
+
+        # input shop url
+        if selected == "X":
+            d = Dialog(dialog="dialog", autowidgetsize=True)
+            d.set_background_title("IP2TOR - Add new Shop")
+            code, shopurl = d.inputbox(
+                "Enter Address of the IP2TOR Shop (OR JUST PRESS OK):",
+                height=10, width=72, init=shopurl,
+                title="Shop Address")
+            if shopurl.find("://") > 0: shopurl = shopurl[shopurl.find("://") + 3:]
+
+        # try & get host list from shop
         os.system('clear')
         try:
             hosts = shopList(shopurl)
@@ -686,6 +717,9 @@ def menuMakeSubscription(blitzServiceName, torAddress, torPort):
         if len(host['terms_of_service']) == 0: host['terms_of_service'] = "-"
         if len(host['terms_of_service_url']) == 0: host['terms_of_service_url'] = "-"
 
+        description=host['terms_of_service']
+        if "description" in host: description = "{0} / {1}".format(host['description'], host['terms_of_service'])
+
         # show details of selected
         d = Dialog(dialog="dialog", autowidgetsize=True)
         d.set_background_title("IP2TOR Bridge Offer Details: {0}".format(shopurl))
@@ -704,7 +738,7 @@ def menuMakeSubscription(blitzServiceName, torAddress, torPort):
 There will be no refunds for not used hours.
 There is no guarantee for quality of service.
 
-The service has the following additional terms:
+The service has the following additional description & terms:
 {5}
 
 More information on the service you can find under:
@@ -715,7 +749,7 @@ def menuMakeSubscription(blitzServiceName, torAddress, torPort):
             host['tor_bridge_price_extension_sats'],
             host['ip'],
             torTarget,
-            host['terms_of_service'],
+            description,
             host['terms_of_service_url'],
             blitzServiceName
         )
diff --git a/home.admin/config.scripts/blitz.subscriptions.py b/home.admin/config.scripts/blitz.subscriptions.py
--- a/home.admin/config.scripts/blitz.subscriptions.py
+++ b/home.admin/config.scripts/blitz.subscriptions.py
@@ -225,7 +225,7 @@ def main():
 
     choices = list()
     choices.append(("LIST", "My Subscriptions"))
-    #choices.append(("NEW1", "+ IP2TOR Bridge (paid)"))
+    choices.append(("NEW1", "+ IP2TOR Bridge (paid)"))
     choices.append(("NEW2", "+ LetsEncrypt HTTPS Domain (free)"))
 
     d = Dialog(dialog="dialog", autowidgetsize=True)


Test patch: