Skip to content

Commit e1abfb5

Browse files
committed
wallet: Introduce and use PreselectedInput class in CCoinControl
Instead of having different maps for selected inputs, external inputs, and input weight in CCoinControl, have a class PreselectedInput which tracks stores that information for each input.
1 parent dce1dfb commit e1abfb5

File tree

2 files changed

+89
-32
lines changed

2 files changed

+89
-32
lines changed

src/wallet/coincontrol.cpp

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,69 +14,104 @@ CCoinControl::CCoinControl()
1414

1515
bool CCoinControl::HasSelected() const
1616
{
17-
return !m_selected_inputs.empty();
17+
return !m_selected.empty();
1818
}
1919

20-
bool CCoinControl::IsSelected(const COutPoint& output) const
20+
bool CCoinControl::IsSelected(const COutPoint& outpoint) const
2121
{
22-
return m_selected_inputs.count(output) > 0;
22+
return m_selected.count(outpoint) > 0;
2323
}
2424

25-
bool CCoinControl::IsExternalSelected(const COutPoint& output) const
25+
bool CCoinControl::IsExternalSelected(const COutPoint& outpoint) const
2626
{
27-
return m_external_txouts.count(output) > 0;
27+
const auto it = m_selected.find(outpoint);
28+
return it != m_selected.end() && it->second.HasTxOut();
2829
}
2930

3031
std::optional<CTxOut> CCoinControl::GetExternalOutput(const COutPoint& outpoint) const
3132
{
32-
const auto ext_it = m_external_txouts.find(outpoint);
33-
if (ext_it == m_external_txouts.end()) {
33+
const auto it = m_selected.find(outpoint);
34+
if (it == m_selected.end() || !it->second.HasTxOut()) {
3435
return std::nullopt;
3536
}
36-
37-
return std::make_optional(ext_it->second);
37+
return it->second.GetTxOut();
3838
}
3939

40-
void CCoinControl::Select(const COutPoint& output)
40+
PreselectedInput& CCoinControl::Select(const COutPoint& outpoint)
4141
{
42-
m_selected_inputs.insert(output);
42+
return m_selected[outpoint];
4343
}
4444

4545
void CCoinControl::SelectExternal(const COutPoint& outpoint, const CTxOut& txout)
4646
{
47-
m_selected_inputs.insert(outpoint);
48-
m_external_txouts.emplace(outpoint, txout);
47+
m_selected[outpoint].SetTxOut(txout);
4948
}
5049

51-
void CCoinControl::UnSelect(const COutPoint& output)
50+
void CCoinControl::UnSelect(const COutPoint& outpoint)
5251
{
53-
m_selected_inputs.erase(output);
52+
m_selected.erase(outpoint);
5453
}
5554

5655
void CCoinControl::UnSelectAll()
5756
{
58-
m_selected_inputs.clear();
57+
m_selected.clear();
5958
}
6059

6160
std::vector<COutPoint> CCoinControl::ListSelected() const
6261
{
63-
return {m_selected_inputs.begin(), m_selected_inputs.end()};
62+
std::vector<COutPoint> outpoints;
63+
std::transform(m_selected.begin(), m_selected.end(), std::back_inserter(outpoints),
64+
[](const std::map<COutPoint, PreselectedInput>::value_type& pair) {
65+
return pair.first;
66+
});
67+
return outpoints;
6468
}
6569

6670
void CCoinControl::SetInputWeight(const COutPoint& outpoint, int64_t weight)
6771
{
68-
m_input_weights[outpoint] = weight;
72+
m_selected[outpoint].SetInputWeight(weight);
6973
}
7074

7175
bool CCoinControl::HasInputWeight(const COutPoint& outpoint) const
7276
{
73-
return m_input_weights.count(outpoint) > 0;
77+
const auto it = m_selected.find(outpoint);
78+
return it != m_selected.end() && it->second.HasInputWeight();
7479
}
7580

7681
int64_t CCoinControl::GetInputWeight(const COutPoint& outpoint) const
7782
{
78-
auto it = m_input_weights.find(outpoint);
79-
assert(it != m_input_weights.end());
80-
return it->second;
83+
return m_selected.at(outpoint).GetInputWeight();
84+
}
85+
86+
void PreselectedInput::SetTxOut(const CTxOut& txout)
87+
{
88+
m_txout = txout;
89+
}
90+
91+
CTxOut PreselectedInput::GetTxOut() const
92+
{
93+
assert(m_txout.has_value());
94+
return m_txout.value();
95+
}
96+
97+
bool PreselectedInput::HasTxOut() const
98+
{
99+
return m_txout.has_value();
100+
}
101+
102+
void PreselectedInput::SetInputWeight(int64_t weight)
103+
{
104+
m_weight = weight;
105+
}
106+
107+
int64_t PreselectedInput::GetInputWeight() const
108+
{
109+
assert(m_weight.has_value());
110+
return m_weight.value();
111+
}
112+
113+
bool PreselectedInput::HasInputWeight() const
114+
{
115+
return m_weight.has_value();
81116
}
82117
} // namespace wallet

