From 019f289548b291719acd13707c6e74894d7f9baa Mon Sep 17 00:00:00 2001 From: CryptAxe Date: Wed, 6 Sep 2017 00:12:34 -0700 Subject: [PATCH 1/3] Update coinbase commitments and drivechain scripts * BIP 141 style coinbase commitment generators in validation: GenerateSCDBCoinbaseCommitment() GeneratBMMCriticalHashCommitment() * When a block is mined, if SCDB is tracking WT^ or BMM data, the miner will CreateSCDBHashMerkleRootCommit. * Add CScript functions: IsBribeHashCommit() IsSCDBHashMerkleRootCommit() IsWTPrimeHashCommit() --- src/miner.cpp | 21 ++++++++------------ src/miner.h | 4 ++-- src/script/script.cpp | 38 +++++++++++++++++++++++++++++++++++- src/script/script.h | 6 +++++- src/validation.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++- src/validation.h | 6 ++++++ 6 files changed, 102 insertions(+), 18 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index cd9fb3b5b2abc..edce2a9741eed 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -203,11 +203,11 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc pblock->vtx.push_back(MakeTransactionRef(std::move(wtx))); } - // Add SidechainDB state - CTransaction stateTx = CreateSidechainStateTx(); - for (const CTxOut& out : stateTx.vout) { - coinbaseTx.vout.push_back(out); - nSideFees += out.nValue; + if (scdb.HasState()) { + // Add SidechainDB hashMerkleRoot coinbase commitment + CTxOut scdbCommit = CreateSCDBHashMerkleRootCommit(); + nSideFees += scdbCommit.nValue; + coinbaseTx.vout.push_back(scdbCommit); } coinbaseTx.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus()); @@ -445,15 +445,10 @@ CTransaction BlockAssembler::CreateSidechainWTJoinTx(uint8_t nSidechain) return mtx; } -CTransaction BlockAssembler::CreateSidechainStateTx() +CTxOut BlockAssembler::CreateSCDBHashMerkleRootCommit() { - CMutableTransaction mtx; - - CScript script = scdb.CreateStateScript(nHeight); - if (!script.empty()) - mtx.vout.push_back(CTxOut(CENT, script)); - - return mtx; + CScript script = GenerateSCDBCoinbaseCommitment(); + return CTxOut(CENT, script); } // Skip entries in mapTx that are already in a block or are present diff --git a/src/miner.h b/src/miner.h index 2924a3aea3eff..323e9a2c53b39 100644 --- a/src/miner.h +++ b/src/miner.h @@ -208,8 +208,8 @@ class BlockAssembler // SidechainDB /** Returns a WT^ payout transaction for nSidechain if there is one */ CTransaction CreateSidechainWTJoinTx(uint8_t nSidechain); - /** Returns a SCDB state update transaction (update script in output) */ - CTransaction CreateSidechainStateTx(); + /** Returns an output with a commitment to the SCDB hashMerkleRoot */ + CTxOut CreateSCDBHashMerkleRootCommit(); }; /** Modify the extranonce in a block */ diff --git a/src/script/script.cpp b/src/script/script.cpp index 839e69b176a21..7b51c8ffc441c 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -251,7 +251,7 @@ bool CScript::IsWitnessProgram(int& version, std::vector& program return false; } -bool CScript::IsBribe() const +bool CScript::IsBribeHashCommit() const { // TODO // Size must be at least: @@ -273,6 +273,42 @@ bool CScript::IsBribe() const return (this->Find(OP_BRIBE)); } +bool CScript::IsSCDBHashMerkleRootCommit() const +{ + // Check script size + size_t size = this->size(); + if (size != 38) // sha256 hash + opcodes + return false; + + // Check script header + if ((*this)[0] != OP_RETURN || + (*this)[1] == 0x43 || + (*this)[2] == 0x50 || + (*this)[3] == 0x50 || + (*this)[4] == 0x53) + return false; + + return true; +} + +bool CScript::IsWTPrimeHashCommit() const +{ + // Check script size + size_t size = this->size(); + if (size < 39 || size > 41) // sha256 hash + nSidechain + opcodes + return false; + + // Check script header + if ((*this)[0] != OP_RETURN || + (*this)[1] == 0x53 || + (*this)[2] == 0x50 || + (*this)[3] == 0x50 || + (*this)[4] == 0x43) + return false; + + return true; +} + bool CScript::IsPushOnly(const_iterator pc) const { while (pc < end()) diff --git a/src/script/script.h b/src/script/script.h index 98c3da5964fd7..ae2eeaf5b229f 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -658,7 +658,11 @@ class CScript : public CScriptBase bool IsPayToScriptHash() const; bool IsPayToWitnessScriptHash() const; bool IsWitnessProgram(int& version, std::vector& program) const; - bool IsBribe() const; + + /** Script formats for Drivechains */ + bool IsBribeHashCommit() const; + bool IsSCDBHashMerkleRootCommit() const; + bool IsWTPrimeHashCommit() const; /** Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical). */ bool IsPushOnly(const_iterator pc) const; diff --git a/src/validation.cpp b/src/validation.cpp index 19c72d52feb93..c8ff7e0c33c0c 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1197,7 +1197,7 @@ bool CScriptCheck::operator()() { const CScriptWitness *witness = &ptxTo->vin[nIn].scriptWitness; std::multimap mapBMMLDCopy; - if (scriptPubKey.IsBribe()) + if (scriptPubKey.IsBribeHashCommit()) mapBMMLDCopy = scdb.GetLinkingData(); return VerifyScript(scriptSig, scriptPubKey, witness, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, amount, cacheStore, *txdata, mapBMMLDCopy), &error); @@ -2877,6 +2877,49 @@ std::vector GenerateCoinbaseCommitment(CBlock& block, const CBloc return commitment; } +CScript GenerateSCDBCoinbaseCommitment() +{ + // TODO + // check consensusParams.vDeployments[Consensus::DEPLOYMENT_DRIVECHAINS] + CScript script; + + // Add script header + script << OP_RETURN; + script.push_back(0x43); + script.push_back(0x50); + script.push_back(0x50); + script.push_back(0x53); + + // Add SCDB hashMerkleRoot + uint256 hashMerkleRoot; // TODO = GetSCDBHashMerkleRoot + script << ToByteVector(hashMerkleRoot); + + return script; +} + +CScript GeneratBMMCriticalHashCommitment() +{ + // TODO + // check consensusParams.vDeployments[Consensus::DEPLOYMENT_DRIVECHAINS] + CScript script; + + // Add script header + script << OP_RETURN; + script.push_back(0x53); + script.push_back(0x50); + script.push_back(0x50); + script.push_back(0x43); + + CScriptNum bn(0); // TODO + script << bn; + + // Add h* + uint256 hashCritical; // TODO = h* the miner wants to commit + script << ToByteVector(hashCritical); + + return script; +} + bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev, int64_t nAdjustedTime) { assert(pindexPrev != NULL); diff --git a/src/validation.h b/src/validation.h index e0da86e2725d7..2a7bbc3d4f7c4 100644 --- a/src/validation.h +++ b/src/validation.h @@ -463,6 +463,12 @@ void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPr /** Produce the necessary coinbase commitment for a block (modifies the hash, don't call for mined blocks). */ std::vector GenerateCoinbaseCommitment(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams); +/** Produce the SCDB hashMerkleRoot coinbase commitment for a block */ +CScript GenerateSCDBCoinbaseCommitment(); + +/** Produce a BMM h* coinbase commitment for a block */ +CScript GeneratBMMCriticalHashCommitment(); + /** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */ class CVerifyDB { public: From ed29c823728f310bfb0054a54c8c4dc3e6518c02 Mon Sep 17 00:00:00 2001 From: CryptAxe Date: Wed, 6 Sep 2017 09:13:57 -0700 Subject: [PATCH 2/3] Fix logic error and typo --- src/script/script.cpp | 8 ++++---- src/validation.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/script/script.cpp b/src/script/script.cpp index 7b51c8ffc441c..4bd7bf678be3d 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -286,9 +286,9 @@ bool CScript::IsSCDBHashMerkleRootCommit() const (*this)[2] == 0x50 || (*this)[3] == 0x50 || (*this)[4] == 0x53) - return false; + return true; - return true; + return false; } bool CScript::IsWTPrimeHashCommit() const @@ -304,9 +304,9 @@ bool CScript::IsWTPrimeHashCommit() const (*this)[2] == 0x50 || (*this)[3] == 0x50 || (*this)[4] == 0x43) - return false; + return true; - return true; + return false; } bool CScript::IsPushOnly(const_iterator pc) const diff --git a/src/validation.cpp b/src/validation.cpp index c8ff7e0c33c0c..8db649cce266b 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2897,7 +2897,7 @@ CScript GenerateSCDBCoinbaseCommitment() return script; } -CScript GeneratBMMCriticalHashCommitment() +CScript GenerateBMMCriticalHashCommitment() { // TODO // check consensusParams.vDeployments[Consensus::DEPLOYMENT_DRIVECHAINS] From d1551e5259bbff16e36d84abe99c1b09567e4900 Mon Sep 17 00:00:00 2001 From: CryptAxe Date: Sat, 30 Sep 2017 12:56:20 -0700 Subject: [PATCH 3/3] Update coinbase commitment generation functions --- src/miner.cpp | 6 +++++- src/script/script.cpp | 24 ++++++++++++------------ src/validation.cpp | 10 ++++------ src/validation.h | 4 ++-- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index edce2a9741eed..9a783003d5a46 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -447,7 +447,11 @@ CTransaction BlockAssembler::CreateSidechainWTJoinTx(uint8_t nSidechain) CTxOut BlockAssembler::CreateSCDBHashMerkleRootCommit() { - CScript script = GenerateSCDBCoinbaseCommitment(); + // TODO this call will be replaced when the MT based update PR Is merged. + // For now just getting the old style SCDB hash and putting it into the + // commitment. + const uint256& hashMerkleRoot = scdb.GetSCDBHash(); + CScript script = GenerateSCDBCoinbaseCommitment(hashMerkleRoot); return CTxOut(CENT, script); } diff --git a/src/script/script.cpp b/src/script/script.cpp index 4bd7bf678be3d..8a5f1d0a13f9e 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -282,13 +282,13 @@ bool CScript::IsSCDBHashMerkleRootCommit() const // Check script header if ((*this)[0] != OP_RETURN || - (*this)[1] == 0x43 || - (*this)[2] == 0x50 || - (*this)[3] == 0x50 || - (*this)[4] == 0x53) - return true; + (*this)[1] != 0x43 || + (*this)[2] != 0x50 || + (*this)[3] != 0x50 || + (*this)[4] != 0x53) + return false; - return false; + return true; } bool CScript::IsWTPrimeHashCommit() const @@ -300,13 +300,13 @@ bool CScript::IsWTPrimeHashCommit() const // Check script header if ((*this)[0] != OP_RETURN || - (*this)[1] == 0x53 || - (*this)[2] == 0x50 || - (*this)[3] == 0x50 || - (*this)[4] == 0x43) - return true; + (*this)[1] != 0x53 || + (*this)[2] != 0x50 || + (*this)[3] != 0x50 || + (*this)[4] != 0x43) + return false; - return false; + return true; } bool CScript::IsPushOnly(const_iterator pc) const diff --git a/src/validation.cpp b/src/validation.cpp index 8db649cce266b..132d397dafba4 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2877,7 +2877,7 @@ std::vector GenerateCoinbaseCommitment(CBlock& block, const CBloc return commitment; } -CScript GenerateSCDBCoinbaseCommitment() +CScript GenerateSCDBCoinbaseCommitment(const uint256& hashMerkleRoot) { // TODO // check consensusParams.vDeployments[Consensus::DEPLOYMENT_DRIVECHAINS] @@ -2891,13 +2891,12 @@ CScript GenerateSCDBCoinbaseCommitment() script.push_back(0x53); // Add SCDB hashMerkleRoot - uint256 hashMerkleRoot; // TODO = GetSCDBHashMerkleRoot script << ToByteVector(hashMerkleRoot); return script; } -CScript GenerateBMMCriticalHashCommitment() +CScript GenerateBMMCriticalHashCommitment(int nHeight, const uint256& hashCritical) { // TODO // check consensusParams.vDeployments[Consensus::DEPLOYMENT_DRIVECHAINS] @@ -2910,11 +2909,10 @@ CScript GenerateBMMCriticalHashCommitment() script.push_back(0x50); script.push_back(0x43); - CScriptNum bn(0); // TODO - script << bn; + // Add block number + script << CScriptNum(nHeight); // Add h* - uint256 hashCritical; // TODO = h* the miner wants to commit script << ToByteVector(hashCritical); return script; diff --git a/src/validation.h b/src/validation.h index 2a7bbc3d4f7c4..1a484b153182d 100644 --- a/src/validation.h +++ b/src/validation.h @@ -464,10 +464,10 @@ void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPr std::vector GenerateCoinbaseCommitment(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams); /** Produce the SCDB hashMerkleRoot coinbase commitment for a block */ -CScript GenerateSCDBCoinbaseCommitment(); +CScript GenerateSCDBCoinbaseCommitment(const uint256& hashMerkleRoot); /** Produce a BMM h* coinbase commitment for a block */ -CScript GeneratBMMCriticalHashCommitment(); +CScript GeneratBMMCriticalHashCommitment(int nHeight, const uint256& hashCritical); /** RAII wrapper for VerifyDB: Verify consistency of the block and coin databases */ class CVerifyDB {