diff options
Diffstat (limited to 'src/wallet/wallet.h')
-rw-r--r-- | src/wallet/wallet.h | 60 |
1 files changed, 32 insertions, 28 deletions
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 3e2d1794d8..fbb87353c1 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -269,6 +269,9 @@ public: bool IsCoinBase() const { return tx->IsCoinBase(); } }; +//Get the marginal bytes of spending the specified output +int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* pwallet); + /** * A transaction with a bunch of additional info that only the owner cares about. * It includes any unrecorded transactions needed to link it back to the block chain. @@ -462,6 +465,12 @@ public: CAmount GetAvailableWatchOnlyCredit(const bool fUseCache=true) const; CAmount GetChange() const; + // Get the marginal bytes if spending the specified output from this transaction + int GetSpendSize(unsigned int out) const + { + return CalculateMaximumSignedInputSize(tx->vout[out], pwallet); + } + void GetAmounts(std::list<COutputEntry>& listReceived, std::list<COutputEntry>& listSent, CAmount& nFee, std::string& strSentAccount, const isminefilter& filter) const; @@ -525,6 +534,9 @@ public: int i; int nDepth; + /** Pre-computed estimated size of this output as a fully-signed input in a transaction. Can be -1 if it could not be calculated */ + int nInputBytes; + /** Whether we have the private keys to spend this output */ bool fSpendable; @@ -540,7 +552,12 @@ public: COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn, bool fSolvableIn, bool fSafeIn) { - tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn; fSolvable = fSolvableIn; fSafe = fSafeIn; + tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn; fSolvable = fSolvableIn; fSafe = fSafeIn; nInputBytes = -1; + // If known and signable by the given wallet, compute nInputBytes + // Failure will keep this value -1 + if (fSpendable && tx) { + nInputBytes = tx->GetSpendSize(i); + } } std::string ToString() const; @@ -981,8 +998,14 @@ public: void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries); bool AddAccountingEntry(const CAccountingEntry&); bool AddAccountingEntry(const CAccountingEntry&, CWalletDB *pwalletdb); - template <typename ContainerType> - bool DummySignTx(CMutableTransaction &txNew, const ContainerType &coins) const; + bool DummySignTx(CMutableTransaction &txNew, const std::set<CTxOut> &txouts) const + { + std::vector<CTxOut> v_txouts(txouts.size()); + std::copy(txouts.begin(), txouts.end(), v_txouts.begin()); + return DummySignTx(txNew, v_txouts); + } + bool DummySignTx(CMutableTransaction &txNew, const std::vector<CTxOut> &txouts) const; + bool DummySignInput(CTxIn &tx_in, const CTxOut &txout) const; static CFeeRate minTxFee; static CFeeRate fallbackFee; @@ -1227,31 +1250,6 @@ public: } }; -// Helper for producing a bunch of max-sized low-S signatures (eg 72 bytes) -// ContainerType is meant to hold pair<CWalletTx *, int>, and be iterable -// so that each entry corresponds to each vIn, in order. -template <typename ContainerType> -bool CWallet::DummySignTx(CMutableTransaction &txNew, const ContainerType &coins) const -{ - // Fill in dummy signatures for fee calculation. - int nIn = 0; - for (const auto& coin : coins) - { - const CScript& scriptPubKey = coin.txout.scriptPubKey; - SignatureData sigdata; - - if (!ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata)) - { - return false; - } else { - UpdateTransaction(txNew, nIn, sigdata); - } - - nIn++; - } - return true; -} - OutputType ParseOutputType(const std::string& str, OutputType default_type = OUTPUT_TYPE_DEFAULT); const std::string& FormatOutputType(OutputType type); @@ -1299,4 +1297,10 @@ public: } }; +// Calculate the size of the transaction assuming all signatures are max size +// Use DummySignatureCreator, which inserts 72 byte signatures everywhere. +// NOTE: this requires that all inputs must be in mapWallet (eg the tx should +// be IsAllFromMe). +int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet); +int64_t CalculateMaximumSignedTxSize(const CTransaction &tx, const CWallet *wallet, const std::vector<CTxOut>& txouts); #endif // BITCOIN_WALLET_WALLET_H |