diff --git a/bal.py b/bal.py index d18a4df..06ce197 100644 --- a/bal.py +++ b/bal.py @@ -1,6 +1,7 @@ import os -#import random -#import zipfile as zipfile_lib + +# import random +# import zipfile as zipfile_lib from electrum import json_db from electrum.logging import get_logger @@ -9,7 +10,7 @@ from electrum.transaction import tx_from_any def get_will_settings(x): - #print(x) + # print(x) pass @@ -18,7 +19,6 @@ json_db.register_dict("will", dict, None) json_db.register_dict("will_settings", lambda x: x, None) - def get_will(x): try: x["tx"] = tx_from_any(x["tx"]) @@ -90,10 +90,10 @@ class BalPlugin(BasePlugin): self.PREVIEW = BalConfig(config, "bal_preview", True) self.SAVE_TXS = BalConfig(config, "bal_save_txs", True) self.WILLEXECUTORS = BalConfig(config, "bal_willexecutors", True) - #self.PING_WILLEXECUTORS = BalConfig(config, "bal_ping_willexecutors", True) - #self.ASK_PING_WILLEXECUTORS = BalConfig( + # self.PING_WILLEXECUTORS = BalConfig(config, "bal_ping_willexecutors", True) + # self.ASK_PING_WILLEXECUTORS = BalConfig( # config, "bal_ask_ping_willexecutors", True - #) + # ) self.NO_WILLEXECUTOR = BalConfig(config, "bal_no_willexecutor", True) self.HIDE_REPLACED = BalConfig(config, "bal_hide_replaced", True) self.HIDE_INVALIDATED = BalConfig(config, "bal_hide_invalidated", True) @@ -149,4 +149,3 @@ class BalPlugin(BasePlugin): def default_will_settings(self): return {"baltx_fees": 100, "threshold": "180d", "locktime": "1y"} - diff --git a/heirs.py b/heirs.py index 1408a36..6e93e57 100644 --- a/heirs.py +++ b/heirs.py @@ -29,6 +29,8 @@ from electrum.util import ( from .util import Util from .willexecutors import Willexecutors +from electrum.util import BitcoinException +from electrum import constants if TYPE_CHECKING: from .simple_config import SimpleConfig @@ -41,6 +43,7 @@ HEIR_ADDRESS = 0 HEIR_AMOUNT = 1 HEIR_LOCKTIME = 2 HEIR_REAL_AMOUNT = 3 +HEIR_DUST_AMOUNT = 4 TRANSACTION_LABEL = "inheritance transaction" @@ -88,6 +91,7 @@ def prepare_transactions(locktimes, available_utxos, fees, wallet): txsout = {} locktime, _ = Util.get_lowest_locktimes(locktimes) if not locktime: + _logger.info("prepare transactions, no locktime") return locktime = locktime[0] @@ -101,22 +105,27 @@ def prepare_transactions(locktimes, available_utxos, fees, wallet): outputs = [] paid_heirs = {} for name, heir in heirs.items(): - - try: - if len(heir) > HEIR_REAL_AMOUNT: + if len(heir) > HEIR_REAL_AMOUNT and not "DUST" in str( + heir[HEIR_REAL_AMOUNT] + ): + try: real_amount = heir[HEIR_REAL_AMOUNT] - out_amount += real_amount - description += f"{name}\n" - paid_heirs[name] = heir outputs.append( PartialTxOutput.from_address_and_value( heir[HEIR_ADDRESS], real_amount ) ) - else: + out_amount += real_amount + description += f"{name}\n" + except BitcoinException as e: + _logger.info("exception decoding output{} - {}".format(type(e), e)) + heir[HEIR_REAL_AMOUNT] = e + + except Exception as e: + heir[HEIR_REAL_AMOUNT] = e + _logger.info(f"error preparing transactions {e}") pass - except Exception as e: - pass + paid_heirs[name] = heir in_amount = 0.0 used_utxos = [] @@ -125,12 +134,18 @@ def prepare_transactions(locktimes, available_utxos, fees, wallet): value = utxo.value_sats() in_amount += value used_utxos.append(utxo) - if in_amount > out_amount: + if in_amount >= out_amount: break except IndexError as e: + _logger.info( + f"error preparing transactions index error {e} {in_amount}, {out_amount}" + ) pass if int(in_amount) < int(out_amount): + _logger.info( + "error preparing transactions in_amount < out_amount ({} < {}) " + ) break heirsvalue = out_amount change = get_change_output(wallet, in_amount, out_amount, fee) @@ -263,9 +278,10 @@ def get_change_output(wallet, in_amount, out_amount, fee): class Heirs(dict, Logger): - def __init__(self, db: "WalletDB"): + def __init__(self, wallet): Logger.__init__(self) - self.db = db + self.db = wallet.db + self.wallet = wallet d = self.db.get("heirs", {}) try: self.update(d) @@ -327,6 +343,10 @@ class Heirs(dict, Logger): if value > wallet.dust_threshold(): heir_list[key].insert(HEIR_REAL_AMOUNT, value) amount += value + else: + heir_list[key].insert(HEIR_REAL_AMOUNT, f"DUST: {value}") + heir_list[key].insert(HEIR_DUST_AMOUNT, value) + _logger.info(f"{key}, {value} is dust will be ignored") except Exception as e: raise e @@ -449,6 +469,7 @@ class Heirs(dict, Logger): ): Heirs._validate(self) if len(self) <= 0: + _logger.info("while building transactions there was no heirs") return balance = 0.0 len_utxo_set = 0 @@ -464,6 +485,7 @@ class Heirs(dict, Logger): len_utxo_set += 1 available_utxos.append(utxo) if len_utxo_set == 0: + _logger.info("no usable utxos") return j = -2 willexecutorsitems = list(willexecutors.items()) @@ -505,6 +527,7 @@ class Heirs(dict, Logger): if not txs: return {} except Exception as e: + _logger.info(f"error preparing transactions{e}") try: if "w!ll3x3c" in e.heirname: Willexecutors.is_selected(willexecutors[w], False) @@ -632,7 +655,7 @@ class Heirs(dict, Logger): return None def validate_address(address): - if not bitcoin.is_address(address): + if not bitcoin.is_address(address, net=constants.net): raise NotAnAddress(f"not an address,{address}") return address @@ -661,12 +684,14 @@ class Heirs(dict, Logger): return (address, amount, locktime) def _validate(data, timestamp_to_check=False): + for k, v in list(data.items()): if k == "heirs": - return Heirs._validate(v) + return Heirs._validate(v, timestamp_to_check) try: - Heirs.validate_heir(k, v) + Heirs.validate_heir(k, v, timestamp_to_check) except Exception as e: + _logger.info(f"exception heir removed {e}") data.pop(k) return data @@ -685,3 +710,7 @@ class LocktimeNotValid(ValueError): class HeirExpiredException(LocktimeNotValid): pass + + +class HeirAmountIsDustException(Exception): + pass diff --git a/qt.py b/qt.py index 13bb0bf..12a1f03 100644 --- a/qt.py +++ b/qt.py @@ -145,7 +145,7 @@ from electrum.util import ( from .bal import BalPlugin from .bal_resources import DEFAULT_ICON, icon_path -from .heirs import Heirs +from .heirs import Heirs, HEIR_REAL_AMOUNT, HEIR_DUST_AMOUNT from .util import Util from .will import ( AmountException, @@ -295,8 +295,8 @@ class Plugin(BalPlugin, Logger): lbl_logo = QLabel() lbl_logo.setPixmap(qicon) - #heir_ping_willexecutors = bal_checkbox(self.PING_WILLEXECUTORS) - #heir_ask_ping_willexecutors = bal_checkbox(self.ASK_PING_WILLEXECUTORS) + # heir_ping_willexecutors = bal_checkbox(self.PING_WILLEXECUTORS) + # heir_ask_ping_willexecutors = bal_checkbox(self.ASK_PING_WILLEXECUTORS) heir_no_willexecutor = bal_checkbox(self.NO_WILLEXECUTOR) def on_multiverse_change(): @@ -327,27 +327,27 @@ class Plugin(BalPlugin, Logger): 2, "Hide invalidated transactions from will detail and list", ) - #add_widget( + # add_widget( # grid, # "Ping Willexecutors", # heir_ping_willexecutors, # 3, # "Ping willexecutors to get payment info before compiling will", - #) - #add_widget( + # ) + # add_widget( # grid, # " - Ask before", # heir_ask_ping_willexecutors, # 4, # "Ask before to ping willexecutor", - #) - #add_widget( + # ) + # add_widget( # grid, # "Backup Transaction", # heir_no_willexecutor, # 5, # "Add transactions without willexecutor", - #) + # ) # add_widget(grid,"Enable Multiverse(EXPERIMENTAL/BROKEN)",heir_enable_multiverse,6,"enable multiple locktimes, will import.... ") grid.addWidget(heir_repush, 7, 0) grid.addWidget( @@ -473,7 +473,7 @@ class BalWindow(Logger): self.bal_plugin, update=False, bal_window=self ) if not self.heirs: - self.heirs = Heirs._validate(Heirs(self.wallet.db)) + self.heirs = Heirs._validate(Heirs(self.wallet)) if not self.will: self.will = self.wallet.db.get_dict("will") Util.fix_will_tx_fees(self.will) @@ -522,7 +522,6 @@ class BalWindow(Logger): tab.is_shown_cv = shown_cv(True) return tab - def new_heir_dialog(self, heir_key=None): heir = self.heirs.get(heir_key) title = "New heir" @@ -655,6 +654,7 @@ class BalWindow(Logger): Will.normalize_will(self.willitems, self.wallet) def build_will(self, ignore_duplicate=True, keep_original=True): + _logger.debug("building will...") will = {} willtodelete = [] willtoappend = {} @@ -670,6 +670,7 @@ class BalWindow(Logger): if Willexecutors.is_selected(w): f = True if not f: + _logger.error("No Will-Executor or backup transaction selected") raise NoWillExecutorNotPresent( "No Will-Executor or backup transaction selected" ) @@ -680,7 +681,8 @@ class BalWindow(Logger): None, self.date_to_check, ) - self.logger.info(txs) + + self.logger.info(f"txs built: {txs}") creation_time = time.time() if txs: for txid in txs: @@ -699,7 +701,13 @@ class BalWindow(Logger): tx["txchildren"] = [] will[txid] = WillItem(tx, _id=txid, wallet=self.wallet) self.update_will(will) + else: + self.logger.info("No transactions was built") + self.logger.info(f"will-settings: {self.will_settings}") + self.logger.info(f"date_to_check:{self.date_to_check}") + self.logger.info(f"heirs: {self.heirs}") except Exception as e: + self.logger.info(f"Exception build_will: {e}") raise e pass return self.willitems @@ -1177,7 +1185,7 @@ class BalWindow(Logger): parent = self def on_success(result): - #del self.waiting_dialog + # del self.waiting_dialog try: parent.willexecutor_list.update() except Exception as e: @@ -1757,7 +1765,9 @@ class BalWizardWEDownloadWidget(BalWizardWidget): def on_success(willexecutors): self.bal_window.willexecutors.update(willexecutors) - self.bal_window.ping_willexecutors(self.bal_window.willexecutors,False) + self.bal_window.ping_willexecutors( + self.bal_window.willexecutors, False + ) if index < 1: for we in self.bal_window.willexecutors: if self.bal_window.willexecutors[we]["status"] == 200: @@ -1828,7 +1838,6 @@ class BalWizardLocktimeAndFeeWidget(BalWizardWidget): self.heir_locktime.get_locktime() if self.heir_locktime.get_locktime() else "1y" - ) self.bal_window.bal_plugin.WILL_SETTINGS.set(self.bal_window.will_settings) @@ -1846,7 +1855,6 @@ class BalWizardLocktimeAndFeeWidget(BalWizardWidget): ) self.bal_window.bal_plugin.WILL_SETTINGS.set(self.bal_window.will_settings) - self.heir_threshold.valueEdited.connect(on_heir_threshold) self.heir_tx_fees = QSpinBox(widget) @@ -2029,7 +2037,7 @@ class BalBuildWillDialog(BalDialog): if not parent: parent = bal_window.window BalDialog.__init__(self, parent, bal_window.bal_plugin, "Building Will") - self.parent=parent + self.parent = parent self.updatemessage.connect(self.update) self.bal_window = bal_window self.message_label = QLabel("Building Will:") @@ -2080,7 +2088,7 @@ class BalBuildWillDialog(BalDialog): self.bal_window.window.wallet.dust_threshold(), ) _logger.debug("variables ok") - self.msg_set_status("checking variables:", varrow,"Ok") + self.msg_set_status("checking variables:", varrow, "Ok") except AmountException: self.msg_set_status( "checking variables", @@ -2093,7 +2101,7 @@ class BalBuildWillDialog(BalDialog): ) + "", ) - + self.msg_set_checking() have_to_build = False try: @@ -2110,7 +2118,7 @@ class BalBuildWillDialog(BalDialog): _logger.debug("no heirs") self.msg_set_checking("No Heirs") except NotCompleteWillException as e: - _logger.debug("not complete", e) + _logger.debug(f"not complete {e} true") message = False have_to_build = True if isinstance(e, HeirChangeException): @@ -2124,7 +2132,7 @@ class BalBuildWillDialog(BalDialog): elif isinstance(e, HeirNotFoundException): message = "Heir not found" if message: - _logger.debug("message") + _logger.debug(f"message: {message}") self.msg_set_checking(message) else: self.msg_set_checking("New") @@ -2140,6 +2148,18 @@ class BalBuildWillDialog(BalDialog): except Exception as e: self.msg_set_building(self.msg_error(e)) return False, None + + excluded_heirs = [] + for wid in Will.only_valid(self.bal_window.willitems): + heirs = self.bal_window.willitems[wid].heirs + for hid, heir in heirs.items(): + if "DUST" in str(heir[HEIR_REAL_AMOUNT]): + self.msg_set_status( + f'{hid},{heir[HEIR_DUST_AMOUNT]} is DUST', + None, + f"Excluded from will {wid}", + ) + have_to_sign = False for wid in Will.only_valid(self.bal_window.willitems): if not self.bal_window.willitems[wid].get_status("COMPLETE"): @@ -2240,7 +2260,7 @@ class BalBuildWillDialog(BalDialog): if not self._stopping: self.loop_push() - def invalidate_task(self,password,bal_window,tx): + def invalidate_task(self, password, bal_window, tx): _logger.debug(f"invalidate tx: {tx}") fee_per_byte = bal_window.will_settings.get("baltx_fees", 1) tx = self.bal_window.wallet.sign_transaction(tx, password) @@ -2269,6 +2289,7 @@ class BalBuildWillDialog(BalDialog): def on_error(self, error): _logger.error(error) pass + def on_success_phase1(self, result): self.have_to_sign, tx = list(result) _logger.debug("have to sign {}".format(self.have_to_sign)) @@ -2287,7 +2308,7 @@ class BalBuildWillDialog(BalDialog): self.close() return self.thread.add( - partial(self.invalidate_task,password,self.bal_window,tx), + partial(self.invalidate_task, password, self.bal_window, tx), on_success=self.on_success_invalidate, on_done=self.on_accept, on_error=self.on_error, @@ -2399,8 +2420,6 @@ class BalBuildWillDialog(BalDialog): self.password = self.bal_window.get_wallet_password(msg, parent=self) def msg_edit_row(self, line, row=None): - _logger.debug(f"{row},{line}") - try: self.labels[row] = line except Exception: @@ -2573,9 +2592,15 @@ class HeirList(MyTreeView, MessageBoxMixin): items[self.Columns.NAME].setEditable(True) items[self.Columns.ADDRESS].setEditable(True) items[self.Columns.AMOUNT].setEditable(True) - items[self.Columns.NAME].setData(key, self.ROLE_HEIR_KEY + self.Columns.NAME) - items[self.Columns.ADDRESS].setData(key, self.ROLE_HEIR_KEY + self.Columns.ADDRESS) - items[self.Columns.AMOUNT].setData(key, self.ROLE_HEIR_KEY + self.Columns.AMOUNT) + items[self.Columns.NAME].setData( + key, self.ROLE_HEIR_KEY + self.Columns.NAME + ) + items[self.Columns.ADDRESS].setData( + key, self.ROLE_HEIR_KEY + self.Columns.ADDRESS + ) + items[self.Columns.AMOUNT].setData( + key, self.ROLE_HEIR_KEY + self.Columns.AMOUNT + ) row_count = self.model().rowCount() self.model().insertRow(row_count, items) @@ -2594,10 +2619,9 @@ class HeirList(MyTreeView, MessageBoxMixin): pass def get_edit_key_from_coordinate(self, row, col): - a= self.get_role_data_from_coordinate( - row, col, role=self.ROLE_HEIR_KEY + col - ) + a = self.get_role_data_from_coordinate(row, col, role=self.ROLE_HEIR_KEY + col) return a + def create_toolbar(self, config): toolbar, menu = self.create_toolbar_with_menu("") menu.addAction(_("&New Heir"), self.bal_window.new_heir_dialog) @@ -2605,6 +2629,7 @@ class HeirList(MyTreeView, MessageBoxMixin): menu.addAction(_("Export"), lambda: self.bal_window.export_heirs()) self.heir_locktime = HeirsLockTimeEdit(self, 0) + def on_heir_locktime(): if not self.heir_locktime.get_locktime(): self.heir_locktime.set_locktime("1y") @@ -2695,7 +2720,6 @@ class HeirList(MyTreeView, MessageBoxMixin): self.heir_threshold.set_locktime(self.bal_window.will_settings["threshold"]) self.heir_tx_fees.setValue(int(self.bal_window.will_settings["baltx_fees"])) - except Exception as e: _logger.debug(f"Exception update_will_settings {e}") @@ -2963,16 +2987,22 @@ class PreviewList(MyTreeView): def check(self): Will.add_willtree(self.bal_window.willitems) - all_utxos =self.bal_window.wallet.get_utxos() + all_utxos = self.bal_window.wallet.get_utxos() utxos_list = Will.utxos_strs(all_utxos) - Will.check_invalidated(self.bal_window.willitems,utxos_list,self.bal_window.wallet) - + Will.check_invalidated( + self.bal_window.willitems, utxos_list, self.bal_window.wallet + ) + close_window = BalBuildWillDialog(self.bal_window) close_window.build_will_task() will = {} for wid, w in self.bal_window.willitems.items(): - if w.get_status("VALID") and w.get_status("PUSHED") and not w.get_status("CHECKED"): + if ( + w.get_status("VALID") + and w.get_status("PUSHED") + and not w.get_status("CHECKED") + ): will[wid] = w if will: self.bal_window.check_transactions(will) @@ -3008,7 +3038,7 @@ class PreviewDialog(BalDialog, MessageBoxMixin): self.setMinimumSize(1000, 200) self.size_label = QLabel() self.transactions_list = PreviewList(self.bal_window, self.will) - + self.bal_window.init_class_variables() self.check_will() @@ -3290,7 +3320,7 @@ class WillExecutorList(MyTreeView): self.Columns.INFO, ], ) - self.parent=parent + self.parent = parent try: self.setModel(QStandardItemModel(self)) self.sortByColumn(self.Columns.SELECTED, Qt.SortOrder.AscendingOrder) @@ -3356,9 +3386,9 @@ class WillExecutorList(MyTreeView): self.update() def get_edit_key_from_coordinate(self, row, col): - role=self.ROLE_HEIR_KEY+col + role = self.ROLE_HEIR_KEY + col a = self.get_role_data_from_coordinate(row, col, role=role) - return a + return a def delete(self, selected_keys): for key in selected_keys: @@ -3416,16 +3446,33 @@ class WillExecutorList(MyTreeView): labels[self.Columns.URL] = url if Willexecutors.is_selected(value): - labels[self.Columns.SELECTED] = [read_QIcon_from_bytes(self.parent.bal_plugin.read_file("icons/confirmed.png")),""] + labels[self.Columns.SELECTED] = [ + read_QIcon_from_bytes( + self.parent.bal_plugin.read_file("icons/confirmed.png") + ), + "", + ] else: labels[self.Columns.SELECTED] = "" labels[self.Columns.BASE_FEE] = Util.decode_amount( value.get("base_fee", 0), self.get_decimal_point() ) if str(value.get("status", 0)) == "200": - labels[self.Columns.STATUS] = [read_QIcon_from_bytes(self.parent.bal_plugin.read_file("icons/status_connected.png")),""] + labels[self.Columns.STATUS] = [ + read_QIcon_from_bytes( + self.parent.bal_plugin.read_file( + "icons/status_connected.png" + ) + ), + "", + ] else: - labels[self.Columns.STATUS] = [read_QIcon_from_bytes(self.parent.bal_plugin.read_file("icons/unconfirmed.png")),""] + labels[self.Columns.STATUS] = [ + read_QIcon_from_bytes( + self.parent.bal_plugin.read_file("icons/unconfirmed.png") + ), + "", + ] labels[self.Columns.ADDRESS] = str(value.get("address", "")) labels[self.Columns.INFO] = str(value.get("info", "")) @@ -3445,10 +3492,18 @@ class WillExecutorList(MyTreeView): items[self.Columns.BASE_FEE].setEditable(True) items[self.Columns.STATUS].setEditable(False) - items[self.Columns.URL].setData(url, self.ROLE_HEIR_KEY + self.Columns.URL) - items[self.Columns.BASE_FEE].setData(url, self.ROLE_HEIR_KEY + self.Columns.BASE_FEE) - items[self.Columns.INFO].setData(url, self.ROLE_HEIR_KEY + self.Columns.INFO) - items[self.Columns.ADDRESS].setData(url, self.ROLE_HEIR_KEY + self.Columns.ADDRESS) + items[self.Columns.URL].setData( + url, self.ROLE_HEIR_KEY + self.Columns.URL + ) + items[self.Columns.BASE_FEE].setData( + url, self.ROLE_HEIR_KEY + self.Columns.BASE_FEE + ) + items[self.Columns.INFO].setData( + url, self.ROLE_HEIR_KEY + self.Columns.INFO + ) + items[self.Columns.ADDRESS].setData( + url, self.ROLE_HEIR_KEY + self.Columns.ADDRESS + ) row_count = self.model().rowCount() self.model().insertRow(row_count, items) if url == current_key: @@ -3516,7 +3571,7 @@ class WillExecutorWidget(QWidget, MessageBoxMixin): buttonbox.addWidget(b) vbox.addLayout(buttonbox) - #self.willexecutor_list.update() + # self.willexecutor_list.update() def add(self): self.willexecutors_list["http://localhost:8080"] = { @@ -3548,7 +3603,7 @@ class WillExecutorWidget(QWidget, MessageBoxMixin): def update_willexecutors(self, wes=None): if not wes: - wes=self.willexecutors_list + wes = self.willexecutors_list self.bal_window.ping_willexecutors(wes, self.parent) self.willexecutors_list.update(wes) self.willexecutor_list.update() diff --git a/will.py b/will.py index 3e6584b..82af78f 100644 --- a/will.py +++ b/will.py @@ -28,7 +28,6 @@ _logger = get_logger(__name__) class Will: - # return an array with the list of children def get_children(will, willid): out = [] for _id in will: @@ -153,6 +152,16 @@ class Will: inp._TxInput__value_sats = change.value return inp + """ + in questa situazione sono presenti due transazioni con id differente(quindi transazioni differenti) + per prima cosa controllo il locktime + se il locktime della nuova transazione e' maggiore del locktime della vecchia transazione, allora + confronto gli eredi, per locktime se corrispondono controllo i willexecutor + se hanno la stessa url ma le fee vecchie sono superiori alle fee nuove, allora anticipare. + + + """ + def check_anticipate(ow: "WillItem", nw: "WillItem"): anticipate = Util.anticipate_locktime(ow.tx.locktime, days=1) if int(nw.tx.locktime) >= int(anticipate): @@ -256,7 +265,7 @@ class Will: to_append = {} new_inputs = Will.get_all_inputs(will, only_valid=True) for nid, nwi in will.items(): - if nwi.search_anticipate(new_inputs) or nwi.search_anticipate(old_inputs): + if nwi.search_anticipate(new_inputs): if nid != nwi.tx.txid(): redo = True to_delete.append(nid) @@ -266,6 +275,17 @@ class Will: Will.change_input( will, nid, i, outputs[i], new_inputs, to_delete, to_append ) + if nwi.search_anticipate(old_inputs): + if nid != nwi.tx.txid(): + redo = True + + to_delete.append(nid) + to_append[nwi.tx.txid()] = nwi + outputs = nwi.tx.outputs() + for i in range(0, len(outputs)): + Will.change_input( + will, nid, i, outputs[i], new_inputs, to_delete, to_append + ) for w in to_delete: try: @@ -275,6 +295,7 @@ class Will: for k, w in to_append.items(): will[k] = w if redo: + Will.search_anticipate_rec(will, old_inputs) def update_will(old_will, new_will): @@ -284,7 +305,6 @@ class Will: # check if the new input is already spent by other transaction # if it is use the same locktime, or anticipate. Will.search_anticipate_rec(new_will, all_old_inputs) - other_inputs = Will.get_all_inputs(old_will, {}) try: Will.normalize_will(new_will, others_inputs=other_inputs) @@ -419,20 +439,22 @@ class Will: # check if transactions are stil valid tecnically valid def check_invalidated(willtree, utxos_list, wallet): for wid, w in willtree.items(): - #if not w.father: - for inp in w.tx.inputs(): - inp_str = Util.utxo_to_str(inp) - if not inp_str in utxos_list: - if wallet: - height = Will.check_tx_height(w.tx, wallet) - if height < 0: - Will.set_invalidate(wid, willtree) - elif height == 0: - w.set_status("PENDING", True) - else: - w.set_status("CONFIRMED", True) - #else: - # print("father",w.father) + if ( + not w.father + or willtree[w.father].get_status("CONFIRMED") + or willtree[w.father].get_status("PENDING") + ): + for inp in w.tx.inputs(): + inp_str = Util.utxo_to_str(inp) + if not inp_str in utxos_list: + if wallet: + height = Will.check_tx_height(w.tx, wallet) + if height < 0: + Will.set_invalidate(wid, willtree) + elif height == 0: + w.set_status("PENDING", True) + else: + w.set_status("CONFIRMED", True) def reflect_to_children(treeitem): if not treeitem.get_status("VALID"): @@ -632,7 +654,6 @@ class Will: class WillItem(Logger): - STATUS_DEFAULT = { "ANTICIPATED": ["Anticipated", False], "BROADCASTED": ["Broadcasted", False], @@ -654,15 +675,15 @@ class WillItem(Logger): } def set_status(self, status, value=True): - #_logger.trace( + # _logger.trace( # "set status {} - {} {} -> {}".format( # self._id, status, self.STATUS[status][1], value # ) - #) + # ) if self.STATUS[status][1] == bool(value): return None - self.status += "." + ("NOT " if not value else "" + _(self.STATUS[status][0])) + self.status += "." + (("NOT " if not value else "") + _(self.STATUS[status][0])) self.STATUS[status][1] = bool(value) if value: if status in ["INVALIDATED", "REPLACED", "CONFIRMED", "PENDING"]: @@ -867,3 +888,7 @@ class PercAmountException(AmountException): class FixedAmountException(AmountException): pass + + +def test_check_invalidated(): + Will.check_invalidated(will, utxos_list, wallet) diff --git a/willexecutors.py b/willexecutors.py index 3a3686b..d567aaf 100644 --- a/willexecutors.py +++ b/willexecutors.py @@ -35,14 +35,16 @@ class Willexecutors: continue Willexecutors.initialize_willexecutor(willexecutors[w], w) for w in to_del: - _logger.error("error Willexecutor to delete type:{} ", type(willexecutor[w]),w) + _logger.error( + "error Willexecutor to delete type:{} ", type(willexecutor[w]), w + ) del willexecutors[w] bal = bal_plugin.WILLEXECUTORS.default.get(constants.net.NET_NAME, {}) for bal_url, bal_executor in bal.items(): if not bal_url in willexecutors: _logger.debug(f"force add {bal_url} willexecutor") willexecutors[bal_url] = bal_executor - #if update: + # if update: # found = False # for url, we in willexecutors.items(): # if Willexecutors.is_selected(we): @@ -119,7 +121,7 @@ class Willexecutors: def send_request(method, url, data=None, *, timeout=10): network = Network.get_instance() if not network: - raise ErrorConnectingServer("You are offline.") + raise Exception("You are offline.") _logger.debug(f"<-- {method} {url} {data}") headers = {} headers["user-agent"] = f"BalPlugin v:{BalPlugin.version()}" @@ -170,8 +172,7 @@ class Willexecutors: def push_transactions_to_willexecutor(willexecutor): out = True try: - - _logger.debug(f"willexecutor['txs']") + _logger.debug(f"{willexecutor['url']}: {willexecutor['txs']}") if w := Willexecutors.send_request( "post", willexecutor["url"] + "/" + constants.net.NET_NAME + "/pushtxs",