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