Skip to content

Commit e0e3d5f

Browse files
committed
Use BasicCoinselectionAlgorithm as dependency of MinimumFeeCoinSelectionAlgorithm
1 parent e8cae94 commit e0e3d5f

File tree

2 files changed

+30
-79
lines changed

2 files changed

+30
-79
lines changed

divi/src/MinimumFeeCoinSelectionAlgorithm.cpp

Lines changed: 24 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -112,89 +112,37 @@ MinimumFeeCoinSelectionAlgorithm::MinimumFeeCoinSelectionAlgorithm(
112112
const I_SignatureSizeEstimator& estimator,
113113
const CFeeRate& minRelayTxFee,
114114
const ChangeOutputType changeOutputType
115-
): keyStore_(keyStore)
116-
, estimator_(estimator)
117-
, minRelayTxFee_(minRelayTxFee)
115+
): minRelayTxFee_(minRelayTxFee)
118116
, changeOutputType_(changeOutputType)
117+
, basicCoinSelectionAlgorithm_(
118+
new BasicCoinSelectionAlgorithm(
119+
keyStore,
120+
estimator,
121+
minRelayTxFee,
122+
changeOutputType,
123+
*static_cast<I_UtxoPriorityAlgorithm*>(this)))
119124
{
120125
}
121126

127+
bool MinimumFeeCoinSelectionAlgorithm::operator()(const CAmount targetAmount, const InputToSpendAndSigSize& first, const InputToSpendAndSigSize& second) const
128+
{
129+
if(changeOutputType_ == ChangeOutputType::VAULT && first.outputRef->nDepth != second.outputRef->nDepth)
130+
{
131+
return first.outputRef->nDepth < second.outputRef->nDepth;
132+
}
133+
const CAmount gapA = first.outputRef->Value() - minRelayTxFee_.GetFee(first.sigSize);
134+
const CAmount gapB = second.outputRef->Value() - minRelayTxFee_.GetFee(second.sigSize);
135+
const bool inputAShouldBePrioritized =
136+
(gapA >= targetAmount && gapB >= targetAmount)
137+
? first.sigSize < second.sigSize
138+
: gapA > gapB || (gapA == gapB && first.sigSize < second.sigSize);
139+
return inputAShouldBePrioritized;
140+
}
141+
122142
std::set<COutput> MinimumFeeCoinSelectionAlgorithm::SelectCoins(
123143
const CMutableTransaction& transactionToSelectCoinsFor,
124144
const std::vector<COutput>& vCoins,
125145
CAmount& fees) const
126146
{
127-
const unsigned nominalChangeOutputSize = static_cast<unsigned>(changeOutputType_); // Vault? Vault-Change : P2PKH change address
128-
CTransaction initialTransaction = CTransaction(transactionToSelectCoinsFor);
129-
const unsigned initialByteSize = ::GetSerializeSize(initialTransaction, SER_NETWORK, PROTOCOL_VERSION);
130-
131-
CAmount maximumAmountAvailable = 0;
132-
std::vector<InputToSpendAndSigSize> inputsToSpendAndSignatureSizeEstimates;
133-
inputsToSpendAndSignatureSizeEstimates.reserve(vCoins.size());
134-
std::set<COutPoint> outputsUsed;
135-
for(const CTxIn& txInput: initialTransaction.vin)
136-
{
137-
outputsUsed.insert(txInput.prevout);
138-
}
139-
CAmount amountAlreadyCovered = 0;
140-
fees += minRelayTxFee_.GetFee(initialByteSize);
141-
for(const COutput& input: vCoins)
142-
{
143-
if(outputsUsed.count(COutPoint(input.tx->GetHash(),input.i))>0)
144-
{
145-
InputToSpendAndSigSize inputWithSigSize(input,keyStore_,estimator_);
146-
amountAlreadyCovered += inputWithSigSize.outputRef->Value();
147-
fees += minRelayTxFee_.GetFee(inputWithSigSize.sigSize);
148-
continue;
149-
}
150-
inputsToSpendAndSignatureSizeEstimates.emplace_back(input,keyStore_,estimator_);
151-
maximumAmountAvailable+= input.Value();
152-
}
153-
const CAmount nTargetValue = transactionToSelectCoinsFor.GetValueOut() - amountAlreadyCovered;
154-
155-
std::set<COutput> inputsSelected;
156-
inputsSelected.clear();
157-
const CAmount minimumNoDustChange = FeeAndPriorityCalculator::instance().MinimumValueForNonDust();
158-
const CAmount totalAmountNeeded = nTargetValue + minimumNoDustChange + fees;
159-
if(totalAmountNeeded > maximumAmountAvailable) return {};
160-
161-
std::sort(
162-
inputsToSpendAndSignatureSizeEstimates.begin(),
163-
inputsToSpendAndSignatureSizeEstimates.end(),
164-
[totalAmountNeeded,this](const InputToSpendAndSigSize& inputA, const InputToSpendAndSigSize& inputB)
165-
{
166-
if(changeOutputType_ == ChangeOutputType::VAULT && inputA.outputRef->nDepth != inputB.outputRef->nDepth)
167-
{
168-
return inputA.outputRef->nDepth < inputB.outputRef->nDepth;
169-
}
170-
const CAmount gapA = inputA.outputRef->Value() - minRelayTxFee_.GetFee(inputA.sigSize);
171-
const CAmount gapB = inputB.outputRef->Value() - minRelayTxFee_.GetFee(inputB.sigSize);
172-
const bool inputAShouldBePrioritized =
173-
(gapA >= totalAmountNeeded && gapB >= totalAmountNeeded)
174-
? inputA.sigSize < inputB.sigSize
175-
: gapA > gapB || (gapA == gapB && inputA.sigSize < inputB.sigSize);
176-
return inputAShouldBePrioritized;
177-
});
178-
CAmount amountCovered =0;
179-
unsigned cummulativeByteSize = nominalChangeOutputSize;
180-
for(const InputToSpendAndSigSize& inputAndSigSize: inputsToSpendAndSignatureSizeEstimates)
181-
{
182-
inputsSelected.insert(*inputAndSigSize.outputRef);
183-
amountCovered += inputAndSigSize.outputRef->Value() - minRelayTxFee_.GetFee(inputAndSigSize.sigSize);
184-
cummulativeByteSize += inputAndSigSize.sigSize;
185-
if(cummulativeByteSize >= MAX_STANDARD_TX_SIZE) return {};
186-
if( amountCovered >= totalAmountNeeded )
187-
{
188-
fees += minRelayTxFee_.GetFee(cummulativeByteSize);
189-
if(minRelayTxFee_.GetMaxTxFee() < fees)
190-
{
191-
return {};
192-
}
193-
else
194-
{
195-
return inputsSelected;
196-
}
197-
}
198-
}
199-
return {};
147+
return basicCoinSelectionAlgorithm_->SelectCoins(transactionToSelectCoinsFor,vCoins,fees);
200148
}

