coin_chooser: make BIP69_sort optional
This commit is contained in:
@@ -225,14 +225,17 @@ class CoinChooserBase(Logger):
|
||||
c.is_change = True
|
||||
return change
|
||||
|
||||
def _construct_tx_from_selected_buckets(self, *, buckets: Sequence[Bucket],
|
||||
base_tx: PartialTransaction, change_addrs,
|
||||
fee_estimator_w, dust_threshold,
|
||||
base_weight) -> Tuple[PartialTransaction, List[PartialTxOutput]]:
|
||||
def _construct_tx_from_selected_buckets(
|
||||
self, *, buckets: Sequence[Bucket],
|
||||
base_tx: PartialTransaction, change_addrs,
|
||||
fee_estimator_w, dust_threshold,
|
||||
base_weight,
|
||||
BIP69_sort: bool,
|
||||
) -> Tuple[PartialTransaction, List[PartialTxOutput]]:
|
||||
# make a copy of base_tx so it won't get mutated
|
||||
tx = PartialTransaction.from_io(base_tx.inputs()[:], base_tx.outputs()[:])
|
||||
tx = PartialTransaction.from_io(base_tx.inputs()[:], base_tx.outputs()[:], BIP69_sort=BIP69_sort)
|
||||
|
||||
tx.add_inputs([coin for b in buckets for coin in b.coins])
|
||||
tx.add_inputs([coin for b in buckets for coin in b.coins], BIP69_sort=BIP69_sort)
|
||||
tx_weight = self._get_tx_weight(buckets, base_weight=base_weight)
|
||||
|
||||
# change is sent back to sending address unless specified
|
||||
@@ -246,7 +249,7 @@ class CoinChooserBase(Logger):
|
||||
output_weight = 4 * Transaction.estimated_output_size_for_address(change_addrs[0])
|
||||
fee_estimator_numchange = lambda count: fee_estimator_w(tx_weight + count * output_weight)
|
||||
change = self._change_outputs(tx, change_addrs, fee_estimator_numchange, dust_threshold)
|
||||
tx.add_outputs(change)
|
||||
tx.add_outputs(change, BIP69_sort=BIP69_sort)
|
||||
|
||||
return tx, change
|
||||
|
||||
@@ -270,9 +273,16 @@ class CoinChooserBase(Logger):
|
||||
|
||||
return total_weight
|
||||
|
||||
def make_tx(self, *, coins: Sequence[PartialTxInput], inputs: List[PartialTxInput],
|
||||
outputs: List[PartialTxOutput], change_addrs: Sequence[str],
|
||||
fee_estimator_vb: Callable, dust_threshold: int) -> PartialTransaction:
|
||||
def make_tx(
|
||||
self, *,
|
||||
coins: Sequence[PartialTxInput],
|
||||
inputs: List[PartialTxInput],
|
||||
outputs: List[PartialTxOutput],
|
||||
change_addrs: Sequence[str],
|
||||
fee_estimator_vb: Callable,
|
||||
dust_threshold: int,
|
||||
BIP69_sort: bool = True,
|
||||
) -> PartialTransaction:
|
||||
"""Select unspent coins to spend to pay outputs. If the change is
|
||||
greater than dust_threshold (after adding the change output to
|
||||
the transaction) it is kept, otherwise none is sent and it is
|
||||
@@ -289,7 +299,7 @@ class CoinChooserBase(Logger):
|
||||
self.p = PRNG(b''.join(sorted(utxos)))
|
||||
|
||||
# Copy the outputs so when adding change we don't modify "outputs"
|
||||
base_tx = PartialTransaction.from_io(inputs[:], outputs[:])
|
||||
base_tx = PartialTransaction.from_io(inputs[:], outputs[:], BIP69_sort=BIP69_sort)
|
||||
input_value = base_tx.input_value()
|
||||
|
||||
# Weight of the transaction with no inputs and no change
|
||||
@@ -320,13 +330,15 @@ class CoinChooserBase(Logger):
|
||||
return total_input >= spent_amount + fee_estimator_w(total_weight)
|
||||
|
||||
def tx_from_buckets(buckets):
|
||||
return self._construct_tx_from_selected_buckets(buckets=buckets,
|
||||
base_tx=base_tx,
|
||||
change_addrs=change_addrs,
|
||||
fee_estimator_w=fee_estimator_w,
|
||||
dust_threshold=dust_threshold,
|
||||
base_weight=base_weight)
|
||||
|
||||
return self._construct_tx_from_selected_buckets(
|
||||
buckets=buckets,
|
||||
base_tx=base_tx,
|
||||
change_addrs=change_addrs,
|
||||
fee_estimator_w=fee_estimator_w,
|
||||
dust_threshold=dust_threshold,
|
||||
base_weight=base_weight,
|
||||
BIP69_sort=BIP69_sort,
|
||||
)
|
||||
# Collect the coins into buckets
|
||||
all_buckets = self.bucketize_coins(coins, fee_estimator_vb=fee_estimator_vb)
|
||||
# Filter some buckets out. Only keep those that have positive effective value.
|
||||
|
||||
@@ -2161,16 +2161,18 @@ class PartialTransaction(Transaction):
|
||||
def outputs(self) -> Sequence[PartialTxOutput]:
|
||||
return self._outputs
|
||||
|
||||
def add_inputs(self, inputs: List[PartialTxInput]) -> None:
|
||||
def add_inputs(self, inputs: List[PartialTxInput], BIP69_sort=True) -> None:
|
||||
self._inputs.extend(inputs)
|
||||
self.BIP69_sort(outputs=False)
|
||||
if BIP69_sort:
|
||||
self.BIP69_sort(outputs=False)
|
||||
self.invalidate_ser_cache()
|
||||
|
||||
def add_outputs(self, outputs: List[PartialTxOutput], *, merge_duplicates: bool = False) -> None:
|
||||
def add_outputs(self, outputs: List[PartialTxOutput], *, merge_duplicates: bool = False, BIP69_sort: bool = True) -> None:
|
||||
self._outputs.extend(outputs)
|
||||
if merge_duplicates:
|
||||
self._outputs = merge_duplicate_tx_outputs(self._outputs)
|
||||
self.BIP69_sort(inputs=False)
|
||||
if BIP69_sort:
|
||||
self.BIP69_sort(inputs=False)
|
||||
self.invalidate_ser_cache()
|
||||
|
||||
def set_rbf(self, rbf: bool) -> None:
|
||||
|
||||
Reference in New Issue
Block a user