transaction: for witness v0 txins, put both UTXO and WIT_UTXO in psbt
Until now we have been only putting PSBT_IN_NON_WITNESS_UTXO (="UTXO", full tx) in segwit witness v0 txins, as signers wanted the full tx anyway due to bip-143 sighash issue [0], and as WITNESS_UTXO can be calculated from UTXO. My reading of bip-174 is that either behaviour is correct, but achow101 said bip-174 expects PSBT_IN_WITNESS_UTXO for segwit inputs. Regardless, including both fields does not increase the tx size too much (UTXO can be very large ofc but we were already including that, WIT_UTXO is small). This also might increase compatibility with some other software - I've found some issues where this might have been the culprit [1][2][3]. closes https://github.com/spesmilo/electrum/issues/8039 related: [0] https://github.com/spesmilo/electrum/pull/6198 [1] https://github.com/cryptoadvance/specter-desktop/issues/868 [2] https://github.com/cryptoadvance/specter-desktop/issues/1046 [3] https://github.com/cryptoadvance/specter-desktop/issues/1544
This commit is contained in:
@@ -36,6 +36,8 @@ class SequentialTestCase(unittest.TestCase):
|
||||
class ElectrumTestCase(SequentialTestCase):
|
||||
"""Base class for our unit tests."""
|
||||
|
||||
# maxDiff = None
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.asyncio_loop, self._stop_loop, self._loop_thread = util.create_and_start_event_loop()
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1250,7 +1250,6 @@ class PartialTxInput(TxInput, PSBTSection):
|
||||
return
|
||||
self._utxo = tx
|
||||
self.validate_data()
|
||||
self.ensure_there_is_only_one_utxo()
|
||||
|
||||
@property
|
||||
def witness_utxo(self):
|
||||
@@ -1260,7 +1259,6 @@ class PartialTxInput(TxInput, PSBTSection):
|
||||
def witness_utxo(self, value: Optional[TxOutput]):
|
||||
self._witness_utxo = value
|
||||
self.validate_data()
|
||||
self.ensure_there_is_only_one_utxo()
|
||||
|
||||
def to_json(self):
|
||||
d = super().to_json()
|
||||
@@ -1387,7 +1385,6 @@ class PartialTxInput(TxInput, PSBTSection):
|
||||
self._unknown[full_key] = val
|
||||
|
||||
def serialize_psbt_section_kvs(self, wr):
|
||||
self.ensure_there_is_only_one_utxo()
|
||||
if self.witness_utxo:
|
||||
wr(PSBTInputType.WITNESS_UTXO, self.witness_utxo.serialize_to_network())
|
||||
if self.utxo:
|
||||
@@ -1515,16 +1512,10 @@ class PartialTxInput(TxInput, PSBTSection):
|
||||
if other_txin.witness_script is not None:
|
||||
self.witness_script = other_txin.witness_script
|
||||
self._unknown.update(other_txin._unknown)
|
||||
self.ensure_there_is_only_one_utxo()
|
||||
self.validate_data()
|
||||
# try to finalize now
|
||||
self.finalize()
|
||||
|
||||
def ensure_there_is_only_one_utxo(self):
|
||||
# we prefer having the full previous tx, even for segwit inputs. see #6198
|
||||
# for witness v1, witness_utxo will be enough though
|
||||
if self.utxo is not None and self.witness_utxo is not None:
|
||||
self.witness_utxo = None
|
||||
|
||||
def convert_utxo_to_witness_utxo(self) -> None:
|
||||
if self.utxo:
|
||||
self._witness_utxo = self.utxo.outputs()[self.prevout.out_idx]
|
||||
|
||||
@@ -2130,9 +2130,12 @@ class Abstract_Wallet(ABC, Logger, EventListener):
|
||||
address: str = None,
|
||||
ignore_network_issues: bool = True,
|
||||
) -> None:
|
||||
# We prefer to include UTXO (full tx) for every input.
|
||||
# We cannot include UTXO if the prev tx is not signed yet though (chain of unsigned txs),
|
||||
# in which case we might include a WITNESS_UTXO.
|
||||
# - We prefer to include UTXO (full tx), even for segwit inputs (see #6198).
|
||||
# - For witness v0 inputs, we include *both* UTXO and WITNESS_UTXO. UTXO is a strict superset,
|
||||
# so this is redundant, but it is (implied to be) "expected" from bip-0174 (see #8039).
|
||||
# Regardless, this might improve compatibility with some other software.
|
||||
# - For witness v1, witness_utxo will be enough though (bip-0341 sighash fixes known prior issues).
|
||||
# - We cannot include UTXO if the prev tx is not signed yet (chain of unsigned txs).
|
||||
address = address or txin.address
|
||||
if txin.witness_utxo is None and txin.is_segwit() and address:
|
||||
received, spent = self.adb.get_addr_io(address)
|
||||
@@ -2142,7 +2145,6 @@ class Abstract_Wallet(ABC, Logger, EventListener):
|
||||
txin.witness_utxo = TxOutput.from_address_and_value(address, txin_value)
|
||||
if txin.utxo is None:
|
||||
txin.utxo = self.get_input_tx(txin.prevout.txid.hex(), ignore_network_issues=ignore_network_issues)
|
||||
txin.ensure_there_is_only_one_utxo()
|
||||
|
||||
def _learn_derivation_path_for_address_from_txinout(self, txinout: Union[PartialTxInput, PartialTxOutput],
|
||||
address: str) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user