@@ -192,6 +192,26 @@ impl TransactionBuilder {
192192 }
193193 } ,
194194 CoinSelectionStrategyCIP2 :: RandomImprove => {
195+ fn add_random_input (
196+ s : & mut TransactionBuilder ,
197+ rng : & mut rand:: rngs:: ThreadRng ,
198+ available_inputs : & mut Vec < TransactionUnspentOutput > ,
199+ input_total : & Value ,
200+ output_total : & Value ,
201+ added : & Value ,
202+ needed : & Value
203+ ) -> Result < ( Value , Value , Value , Value , TransactionUnspentOutput ) , JsError > {
204+ let random_index = rng. gen_range ( 0 ..available_inputs. len ( ) ) ;
205+ let input = available_inputs. swap_remove ( random_index) ;
206+ // differing from CIP2, we include the needed fees in the targets instead of just output values
207+ let input_fee = s. fee_for_input ( & input. output . address , & input. input , & input. output . amount ) ?;
208+ s. add_input ( & input. output . address , & input. input , & input. output . amount ) ;
209+ let new_input_total = input_total. checked_add ( & input. output . amount ) ?;
210+ let new_output_total = output_total. checked_add ( & Value :: new ( & input_fee) ) ?;
211+ let new_needed = needed. checked_add ( & Value :: new ( & input_fee) ) ?;
212+ let new_added = added. checked_add ( & input. output . amount ) ?;
213+ Ok ( ( new_input_total, new_output_total, new_added, new_needed, input) )
214+ }
195215 use rand:: Rng ;
196216 if self . outputs . 0 . iter ( ) . any ( |output| output. amount . multiasset . is_some ( ) ) {
197217 return Err ( JsError :: from_str ( "Multiasset values not supported by RandomImprove. Please use LargestFirst" ) ) ;
@@ -208,15 +228,11 @@ impl TransactionBuilder {
208228 if available_inputs. is_empty ( ) {
209229 return Err ( JsError :: from_str ( "UTxO Balance Insufficient" ) ) ;
210230 }
211- let random_index = rng. gen_range ( 0 ..available_inputs. len ( ) ) ;
212- let input = available_inputs. swap_remove ( random_index) ;
213- // differing from CIP2, we include the needed fees in the targets instead of just output values
214- let input_fee = self . fee_for_input ( & input. output . address , & input. input , & input. output . amount ) ?;
215- self . add_input ( & input. output . address , & input. input , & input. output . amount ) ;
216- input_total = input_total. checked_add ( & input. output . amount ) ?;
217- output_total = output_total. checked_add ( & Value :: new ( & input_fee) ) ?;
218- needed = needed. checked_add ( & Value :: new ( & input_fee) ) ?;
219- added = added. checked_add ( & input. output . amount ) ?;
231+ let ( new_input_total, new_output_total, new_added, new_needed, input) = add_random_input ( self , & mut rng, & mut available_inputs, & input_total, & output_total, & added, & needed) ?;
232+ input_total = new_input_total;
233+ output_total = new_output_total;
234+ added = new_added;
235+ needed = new_needed;
220236 associated_inputs. entry ( output. clone ( ) ) . or_default ( ) . push ( input) ;
221237 }
222238 }
0 commit comments