Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.cpp
Show First 20 Lines • Show All 1,606 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
int64_t CWalletTx::GetTxTime() const { | int64_t CWalletTx::GetTxTime() const { | ||||
int64_t n = nTimeSmart; | int64_t n = nTimeSmart; | ||||
return n ? n : nTimeReceived; | return n ? n : nTimeReceived; | ||||
} | } | ||||
// Helper for producing a max-sized low-S low-R signature (eg 71 bytes) | // Helper for producing a max-sized low-S low-R signature (eg 71 bytes) | ||||
bool CWallet::DummySignInput(CTxIn &tx_in, const CTxOut &txout) const { | // or a max-sized low-S signature (e.g. 72 bytes) if use_max_sig is true | ||||
bool CWallet::DummySignInput(CTxIn &tx_in, const CTxOut &txout, | |||||
bool use_max_sig) const { | |||||
// Fill in dummy signatures for fee calculation. | // Fill in dummy signatures for fee calculation. | ||||
const CScript &scriptPubKey = txout.scriptPubKey; | const CScript &scriptPubKey = txout.scriptPubKey; | ||||
SignatureData sigdata; | SignatureData sigdata; | ||||
if (!ProduceSignature(*this, DUMMY_SIGNATURE_CREATOR, scriptPubKey, | if (!ProduceSignature(*this, | ||||
sigdata)) { | use_max_sig ? DUMMY_MAXIMUM_SIGNATURE_CREATOR | ||||
: DUMMY_SIGNATURE_CREATOR, | |||||
scriptPubKey, sigdata)) { | |||||
return false; | return false; | ||||
} | } | ||||
UpdateInput(tx_in, sigdata); | UpdateInput(tx_in, sigdata); | ||||
return true; | return true; | ||||
} | } | ||||
// Helper for producing a bunch of max-sized low-S low-R signatures (eg 71 | // Helper for producing a bunch of max-sized low-S low-R signatures (eg 71 | ||||
// bytes) | // bytes) | ||||
bool CWallet::DummySignTx(CMutableTransaction &txNew, | bool CWallet::DummySignTx(CMutableTransaction &txNew, | ||||
const std::vector<CTxOut> &txouts) const { | const std::vector<CTxOut> &txouts, | ||||
bool use_max_sig) const { | |||||
// Fill in dummy signatures for fee calculation. | // Fill in dummy signatures for fee calculation. | ||||
int nIn = 0; | int nIn = 0; | ||||
for (const auto &txout : txouts) { | for (const auto &txout : txouts) { | ||||
if (!DummySignInput(txNew.vin[nIn], txout)) { | if (!DummySignInput(txNew.vin[nIn], txout, use_max_sig)) { | ||||
return false; | return false; | ||||
} | } | ||||
nIn++; | nIn++; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, | int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, | ||||
const CWallet *wallet) { | const CWallet *wallet, bool use_max_sig) { | ||||
std::vector<CTxOut> txouts; | std::vector<CTxOut> txouts; | ||||
// Look up the inputs. We should have already checked that this transaction | // Look up the inputs. We should have already checked that this transaction | ||||
// IsAllFromMe(ISMINE_SPENDABLE), so every input should already be in our | // IsAllFromMe(ISMINE_SPENDABLE), so every input should already be in our | ||||
// wallet, with a valid index into the vout array, and the ability to sign. | // wallet, with a valid index into the vout array, and the ability to sign. | ||||
for (auto &input : tx.vin) { | for (auto &input : tx.vin) { | ||||
const auto mi = wallet->mapWallet.find(input.prevout.GetTxId()); | const auto mi = wallet->mapWallet.find(input.prevout.GetTxId()); | ||||
if (mi == wallet->mapWallet.end()) { | if (mi == wallet->mapWallet.end()) { | ||||
return -1; | return -1; | ||||
} | } | ||||
assert(input.prevout.GetN() < mi->second.tx->vout.size()); | assert(input.prevout.GetN() < mi->second.tx->vout.size()); | ||||
txouts.emplace_back(mi->second.tx->vout[input.prevout.GetN()]); | txouts.emplace_back(mi->second.tx->vout[input.prevout.GetN()]); | ||||
} | } | ||||
return CalculateMaximumSignedTxSize(tx, wallet, txouts); | return CalculateMaximumSignedTxSize(tx, wallet, txouts, use_max_sig); | ||||
} | } | ||||
// txouts needs to be in the order of tx.vin | // txouts needs to be in the order of tx.vin | ||||
int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, | int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, | ||||
const CWallet *wallet, | const CWallet *wallet, | ||||
const std::vector<CTxOut> &txouts) { | const std::vector<CTxOut> &txouts, | ||||
bool use_max_sig) { | |||||
CMutableTransaction txNew(tx); | CMutableTransaction txNew(tx); | ||||
if (!wallet->DummySignTx(txNew, txouts)) { | if (!wallet->DummySignTx(txNew, txouts, use_max_sig)) { | ||||
// This should never happen, because IsAllFromMe(ISMINE_SPENDABLE) | // This should never happen, because IsAllFromMe(ISMINE_SPENDABLE) | ||||
// implies that we can sign for every input. | // implies that we can sign for every input. | ||||
return -1; | return -1; | ||||
} | } | ||||
return GetVirtualTransactionSize(CTransaction(txNew)); | return GetVirtualTransactionSize(CTransaction(txNew)); | ||||
} | } | ||||
int CalculateMaximumSignedInputSize(const CTxOut &txout, | int CalculateMaximumSignedInputSize(const CTxOut &txout, const CWallet *wallet, | ||||
const CWallet *wallet) { | bool use_max_sig) { | ||||
CMutableTransaction txn; | CMutableTransaction txn; | ||||
txn.vin.push_back(CTxIn(COutPoint())); | txn.vin.push_back(CTxIn(COutPoint())); | ||||
if (!wallet->DummySignInput(txn.vin[0], txout)) { | if (!wallet->DummySignInput(txn.vin[0], txout, use_max_sig)) { | ||||
// This should never happen, because IsAllFromMe(ISMINE_SPENDABLE) | // This should never happen, because IsAllFromMe(ISMINE_SPENDABLE) | ||||
// implies that we can sign for every input. | // implies that we can sign for every input. | ||||
return -1; | return -1; | ||||
} | } | ||||
return GetVirtualTransactionInputSize(txn.vin[0]); | return GetVirtualTransactionInputSize(txn.vin[0]); | ||||
} | } | ||||
void CWalletTx::GetAmounts(std::list<COutputEntry> &listReceived, | void CWalletTx::GetAmounts(std::list<COutputEntry> &listReceived, | ||||
▲ Show 20 Lines • Show All 808 Lines • ▼ Show 20 Lines | for (const auto &entry : mapWallet) { | ||||
bool fSpendableIn = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || | bool fSpendableIn = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || | ||||
(coinControl && coinControl->fAllowWatchOnly && | (coinControl && coinControl->fAllowWatchOnly && | ||||
(mine & ISMINE_WATCH_SOLVABLE) != ISMINE_NO); | (mine & ISMINE_WATCH_SOLVABLE) != ISMINE_NO); | ||||
bool fSolvableIn = | bool fSolvableIn = | ||||
(mine & (ISMINE_SPENDABLE | ISMINE_WATCH_SOLVABLE)) != | (mine & (ISMINE_SPENDABLE | ISMINE_WATCH_SOLVABLE)) != | ||||
ISMINE_NO; | ISMINE_NO; | ||||
vCoins.push_back( | vCoins.push_back( | ||||
COutput(pcoin, i, nDepth, fSpendableIn, fSolvableIn, safeTx)); | COutput(pcoin, i, nDepth, fSpendableIn, fSolvableIn, safeTx, | ||||
(coinControl && coinControl->fAllowWatchOnly))); | |||||
// Checks the sum amount of all UTXO's. | // Checks the sum amount of all UTXO's. | ||||
if (nMinimumSumAmount != MAX_MONEY) { | if (nMinimumSumAmount != MAX_MONEY) { | ||||
nTotal += pcoin->tx->vout[i].nValue; | nTotal += pcoin->tx->vout[i].nValue; | ||||
if (nTotal >= nMinimumSumAmount) { | if (nTotal >= nMinimumSumAmount) { | ||||
return; | return; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 627 Lines • ▼ Show 20 Lines | assert(txNew.nLockTime < LOCKTIME_THRESHOLD); | ||||
// Dummy fill vin for maximum size estimation | // Dummy fill vin for maximum size estimation | ||||
// | // | ||||
for (const auto &coin : setCoins) { | for (const auto &coin : setCoins) { | ||||
txNew.vin.push_back(CTxIn(coin.outpoint, CScript())); | txNew.vin.push_back(CTxIn(coin.outpoint, CScript())); | ||||
} | } | ||||
CTransaction txNewConst(txNew); | CTransaction txNewConst(txNew); | ||||
int nBytes = CalculateMaximumSignedTxSize(txNewConst, this); | int nBytes = CalculateMaximumSignedTxSize( | ||||
txNewConst, this, coinControl.fAllowWatchOnly); | |||||
if (nBytes < 0) { | if (nBytes < 0) { | ||||
strFailReason = _("Signing transaction failed"); | strFailReason = _("Signing transaction failed"); | ||||
return false; | return false; | ||||
} | } | ||||
Amount nFeeNeeded = | Amount nFeeNeeded = | ||||
GetMinimumFee(*this, nBytes, coinControl, g_mempool); | GetMinimumFee(*this, nBytes, coinControl, g_mempool); | ||||
▲ Show 20 Lines • Show All 1,673 Lines • Show Last 20 Lines |