diff --git a/src/core_io.h b/src/core_io.h index e1bf406b6..1ad776b4c 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -1,36 +1,36 @@ // Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_CORE_IO_H #define BITCOIN_CORE_IO_H #include #include class CBlock; +class CMutableTransaction; class CScript; class CTransaction; -struct CMutableTransaction; class uint256; class UniValue; // core_read.cpp CScript ParseScript(const std::string &s); std::string ScriptToAsmStr(const CScript &script, const bool fAttemptSighashDecode = false); bool DecodeHexTx(CMutableTransaction &tx, const std::string &strHexTx); bool DecodeHexBlk(CBlock &, const std::string &strHexBlk); uint256 ParseHashUV(const UniValue &v, const std::string &strName); uint256 ParseHashStr(const std::string &, const std::string &strName); std::vector ParseHexUV(const UniValue &v, const std::string &strName); // core_write.cpp std::string FormatScript(const CScript &script); std::string EncodeHexTx(const CTransaction &tx, const int serializeFlags = 0); void ScriptPubKeyToUniv(const CScript &scriptPubKey, UniValue &out, bool fIncludeHex); void TxToUniv(const CTransaction &tx, const uint256 &hashBlock, UniValue &entry); #endif // BITCOIN_CORE_IO_H diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 3b205c1f5..853e52f4b 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -1,365 +1,368 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_PRIMITIVES_TRANSACTION_H #define BITCOIN_PRIMITIVES_TRANSACTION_H #include "amount.h" #include "script/script.h" #include "serialize.h" #include "uint256.h" static const int SERIALIZE_TRANSACTION = 0x00; /** An outpoint - a combination of a transaction hash and an index n into its * vout */ class COutPoint { public: uint256 hash; uint32_t n; COutPoint() { SetNull(); } COutPoint(uint256 hashIn, uint32_t nIn) { hash = hashIn; n = nIn; } ADD_SERIALIZE_METHODS; template inline void SerializationOp(Stream &s, Operation ser_action) { READWRITE(hash); READWRITE(n); } void SetNull() { hash.SetNull(); n = (uint32_t)-1; } bool IsNull() const { return (hash.IsNull() && n == (uint32_t)-1); } friend bool operator<(const COutPoint &a, const COutPoint &b) { int cmp = a.hash.Compare(b.hash); return cmp < 0 || (cmp == 0 && a.n < b.n); } friend bool operator==(const COutPoint &a, const COutPoint &b) { return (a.hash == b.hash && a.n == b.n); } friend bool operator!=(const COutPoint &a, const COutPoint &b) { return !(a == b); } std::string ToString() const; }; /** 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; uint32_t nSequence; /* Setting nSequence to this value for every input in a transaction * disables nLockTime. */ static const uint32_t SEQUENCE_FINAL = 0xffffffff; /* Below flags apply in the context of BIP 68*/ /* If this flag set, CTxIn::nSequence is NOT interpreted as a * relative lock-time. */ static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1 << 31); /* If CTxIn::nSequence encodes a relative lock-time and this flag * is set, the relative lock-time has units of 512 seconds, * otherwise it specifies blocks with a granularity of 1. */ static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22); /* If CTxIn::nSequence encodes a relative lock-time, this mask is * applied to extract that lock-time from the sequence field. */ static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff; /* In order to use the same number of bits to encode roughly the * same wall-clock duration, and because blocks are naturally * limited to occur every 600s on average, the minimum granularity * for time-based relative lock-time is fixed at 512 seconds. * Converting from CTxIn::nSequence to seconds is performed by * multiplying by 512 = 2^9, or equivalently shifting up by * 9 bits. */ static const int SEQUENCE_LOCKTIME_GRANULARITY = 9; CTxIn() { nSequence = SEQUENCE_FINAL; } explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn = CScript(), uint32_t nSequenceIn = SEQUENCE_FINAL); CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn = CScript(), uint32_t nSequenceIn = SEQUENCE_FINAL); ADD_SERIALIZE_METHODS; template inline void SerializationOp(Stream &s, Operation ser_action) { READWRITE(prevout); READWRITE(*(CScriptBase *)(&scriptSig)); READWRITE(nSequence); } 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; }; /** * 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: Amount nValue; CScript scriptPubKey; CTxOut() { SetNull(); } CTxOut(const Amount &nValueIn, CScript scriptPubKeyIn); ADD_SERIALIZE_METHODS; template inline void SerializationOp(Stream &s, Operation ser_action) { READWRITE(nValue); READWRITE(*(CScriptBase *)(&scriptPubKey)); } void SetNull() { nValue = Amount(-1); scriptPubKey.clear(); } bool IsNull() const { return (nValue == Amount(-1)); } Amount GetDustThreshold(const CFeeRate &minRelayTxFee) const { // "Dust" is defined in terms of CTransaction::minRelayTxFee, which has // units satoshis-per-kilobyte. If you'd pay more than 1/3 in fees to // spend something, then we consider it dust. A typical spendable // non-segwit txout is 34 bytes big, and will need a CTxIn of at least // 148 bytes to spend: so dust is a spendable txout less than // 546*minRelayTxFee/1000 (in satoshis). A typical spendable segwit // txout is 31 bytes big, and will need a CTxIn of at least 67 bytes to // spend: so dust is a spendable txout less than 294*minRelayTxFee/1000 // (in satoshis). if (scriptPubKey.IsUnspendable()) return Amount(0); size_t nSize = GetSerializeSize(*this, SER_DISK, 0); // the 148 mentioned above nSize += (32 + 4 + 1 + 107 + 4); return 3 * minRelayTxFee.GetFee(nSize); } bool IsDust(const CFeeRate &minRelayTxFee) const { return (nValue < GetDustThreshold(minRelayTxFee)); } 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); } std::string ToString() const; }; -struct CMutableTransaction; +class CMutableTransaction; /** * Basic transaction serialization format: * - int32_t nVersion * - std::vector vin * - std::vector vout * - uint32_t nLockTime */ template inline void UnserializeTransaction(TxType &tx, Stream &s) { s >> tx.nVersion; tx.vin.clear(); tx.vout.clear(); /* Try to read the vin. In case the dummy is there, this will be read as an * empty vector. */ s >> tx.vin; /* We read a non-empty vin. Assume a normal vout follows. */ s >> tx.vout; s >> tx.nLockTime; } template inline void SerializeTransaction(const TxType &tx, Stream &s) { s << tx.nVersion; s << tx.vin; s << tx.vout; s << tx.nLockTime; } /** The basic transaction that is broadcasted on the network and contained in * blocks. A transaction can contain multiple inputs and outputs. */ class CTransaction { public: // Default transaction version. static const int32_t CURRENT_VERSION = 2; // Changing the default transaction version requires a two step process: // first adapting relay policy by bumping MAX_STANDARD_VERSION, and then // later date bumping the default CURRENT_VERSION at which point both // CURRENT_VERSION and MAX_STANDARD_VERSION will be equal. static const int32_t MAX_STANDARD_VERSION = 2; // The local variables are made const to prevent unintended modification // without updating the cached hash value. However, CTransaction is not // actually immutable; deserialization and assignment are implemented, // and bypass the constness. This is safe, as they update the entire // structure, including the hash. const int32_t nVersion; const std::vector vin; const std::vector vout; const uint32_t nLockTime; private: /** Memory only. */ const uint256 hash; uint256 ComputeHash() const; public: /** Construct a CTransaction that qualifies as IsNull() */ CTransaction(); /** Convert a CMutableTransaction into a CTransaction. */ CTransaction(const CMutableTransaction &tx); CTransaction(CMutableTransaction &&tx); template inline void Serialize(Stream &s) const { SerializeTransaction(*this, s); } /** This deserializing constructor is provided instead of an Unserialize * method. Unserialize is not possible, since it would require overwriting * const fields. */ template CTransaction(deserialize_type, Stream &s) : CTransaction(CMutableTransaction(deserialize, s)) {} bool IsNull() const { return vin.empty() && vout.empty(); } const uint256 &GetId() const { return hash; } // Compute a hash that includes both transaction and witness data uint256 GetHash() const; // Return sum of txouts. Amount GetValueOut() const; // GetValueIn() is a method on CCoinsViewCache, because // inputs must be known to compute value in. // Compute priority, given priority of inputs and (optionally) tx size double ComputePriority(double dPriorityInputs, unsigned int nTxSize = 0) const; // Compute modified tx size for priority calculation (optionally given tx // size) unsigned int CalculateModifiedSize(unsigned int nTxSize = 0) const; /** * Get the total transaction size in bytes. * @return Total transaction size in bytes */ unsigned int GetTotalSize() const; bool IsCoinBase() const { return (vin.size() == 1 && vin[0].prevout.IsNull()); } friend bool operator==(const CTransaction &a, const CTransaction &b) { return a.hash == b.hash; } friend bool operator!=(const CTransaction &a, const CTransaction &b) { return a.hash != b.hash; } std::string ToString() const; }; -/** A mutable version of CTransaction. */ -struct CMutableTransaction { +/** + * A mutable version of CTransaction. + */ +class CMutableTransaction { +public: int32_t nVersion; std::vector vin; std::vector vout; uint32_t nLockTime; CMutableTransaction(); CMutableTransaction(const CTransaction &tx); template inline void Serialize(Stream &s) const { SerializeTransaction(*this, s); } template inline void Unserialize(Stream &s) { UnserializeTransaction(*this, s); } template CMutableTransaction(deserialize_type, Stream &s) { Unserialize(s); } /** Compute the hash of this CMutableTransaction. This is computed on the * fly, as opposed to GetId() in CTransaction, which uses a cached result. */ uint256 GetId() const; friend bool operator==(const CMutableTransaction &a, const CMutableTransaction &b) { return a.GetId() == b.GetId(); } }; typedef std::shared_ptr CTransactionRef; static inline CTransactionRef MakeTransactionRef() { return std::make_shared(); } template static inline CTransactionRef MakeTransactionRef(Tx &&txIn) { return std::make_shared(std::forward(txIn)); } /** Compute the size of a transaction */ int64_t GetTransactionSize(const CTransaction &tx); /** Precompute sighash midstate to avoid quadratic hashing */ struct PrecomputedTransactionData { uint256 hashPrevouts, hashSequence, hashOutputs; PrecomputedTransactionData() : hashPrevouts(), hashSequence(), hashOutputs() {} PrecomputedTransactionData(const PrecomputedTransactionData &txdata) : hashPrevouts(txdata.hashPrevouts), hashSequence(txdata.hashSequence), hashOutputs(txdata.hashOutputs) {} PrecomputedTransactionData(const CTransaction &tx); }; #endif // BITCOIN_PRIMITIVES_TRANSACTION_H diff --git a/src/script/sign.h b/src/script/sign.h index 05de6398f..c52ce751c 100644 --- a/src/script/sign.h +++ b/src/script/sign.h @@ -1,107 +1,106 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_SCRIPT_SIGN_H #define BITCOIN_SCRIPT_SIGN_H #include "script/interpreter.h" class CKeyID; class CKeyStore; +class CMutableTransaction; class CScript; class CTransaction; -struct CMutableTransaction; - /** Virtual base class for signature creators. */ class BaseSignatureCreator { protected: const CKeyStore *keystore; public: BaseSignatureCreator(const CKeyStore *keystoreIn) : keystore(keystoreIn) {} const CKeyStore &KeyStore() const { return *keystore; }; virtual ~BaseSignatureCreator() {} virtual const BaseSignatureChecker &Checker() const = 0; /** Create a singular (non-script) signature. */ virtual bool CreateSig(std::vector &vchSig, const CKeyID &keyid, const CScript &scriptCode) const = 0; }; /** A signature creator for transactions. */ class TransactionSignatureCreator : public BaseSignatureCreator { const CTransaction *txTo; unsigned int nIn; Amount amount; uint32_t nHashType; const TransactionSignatureChecker checker; public: TransactionSignatureCreator(const CKeyStore *keystoreIn, const CTransaction *txToIn, unsigned int nInIn, const Amount amountIn, uint32_t nHashTypeIn = SIGHASH_ALL); const BaseSignatureChecker &Checker() const { return checker; } bool CreateSig(std::vector &vchSig, const CKeyID &keyid, const CScript &scriptCode) const; }; class MutableTransactionSignatureCreator : public TransactionSignatureCreator { CTransaction tx; public: MutableTransactionSignatureCreator(const CKeyStore *keystoreIn, const CMutableTransaction *txToIn, unsigned int nInIn, const Amount amount, uint32_t nHashTypeIn) : TransactionSignatureCreator(keystoreIn, &tx, nInIn, amount, nHashTypeIn), tx(*txToIn) {} }; /** A signature creator that just produces 72-byte empty signatures. */ class DummySignatureCreator : public BaseSignatureCreator { public: DummySignatureCreator(const CKeyStore *keystoreIn) : BaseSignatureCreator(keystoreIn) {} const BaseSignatureChecker &Checker() const; bool CreateSig(std::vector &vchSig, const CKeyID &keyid, const CScript &scriptCode) const; }; struct SignatureData { CScript scriptSig; SignatureData() {} explicit SignatureData(const CScript &script) : scriptSig(script) {} }; /** Produce a script signature using a generic signature creator. */ bool ProduceSignature(const BaseSignatureCreator &creator, const CScript &scriptPubKey, SignatureData &sigdata); /** Produce a script signature for a transaction. */ bool SignSignature(const CKeyStore &keystore, const CScript &fromPubKey, CMutableTransaction &txTo, unsigned int nIn, const Amount amount, uint32_t nHashType); bool SignSignature(const CKeyStore &keystore, const CTransaction &txFrom, CMutableTransaction &txTo, unsigned int nIn, uint32_t nHashType); /** Combine two script signatures using a generic signature checker, * intelligently, possibly with OP_0 placeholders. */ SignatureData CombineSignatures(const CScript &scriptPubKey, const BaseSignatureChecker &checker, const SignatureData &scriptSig1, const SignatureData &scriptSig2); /** Extract signature data from a transaction, and insert it. */ SignatureData DataFromTransaction(const CMutableTransaction &tx, unsigned int nIn); void UpdateTransaction(CMutableTransaction &tx, unsigned int nIn, const SignatureData &data); #endif // BITCOIN_SCRIPT_SIGN_H diff --git a/src/test/test_bitcoin.h b/src/test/test_bitcoin.h index da891a142..4f078147d 100644 --- a/src/test/test_bitcoin.h +++ b/src/test/test_bitcoin.h @@ -1,112 +1,112 @@ // Copyright (c) 2015-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_TEST_TEST_BITCOIN_H #define BITCOIN_TEST_TEST_BITCOIN_H #include "chainparamsbase.h" #include "key.h" #include "pubkey.h" #include "txdb.h" #include "txmempool.h" #include #include /** Basic testing setup. * This just configures logging and chain parameters. */ struct BasicTestingSetup { ECCVerifyHandle globalVerifyHandle; BasicTestingSetup(const std::string &chainName = CBaseChainParams::MAIN); ~BasicTestingSetup(); }; /** Testing setup that configures a complete environment. * Included are data directory, coins database, script check threads setup. */ class CConnman; struct TestingSetup : public BasicTestingSetup { CCoinsViewDB *pcoinsdbview; boost::filesystem::path pathTemp; boost::thread_group threadGroup; CConnman *connman; TestingSetup(const std::string &chainName = CBaseChainParams::MAIN); ~TestingSetup(); }; class CBlock; -struct CMutableTransaction; +class CMutableTransaction; class CScript; // // Testing fixture that pre-creates a // 100-block REGTEST-mode block chain // struct TestChain100Setup : public TestingSetup { TestChain100Setup(); // Create a new block with just given transactions, coinbase paying to // scriptPubKey, and try to add it to the current chain. CBlock CreateAndProcessBlock(const std::vector &txns, const CScript &scriptPubKey); ~TestChain100Setup(); // For convenience, coinbase transactions. std::vector coinbaseTxns; // private/public key needed to spend coinbase transactions. CKey coinbaseKey; }; class CTxMemPoolEntry; class CTxMemPool; struct TestMemPoolEntryHelper { // Default values Amount nFee; int64_t nTime; double dPriority; unsigned int nHeight; bool spendsCoinbase; unsigned int sigOpCost; LockPoints lp; TestMemPoolEntryHelper() : nFee(0), nTime(0), dPriority(0.0), nHeight(1), spendsCoinbase(false), sigOpCost(4) {} CTxMemPoolEntry FromTx(const CMutableTransaction &tx, CTxMemPool *pool = nullptr); CTxMemPoolEntry FromTx(const CTransaction &tx, CTxMemPool *pool = nullptr); // Change the default value TestMemPoolEntryHelper &Fee(Amount _fee) { nFee = _fee; return *this; } TestMemPoolEntryHelper &Time(int64_t _time) { nTime = _time; return *this; } TestMemPoolEntryHelper &Priority(double _priority) { dPriority = _priority; return *this; } TestMemPoolEntryHelper &Height(unsigned int _height) { nHeight = _height; return *this; } TestMemPoolEntryHelper &SpendsCoinbase(bool _flag) { spendsCoinbase = _flag; return *this; } TestMemPoolEntryHelper &SigOpsCost(unsigned int _sigopsCost) { sigOpCost = _sigopsCost; return *this; } }; #endif