Skip to content

Commit a7d55c9

Browse files
committed
Merge #9465: [Wallet] Do not perform ECDSA signing in the fee calculation inner loop.
b3d7b1c Wallet: Do not perform ECDSA in the fee calculation inner loop. (Gregory Maxwell)
2 parents fd7d8c7 + b3d7b1c commit a7d55c9

File tree

1 file changed

+46
-31
lines changed

1 file changed

+46
-31
lines changed

src/wallet/wallet.cpp

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2245,7 +2245,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
22452245
CAmount nValue = 0;
22462246
int nChangePosRequest = nChangePosInOut;
22472247
unsigned int nSubtractFeeFromAmount = 0;
2248-
BOOST_FOREACH (const CRecipient& recipient, vecSend)
2248+
for (const auto& recipient : vecSend)
22492249
{
22502250
if (nValue < 0 || recipient.nAmount < 0)
22512251
{
@@ -2300,6 +2300,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
23002300
assert(txNew.nLockTime < LOCKTIME_THRESHOLD);
23012301

23022302
{
2303+
set<pair<const CWalletTx*,unsigned int> > setCoins;
23032304
LOCK2(cs_main, cs_wallet);
23042305
{
23052306
std::vector<COutput> vAvailableCoins;
@@ -2320,7 +2321,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
23202321
nValueToSelect += nFeeRet;
23212322
double dPriority = 0;
23222323
// vouts to the payees
2323-
BOOST_FOREACH (const CRecipient& recipient, vecSend)
2324+
for (const auto& recipient : vecSend)
23242325
{
23252326
CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
23262327

@@ -2352,14 +2353,14 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
23522353
}
23532354

23542355
// Choose coins to use
2355-
set<pair<const CWalletTx*,unsigned int> > setCoins;
23562356
CAmount nValueIn = 0;
2357+
setCoins.clear();
23572358
if (!SelectCoins(vAvailableCoins, nValueToSelect, setCoins, nValueIn, coinControl))
23582359
{
23592360
strFailReason = _("Insufficient funds");
23602361
return false;
23612362
}
2362-
BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
2363+
for (const auto& pcoin : setCoins)
23632364
{
23642365
CAmount nCredit = pcoin.first->tx->vout[pcoin.second].nValue;
23652366
//The coin age after the next block (depth+1) is used instead of the current,
@@ -2470,24 +2471,18 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
24702471
// to avoid conflicting with other possible uses of nSequence,
24712472
// and in the spirit of "smallest posible change from prior
24722473
// behavior."
2473-
BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
2474+
for (const auto& coin : setCoins)
24742475
txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(),
24752476
std::numeric_limits<unsigned int>::max() - (fWalletRbf ? 2 : 1)));
24762477

2477-
// Sign
2478+
// Fill in dummy signatures for fee calculation.
24782479
int nIn = 0;
2479-
CTransaction txNewConst(txNew);
2480-
BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
2480+
for (const auto& coin : setCoins)
24812481
{
2482-
bool signSuccess;
24832482
const CScript& scriptPubKey = coin.first->tx->vout[coin.second].scriptPubKey;
24842483
SignatureData sigdata;
2485-
if (sign)
2486-
signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.first->tx->vout[coin.second].nValue, SIGHASH_ALL), scriptPubKey, sigdata);
2487-
else
2488-
signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata);
24892484

2490-
if (!signSuccess)
2485+
if (!ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata))
24912486
{
24922487
strFailReason = _("Signing transaction failed");
24932488
return false;
@@ -2500,26 +2495,15 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
25002495

25012496
unsigned int nBytes = GetVirtualTransactionSize(txNew);
25022497

2503-
// Remove scriptSigs if we used dummy signatures for fee calculation
2504-
if (!sign) {
2505-
BOOST_FOREACH (CTxIn& vin, txNew.vin) {
2506-
vin.scriptSig = CScript();
2507-
vin.scriptWitness.SetNull();
2508-
}
2509-
}
2510-
2511-
// Embed the constructed transaction data in wtxNew.
2512-
wtxNew.SetTx(MakeTransactionRef(std::move(txNew)));
2498+
CTransaction txNewConst(txNew);
2499+
dPriority = txNewConst.ComputePriority(dPriority, nBytes);
25132500

2514-
// Limit size
2515-
if (GetTransactionWeight(wtxNew) >= MAX_STANDARD_TX_WEIGHT)
2516-
{
2517-
strFailReason = _("Transaction too large");
2518-
return false;
2501+
// Remove scriptSigs to eliminate the fee calculation dummy signatures
2502+
for (auto& vin : txNew.vin) {
2503+
vin.scriptSig = CScript();
2504+
vin.scriptWitness.SetNull();
25192505
}
25202506

2521-
dPriority = wtxNew.tx->ComputePriority(dPriority, nBytes);
2522-
25232507
// Allow to override the default confirmation target over the CoinControl instance
25242508
int currentConfirmationTarget = nTxConfirmTarget;
25252509
if (coinControl && coinControl->nConfirmTarget > 0)
@@ -2558,6 +2542,37 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
25582542
continue;
25592543
}
25602544
}
2545+
2546+
if (sign)
2547+
{
2548+
CTransaction txNewConst(txNew);
2549+
int nIn = 0;
2550+
for (const auto& coin : setCoins)
2551+
{
2552+
const CScript& scriptPubKey = coin.first->tx->vout[coin.second].scriptPubKey;
2553+
SignatureData sigdata;
2554+
2555+
if (!ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.first->tx->vout[coin.second].nValue, SIGHASH_ALL), scriptPubKey, sigdata))
2556+
{
2557+
strFailReason = _("Signing transaction failed");
2558+
return false;
2559+
} else {
2560+
UpdateTransaction(txNew, nIn, sigdata);
2561+
}
2562+
2563+
nIn++;
2564+
}
2565+
}
2566+
2567+
// Embed the constructed transaction data in wtxNew.
2568+
wtxNew.SetTx(MakeTransactionRef(std::move(txNew)));
2569+
2570+
// Limit size
2571+
if (GetTransactionWeight(wtxNew) >= MAX_STANDARD_TX_WEIGHT)
2572+
{
2573+
strFailReason = _("Transaction too large");
2574+
return false;
2575+
}
25612576
}
25622577

25632578
if (GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) {

0 commit comments

Comments
 (0)