mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-08-27 15:31:31 +00:00
transaction: change Transaction.is_segwit_input(txin) to txin.is_segwit()
This commit is contained in:
parent
4c7a92f39c
commit
eefb68c82b
6 changed files with 32 additions and 30 deletions
|
@ -120,7 +120,7 @@ class CoinChooserBase(Logger):
|
|||
constant_fee = fee_estimator_vb(2000) == fee_estimator_vb(200)
|
||||
|
||||
def make_Bucket(desc: str, coins: List[PartialTxInput]):
|
||||
witness = any(Transaction.is_segwit_input(coin, guess_for_address=True) for coin in coins)
|
||||
witness = any(coin.is_segwit(guess_for_address=True) for coin in coins)
|
||||
# note that we're guessing whether the tx uses segwit based
|
||||
# on this single bucket
|
||||
weight = sum(Transaction.estimated_input_weight(coin, witness)
|
||||
|
|
|
@ -53,7 +53,7 @@ class KeepKey_KeyStore(Hardware_KeyStore):
|
|||
prev_tx = {}
|
||||
for txin in tx.inputs():
|
||||
tx_hash = txin.prevout.txid.hex()
|
||||
if txin.utxo is None and not Transaction.is_segwit_input(txin):
|
||||
if txin.utxo is None and not txin.is_segwit():
|
||||
raise UserFacingException(_('Missing previous tx for legacy input.'))
|
||||
prev_tx[tx_hash] = txin.utxo
|
||||
|
||||
|
|
|
@ -384,7 +384,7 @@ class Ledger_KeyStore(Hardware_KeyStore):
|
|||
|
||||
redeemScript = Transaction.get_preimage_script(txin)
|
||||
txin_prev_tx = txin.utxo
|
||||
if txin_prev_tx is None and not Transaction.is_segwit_input(txin):
|
||||
if txin_prev_tx is None and not txin.is_segwit():
|
||||
raise UserFacingException(_('Missing previous tx for legacy input.'))
|
||||
txin_prev_tx_raw = txin_prev_tx.serialize() if txin_prev_tx else None
|
||||
inputs.append([txin_prev_tx_raw,
|
||||
|
|
|
@ -51,7 +51,7 @@ class SafeTKeyStore(Hardware_KeyStore):
|
|||
prev_tx = {}
|
||||
for txin in tx.inputs():
|
||||
tx_hash = txin.prevout.txid.hex()
|
||||
if txin.utxo is None and not Transaction.is_segwit_input(txin):
|
||||
if txin.utxo is None and not txin.is_segwit():
|
||||
raise UserFacingException(_('Missing previous tx for legacy input.'))
|
||||
prev_tx[tx_hash] = txin.utxo
|
||||
|
||||
|
|
|
@ -243,6 +243,11 @@ class TxInput:
|
|||
n = vds.read_compact_size()
|
||||
return list(vds.read_bytes(vds.read_compact_size()) for i in range(n))
|
||||
|
||||
def is_segwit(self, *, guess_for_address=False) -> bool:
|
||||
if self.witness not in (b'\x00', b'', None):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class BCDataStream(object):
|
||||
"""Workalike python implementation of Bitcoin's CDataStream class."""
|
||||
|
@ -635,7 +640,7 @@ class Transaction:
|
|||
assert isinstance(txin, PartialTxInput)
|
||||
|
||||
_type = txin.script_type
|
||||
if not cls.is_segwit_input(txin):
|
||||
if not txin.is_segwit():
|
||||
return construct_witness([])
|
||||
|
||||
if _type in ('address', 'unknown') and estimate_size:
|
||||
|
@ -650,23 +655,6 @@ class Transaction:
|
|||
return construct_witness([])
|
||||
raise UnknownTxinType(f'cannot construct witness for txin_type: {_type}')
|
||||
|
||||
@classmethod
|
||||
def is_segwit_input(cls, txin: 'TxInput', *, guess_for_address=False) -> bool:
|
||||
if txin.witness not in (b'\x00', b'', None):
|
||||
return True
|
||||
if not isinstance(txin, PartialTxInput):
|
||||
return False
|
||||
if txin.is_native_segwit() or txin.is_p2sh_segwit():
|
||||
return True
|
||||
if txin.is_native_segwit() is False and txin.is_p2sh_segwit() is False:
|
||||
return False
|
||||
if txin.witness_script:
|
||||
return True
|
||||
_type = txin.script_type
|
||||
if _type == 'address' and guess_for_address:
|
||||
_type = cls.guess_txintype_from_address(txin.address)
|
||||
return is_segwit_script_type(_type)
|
||||
|
||||
@classmethod
|
||||
def guess_txintype_from_address(cls, addr: Optional[str]) -> str:
|
||||
# It's not possible to tell the script type in general
|
||||
|
@ -771,7 +759,7 @@ class Transaction:
|
|||
hashOutputs=hashOutputs)
|
||||
|
||||
def is_segwit(self, *, guess_for_address=False):
|
||||
return any(self.is_segwit_input(txin, guess_for_address=guess_for_address)
|
||||
return any(txin.is_segwit(guess_for_address=guess_for_address)
|
||||
for txin in self.inputs())
|
||||
|
||||
def invalidate_ser_cache(self):
|
||||
|
@ -829,7 +817,7 @@ class Transaction:
|
|||
def txid(self) -> Optional[str]:
|
||||
if self._cached_txid is None:
|
||||
self.deserialize()
|
||||
all_segwit = all(self.is_segwit_input(x) for x in self.inputs())
|
||||
all_segwit = all(txin.is_segwit() for txin in self.inputs())
|
||||
if not all_segwit and not self.is_complete():
|
||||
return None
|
||||
try:
|
||||
|
@ -873,7 +861,7 @@ class Transaction:
|
|||
script = cls.input_script(txin, estimate_size=True)
|
||||
input_size = len(cls.serialize_input(txin, script)) // 2
|
||||
|
||||
if cls.is_segwit_input(txin, guess_for_address=True):
|
||||
if txin.is_segwit(guess_for_address=True):
|
||||
witness_size = len(cls.serialize_witness(txin, estimate_size=True)) // 2
|
||||
else:
|
||||
witness_size = 1 if is_segwit_tx else 0
|
||||
|
@ -1200,7 +1188,7 @@ class PartialTxInput(TxInput, PSBTSection):
|
|||
# without verifying the input amount. This means, given a maliciously modified PSBT,
|
||||
# for non-segwit inputs, we might end up burning coins as miner fees.
|
||||
if for_signing and False:
|
||||
if not Transaction.is_segwit_input(self) and self.witness_utxo:
|
||||
if not self.is_segwit() and self.witness_utxo:
|
||||
raise PSBTInputConsistencyFailure(f"PSBT input validation: "
|
||||
f"If a witness UTXO is provided, no non-witness signature may be created")
|
||||
if self.redeem_script and self.address:
|
||||
|
@ -1340,7 +1328,7 @@ class PartialTxInput(TxInput, PSBTSection):
|
|||
return True
|
||||
if self.is_coinbase_input():
|
||||
return True
|
||||
if self.script_sig is not None and not Transaction.is_segwit_input(self):
|
||||
if self.script_sig is not None and not self.is_segwit():
|
||||
return True
|
||||
signatures = list(self.part_sigs.values())
|
||||
s = len(signatures)
|
||||
|
@ -1442,6 +1430,20 @@ class PartialTxInput(TxInput, PSBTSection):
|
|||
self._is_p2sh_segwit = calc_if_p2sh_segwit_now()
|
||||
return self._is_p2sh_segwit
|
||||
|
||||
def is_segwit(self, *, guess_for_address=False) -> bool:
|
||||
if super().is_segwit():
|
||||
return True
|
||||
if self.is_native_segwit() or self.is_p2sh_segwit():
|
||||
return True
|
||||
if self.is_native_segwit() is False and self.is_p2sh_segwit() is False:
|
||||
return False
|
||||
if self.witness_script:
|
||||
return True
|
||||
_type = self.script_type
|
||||
if _type == 'address' and guess_for_address:
|
||||
_type = Transaction.guess_txintype_from_address(self.address)
|
||||
return is_segwit_script_type(_type)
|
||||
|
||||
def already_has_some_signatures(self) -> bool:
|
||||
"""Returns whether progress has been made towards completing this input."""
|
||||
return (self.part_sigs
|
||||
|
@ -1790,7 +1792,7 @@ class PartialTransaction(Transaction):
|
|||
raise Exception("only SIGHASH_ALL signing is supported!")
|
||||
nHashType = int_to_hex(sighash, 4)
|
||||
preimage_script = self.get_preimage_script(txin)
|
||||
if self.is_segwit_input(txin):
|
||||
if txin.is_segwit():
|
||||
if bip143_shared_txdigest_fields is None:
|
||||
bip143_shared_txdigest_fields = self._calc_bip143_shared_txdigest_fields()
|
||||
hashPrevouts = bip143_shared_txdigest_fields.hashPrevouts
|
||||
|
|
|
@ -2162,7 +2162,7 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
|
|||
if all([txin.utxo for txin in tx.inputs()]):
|
||||
return None
|
||||
# a single segwit input -> fine
|
||||
if len(tx.inputs()) == 1 and Transaction.is_segwit_input(tx.inputs()[0]) and tx.inputs()[0].witness_utxo:
|
||||
if len(tx.inputs()) == 1 and tx.inputs()[0].is_segwit() and tx.inputs()[0].witness_utxo:
|
||||
return None
|
||||
# coinjoin or similar
|
||||
if any([not self.is_mine(txin.address) for txin in tx.inputs()]):
|
||||
|
@ -2170,7 +2170,7 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
|
|||
+ _("The input amounts could not be verified as the previous transactions are missing.\n"
|
||||
"The amount of money being spent CANNOT be verified."))
|
||||
# some inputs are legacy
|
||||
if any([not Transaction.is_segwit_input(txin) for txin in tx.inputs()]):
|
||||
if any([not txin.is_segwit() for txin in tx.inputs()]):
|
||||
return (_("Warning") + ": "
|
||||
+ _("The fee could not be verified. Signing non-segwit inputs is risky:\n"
|
||||
"if this transaction was maliciously modified before you sign,\n"
|
||||
|
|
Loading…
Add table
Reference in a new issue