mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-01-17 18:40:09 +00:00
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)
This commit is contained in:
commit
a7d55c9338
@ -2245,7 +2245,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
|||||||
CAmount nValue = 0;
|
CAmount nValue = 0;
|
||||||
int nChangePosRequest = nChangePosInOut;
|
int nChangePosRequest = nChangePosInOut;
|
||||||
unsigned int nSubtractFeeFromAmount = 0;
|
unsigned int nSubtractFeeFromAmount = 0;
|
||||||
BOOST_FOREACH (const CRecipient& recipient, vecSend)
|
for (const auto& recipient : vecSend)
|
||||||
{
|
{
|
||||||
if (nValue < 0 || recipient.nAmount < 0)
|
if (nValue < 0 || recipient.nAmount < 0)
|
||||||
{
|
{
|
||||||
@ -2300,6 +2300,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
|||||||
assert(txNew.nLockTime < LOCKTIME_THRESHOLD);
|
assert(txNew.nLockTime < LOCKTIME_THRESHOLD);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
set<pair<const CWalletTx*,unsigned int> > setCoins;
|
||||||
LOCK2(cs_main, cs_wallet);
|
LOCK2(cs_main, cs_wallet);
|
||||||
{
|
{
|
||||||
std::vector<COutput> vAvailableCoins;
|
std::vector<COutput> vAvailableCoins;
|
||||||
@ -2320,7 +2321,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
|||||||
nValueToSelect += nFeeRet;
|
nValueToSelect += nFeeRet;
|
||||||
double dPriority = 0;
|
double dPriority = 0;
|
||||||
// vouts to the payees
|
// vouts to the payees
|
||||||
BOOST_FOREACH (const CRecipient& recipient, vecSend)
|
for (const auto& recipient : vecSend)
|
||||||
{
|
{
|
||||||
CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
|
CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
|
||||||
|
|
||||||
@ -2352,14 +2353,14 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Choose coins to use
|
// Choose coins to use
|
||||||
set<pair<const CWalletTx*,unsigned int> > setCoins;
|
|
||||||
CAmount nValueIn = 0;
|
CAmount nValueIn = 0;
|
||||||
|
setCoins.clear();
|
||||||
if (!SelectCoins(vAvailableCoins, nValueToSelect, setCoins, nValueIn, coinControl))
|
if (!SelectCoins(vAvailableCoins, nValueToSelect, setCoins, nValueIn, coinControl))
|
||||||
{
|
{
|
||||||
strFailReason = _("Insufficient funds");
|
strFailReason = _("Insufficient funds");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
|
for (const auto& pcoin : setCoins)
|
||||||
{
|
{
|
||||||
CAmount nCredit = pcoin.first->tx->vout[pcoin.second].nValue;
|
CAmount nCredit = pcoin.first->tx->vout[pcoin.second].nValue;
|
||||||
//The coin age after the next block (depth+1) is used instead of the current,
|
//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
|
|||||||
// to avoid conflicting with other possible uses of nSequence,
|
// to avoid conflicting with other possible uses of nSequence,
|
||||||
// and in the spirit of "smallest posible change from prior
|
// and in the spirit of "smallest posible change from prior
|
||||||
// behavior."
|
// behavior."
|
||||||
BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
|
for (const auto& coin : setCoins)
|
||||||
txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(),
|
txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(),
|
||||||
std::numeric_limits<unsigned int>::max() - (fWalletRbf ? 2 : 1)));
|
std::numeric_limits<unsigned int>::max() - (fWalletRbf ? 2 : 1)));
|
||||||
|
|
||||||
// Sign
|
// Fill in dummy signatures for fee calculation.
|
||||||
int nIn = 0;
|
int nIn = 0;
|
||||||
CTransaction txNewConst(txNew);
|
for (const auto& coin : setCoins)
|
||||||
BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
|
|
||||||
{
|
{
|
||||||
bool signSuccess;
|
|
||||||
const CScript& scriptPubKey = coin.first->tx->vout[coin.second].scriptPubKey;
|
const CScript& scriptPubKey = coin.first->tx->vout[coin.second].scriptPubKey;
|
||||||
SignatureData sigdata;
|
SignatureData sigdata;
|
||||||
if (sign)
|
|
||||||
signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.first->tx->vout[coin.second].nValue, SIGHASH_ALL), scriptPubKey, sigdata);
|
|
||||||
else
|
|
||||||
signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata);
|
|
||||||
|
|
||||||
if (!signSuccess)
|
if (!ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata))
|
||||||
{
|
{
|
||||||
strFailReason = _("Signing transaction failed");
|
strFailReason = _("Signing transaction failed");
|
||||||
return false;
|
return false;
|
||||||
@ -2500,26 +2495,15 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
|||||||
|
|
||||||
unsigned int nBytes = GetVirtualTransactionSize(txNew);
|
unsigned int nBytes = GetVirtualTransactionSize(txNew);
|
||||||
|
|
||||||
// Remove scriptSigs if we used dummy signatures for fee calculation
|
CTransaction txNewConst(txNew);
|
||||||
if (!sign) {
|
dPriority = txNewConst.ComputePriority(dPriority, nBytes);
|
||||||
BOOST_FOREACH (CTxIn& vin, txNew.vin) {
|
|
||||||
vin.scriptSig = CScript();
|
// Remove scriptSigs to eliminate the fee calculation dummy signatures
|
||||||
vin.scriptWitness.SetNull();
|
for (auto& vin : txNew.vin) {
|
||||||
}
|
vin.scriptSig = CScript();
|
||||||
|
vin.scriptWitness.SetNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Embed the constructed transaction data in wtxNew.
|
|
||||||
wtxNew.SetTx(MakeTransactionRef(std::move(txNew)));
|
|
||||||
|
|
||||||
// Limit size
|
|
||||||
if (GetTransactionWeight(wtxNew) >= MAX_STANDARD_TX_WEIGHT)
|
|
||||||
{
|
|
||||||
strFailReason = _("Transaction too large");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
dPriority = wtxNew.tx->ComputePriority(dPriority, nBytes);
|
|
||||||
|
|
||||||
// Allow to override the default confirmation target over the CoinControl instance
|
// Allow to override the default confirmation target over the CoinControl instance
|
||||||
int currentConfirmationTarget = nTxConfirmTarget;
|
int currentConfirmationTarget = nTxConfirmTarget;
|
||||||
if (coinControl && coinControl->nConfirmTarget > 0)
|
if (coinControl && coinControl->nConfirmTarget > 0)
|
||||||
@ -2558,6 +2542,37 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sign)
|
||||||
|
{
|
||||||
|
CTransaction txNewConst(txNew);
|
||||||
|
int nIn = 0;
|
||||||
|
for (const auto& coin : setCoins)
|
||||||
|
{
|
||||||
|
const CScript& scriptPubKey = coin.first->tx->vout[coin.second].scriptPubKey;
|
||||||
|
SignatureData sigdata;
|
||||||
|
|
||||||
|
if (!ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.first->tx->vout[coin.second].nValue, SIGHASH_ALL), scriptPubKey, sigdata))
|
||||||
|
{
|
||||||
|
strFailReason = _("Signing transaction failed");
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
UpdateTransaction(txNew, nIn, sigdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
nIn++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Embed the constructed transaction data in wtxNew.
|
||||||
|
wtxNew.SetTx(MakeTransactionRef(std::move(txNew)));
|
||||||
|
|
||||||
|
// Limit size
|
||||||
|
if (GetTransactionWeight(wtxNew) >= MAX_STANDARD_TX_WEIGHT)
|
||||||
|
{
|
||||||
|
strFailReason = _("Transaction too large");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) {
|
if (GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user