The trait is currently defined as:
fn coin_select(
&self,
utxos: Vec<UTXO>,
use_all_utxos: bool,
fee_rate: FeeRate,
amount_needed: u64,
input_witness_weight: usize,
fee_amount: f32
) -> Result<CoinSelectionResult, Error>
The first thing I would add is a reference to the database, so that the algorithm can lookup additional details about the utxos, such as their age (see #120), if it needs to.
It would also make sense to give the algorithm two "input witness weights" for the two "external" and "internal" descriptors. We currently use the max of the two as a worst-case scenario, but that's inefficient. The UTXO struct already contains a field to tell whether a utxo is internal or not.
The use_all_utxos seems pretty dumb, in that case we are basically using the coin selection algorithm to compute the fee cost of using all the utxos. Also it's not particularly useful by itself, because in some cases (e.g. RBF) we don't want to use all of them but we also don't want to let the coin selection pick whatever utxos it wants. We could change this to a list of "mandatory utxos" to use, which in the case of use_all_utxos would just contain all the utxos, but in case of RBF it would contain the inputs that the transaction is already spending, an then the coin selection can select more inputs for the additional fees that need to be covered.
We could also consider the option of not giving a list of utxos at all and just letting the algorithm extract them from the database: that would definitely be useful on larger wallets where the list could become huge to maintain in memory, but it has the disadvantage that we would not be able to do filtering outside (like excluding internal/external utxos, blacklisting utxos, etc). I think that would be an interesting topic to research but I would leave that for a future more "performance-focused" upgrade.
Overall, for this initial update, I would try to make it look like:
fn coin_select<D: Database>(
&self,
database: &D,
utxos: Vec<UTXO>,
mandatory_utxos: Vec<UTXO>,
fee_rate: FeeRate,
amount_needed: u64,
input_witness_internal_weight: usize,
input_witness_external_weight: usize,
fee_amount: f32
) -> Result<CoinSelectionResult, Error>
The trait is currently defined as:
The first thing I would add is a reference to the database, so that the algorithm can lookup additional details about the utxos, such as their age (see #120), if it needs to.
It would also make sense to give the algorithm two "input witness weights" for the two "external" and "internal" descriptors. We currently use the max of the two as a worst-case scenario, but that's inefficient. The
UTXOstruct already contains a field to tell whether a utxo is internal or not.The
use_all_utxosseems pretty dumb, in that case we are basically using the coin selection algorithm to compute the fee cost of using all the utxos. Also it's not particularly useful by itself, because in some cases (e.g. RBF) we don't want to use all of them but we also don't want to let the coin selection pick whatever utxos it wants. We could change this to a list of "mandatory utxos" to use, which in the case ofuse_all_utxoswould just contain all the utxos, but in case of RBF it would contain the inputs that the transaction is already spending, an then the coin selection can select more inputs for the additional fees that need to be covered.We could also consider the option of not giving a list of utxos at all and just letting the algorithm extract them from the database: that would definitely be useful on larger wallets where the list could become huge to maintain in memory, but it has the disadvantage that we would not be able to do filtering outside (like excluding internal/external utxos, blacklisting utxos, etc). I think that would be an interesting topic to research but I would leave that for a future more "performance-focused" upgrade.
Overall, for this initial update, I would try to make it look like: