Skip to content

Commit

Permalink
Merge pull request bitcoin#44 from CryptAxe/ExCDPR
Browse files Browse the repository at this point in the history
Add new optional data to extended transactions
  • Loading branch information
psztorc committed Oct 19, 2017
2 parents 61f4244 + 9ce6a4e commit f6bb3d8
Show file tree
Hide file tree
Showing 11 changed files with 363 additions and 40 deletions.
1 change: 1 addition & 0 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ BITCOIN_TESTS =\
test/timedata_tests.cpp \
test/torcontrol_tests.cpp \
test/transaction_tests.cpp \
test/transaction_criticaldata_tests.cpp \
test/txvalidationcache_tests.cpp \
test/versionbits_tests.cpp \
test/uint256_tests.cpp \
Expand Down
2 changes: 1 addition & 1 deletion src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ CTxOut BlockAssembler::CreateSCDBHashMerkleRootCommit()
// For now just getting the old style SCDB hash and putting it into the
// commitment.
const uint256& hashMerkleRoot = scdb.GetSCDBHash();
CScript script = GenerateSCDBCoinbaseCommitment(hashMerkleRoot);
CScript script = GenerateSCDBHashMerkleRootCommitment(hashMerkleRoot);
return CTxOut(CENT, script);
}

Expand Down
14 changes: 9 additions & 5 deletions src/primitives/transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ std::string CTxOut::ToString() const
}

CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {}
CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {}

CMutableTransaction::CMutableTransaction(const CTransaction& tx) : vin(tx.vin), vout(tx.vout), criticalData(tx.criticalData), nVersion(tx.nVersion), nLockTime(tx.nLockTime) {}
uint256 CMutableTransaction::GetHash() const
{
return SerializeHash(*this, SER_GETHASH, SERIALIZE_TRANSACTION_NO_WITNESS);
Expand Down Expand Up @@ -95,9 +94,9 @@ bool CTransaction::GetBWTHash(uint256& hashRet) const
}

/* For backward compatibility, the hash is initialized to 0. TODO: remove the need for this default constructor entirely. */
CTransaction::CTransaction() : nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0), hash() {}
CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime), hash(ComputeHash()) {}
CTransaction::CTransaction(CMutableTransaction &&tx) : nVersion(tx.nVersion), vin(std::move(tx.vin)), vout(std::move(tx.vout)), nLockTime(tx.nLockTime), hash(ComputeHash()) {}
CTransaction::CTransaction() : vin(), vout(), criticalData(), nVersion(CTransaction::CURRENT_VERSION), nLockTime(0), hash() {}
CTransaction::CTransaction(const CMutableTransaction &tx) : vin(tx.vin), vout(tx.vout), criticalData(tx.criticalData), nVersion(tx.nVersion), nLockTime(tx.nLockTime), hash(ComputeHash()) {}
CTransaction::CTransaction(CMutableTransaction &&tx) : vin(std::move(tx.vin)), vout(std::move(tx.vout)), criticalData(tx.criticalData), nVersion(tx.nVersion), nLockTime(tx.nLockTime), hash(ComputeHash()) {}

CAmount CTransaction::GetValueOut() const
{
Expand Down Expand Up @@ -131,6 +130,11 @@ std::string CTransaction::ToString() const
str += " " + vin[i].scriptWitness.ToString() + "\n";
for (unsigned int i = 0; i < vout.size(); i++)
str += " " + vout[i].ToString() + "\n";
if (!criticalData.IsNull()) {
str += strprintf("Critical Data:\nbytes=%s\nhashCritical=%s",
std::string(criticalData.bytes.begin(), criticalData.bytes.end()),
criticalData.hashCritical.ToString());
}
return str;
}

Expand Down
61 changes: 56 additions & 5 deletions src/primitives/transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,37 @@ class CTxOut

struct CMutableTransaction;

class CCriticalData
{
public:
std::vector<unsigned char> bytes;
uint256 hashCritical;

CCriticalData()
{
SetNull();
}

ADD_SERIALIZE_METHODS;

template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(bytes);
READWRITE(hashCritical);
}

void SetNull()
{
bytes.clear();
hashCritical.SetNull();
}

bool IsNull() const
{
return (bytes.empty() && hashCritical.IsNull());
}
};

