aboutsummaryrefslogtreecommitdiff
path: root/src/primitives/transaction.h
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2016-06-24 16:25:44 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2016-06-24 18:07:44 +0200
commitd612837814020ae832499d18e6ee5eb919a87907 (patch)
treea93b5e382503577109efaa5cf7526e4dc378b7ea /src/primitives/transaction.h
parentaf2421c291c42fd0119bf27261fdeeba93cadbcc (diff)
parentf8528134fc188abc5c7175a19680206964a8fade (diff)
downloadbitcoin-d612837814020ae832499d18e6ee5eb919a87907.tar.xz
Merge #8149: Segregated witness rebased
f852813 BIP9 parameters for testnet (Johnson Lau) 070dbc4 --- [SEGWIT] begin: deployment --- (Pieter Wuille) fdb43df [qa] Add GetTransactionSigOpCost unit tests (Jonas Nick) d846e02 [qa] script_tests: witness tests can specify tx amount (Suhas Daftuar) 330b0f3 [qa] p2p segwit tests (Suhas Daftuar) 4f7ff00 [qa] Add rpc test for segwit (Alex Morcos) 66cca79 [qa] Autogeneration support for witness in script_tests (Pieter Wuille) 06d3805 [qa] Add segwit support to script_tests (Pieter Wuille) 00f46cb [qa] Add transaction tests for segwit (NicolasDorier) 0aa9207 [qa] Witness version 0 signing unit tests (Pieter Wuille) 978e200 --- [SEGWIT] begin: tests --- (Pieter Wuille) 745eb67 [RPC] signrawtransaction can sign P2WSH (NicolasDorier) f4691ab [RPC] Add wallet support for witness transactions (using P2SH) (Pieter Wuille) 605e847 BIP143: Signing logic (Pieter Wuille) 9757b57 --- [SEGWIT] begin: wallet --- (Pieter Wuille) af87a67 Do not use compact blocks when segwit is enabled (Pieter Wuille) 6032f69 Add rewind logic to deal with post-fork software updates (Pieter Wuille) b7dbeb2 [libconsensus] Script verification API with amounts (Thomas Kerin) 2b1f6f9 BIP141: Other consensus critical limits, and BIP145 (Pieter Wuille) 7c4bf77 [RPC] Return witness data in blockchain RPCs (Johnson Lau) 3dd4102 BIP143: Verification logic (Pieter Wuille) 0ef1dd3 Refactor script validation to observe amounts (Pieter Wuille) b8a9749 BIP144: Handshake and relay (receiver side) (Pieter Wuille) 8b49040 BIP141: Commitment structure and deployment (Pieter Wuille) 449f9b8 BIP141: Witness program (Pieter Wuille) 7030d9e BIP144: Serialization, hashes, relay (sender side) (Pieter Wuille) ecacfd9 --- [SEGWIT] begin: P2P/node/consensus --- (Pieter Wuille)
Diffstat (limited to 'src/primitives/transaction.h')
-rw-r--r--src/primitives/transaction.h182
1 files changed, 166 insertions, 16 deletions
diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h
index 149816406a..e87ad90f0d 100644
--- a/src/primitives/transaction.h
+++ b/src/primitives/transaction.h
@@ -11,6 +11,10 @@
#include "serialize.h"
#include "uint256.h"
+static const int SERIALIZE_TRANSACTION_NO_WITNESS = 0x40000000;
+
+static const int WITNESS_SCALE_FACTOR = 4;
+
/** An outpoint - a combination of a transaction hash and an index n into its vout */
class COutPoint
{
@@ -164,15 +168,30 @@ public:
// 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 txout is 34 bytes big, and will
+ // 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)
+ // 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 0;
- size_t nSize = GetSerializeSize(SER_DISK,0)+148u;
- return 3*minRelayTxFee.GetFee(nSize);
+ size_t nSize = GetSerializeSize(SER_DISK, 0);
+ int witnessversion = 0;
+ std::vector<unsigned char> witnessprogram;
+
+ if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
+ // sum the sizes of the parts of a transaction input
+ // with 75% segwit discount applied to the script size.
+ nSize += (32 + 4 + 1 + (107 / WITNESS_SCALE_FACTOR) + 4);
+ } else {
+ nSize += (32 + 4 + 1 + 107 + 4); // the 148 mentioned above
+ }
+
+ return 3 * minRelayTxFee.GetFee(nSize);
}
bool IsDust(const CFeeRate &minRelayTxFee) const
@@ -194,8 +213,137 @@ public:
std::string ToString() const;
};
+class CTxinWitness
+{
+public:
+ CScriptWitness scriptWitness;
+
+ ADD_SERIALIZE_METHODS;
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
+ {
+ READWRITE(scriptWitness.stack);
+ }
+
+ bool IsNull() const { return scriptWitness.IsNull(); }
+
+ CTxinWitness() { }
+};
+
+class CTxWitness
+{
+public:
+ /** In case vtxinwit is missing, all entries are treated as if they were empty CTxInWitnesses */
+ std::vector<CTxinWitness> vtxinwit;
+
+ ADD_SERIALIZE_METHODS;
+
+ bool IsEmpty() const { return vtxinwit.empty(); }
+
+ bool IsNull() const
+ {
+ for (size_t n = 0; n < vtxinwit.size(); n++) {
+ if (!vtxinwit[n].IsNull()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ void SetNull()
+ {
+ vtxinwit.clear();
+ }
+
+ template <typename Stream, typename Operation>
+ inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
+ {
+ for (size_t n = 0; n < vtxinwit.size(); n++) {
+ READWRITE(vtxinwit[n]);
+ }
+ if (IsNull()) {
+ /* It's illegal to encode a witness when all vtxinwit entries are empty. */
+ throw std::ios_base::failure("Superfluous witness record");
+ }
+ }
+};
+
struct CMutableTransaction;
+/**
+ * Basic transaction serialization format:
+ * - int32_t nVersion
+ * - std::vector<CTxIn> vin
+ * - std::vector<CTxOut> vout
+ * - uint32_t nLockTime
+ *
+ * Extended transaction serialization format:
+ * - int32_t nVersion
+ * - unsigned char dummy = 0x00
+ * - unsigned char flags (!= 0)
+ * - std::vector<CTxIn> vin
+ * - std::vector<CTxOut> vout
+ * - if (flags & 1):
+ * - CTxWitness wit;
+ * - uint32_t nLockTime
+ */
+template<typename Stream, typename Operation, typename TxType>
+inline void SerializeTransaction(TxType& tx, Stream& s, Operation ser_action, int nType, int nVersion) {
+ READWRITE(*const_cast<int32_t*>(&tx.nVersion));
+ unsigned char flags = 0;
+ if (ser_action.ForRead()) {
+ const_cast<std::vector<CTxIn>*>(&tx.vin)->clear();
+ const_cast<std::vector<CTxOut>*>(&tx.vout)->clear();
+ const_cast<CTxWitness*>(&tx.wit)->SetNull();
+ /* Try to read the vin. In case the dummy is there, this will be read as an empty vector. */
+ READWRITE(*const_cast<std::vector<CTxIn>*>(&tx.vin));
+ if (tx.vin.size() == 0 && !(nVersion & SERIALIZE_TRANSACTION_NO_WITNESS)) {
+ /* We read a dummy or an empty vin. */
+ READWRITE(flags);
+ if (flags != 0) {
+ READWRITE(*const_cast<std::vector<CTxIn>*>(&tx.vin));
+ READWRITE(*const_cast<std::vector<CTxOut>*>(&tx.vout));
+ }
+ } else {
+ /* We read a non-empty vin. Assume a normal vout follows. */
+ READWRITE(*const_cast<std::vector<CTxOut>*>(&tx.vout));
+ }
+ if ((flags & 1) && !(nVersion & SERIALIZE_TRANSACTION_NO_WITNESS)) {
+ /* The witness flag is present, and we support witnesses. */
+ flags ^= 1;
+ const_cast<CTxWitness*>(&tx.wit)->vtxinwit.resize(tx.vin.size());
+ READWRITE(tx.wit);
+ }
+ if (flags) {
+ /* Unknown flag in the serialization */
+ throw std::ios_base::failure("Unknown transaction optional data");
+ }
+ } else {
+ // Consistency check
+ assert(tx.wit.vtxinwit.size() <= tx.vin.size());
+ if (!(nVersion & SERIALIZE_TRANSACTION_NO_WITNESS)) {
+ /* Check whether witnesses need to be serialized. */
+ if (!tx.wit.IsNull()) {
+ flags |= 1;
+ }
+ }
+ if (flags) {
+ /* Use extended format in case witnesses are to be serialized. */
+ std::vector<CTxIn> vinDummy;
+ READWRITE(vinDummy);
+ READWRITE(flags);
+ }
+ READWRITE(*const_cast<std::vector<CTxIn>*>(&tx.vin));
+ READWRITE(*const_cast<std::vector<CTxOut>*>(&tx.vout));
+ if (flags & 1) {
+ const_cast<CTxWitness*>(&tx.wit)->vtxinwit.resize(tx.vin.size());
+ READWRITE(tx.wit);
+ }
+ }
+ READWRITE(*const_cast<uint32_t*>(&tx.nLockTime));
+}
+
/** The basic transaction that is broadcasted on the network and contained in
* blocks. A transaction can contain multiple inputs and outputs.
*/
@@ -204,7 +352,6 @@ class CTransaction
private:
/** Memory only. */
const uint256 hash;
- void UpdateHash() const;
public:
// Default transaction version.
@@ -224,6 +371,7 @@ public:
const int32_t nVersion;
const std::vector<CTxIn> vin;
const std::vector<CTxOut> vout;
+ CTxWitness wit; // Not const: can change without invalidating the txid cache
const uint32_t nLockTime;
/** Construct a CTransaction that qualifies as IsNull() */
@@ -238,13 +386,10 @@ public:
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(*const_cast<int32_t*>(&this->nVersion));
- nVersion = this->nVersion;
- READWRITE(*const_cast<std::vector<CTxIn>*>(&vin));
- READWRITE(*const_cast<std::vector<CTxOut>*>(&vout));
- READWRITE(*const_cast<uint32_t*>(&nLockTime));
- if (ser_action.ForRead())
+ SerializeTransaction(*this, s, ser_action, nType, nVersion);
+ if (ser_action.ForRead()) {
UpdateHash();
+ }
}
bool IsNull() const {
@@ -255,6 +400,9 @@ public:
return hash;
}
+ // Compute a hash that includes both transaction and witness data
+ uint256 GetWitnessHash() const;
+
// Return sum of txouts.
CAmount GetValueOut() const;
// GetValueIn() is a method on CCoinsViewCache, because
@@ -282,6 +430,8 @@ public:
}
std::string ToString() const;
+
+ void UpdateHash() const;
};
/** A mutable version of CTransaction. */
@@ -290,6 +440,7 @@ struct CMutableTransaction
int32_t nVersion;
std::vector<CTxIn> vin;
std::vector<CTxOut> vout;
+ CTxWitness wit;
uint32_t nLockTime;
CMutableTransaction();
@@ -299,11 +450,7 @@ struct CMutableTransaction
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(this->nVersion);
- nVersion = this->nVersion;
- READWRITE(vin);
- READWRITE(vout);
- READWRITE(nLockTime);
+ SerializeTransaction(*this, s, ser_action, nType, nVersion);
}
/** Compute the hash of this CMutableTransaction. This is computed on the
@@ -312,4 +459,7 @@ struct CMutableTransaction
uint256 GetHash() const;
};
+/** Compute the cost of a transaction, as defined by BIP 141 */
+int64_t GetTransactionCost(const CTransaction &tx);
+
#endif // BITCOIN_PRIMITIVES_TRANSACTION_H