SHOWING: First 60
#65,798,853text fn select_cardinal_utxo(
&mut self,
target_value: Amount,
prefer_under: bool,
) -> Result<(OutPoint, Amount)> {
tprintln!(
"looking for {} cardinal worth {target_value}",
if prefer_under { "smaller" } else { "bigger" }
);
let inscribed_utxos = self
.inscriptions
.keys()
.map(|satpoint| satpoint.outpoint)
.collect::<BTreeSet<OutPoint>>();
let mut best_match = None;
for utxo in &self.utxos {
if inscribed_utxos.contains(utxo) || self.locked_utxos.contains(utxo) {
continue;
}
let current_value = self.amounts[utxo];
let (_, best_value) = match best_match {
Some(prev) => prev,
None => {
best_match = Some((*utxo, current_value));
(*utxo, current_value)
}
};
let abs_diff = |a: Amount, b: Amount| -> Amount { max(a, b) - min(a, b) };
let is_closer = abs_diff(current_value, target_value) < abs_diff(best_value, target_value);
let not_preference_but_closer = if prefer_under {
#44,979,203text }
let expected_fee = self.fee_rate.fee(modified_tx.vsize());
assert_eq!(
actual_fee, expected_fee,
"invariant: fee estimation is correct",
);
for tx_out in &transaction.output {
assert!(
Amount::from_sat(tx_out.value) >= tx_out.script_pubkey.dust_value(),
"invariant: all outputs are above dust limit",
);
}
Ok(transaction)
}
fn calculate_sat_offset(&self) -> u64 {
let mut sat_offset = 0;
for outpoint in &self.inputs {
if *outpoint == self.outgoing.outpoint {
return sat_offset + self.outgoing.offset;
} else {
sat_offset += self.amounts[outpoint].to_sat();
}
}
panic!("Could not find outgoing sat in inputs");
}
/// Cardinal UTXOs are those that contain no inscriptions and can therefore
/// be used to pad transactions. Sometimes multiple of these UTXOs are needed
/// and depending on the context we want to select either ones above or
/// under (when trying to consolidate dust outputs) the target value.
#44,979,202text )
}
#[test]
fn excess_additional_postage_is_stripped() {
let utxos = vec![
(outpoint(1), Amount::from_sat(5_000)),
(outpoint(2), Amount::from_sat(25_000)),
];
pretty_assert_eq!(
TransactionBuilder::new(
satpoint(1, 4_950),
BTreeMap::new(),
utxos.into_iter().collect(),
BTreeSet::new(),
recipient(),
[change(0), change(1)],
FeeRate::try_from(1.0).unwrap(),
Target::Postage,
)
.build_transaction(),
Ok(Transaction {
version: 1,
lock_time: LockTime::ZERO,
input: vec![tx_in(outpoint(1)), tx_in(outpoint(2))],
output: vec![
tx_out(4_950, change(1)),
tx_out(TransactionBuilder::TARGET_POSTAGE.to_sat(), recipient()),
tx_out(14_831, change(0)),
],
})
)
}
#[test]
#[should_panic(expected = "invariant: outgoing sat is contained in utxos")]
fn invariant_satpoint_outpoint_is_contained_in_utxos() {
TransactionBuilder::new(
#44,979,199textdmt-mint.magic#44,751,043tapdmt-mint.magic#44,751,042tapdmt-mint.magic#44,751,041tapdmt-mint.magic#44,751,035tapdmt-mint.magic#44,751,034tapdmt-mint.magic#44,751,031tapdmt-mint.magic#44,751,030taptoken-mint1.tapart tapx 44226185#44,520,782tapdmt-mint.nat#44,347,641tapdmt-mint.nat#44,347,639tapdmt-mint.nat#44,347,637tapdmt-mint.nat#44,347,631tapdmt-mint.nat#44,347,628tapdmt-mint.nat#44,347,626tapdmt-mint.nat#44,347,622tapdmt-mint.nat#44,347,620tapdmt-mint.nat#44,347,618tapdmt-mint.nat#44,347,614tapdmt-mint.nat#44,347,610tapdmt-mint.nat#44,347,609tapdmt-mint.nat#44,347,606tapdmt-mint.nat#44,347,602tapdmt-mint.nat#44,347,600tapdmt-mint.nat#44,347,597tapdmt-mint.nat#44,347,590tapdmt-mint.nat#44,347,588tapdmt-mint.nat#44,347,587tapdmt-mint.nat#44,347,583tapdmt-mint.nat#44,347,575tapdmt-mint.nat#44,347,574tapdmt-mint.nat#44,347,569tapdmt-mint.nat#44,347,565tapdmt-mint.nat#44,347,564tapdmt-mint.nat#44,347,563tapdmt-mint.nat#44,347,554tapdmt-mint.nat#44,347,550tapdmt-mint.nat#44,347,542tapdmt-mint.nat#44,347,538tapdmt-mint.nat#44,347,535tapdmt-mint.nat#44,347,526tapdmt-mint.nat#44,347,525tapdmt-mint.nat#44,347,523tapdmt-mint.nat#44,347,521tap