/**
* Basic transaction serialization format:
* - int32_t nVersion
Expand All @@ -191,12 +222,15 @@ struct CMutableTransaction;
* - std::vector<CTxIn> vin
* - std::vector<CTxOut> vout
* - if (flags & 1):
* - CTxWitness wit;
* - CScriptWitness scriptWitness;
* - if (flags & 2):
* - CCriticalData criticalData;
* - uint32_t nLockTime
*/
template<typename Stream, typename TxType>
inline void UnserializeTransaction(TxType& tx, Stream& s) {
const bool fAllowWitness = !(s.GetVersion() & SERIALIZE_TRANSACTION_NO_WITNESS);
const bool fAllowCriticalData = true; // TODO

s >> tx.nVersion;
unsigned char flags = 0;
Expand All @@ -222,6 +256,11 @@ inline void UnserializeTransaction(TxType& tx, Stream& s) {
s >> tx.vin[i].scriptWitness.stack;
}
}
if ((flags & 2) && fAllowCriticalData) {
/* The critical data flag is present, and we support critical data. */
flags ^= 2;
s >> tx.criticalData;
}
if (flags) {
/* Unknown flag in the serialization */
throw std::ios_base::failure("Unknown transaction optional data");
Expand All @@ -232,18 +271,25 @@ inline void UnserializeTransaction(TxType& tx, Stream& s) {
template<typename Stream, typename TxType>
inline void SerializeTransaction(const TxType& tx, Stream& s) {
const bool fAllowWitness = !(s.GetVersion() & SERIALIZE_TRANSACTION_NO_WITNESS);
const bool fAllowCriticalData = true; // TODO

s << tx.nVersion;
unsigned char flags = 0;
// Consistency check
/* Check whether extra data needs to be serialized. */
if (fAllowWitness) {
/* Check whether witnesses need to be serialized. */
if (tx.HasWitness()) {
flags |= 1;
}
}
if (fAllowCriticalData) {
/* Check whether critical data needs to be serialized. */
if (!tx.criticalData.IsNull()) {
flags |= 2;
}
}
if (flags) {
/* Use extended format in case witnesses are to be serialized. */
/* Use extended format in case extra data is to be serialized. */
std::vector<CTxIn> vinDummy;
s << vinDummy;
s << flags;
Expand All @@ -255,6 +301,9 @@ inline void SerializeTransaction(const TxType& tx, Stream& s) {
s << tx.vin[i].scriptWitness.stack;
}
}
if (flags & 2) {
s << tx.criticalData;
}
s << tx.nLockTime;
}

Expand All @@ -279,9 +328,10 @@ class CTransaction
// 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<CTxIn> vin;
const std::vector<CTxOut> vout;
const CCriticalData criticalData;
const int32_t nVersion;
const uint32_t nLockTime;

private:
Expand Down Expand Up @@ -365,9 +415,10 @@ class CTransaction
/** A mutable version of CTransaction. */
struct CMutableTransaction
{
int32_t nVersion;
std::vector<CTxIn> vin;
std::vector<CTxOut> vout;
CCriticalData criticalData;
int32_t nVersion;
uint32_t nLockTime;

CMutableTransaction();
Expand Down
21 changes: 11 additions & 10 deletions src/script/script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,26 +251,27 @@ bool CScript::IsWitnessProgram(int& version, std::vector<unsigned char>& program
return false;
}

bool CScript::IsBribeHashCommit() const
bool CScript::IsCriticalHashCommit() const
{
// TODO
// Check script size
// Size must be at least:
// sizeof(uint256) to include h*
// +
// sizeof(uint160) for keyID
// +
// opcode count
//
size_t size = this->size();
if (size < 32 )
if (size < 32)
return false;

// TODO
// The format of a bribe script is currently being discussed on the
// bitcoin-dev mailing list. For now we are just checking if the script
// is large enough to contain an h* and contains an OP_BRIBE op.
// Check script header
if ((*this)[0] != OP_RETURN ||
(*this)[1] != 0x23 ||
(*this)[2] != 0x50 ||
(*this)[3] != 0x50 ||
(*this)[4] != 0x33)
return false;

return (this->Find(OP_BRIBE));
return true;
}

bool CScript::IsSCDBHashMerkleRootCommit() const
Expand Down
2 changes: 1 addition & 1 deletion src/script/script.h
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ class CScript : public CScriptBase
bool IsWitnessProgram(int& version, std::vector<unsigned char>& program) const;

/** Script formats for Drivechains */
bool IsBribeHashCommit() const;
bool IsCriticalHashCommit() const;
bool IsSCDBHashMerkleRootCommit() const;
bool IsWTPrimeHashCommit() const;

Expand Down
7 changes: 5 additions & 2 deletions src/test/test_bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,17 @@ TestChain100Setup::TestChain100Setup() : TestingSetup(CBaseChainParams::REGTEST)
// scriptPubKey, and try to add it to the current chain.
//
CBlock
TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns, const CScript& scriptPubKey)
TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns, const CScript& scriptPubKey, bool fReplaceCoinbase)
{
const CChainParams& chainparams = Params();
std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey);
CBlock& block = pblocktemplate->block;

// Replace mempool-selected txns with just coinbase plus passed-in txns:
block.vtx.resize(1);
if (fReplaceCoinbase)
block.vtx.clear();
else
block.vtx.resize(1);
BOOST_FOREACH(const CMutableTransaction& tx, txns)
block.vtx.push_back(MakeTransactionRef(tx));
// IncrementExtraNonce creates a valid coinbase and merkleRoot
Expand Down
5 changes: 3 additions & 2 deletions src/test/test_bitcoin.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ struct TestChain100Setup : public TestingSetup {
// 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<CMutableTransaction>& txns,
const CScript& scriptPubKey);
const CScript& scriptPubKey,
bool fReplaceCoinbase = false);

~TestChain100Setup();

Expand All @@ -75,7 +76,7 @@ struct TestMemPoolEntryHelper
TestMemPoolEntryHelper() :
nFee(0), nTime(0), nHeight(1),
spendsCoinbase(false), sigOpCost(4) { }

CTxMemPoolEntry FromTx(const CMutableTransaction &tx);
CTxMemPoolEntry FromTx(const CTransaction &tx);

Expand Down
Loading

0 comments on commit f6bb3d8

Please sign in to comment.