Skip to content

Commit

Permalink
Porting: Mitigating taproot issue (#2087) for the uiux-revamp branch (#…
Browse files Browse the repository at this point in the history
…2088)

* Bugfix: mitigating taproot hotwallet issue 2078 (#2083)

* Some smaller improvements and fixes

* mitigating 2078

* removed Microsoft link tracking

* wrap up a failed update properly

* better decode and better error_handling

* kick

* removed commented code
  • Loading branch information
k9ert authored Jan 30, 2023
1 parent 373e96e commit f2d0857
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 33 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
// For more information, visit: https://code.visualstudio.com/docs/editor/debugging#_launch-configurations
"version": "0.2.0",
"configurations": [
{
Expand Down
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true
}
17 changes: 8 additions & 9 deletions src/cryptoadvance/specter/managers/wallet_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def _update(self, wallets_update_list: Dict):
)
self.wallets[wallet_name] = loaded_wallet
except Exception as e:
handle_exception(e)
logger.exception(e)
self._failed_load_wallets.append(
{
**wallets_update_list[wallet],
Expand All @@ -263,14 +263,13 @@ def _update(self, wallets_update_list: Dict):
# only ignore rpc errors
except RpcError as e:
logger.error(f"Failed updating wallet manager. RPC error: {e}")
logger.info("Updating wallet manager done. Result:")
logger.info(f" * loaded_wallets: {len(self.wallets)}")
logger.info(f" * failed_load_wallets: {len(self._failed_load_wallets)}")
for wallet in self._failed_load_wallets:
logger.info(f" * {wallet['name']} : {wallet['loading_error']}")

wallets_update_list = {}
self.is_loading = False
finally:
self.is_loading = False
logger.info("Updating wallet manager done. Result:")
logger.info(f" * loaded_wallets: {len(self.wallets)}")
logger.info(f" * failed_load_wallets: {len(self._failed_load_wallets)}")
for wallet in self._failed_load_wallets:
logger.info(f" * {wallet['name']} : {wallet['loading_error']}")

def get_by_alias(self, alias):
for wallet_name in self.wallets:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ def history(wallet_alias):
wallet.update_balance()
wallet.check_utxo()

renderting = render_template(
return render_template(
"wallet/history/wallet_history.jinja",
wallet_alias=wallet_alias,
wallet=wallet,
Expand All @@ -453,8 +453,6 @@ def history(wallet_alias):
rand=rand,
services=app.specter.service_manager.services,
)
logger.info("-------------------end render_template()")
return renderting


###### Wallet receive ######
Expand Down
42 changes: 30 additions & 12 deletions src/cryptoadvance/specter/txlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from .specter_error import SpecterError, SpecterInternalException
from embit.descriptor import Descriptor
from embit.liquid.descriptor import LDescriptor
from .util.common import str2bool
from .util.psbt import (
AbstractTxContext,
SpecterInputScope,
Expand Down Expand Up @@ -84,6 +85,7 @@ class TxItem(dict, AbstractTxListContext):
"vsize",
"address",
]
# type_converter will be used to _read_csv to have a proper mapping
type_converter = [
str,
int,
Expand Down Expand Up @@ -289,13 +291,14 @@ def __dict__(self):

class WalletAwareTxItem(TxItem):
PSBTCls = SpecterPSBT

# Columns for writing CSVs, type_converter for reading
columns = TxItem.columns.copy()
columns.extend(
["category", "flow_amount", "utxo_amount", "ismine"],
)

type_converter = TxItem.type_converter.copy()
type_converter.extend([str, float, float, bool])
type_converter.extend([str, float, float, str2bool])

def __init__(self, parent, addresses, rawdir, **kwargs):
super().__init__(parent, addresses, rawdir, **kwargs)
Expand Down Expand Up @@ -323,6 +326,24 @@ def psbt(self) -> SpecterPSBT:
self._psbt.update(updated)
return self._psbt

@property
def is_taproot(self):
return str(self.descriptor).startswith("tr(")

def decode_psbt(self, mode="embit") -> SpecterPSBT:
"""Utility function which decodes this tx as psbt
as in the core rpc-call 'decodepsbt'.
However, it uses embit to calculate the details
use mode=core to ask core directly.
embit might support taproot, core might not.
"""
if mode == "core":
return self.rpc.decodepsbt(str(self.psbt))
elif mode == "embit":
return self.psbt.to_dict()
else:
raise SpecterInternalException(f"Mode {mode} does not exist")

@property
def category(self):
"""One of mixed (default), generate, selftransfer, receive or send"""
Expand Down Expand Up @@ -385,8 +406,11 @@ def flow_amount(self) -> float:
def ismine(self) -> bool:
if self.get("ismine"):
return self["ismine"]
inputs = self.psbt.inputs
outputs = self.psbt.outputs
if self.is_taproot:
# This is a bug mitigation, see #2078
return True
inputs: List[SpecterInputScope] = self.psbt.inputs
outputs: List[SpecterOutputScope] = self.psbt.outputs
any_inputs_mine = any([inp.is_mine for inp in inputs])
any_outputs_mine = any([out.is_mine for out in outputs])
self["ismine"] = any_inputs_mine or any_outputs_mine
Expand Down Expand Up @@ -417,14 +441,6 @@ def address(self):
self["address"] = addresses[0]
return self["address"]

def __dict__(self):
super_dict = dict(self)
super_dict["category"] = self.category
super_dict["flow_amount"] = self.flow_amount
super_dict["utxo_amount"] = self.utxo_amount
super_dict["ismine"] = (self["ismine"] or self.ismine,)
return super_dict


class TxList(dict, AbstractTxListContext):
"""A TxList is a dict with txids as keys and TxItems as values."""
Expand Down Expand Up @@ -474,6 +490,8 @@ def clear_cache(self):
tx.clear_cache()
delete_file(self.path)
self._file_exists = False
self.clear()

logger.info(f"Cleared the Cache for {self.path} (and rawdir)")

def getfetch(self, txid):
Expand Down
9 changes: 4 additions & 5 deletions src/cryptoadvance/specter/util/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import json
from flask_babel.speaklater import LazyString
from typing import Union
from distutils.util import strtobool

logger = logging.getLogger(__name__)

Expand All @@ -12,11 +13,9 @@ def str2bool(my_str):
"""returns a reasonable boolean from a string so that "False" will result in False"""
if my_str is None:
return False
elif isinstance(my_str, str) and my_str.lower() == "false":
return False
elif isinstance(my_str, str) and my_str.lower() == "off":
return False
return bool(my_str)
elif isinstance(my_str, bool):
return my_str
return bool(strtobool(my_str))


def camelcase2snake_case(name):
Expand Down
2 changes: 1 addition & 1 deletion src/cryptoadvance/specter/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,7 @@ def check_utxo(self):
except Exception as e:
logger.exception(e)
self._full_utxo = []
raise SpecterError(f"Failed to load utxos, {e}")
raise SpecterError(f"Failed to load utxos, {type(e).__name__}: {e}")

def check_utxo_orig(self):
"""fetches the utxo-set from core and stores the result in self.__full_utxo which is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@
<br><br>
<input name="Submit" class="btn" type="submit" value="Submit" />
</form>
you can also do that in any javascript.console with:
Press <b>F12</b> to open the dev-console (helpful to see objects)<br>
You can also do that in any javascript.console with:
<pre>
await pythonCommand("app.specter")
await pythonCommand('app.specter')
</pre>
Some usefull idioms:
<pre>
Expand Down Expand Up @@ -109,6 +110,7 @@
} else {
console.log(result)
if (result == "") {
result = "(empty string)"
}
Expand Down
4 changes: 4 additions & 0 deletions src/cryptoadvance/specterext/spectrum/spectrum_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,7 @@ def node_logo_template(self):

def node_connection_template(self):
return "spectrum/components/spectrum_node_connection.jinja"

@property
def taproot_support(self):
return False

0 comments on commit f2d0857

Please sign in to comment.