MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / SelectCoins

Function SelectCoins

src/wallet/spend.cpp:810–866  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

808}
809
810util::Result<SelectionResult> SelectCoins(const CWallet& wallet, CoinsResult& available_coins, const CoinsResult& pre_set_inputs,
811 const CAmount& nTargetValue, const CCoinControl& coin_control,
812 const CoinSelectionParams& coin_selection_params)
813{
814 // Deduct preset inputs amount from the search target
815 CAmount selection_target = nTargetValue - pre_set_inputs.GetAppropriateTotal(coin_selection_params.m_subtract_fee_outputs).value_or(0);
816
817 // Return if automatic coin selection is disabled, and we don't cover the selection target
818 if (!coin_control.m_allow_other_inputs && selection_target > 0) {
819 return util::Error{_("The preselected coins total amount does not cover the transaction target. "
820 "Please allow other inputs to be automatically selected or include more coins manually")};
821 }
822
823 OutputSet preset_coin_set;
824 for (const auto& output: pre_set_inputs.All()) {
825 preset_coin_set.insert(std::make_shared<COutput>(output));
826 }
827
828 // Return if we can cover the target only with the preset inputs
829 if (selection_target <= 0) {
830 SelectionResult result(nTargetValue, SelectionAlgorithm::MANUAL);
831 result.AddInputs(preset_coin_set, coin_selection_params.m_subtract_fee_outputs);
832 result.RecalculateWaste(coin_selection_params.min_viable_change, coin_selection_params.m_cost_of_change, coin_selection_params.m_change_fee);
833 return result;
834 }
835
836 // Return early if we cannot cover the target with the wallet's UTXO.
837 // We use the total effective value if we are not subtracting fee from outputs and 'available_coins' contains the data.
838 CAmount available_coins_total_amount = available_coins.GetAppropriateTotal(coin_selection_params.m_subtract_fee_outputs).value_or(0);
839 if (selection_target > available_coins_total_amount) {
840 return util::Error(); // Insufficient funds
841 }
842
843 // Start wallet Coin Selection procedure
844 auto op_selection_result = AutomaticCoinSelection(wallet, available_coins, selection_target, coin_selection_params);
845 if (!op_selection_result) return op_selection_result;
846
847 // If needed, add preset inputs to the automatic coin selection result
848 if (!pre_set_inputs.coins.empty()) {
849 auto preset_total = pre_set_inputs.GetAppropriateTotal(coin_selection_params.m_subtract_fee_outputs);
850 assert(preset_total.has_value());
851 SelectionResult preselected(preset_total.value(), SelectionAlgorithm::MANUAL);
852 preselected.AddInputs(preset_coin_set, coin_selection_params.m_subtract_fee_outputs);
853 op_selection_result->Merge(preselected);
854 op_selection_result->RecalculateWaste(coin_selection_params.min_viable_change,
855 coin_selection_params.m_cost_of_change,
856 coin_selection_params.m_change_fee);
857
858 // Verify we haven't exceeded the maximum allowed weight
859 int max_inputs_weight = coin_selection_params.m_max_tx_weight.value_or(MAX_STANDARD_TX_WEIGHT) - (coin_selection_params.tx_noinputs_size * WITNESS_SCALE_FACTOR);
860 if (op_selection_result->GetWeight() > max_inputs_weight) {
861 return util::Error{_("The combination of the pre-selected inputs and the wallet automatic inputs selection exceeds the transaction maximum weight. "
862 "Please try sending a smaller amount or manually consolidating your wallet's UTXOs")};
863 }
864 }
865 return op_selection_result;
866}
867

Callers 3

spend.cppFile · 0.85
BOOST_AUTO_TEST_CASEFunction · 0.85
select_coinsFunction · 0.85

Calls 14

_Function · 0.85
ErrorClass · 0.85
AutomaticCoinSelectionFunction · 0.85
GetAppropriateTotalMethod · 0.80
AllMethod · 0.80
AddInputsMethod · 0.80
RecalculateWasteMethod · 0.80
GetWeightMethod · 0.80
value_orMethod · 0.45
insertMethod · 0.45
emptyMethod · 0.45
has_valueMethod · 0.45

Tested by 2

BOOST_AUTO_TEST_CASEFunction · 0.68
select_coinsFunction · 0.68