src/wallet/coincontrol.h

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,33 @@ const int DEFAULT_MAX_DEPTH = 9999999;
2424
//! Default for -avoidpartialspends
2525
static constexpr bool DEFAULT_AVOIDPARTIALSPENDS = false;
2626

27+
class PreselectedInput
28+
{
29+
private:
30+
//! The previous output being spent by this input
31+
std::optional<CTxOut> m_txout;
32+
//! The input weight for spending this input
33+
std::optional<int64_t> m_weight;
34+
35+
public:
36+
/**
37+
* Set the previous output for this input.
38+
* Only necessary if the input is expected to be an external input.
39+
*/
40+
void SetTxOut(const CTxOut& txout);
41+
/** Retrieve the previous output for this input. */
42+
CTxOut GetTxOut() const;
43+
/** Return whether the previous output is set for this input. */
44+
bool HasTxOut() const;
45+
46+
/** Set the weight for this input. */
47+
void SetInputWeight(int64_t weight);
48+
/** Retrieve the input weight for this input. */
49+
int64_t GetInputWeight() const;
50+
/** Return whether the input weight is set. */
51+
bool HasInputWeight() const;
52+
};
53+
2754
/** Coin Control Features. */
2855
class CCoinControl
2956
{
@@ -69,11 +96,11 @@ class CCoinControl
6996
/**
7097
* Returns true if the given output is pre-selected.
7198
*/
72-
bool IsSelected(const COutPoint& output) const;
99+
bool IsSelected(const COutPoint& outpoint) const;
73100
/**
74101
* Returns true if the given output is selected as an external input.
75102
*/
76-
bool IsExternalSelected(const COutPoint& output) const;
103+
bool IsExternalSelected(const COutPoint& outpoint) const;
77104
/**
78105
* Returns the external output for the given outpoint if it exists.
79106
*/
@@ -82,7 +109,7 @@ class CCoinControl
82109
* Lock-in the given output for spending.
83110
* The output will be included in the transaction even if it's not the most optimal choice.
84111
*/
85-
void Select(const COutPoint& output);
112+
PreselectedInput& Select(const COutPoint& outpoint);
86113
/**
87114
* Lock-in the given output as an external input for spending because it is not in the wallet.
88115
* The output will be included in the transaction even if it's not the most optimal choice.
@@ -91,7 +118,7 @@ class CCoinControl
91118
/**
92119
* Unselects the given output.
93120
*/
94-
void UnSelect(const COutPoint& output);
121+
void UnSelect(const COutPoint& outpoint);
95122
/**
96123
* Unselects all outputs.
97124
*/
@@ -115,12 +142,7 @@ class CCoinControl
115142

116143
private:
117144
//! Selected inputs (inputs that will be used, regardless of whether they're optimal or not)
118-
std::set<COutPoint> m_selected_inputs;
119-
//! Map of external inputs to include in the transaction
120-
//! These are not in the wallet, so we need to track them separately
121-
std::map<COutPoint, CTxOut> m_external_txouts;
122-
//! Map of COutPoints to the maximum weight for that input
123-
std::map<COutPoint, int64_t> m_input_weights;
145+
std::map<COutPoint, PreselectedInput> m_selected;
124146
};
125147
} // namespace wallet
126148

0 commit comments

Comments
 (0)