divi/src/MinimumFeeCoinSelectionAlgorithm.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#define MINIMUM_FEE_COIN_SELECTION_ALGORITHM_H
33
#include <I_CoinSelectionAlgorithm.h>
44
#include <I_UtxoPriorityAlgorithm.h>
5+
#include <memory>
6+
57
class CKeyStore;
68
class I_SignatureSizeEstimator;
79
class CFeeRate;
@@ -46,13 +48,14 @@ class BasicCoinSelectionAlgorithm final: public I_CoinSelectionAlgorithm
4648
CAmount& fees) const override;
4749
};
4850

49-
class MinimumFeeCoinSelectionAlgorithm final: public I_CoinSelectionAlgorithm
51+
class MinimumFeeCoinSelectionAlgorithm final: public I_CoinSelectionAlgorithm, private I_UtxoPriorityAlgorithm
5052
{
5153
private:
52-
const CKeyStore& keyStore_;
53-
const I_SignatureSizeEstimator& estimator_;
5454
const CFeeRate& minRelayTxFee_;
5555
const ChangeOutputType changeOutputType_;
56+
std::unique_ptr<BasicCoinSelectionAlgorithm> basicCoinSelectionAlgorithm_;
57+
bool operator()(const CAmount targetAmount, const InputToSpendAndSigSize& first, const InputToSpendAndSigSize& second) const override;
58+
5659
public:
5760
MinimumFeeCoinSelectionAlgorithm(
5861
const CKeyStore& keyStore,

0 commit comments

Comments
 (0)