From 1b834a7a7887af7f67952b7152928b62484a806b Mon Sep 17 00:00:00 2001 From: SomberNight Date: Thu, 14 Jun 2018 22:19:06 +0200 Subject: [PATCH] fix RBF --- gui/qt/main_window.py | 3 ++- lib/transaction.py | 13 +++++++------ lib/wallet.py | 2 ++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py index 201ebbc97..13ff3388e 100644 --- a/gui/qt/main_window.py +++ b/gui/qt/main_window.py @@ -3166,7 +3166,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): try: new_tx = self.wallet.bump_fee(tx, delta) except BaseException as e: - self.show_error(str(e)) + traceback.print_exc(file=sys.stderr) + self.show_error(_('Error bumping fee') + ':\n' + str(e)) return if is_final: new_tx.set_rbf(False) diff --git a/lib/transaction.py b/lib/transaction.py index f19baca09..56091acf9 100644 --- a/lib/transaction.py +++ b/lib/transaction.py @@ -495,7 +495,7 @@ def parse_witness(vds, txin, full_parse: bool): return try: - if txin['witness_version'] != 0: + if txin.get('witness_version', 0) != 0: raise UnknownTxinType() if txin['type'] == 'coinbase': pass @@ -545,7 +545,7 @@ def parse_output(vds, i): return d -def deserialize(raw: str) -> dict: +def deserialize(raw: str, force_full_parse=False) -> dict: raw_bytes = bfh(raw) d = {} if raw_bytes[:5] == PARTIAL_TXN_HEADER_MAGIC: @@ -557,6 +557,7 @@ def deserialize(raw: str) -> dict: raw_bytes = raw_bytes[6:] else: d['partial'] = is_partial = False + full_parse = force_full_parse or is_partial vds = BCDataStream() vds.write(raw_bytes) d['version'] = vds.read_int32() @@ -568,13 +569,13 @@ def deserialize(raw: str) -> dict: raise ValueError('invalid txn marker byte: {}'.format(marker)) n_vin = vds.read_compact_size() d['segwit_ser'] = is_segwit - d['inputs'] = [parse_input(vds, full_parse=is_partial) for i in range(n_vin)] + d['inputs'] = [parse_input(vds, full_parse=full_parse) for i in range(n_vin)] n_vout = vds.read_compact_size() d['outputs'] = [parse_output(vds, i) for i in range(n_vout)] if is_segwit: for i in range(n_vin): txin = d['inputs'][i] - parse_witness(vds, txin, full_parse=is_partial) + parse_witness(vds, txin, full_parse=full_parse) d['lockTime'] = vds.read_uint32() if vds.can_read_more(): raise SerializationError('extra junk at the end') @@ -696,13 +697,13 @@ class Transaction: txin['scriptSig'] = None # force re-serialization txin['witness'] = None # force re-serialization - def deserialize(self): + def deserialize(self, force_full_parse=False): if self.raw is None: return #self.raw = self.serialize() if self._inputs is not None: return - d = deserialize(self.raw) + d = deserialize(self.raw, force_full_parse) self._inputs = d['inputs'] self._outputs = [(x['type'], x['address'], x['value']) for x in d['outputs']] self.locktime = d['lockTime'] diff --git a/lib/wallet.py b/lib/wallet.py index d68af11ef..e0f968f7e 100644 --- a/lib/wallet.py +++ b/lib/wallet.py @@ -1378,6 +1378,8 @@ class Abstract_Wallet(PrintError): def bump_fee(self, tx, delta): if tx.is_final(): raise Exception(_('Cannot bump fee') + ': ' + _('transaction is final')) + tx = Transaction(tx.serialize()) + tx.deserialize(force_full_parse=True) # need to parse inputs inputs = copy.deepcopy(tx.inputs()) outputs = copy.deepcopy(tx.outputs()) for txin in inputs: