change logic so it doesn't fail when the inputs aren't ordered
@@ -329,7 +329,7 @@ impl<'a> ClientMessageBuilder<'a> {
// We store output responses locally in outputs and dust_allowance_outputs and after each output we sort
// them and try to get enough inputs for the transaction, so we don't request more
// outputs than we need
- for output_id in address_outputs.iter() {
+ for (output_index, output_id) in address_outputs.iter().enumerate() {
let output = self.client.get_output(output_id).await?;
if !output.is_spent {
let (amount, _, _) = ClientMessageBuilder::get_output_amount_and_address(&output.output)?;
@@ -349,14 +349,26 @@ impl<'a> ClientMessageBuilder<'a> {
// Order outputs descending, so that as few inputs as necessary are used
outputs.sort_by(|l, r| r.amount.cmp(&l.amount));
+ // We only need dust_allowance_outputs in the last iterator
+ if output_index != address_outputs.len() {
dust_allowance_outputs.sort_by(|l, r| r.amount.cmp(&l.amount));
+ }
// We start using the signature locked outputs, so we don't move dust_allowance_outputs first
// which could result in a unconfirmable transaction if we still have
// dust on that address
- for (_offset, output_wrapper) in outputs
+ let mut iterator = outputs.clone();
+ // We only need dust_allowance_outputs in the last iterator, because otherwise we could use
+ // a dust allowance output as input while still having dust on the address
+ if output_index != address_outputs.len() {
+ iterator = iterator
+ .into_iter()
+ .chain(dust_allowance_outputs.clone().into_iter())
+ .collect();
+ }
+
+ for (_offset, output_wrapper) in iterator
.iter()
- .chain(dust_allowance_outputs.iter())
// Max inputs is 127
.take(INPUT_OUTPUT_COUNT_MAX)
.enumerate()
