mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-08-23 17:47:31 +00:00
wallet: only select mature coins by default
this is a regression from #5721 Removed the `TxInput.is_coinbase` method as I think it is a confusing API, instead we now have `TxInput.is_coinbase_input` and `TxInput.is_coinbase_output`. related #5872
This commit is contained in:
parent
6709ec4117
commit
d2f132738a
10 changed files with 36 additions and 24 deletions
|
@ -194,7 +194,7 @@ class AddressSynchronizer(Logger):
|
||||||
conflicting_txns = set()
|
conflicting_txns = set()
|
||||||
with self.transaction_lock:
|
with self.transaction_lock:
|
||||||
for txin in tx.inputs():
|
for txin in tx.inputs():
|
||||||
if txin.is_coinbase():
|
if txin.is_coinbase_input():
|
||||||
continue
|
continue
|
||||||
prevout_hash = txin.prevout.txid.hex()
|
prevout_hash = txin.prevout.txid.hex()
|
||||||
prevout_n = txin.prevout.out_idx
|
prevout_n = txin.prevout.out_idx
|
||||||
|
@ -228,7 +228,7 @@ class AddressSynchronizer(Logger):
|
||||||
# BUT we track is_mine inputs in a txn, and during subsequent calls
|
# BUT we track is_mine inputs in a txn, and during subsequent calls
|
||||||
# of add_transaction tx, we might learn of more-and-more inputs of
|
# of add_transaction tx, we might learn of more-and-more inputs of
|
||||||
# being is_mine, as we roll the gap_limit forward
|
# being is_mine, as we roll the gap_limit forward
|
||||||
is_coinbase = tx.inputs()[0].is_coinbase()
|
is_coinbase = tx.inputs()[0].is_coinbase_input()
|
||||||
tx_height = self.get_tx_height(tx_hash).height
|
tx_height = self.get_tx_height(tx_hash).height
|
||||||
if not allow_unrelated:
|
if not allow_unrelated:
|
||||||
# note that during sync, if the transactions are not properly sorted,
|
# note that during sync, if the transactions are not properly sorted,
|
||||||
|
@ -279,7 +279,7 @@ class AddressSynchronizer(Logger):
|
||||||
self._get_addr_balance_cache.pop(addr, None) # invalidate cache
|
self._get_addr_balance_cache.pop(addr, None) # invalidate cache
|
||||||
return
|
return
|
||||||
for txi in tx.inputs():
|
for txi in tx.inputs():
|
||||||
if txi.is_coinbase():
|
if txi.is_coinbase_input():
|
||||||
continue
|
continue
|
||||||
prevout_hash = txi.prevout.txid.hex()
|
prevout_hash = txi.prevout.txid.hex()
|
||||||
prevout_n = txi.prevout.out_idx
|
prevout_n = txi.prevout.out_idx
|
||||||
|
@ -314,7 +314,7 @@ class AddressSynchronizer(Logger):
|
||||||
if tx is not None:
|
if tx is not None:
|
||||||
# if we have the tx, this branch is faster
|
# if we have the tx, this branch is faster
|
||||||
for txin in tx.inputs():
|
for txin in tx.inputs():
|
||||||
if txin.is_coinbase():
|
if txin.is_coinbase_input():
|
||||||
continue
|
continue
|
||||||
prevout_hash = txin.prevout.txid.hex()
|
prevout_hash = txin.prevout.txid.hex()
|
||||||
prevout_n = txin.prevout.out_idx
|
prevout_n = txin.prevout.out_idx
|
||||||
|
@ -758,7 +758,8 @@ class AddressSynchronizer(Logger):
|
||||||
for prevout_str, v in coins.items():
|
for prevout_str, v in coins.items():
|
||||||
tx_height, value, is_cb = v
|
tx_height, value, is_cb = v
|
||||||
prevout = TxOutpoint.from_str(prevout_str)
|
prevout = TxOutpoint.from_str(prevout_str)
|
||||||
utxo = PartialTxInput(prevout=prevout)
|
utxo = PartialTxInput(prevout=prevout,
|
||||||
|
is_coinbase_output=is_cb)
|
||||||
utxo._trusted_address = address
|
utxo._trusted_address = address
|
||||||
utxo._trusted_value_sats = value
|
utxo._trusted_value_sats = value
|
||||||
utxo.block_height = tx_height
|
utxo.block_height = tx_height
|
||||||
|
@ -825,7 +826,7 @@ class AddressSynchronizer(Logger):
|
||||||
continue
|
continue
|
||||||
if nonlocal_only and utxo.block_height == TX_HEIGHT_LOCAL:
|
if nonlocal_only and utxo.block_height == TX_HEIGHT_LOCAL:
|
||||||
continue
|
continue
|
||||||
if (mature_only and utxo.prevout.is_coinbase()
|
if (mature_only and utxo.is_coinbase_output()
|
||||||
and utxo.block_height + COINBASE_MATURITY > mempool_height):
|
and utxo.block_height + COINBASE_MATURITY > mempool_height):
|
||||||
continue
|
continue
|
||||||
coins.append(utxo)
|
coins.append(utxo)
|
||||||
|
|
|
@ -480,7 +480,7 @@ class BaseTxDialog(QDialog, MessageBoxMixin):
|
||||||
i_text.setReadOnly(True)
|
i_text.setReadOnly(True)
|
||||||
cursor = i_text.textCursor()
|
cursor = i_text.textCursor()
|
||||||
for txin in self.tx.inputs():
|
for txin in self.tx.inputs():
|
||||||
if txin.is_coinbase():
|
if txin.is_coinbase_input():
|
||||||
cursor.insertText('coinbase')
|
cursor.insertText('coinbase')
|
||||||
else:
|
else:
|
||||||
prevout_hash = txin.prevout.txid.hex()
|
prevout_hash = txin.prevout.txid.hex()
|
||||||
|
|
|
@ -424,7 +424,7 @@ class JsonDB(Logger):
|
||||||
for txid, raw_tx in transactions.items():
|
for txid, raw_tx in transactions.items():
|
||||||
tx = Transaction(raw_tx)
|
tx = Transaction(raw_tx)
|
||||||
for txin in tx.inputs():
|
for txin in tx.inputs():
|
||||||
if txin.is_coinbase():
|
if txin.is_coinbase_input():
|
||||||
continue
|
continue
|
||||||
prevout_hash = txin.prevout.txid.hex()
|
prevout_hash = txin.prevout.txid.hex()
|
||||||
prevout_n = txin.prevout.out_idx
|
prevout_n = txin.prevout.out_idx
|
||||||
|
|
|
@ -539,7 +539,7 @@ class DigitalBitbox_KeyStore(Hardware_KeyStore):
|
||||||
|
|
||||||
# Build hasharray from inputs
|
# Build hasharray from inputs
|
||||||
for i, txin in enumerate(tx.inputs()):
|
for i, txin in enumerate(tx.inputs()):
|
||||||
if txin.is_coinbase():
|
if txin.is_coinbase_input():
|
||||||
self.give_error("Coinbase not supported") # should never happen
|
self.give_error("Coinbase not supported") # should never happen
|
||||||
|
|
||||||
if txin.script_type != 'p2pkh':
|
if txin.script_type != 'p2pkh':
|
||||||
|
|
|
@ -364,7 +364,7 @@ class KeepKeyPlugin(HW_PluginBase):
|
||||||
inputs = []
|
inputs = []
|
||||||
for txin in tx.inputs():
|
for txin in tx.inputs():
|
||||||
txinputtype = self.types.TxInputType()
|
txinputtype = self.types.TxInputType()
|
||||||
if txin.is_coinbase():
|
if txin.is_coinbase_input():
|
||||||
prev_hash = b"\x00"*32
|
prev_hash = b"\x00"*32
|
||||||
prev_index = 0xffffffff # signed int -1
|
prev_index = 0xffffffff # signed int -1
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -330,7 +330,7 @@ class Ledger_KeyStore(Hardware_KeyStore):
|
||||||
|
|
||||||
# Fetch inputs of the transaction to sign
|
# Fetch inputs of the transaction to sign
|
||||||
for txin in tx.inputs():
|
for txin in tx.inputs():
|
||||||
if txin.is_coinbase():
|
if txin.is_coinbase_input():
|
||||||
self.give_error("Coinbase not supported") # should never happen
|
self.give_error("Coinbase not supported") # should never happen
|
||||||
|
|
||||||
if txin.script_type in ['p2sh']:
|
if txin.script_type in ['p2sh']:
|
||||||
|
|
|
@ -338,7 +338,7 @@ class SafeTPlugin(HW_PluginBase):
|
||||||
inputs = []
|
inputs = []
|
||||||
for txin in tx.inputs():
|
for txin in tx.inputs():
|
||||||
txinputtype = self.types.TxInputType()
|
txinputtype = self.types.TxInputType()
|
||||||
if txin.is_coinbase():
|
if txin.is_coinbase_input():
|
||||||
prev_hash = b"\x00"*32
|
prev_hash = b"\x00"*32
|
||||||
prev_index = 0xffffffff # signed int -1
|
prev_index = 0xffffffff # signed int -1
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -361,7 +361,7 @@ class TrezorPlugin(HW_PluginBase):
|
||||||
inputs = []
|
inputs = []
|
||||||
for txin in tx.inputs():
|
for txin in tx.inputs():
|
||||||
txinputtype = TxInputType()
|
txinputtype = TxInputType()
|
||||||
if txin.is_coinbase():
|
if txin.is_coinbase_input():
|
||||||
prev_hash = b"\x00"*32
|
prev_hash = b"\x00"*32
|
||||||
prev_index = 0xffffffff # signed int -1
|
prev_index = 0xffffffff # signed int -1
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -38,7 +38,7 @@ def serialize_tx_in_legacy_format(tx: PartialTransaction, *, wallet: Multisig_Wa
|
||||||
tx = copy.deepcopy(tx)
|
tx = copy.deepcopy(tx)
|
||||||
|
|
||||||
def get_siglist(txin: 'PartialTxInput', *, estimate_size=False):
|
def get_siglist(txin: 'PartialTxInput', *, estimate_size=False):
|
||||||
if txin.prevout.is_coinbase():
|
if txin.is_coinbase_input():
|
||||||
return [], []
|
return [], []
|
||||||
if estimate_size:
|
if estimate_size:
|
||||||
try:
|
try:
|
||||||
|
@ -80,7 +80,7 @@ def serialize_tx_in_legacy_format(tx: PartialTransaction, *, wallet: Multisig_Wa
|
||||||
assert estimate_size is False
|
assert estimate_size is False
|
||||||
if txin.witness is not None:
|
if txin.witness is not None:
|
||||||
return txin.witness.hex()
|
return txin.witness.hex()
|
||||||
if txin.prevout.is_coinbase():
|
if txin.is_coinbase_input():
|
||||||
return ''
|
return ''
|
||||||
assert isinstance(txin, PartialTxInput)
|
assert isinstance(txin, PartialTxInput)
|
||||||
if not self.is_segwit_input(txin):
|
if not self.is_segwit_input(txin):
|
||||||
|
|
|
@ -192,20 +192,30 @@ class TxInput:
|
||||||
script_sig: Optional[bytes]
|
script_sig: Optional[bytes]
|
||||||
nsequence: int
|
nsequence: int
|
||||||
witness: Optional[bytes]
|
witness: Optional[bytes]
|
||||||
|
_is_coinbase_output: bool
|
||||||
|
|
||||||
def __init__(self, *,
|
def __init__(self, *,
|
||||||
prevout: TxOutpoint,
|
prevout: TxOutpoint,
|
||||||
script_sig: bytes = None,
|
script_sig: bytes = None,
|
||||||
nsequence: int = 0xffffffff - 1,
|
nsequence: int = 0xffffffff - 1,
|
||||||
witness: bytes = None):
|
witness: bytes = None,
|
||||||
|
is_coinbase_output: bool = False):
|
||||||
self.prevout = prevout
|
self.prevout = prevout
|
||||||
self.script_sig = script_sig
|
self.script_sig = script_sig
|
||||||
self.nsequence = nsequence
|
self.nsequence = nsequence
|
||||||
self.witness = witness
|
self.witness = witness
|
||||||
|
self._is_coinbase_output = is_coinbase_output
|
||||||
|
|
||||||
def is_coinbase(self) -> bool:
|
def is_coinbase_input(self) -> bool:
|
||||||
|
"""Whether this is the input of a coinbase tx."""
|
||||||
return self.prevout.is_coinbase()
|
return self.prevout.is_coinbase()
|
||||||
|
|
||||||
|
def is_coinbase_output(self) -> bool:
|
||||||
|
"""Whether the coin being spent is an output of a coinbase tx.
|
||||||
|
This matters for coin maturity.
|
||||||
|
"""
|
||||||
|
return self._is_coinbase_output
|
||||||
|
|
||||||
def value_sats(self) -> Optional[int]:
|
def value_sats(self) -> Optional[int]:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -213,7 +223,7 @@ class TxInput:
|
||||||
d = {
|
d = {
|
||||||
'prevout_hash': self.prevout.txid.hex(),
|
'prevout_hash': self.prevout.txid.hex(),
|
||||||
'prevout_n': self.prevout.out_idx,
|
'prevout_n': self.prevout.out_idx,
|
||||||
'coinbase': self.is_coinbase(),
|
'coinbase': self.is_coinbase_output(),
|
||||||
'nsequence': self.nsequence,
|
'nsequence': self.nsequence,
|
||||||
}
|
}
|
||||||
if self.script_sig is not None:
|
if self.script_sig is not None:
|
||||||
|
@ -550,7 +560,7 @@ class Transaction:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_siglist(self, txin: 'PartialTxInput', *, estimate_size=False):
|
def get_siglist(self, txin: 'PartialTxInput', *, estimate_size=False):
|
||||||
if txin.prevout.is_coinbase():
|
if txin.is_coinbase_input():
|
||||||
return [], []
|
return [], []
|
||||||
|
|
||||||
if estimate_size:
|
if estimate_size:
|
||||||
|
@ -579,7 +589,7 @@ class Transaction:
|
||||||
def serialize_witness(cls, txin: TxInput, *, estimate_size=False) -> str:
|
def serialize_witness(cls, txin: TxInput, *, estimate_size=False) -> str:
|
||||||
if txin.witness is not None:
|
if txin.witness is not None:
|
||||||
return txin.witness.hex()
|
return txin.witness.hex()
|
||||||
if txin.prevout.is_coinbase():
|
if txin.is_coinbase_input():
|
||||||
return ''
|
return ''
|
||||||
assert isinstance(txin, PartialTxInput)
|
assert isinstance(txin, PartialTxInput)
|
||||||
|
|
||||||
|
@ -643,7 +653,7 @@ class Transaction:
|
||||||
def input_script(self, txin: TxInput, *, estimate_size=False) -> str:
|
def input_script(self, txin: TxInput, *, estimate_size=False) -> str:
|
||||||
if txin.script_sig is not None:
|
if txin.script_sig is not None:
|
||||||
return txin.script_sig.hex()
|
return txin.script_sig.hex()
|
||||||
if txin.prevout.is_coinbase():
|
if txin.is_coinbase_input():
|
||||||
return ''
|
return ''
|
||||||
assert isinstance(txin, PartialTxInput)
|
assert isinstance(txin, PartialTxInput)
|
||||||
|
|
||||||
|
@ -1090,7 +1100,8 @@ class PartialTxInput(TxInput, PSBTSection):
|
||||||
res = PartialTxInput(prevout=txin.prevout,
|
res = PartialTxInput(prevout=txin.prevout,
|
||||||
script_sig=None if strip_witness else txin.script_sig,
|
script_sig=None if strip_witness else txin.script_sig,
|
||||||
nsequence=txin.nsequence,
|
nsequence=txin.nsequence,
|
||||||
witness=None if strip_witness else txin.witness)
|
witness=None if strip_witness else txin.witness,
|
||||||
|
is_coinbase_output=txin.is_coinbase_output())
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def validate_data(self, *, for_signing=False) -> None:
|
def validate_data(self, *, for_signing=False) -> None:
|
||||||
|
@ -1243,7 +1254,7 @@ class PartialTxInput(TxInput, PSBTSection):
|
||||||
def is_complete(self) -> bool:
|
def is_complete(self) -> bool:
|
||||||
if self.script_sig is not None and self.witness is not None:
|
if self.script_sig is not None and self.witness is not None:
|
||||||
return True
|
return True
|
||||||
if self.prevout.is_coinbase():
|
if self.is_coinbase_input():
|
||||||
return True
|
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 Transaction.is_segwit_input(self):
|
||||||
return True
|
return True
|
||||||
|
@ -1750,7 +1761,7 @@ class PartialTransaction(Transaction):
|
||||||
s = 0 # "num Sigs we have"
|
s = 0 # "num Sigs we have"
|
||||||
r = 0 # "Required"
|
r = 0 # "Required"
|
||||||
for txin in self.inputs():
|
for txin in self.inputs():
|
||||||
if txin.prevout.is_coinbase():
|
if txin.is_coinbase_input():
|
||||||
continue
|
continue
|
||||||
signatures = list(txin.part_sigs.values())
|
signatures = list(txin.part_sigs.values())
|
||||||
s += len(signatures)
|
s += len(signatures)
|
||||||
|
|
Loading…
Add table
Reference in a new issue