aboutsummaryrefslogtreecommitdiff
path: root/src/main.h
diff options
context:
space:
mode:
authorEric Lombrozo <elombrozo@gmail.com>2013-01-08 04:17:15 -0800
committerEric Lombrozo <elombrozo@gmail.com>2013-06-05 23:15:20 -0700
commit05df3fc68d68e87415ed9e534db3ea3160dc3092 (patch)
tree50e1da470312d2300da4a1ec0ae2c1941f681b29 /src/main.h
parent788536f1755c6a9ea81394a2199ca27c9e90944e (diff)
downloadbitcoin-05df3fc68d68e87415ed9e534db3ea3160dc3092.tar.xz
Removed AcceptToMemoryPool method from CTransaction. This method belongs to the mempool instance.
Removed AreInputsStandard from CTransaction, made it a regular function in main. Moved CTransaction::GetOutputFor to CCoinsViewCache. Moved GetLegacySigOpCount and GetP2SHSigOpCount out of CTransaction into regular functions in main. Moved GetValueIn and HaveInputs from CTransaction into CCoinsViewCache. Moved AllowFree, ClientCheckInputs, CheckInputs, UpdateCoins, and CheckTransaction out of CTransaction and into main. Moved IsStandard and IsFinal out of CTransaction and put them in main as IsStandardTx and IsFinalTx. Moved GetValueOut out of CTransaction into main. Moved CTxIn, CTxOut, and CTransaction into core. Added minimum fee parameter to CTxOut::IsDust() temporarily until CTransaction is moved to core.h so that CTxOut needn't know about CTransaction.
Diffstat (limited to 'src/main.h')
-rw-r--r--src/main.h406
1 files changed, 64 insertions, 342 deletions
diff --git a/src/main.h b/src/main.h
index c3c7ee3966..7069d4bab3 100644
--- a/src/main.h
+++ b/src/main.h
@@ -254,155 +254,6 @@ struct CDiskTxPos : public CDiskBlockPos
-
-/** An input of a transaction. It contains the location of the previous
- * transaction's output that it claims and a signature that matches the
- * output's public key.
- */
-class CTxIn
-{
-public:
- COutPoint prevout;
- CScript scriptSig;
- unsigned int nSequence;
-
- CTxIn()
- {
- nSequence = std::numeric_limits<unsigned int>::max();
- }
-
- explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits<unsigned int>::max())
- {
- prevout = prevoutIn;
- scriptSig = scriptSigIn;
- nSequence = nSequenceIn;
- }
-
- CTxIn(uint256 hashPrevTx, unsigned int nOut, CScript scriptSigIn=CScript(), unsigned int nSequenceIn=std::numeric_limits<unsigned int>::max())
- {
- prevout = COutPoint(hashPrevTx, nOut);
- scriptSig = scriptSigIn;
- nSequence = nSequenceIn;
- }
-
- IMPLEMENT_SERIALIZE
- (
- READWRITE(prevout);
- READWRITE(scriptSig);
- READWRITE(nSequence);
- )
-
- bool IsFinal() const
- {
- return (nSequence == std::numeric_limits<unsigned int>::max());
- }
-
- friend bool operator==(const CTxIn& a, const CTxIn& b)
- {
- return (a.prevout == b.prevout &&
- a.scriptSig == b.scriptSig &&
- a.nSequence == b.nSequence);
- }
-
- friend bool operator!=(const CTxIn& a, const CTxIn& b)
- {
- return !(a == b);
- }
-
- std::string ToString() const
- {
- std::string str;
- str += "CTxIn(";
- str += prevout.ToString();
- if (prevout.IsNull())
- str += strprintf(", coinbase %s", HexStr(scriptSig).c_str());
- else
- str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
- if (nSequence != std::numeric_limits<unsigned int>::max())
- str += strprintf(", nSequence=%u", nSequence);
- str += ")";
- return str;
- }
-
- void print() const
- {
- printf("%s\n", ToString().c_str());
- }
-};
-
-
-
-
-/** An output of a transaction. It contains the public key that the next input
- * must be able to sign with to claim it.
- */
-class CTxOut
-{
-public:
- int64 nValue;
- CScript scriptPubKey;
-
- CTxOut()
- {
- SetNull();
- }
-
- CTxOut(int64 nValueIn, CScript scriptPubKeyIn)
- {
- nValue = nValueIn;
- scriptPubKey = scriptPubKeyIn;
- }
-
- IMPLEMENT_SERIALIZE
- (
- READWRITE(nValue);
- READWRITE(scriptPubKey);
- )
-
- void SetNull()
- {
- nValue = -1;
- scriptPubKey.clear();
- }
-
- bool IsNull() const
- {
- return (nValue == -1);
- }
-
- uint256 GetHash() const
- {
- return SerializeHash(*this);
- }
-
- friend bool operator==(const CTxOut& a, const CTxOut& b)
- {
- return (a.nValue == b.nValue &&
- a.scriptPubKey == b.scriptPubKey);
- }
-
- friend bool operator!=(const CTxOut& a, const CTxOut& b)
- {
- return !(a == b);
- }
-
- bool IsDust() const;
-
- std::string ToString() const
- {
- if (scriptPubKey.size() < 6)
- return "CTxOut(error)";
- return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30).c_str());
- }
-
- void print() const
- {
- printf("%s\n", ToString().c_str());
- }
-};
-
-
-
enum GetMinFee_mode
{
GMF_BLOCK,
@@ -412,215 +263,71 @@ enum GetMinFee_mode
int64 GetMinFee(const CTransaction& tx, unsigned int nBlockSize = 1, bool fAllowFree = true, enum GetMinFee_mode mode = GMF_BLOCK);
-/** The basic transaction that is broadcasted on the network and contained in
- * blocks. A transaction can contain multiple inputs and outputs.
- */
-class CTransaction
-{
-public:
- static int64 nMinTxFee;
- static int64 nMinRelayTxFee;
- static const int CURRENT_VERSION=1;
- int nVersion;
- std::vector<CTxIn> vin;
- std::vector<CTxOut> vout;
- unsigned int nLockTime;
-
- CTransaction()
- {
- SetNull();
- }
-
- IMPLEMENT_SERIALIZE
- (
- READWRITE(this->nVersion);
- nVersion = this->nVersion;
- READWRITE(vin);
- READWRITE(vout);
- READWRITE(nLockTime);
- )
-
- void SetNull()
- {
- nVersion = CTransaction::CURRENT_VERSION;
- vin.clear();
- vout.clear();
- nLockTime = 0;
- }
-
- bool IsNull() const
- {
- return (vin.empty() && vout.empty());
- }
-
- uint256 GetHash() const
- {
- return SerializeHash(*this);
- }
-
- bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const
- {
- // Time based nLockTime implemented in 0.1.6
- if (nLockTime == 0)
- return true;
- if (nBlockHeight == 0)
- nBlockHeight = nBestHeight;
- if (nBlockTime == 0)
- nBlockTime = GetAdjustedTime();
- if ((int64)nLockTime < ((int64)nLockTime < LOCKTIME_THRESHOLD ? (int64)nBlockHeight : nBlockTime))
- return true;
- BOOST_FOREACH(const CTxIn& txin, vin)
- if (!txin.IsFinal())
- return false;
- return true;
- }
-
- bool IsNewerThan(const CTransaction& old) const
- {
- if (vin.size() != old.vin.size())
- return false;
- for (unsigned int i = 0; i < vin.size(); i++)
- if (vin[i].prevout != old.vin[i].prevout)
- return false;
-
- bool fNewer = false;
- unsigned int nLowest = std::numeric_limits<unsigned int>::max();
- for (unsigned int i = 0; i < vin.size(); i++)
- {
- if (vin[i].nSequence != old.vin[i].nSequence)
- {
- if (vin[i].nSequence <= nLowest)
- {
- fNewer = false;
- nLowest = vin[i].nSequence;
- }
- if (old.vin[i].nSequence < nLowest)
- {
- fNewer = true;
- nLowest = old.vin[i].nSequence;
- }
- }
- }
- return fNewer;
- }
-
- bool IsCoinBase() const
- {
- return (vin.size() == 1 && vin[0].prevout.IsNull());
- }
-
- /** Check for standard transaction types
- @return True if all outputs (scriptPubKeys) use only standard transaction forms
- */
- bool IsStandard() const;
+//
+// Check transaction inputs, and make sure any
+// pay-to-script-hash transactions are evaluating IsStandard scripts
+//
+// Why bother? To avoid denial-of-service attacks; an attacker
+// can submit a standard HASH... OP_EQUAL transaction,
+// which will get accepted into blocks. The redemption
+// script can be anything; an attacker could use a very
+// expensive-to-check-upon-redemption script like:
+// DUP CHECKSIG DROP ... repeated 100 times... OP_1
+//
/** Check for standard transaction types
- @param[in] mapInputs Map of previous transactions that have outputs we're spending
+ @param[in] mapInputs Map of previous transactions that have outputs we're spending
@return True if all inputs (scriptSigs) use only standard transaction forms
*/
- bool AreInputsStandard(CCoinsViewCache& mapInputs) const;
+bool AreInputsStandard(const CTransaction& tx, CCoinsViewCache& mapInputs);
- /** Count ECDSA signature operations the old-fashioned (pre-0.6) way
- @return number of sigops this transaction's outputs will produce when spent
- */
- unsigned int GetLegacySigOpCount() const;
+/** Count ECDSA signature operations the old-fashioned (pre-0.6) way
+ @return number of sigops this transaction's outputs will produce when spent
+ @see CTransaction::FetchInputs
+*/
+unsigned int GetLegacySigOpCount(const CTransaction& tx);
- /** Count ECDSA signature operations in pay-to-script-hash inputs.
-
- @param[in] mapInputs Map of previous transactions that have outputs we're spending
- @return maximum number of sigops required to validate this transaction's inputs
- */
- unsigned int GetP2SHSigOpCount(CCoinsViewCache& mapInputs) const;
-
- /** Amount of bitcoins spent by this transaction.
- @return sum of all outputs (note: does not include fees)
- */
- int64 GetValueOut() const
- {
- int64 nValueOut = 0;
- BOOST_FOREACH(const CTxOut& txout, vout)
- {
- nValueOut += txout.nValue;
- if (!MoneyRange(txout.nValue) || !MoneyRange(nValueOut))
- throw std::runtime_error("CTransaction::GetValueOut() : value out of range");
- }
- return nValueOut;
- }
-
- /** Amount of bitcoins coming in to this transaction
- Note that lightweight clients may not know anything besides the hash of previous transactions,
- so may not be able to calculate this.
-
- @param[in] mapInputs Map of previous transactions that have outputs we're spending
- @return Sum of value of all inputs (scriptSigs)
- */
- int64 GetValueIn(CCoinsViewCache& mapInputs) const;
-
- static bool AllowFree(double dPriority)
- {
- // Large (in bytes) low-priority (new, small-coin) transactions
- // need a fee.
- return dPriority > COIN * 144 / 250;
- }
-
- friend bool operator==(const CTransaction& a, const CTransaction& b)
- {
- return (a.nVersion == b.nVersion &&
- a.vin == b.vin &&
- a.vout == b.vout &&
- a.nLockTime == b.nLockTime);
- }
-
- friend bool operator!=(const CTransaction& a, const CTransaction& b)
- {
- return !(a == b);
- }
+/** Count ECDSA signature operations in pay-to-script-hash inputs.
+ @param[in] mapInputs Map of previous transactions that have outputs we're spending
+ @return maximum number of sigops required to validate this transaction's inputs
+ @see CTransaction::FetchInputs
+ */
+unsigned int GetP2SHSigOpCount(const CTransaction& tx, CCoinsViewCache& mapInputs);
- std::string ToString() const
- {
- std::string str;
- str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%"PRIszu", vout.size=%"PRIszu", nLockTime=%u)\n",
- GetHash().ToString().c_str(),
- nVersion,
- vin.size(),
- vout.size(),
- nLockTime);
- for (unsigned int i = 0; i < vin.size(); i++)
- str += " " + vin[i].ToString() + "\n";
- for (unsigned int i = 0; i < vout.size(); i++)
- str += " " + vout[i].ToString() + "\n";
- return str;
- }
- void print() const
- {
- printf("%s", ToString().c_str());
- }
+inline bool AllowFree(double dPriority)
+{
+ // Large (in bytes) low-priority (new, small-coin) transactions
+ // need a fee.
+ return dPriority > COIN * 144 / 250;
+}
+// Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts)
+// This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it
+// instead of being performed inline.
+bool CheckInputs(const CTransaction& tx, CValidationState &state, CCoinsViewCache &view, bool fScriptChecks = true,
+ unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC,
+ std::vector<CScriptCheck> *pvChecks = NULL);
- // Check whether all prevouts of this transaction are present in the UTXO set represented by view
- bool HaveInputs(CCoinsViewCache &view) const;
+// Apply the effects of this transaction on the UTXO set represented by view
+bool UpdateCoins(const CTransaction& tx, CCoinsViewCache &view, CTxUndo &txundo, int nHeight, const uint256 &txhash);
- // Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts)
- // This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it
- // instead of being performed inline.
- bool CheckInputs(CValidationState &state, CCoinsViewCache &view, bool fScriptChecks = true,
- unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC,
- std::vector<CScriptCheck> *pvChecks = NULL) const;
+// Context-independent validity checks
+bool CheckTransaction(const CTransaction& tx, CValidationState& state);
- // Apply the effects of this transaction on the UTXO set represented by view
- void UpdateCoins(CValidationState &state, CCoinsViewCache &view, CTxUndo &txundo, int nHeight, const uint256 &txhash) const;
+/** Check for standard transaction types
+ @return True if all outputs (scriptPubKeys) use only standard transaction forms
+*/
+bool IsStandardTx(const CTransaction& tx);
- // Context-independent validity checks
- bool CheckTransaction(CValidationState &state) const;
+bool IsFinalTx(const CTransaction &tx, int nBlockHeight = 0, int64 nBlockTime = 0);
- // Try to accept this transaction into the memory pool
- bool AcceptToMemoryPool(CValidationState &state, bool fCheckInputs=true, bool fLimitFree = true, bool* pfMissingInputs=NULL);
+/** Amount of bitcoins spent by the transaction.
+ @return sum of all outputs (note: does not include fees)
+ */
+int64 GetValueOut(const CTransaction& tx);
-protected:
- static const CTxOut &GetOutputFor(const CTxIn& input, CCoinsViewCache& mapInputs);
-};
/** wrapper for CTxOut that provides a more compact serialization */
class CTxOutCompressor
@@ -2132,6 +1839,21 @@ public:
// Calculate the size of the cache (in number of transactions)
unsigned int GetCacheSize();
+ /** Amount of bitcoins coming in to a transaction
+ Note that lightweight clients may not know anything besides the hash of previous transactions,
+ so may not be able to calculate this.
+
+ @param[in] tx transaction for which we are checking input total
+ @return Sum of value of all inputs (scriptSigs)
+ @see CTransaction::FetchInputs
+ */
+ int64 GetValueIn(const CTransaction& tx);
+
+ // Check whether all prevouts of the transaction are present in the UTXO set represented by this view
+ bool HaveInputs(const CTransaction& tx);
+
+ const CTxOut &GetOutputFor(const CTxIn& input);
+
private:
std::map<uint256,CCoins>::iterator FetchCoins(const uint256 &txid);
};