Skip to content

Commit

Permalink
Merge AuxPoW support from Namecore
Browse files Browse the repository at this point in the history
Changes are as below:

* Wrap CBlockHeader::nVersion into a new class (CBlockVersion).  This allows to take care of interpreting the field into a base version, auxpow flag and the chain ID.
* Update getauxblock.py for new 'generate' RPC call.
* Add 'auxpow' to block JSON.
* Accept auxpow as PoW verification.
* Add unit tests for auxpow verification.
* Add check for memory-layout of CBlockVersion.
* Weaken auxpow chain ID checks for the testnet.
* Allow Params() to overrule when to check the auxpow chain ID and for legacy blocks.  Use this to disable the checks on testnet.
* Split the block header part that is used by auxpow and the "real" block header (that uses auxpow) to resolve the cyclic dependency between the two.
* Differentiate between uint256 and arith_uint256.
* Add missing lock in auxpow_tests.
* Fix REST header check for auxpow headers.
  * Those can be longer, thus take that into account.  Also perform the check actually on an auxpow header.
* Correctly set the coinbase for getauxblock results.
* Call IncrementExtraNonce in getauxblock so that the coinbase is actually initialised with the stuff it should be.  (BIP30 block height and COINBASE_FLAGS.)
* Implement getauxblock plus regression test.
* Turn auxpow test into FIXTURE test.
  * This allows using of the Params() calls.
* Move CMerkleTx code to auxpow.cpp.
  * Otherwise we get linker errors when building without wallet.
* Fix rebase with BIP66.
* Update the code to handle BIP66's nVersion=3.
* Enforce that auxpow parent blocks have no auxpow block version.
  * This is for compatibility with namecoind.  See also namecoin/namecoin-legacy#199.
* Move auxpow-related parameters to Consensus::Params.
  • Loading branch information
micaelmalta authored and Ross Nicoll committed Nov 14, 2021
1 parent 233d998 commit f89ad55
Show file tree
Hide file tree
Showing 30 changed files with 1,395 additions and 304 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ install:
before_script:
# Temporary workaround for https://github.com/bitcoin/bitcoin/issues/16368
- for i in {1..4}; do echo "$(sleep 500)" ; done &
- set -o errexit; source ./ci/test/05_before_script.sh &> "/dev/null"
- set -o errexit; source ./ci/test/05_before_script.sh
script:
- export CONTINUE=1
- if [ $SECONDS -gt 1200 ]; then export CONTINUE=0; fi # Likely the depends build took very long
- if [ $SECONDS -gt 1800 ]; then export CONTINUE=0; fi # Likely the depends build took very long
- if [ $TRAVIS_REPO_SLUG = "bitcoin/bitcoin" ]; then export CONTINUE=1; fi # continue on repos with extended build time (90 minutes)
- if [ $CONTINUE = "1" ]; then set -o errexit; source ./ci/test/06_script_a.sh; else set +o errexit; echo "$CACHE_ERR_MSG"; false; fi
- if [[ $SECONDS -gt 50*60-$EXPECTED_TESTS_DURATION_IN_SECONDS ]]; then export CONTINUE=0; fi
Expand Down
5 changes: 5 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,12 @@ BITCOIN_CORE_H = \
random.h \
randomenv.h \
reverse_iterator.h \
rpc/auxpow_miner.h \
rpc/blockchain.h \
rpc/client.h \
rpc/mining.h \
rpc/protocol.h \
rpc/rawtransaction.h \
rpc/rawtransaction_util.h \
rpc/register.h \
rpc/request.h \
Expand Down Expand Up @@ -318,6 +320,7 @@ libbitcoin_server_a_SOURCES = \
policy/settings.cpp \
pow.cpp \
rest.cpp \
rpc/auxpow_miner.cpp \
rpc/blockchain.cpp \
rpc/mining.cpp \
rpc/misc.cpp \
Expand Down Expand Up @@ -590,8 +593,10 @@ if TARGET_WINDOWS
dogecoin_daemon_sources += bitcoind-res.rc
endif

# FIXME: Remove SERVER once we have cleaned up getauxblock.
dogecoin_bin_ldadd = \
$(LIBBITCOIN_WALLET) \
$(LIBBITCOIN_SERVER) \
$(LIBBITCOIN_COMMON) \
$(LIBBITCOIN_UTIL) \
$(LIBUNIVALUE) \
Expand Down
2 changes: 1 addition & 1 deletion src/chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ bool ReadBlockHeaderFromDisk(CBlockHeader& block, const CBlockIndex* pindex, con

/* Moved here from the header, because we need auxpow and the logic
becomes more involved. */
CBlockHeader CBlockIndex::GetBlockHeader(const Consensus::Params& consensusParams, bool fCheckPOW) const
CBlockHeader CBlockIndex::GetBlockHeader(const Consensus::Params& consensusParams, const bool fCheckPOW) const
{
CBlockHeader block;

Expand Down
4 changes: 2 additions & 2 deletions src/chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ class CBlockIndex
{
}

explicit CBlockIndex(const CBlockHeader& block)
explicit CBlockIndex(const CPureBlockHeader& block)
: nVersion{block.nVersion},
hashMerkleRoot{block.hashMerkleRoot},
nTime{block.nTime},
Expand All @@ -218,7 +218,7 @@ class CBlockIndex
return ret;
}

CBlockHeader GetBlockHeader(const Consensus::Params& consensusParams, bool fCheckPOW = true) const;
CBlockHeader GetBlockHeader(const Consensus::Params& consensusParams, const bool fCheckPOW = true) const;

uint256 GetBlockHash() const
{
Expand Down
3 changes: 3 additions & 0 deletions src/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ class CChainParams
const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
const CCheckpointData& Checkpoints() const { return checkpointData; }
const ChainTxData& TxData() const { return chainTxData; }

void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout);

protected:
CChainParams() {}

Expand Down
3 changes: 2 additions & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <policy/settings.h>
#include <primitives/pureheader.h>
#include <protocol.h>
#include <rpc/auxpow_miner.h>
#include <rpc/blockchain.h>
#include <rpc/register.h>
#include <rpc/server.h>
Expand Down Expand Up @@ -600,7 +601,7 @@ void SetupServerArgs(NodeContext& node)

std::string LicenseInfo()
{
const std::string URL_SOURCE_CODE = "<https://github.com/bitcoin/bitcoin>";
const std::string URL_SOURCE_CODE = "<https://github.com/dogecoin/dogecoin>";

return CopyrightHolders(strprintf(_("Copyright (C) %i-%i").translated, 2009, COPYRIGHT_YEAR) + " ") + "\n" +
"\n" +
Expand Down
3 changes: 3 additions & 0 deletions src/miner.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,12 @@ class BlockAssembler
// Configuration parameters for the block size
bool fIncludeWitness;
unsigned int nBlockMaxWeight;
bool fNeedSizeAccounting;
CFeeRate blockMinFeeRate;

// Information on the current status of the block
uint64_t nBlockWeight;
uint64_t nBlockSize;
uint64_t nBlockTx;
uint64_t nBlockSigOpsCost;
CAmount nFees;
Expand Down Expand Up @@ -200,6 +202,7 @@ class BlockAssembler
/** Modify the extranonce in a block */
void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
bool ProcessBlockFound(const CBlock* pblock, const CChainParams& chainParams);

/** Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed */
void RegenerateCommitments(CBlock& block);
Expand Down
40 changes: 40 additions & 0 deletions src/pow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@

#include <pow.h>

#include <auxpow.h>
#include <arith_uint256.h>
#include <chain.h>
#include <dogecoin.h>
#include <primitives/block.h>
#include <util/system.h>
#include <uint256.h>

unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
Expand Down Expand Up @@ -114,3 +116,41 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&

return true;
}

bool CheckAuxPowProofOfWork(const CBlockHeader& block, const Consensus::Params& params)
{
/* Except for legacy blocks with full version 1, ensure that
the chain ID is correct. Legacy blocks are not allowed since
the merge-mining start, which is checked in AcceptBlockHeader
where the height is known. */
if (!block.IsLegacy() && params.fStrictChainId
&& block.GetChainId() != params.nAuxpowChainId)
return error("%s : block does not have our chain ID"
" (got %d, expected %d, full nVersion %d)",
__func__, block.GetChainId(),
params.nAuxpowChainId, block.nVersion);

/* If there is no auxpow, just check the block hash. */
if (!block.auxpow) {
if (block.IsAuxpow())
return error("%s : no auxpow on block with auxpow version",
__func__);

if (!CheckProofOfWork(block.GetPoWHash(), block.nBits, params))
return error("%s : non-AUX proof of work failed", __func__);

return true;
}

/* We have auxpow. Check it. */

if (!block.IsAuxpow())
return error("%s : auxpow on block with non-auxpow version", __func__);

if (!block.auxpow->check(block.GetHash(), block.GetChainId(), params))
return error("%s : AUX POW is not valid", __func__);
if (!CheckProofOfWork(block.auxpow->getParentBlockPoWHash(), block.nBits, params))
return error("%s : AUX proof of work failed", __func__);

return true;
}
8 changes: 8 additions & 0 deletions src/pow.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,12 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF
/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&);

/**
* Check proof-of-work of a block header, taking auxpow into account.
* @param block The block header.
* @param params Consensus parameters.
* @return True iff the PoW is correct.
*/
bool CheckAuxPowProofOfWork(const CBlockHeader& block, const Consensus::Params& params);

#endif // BITCOIN_POW_H
1 change: 0 additions & 1 deletion src/protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ bool CMessageHeader::IsCommandValid() const
return true;
}


ServiceFlags GetDesirableServiceFlags(ServiceFlags services) {
if ((services & NODE_NETWORK_LIMITED) && g_initial_block_download_completed) {
return ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS);
Expand Down
2 changes: 1 addition & 1 deletion src/qt/test/wallettests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ void BumpFee(TransactionView& view, const uint256& txid, bool expectDisabled, st
// QT_QPA_PLATFORM=cocoa src/qt/test/test_bitcoin-qt # macOS
void TestGUI(interfaces::Node& node)
{
// Set up wallet and chain with 105 blocks (5 mature blocks for spending).
// Set up wallet and chain with 245 blocks (5 mature blocks for spending).
TestChain240Setup test;
for (int i = 0; i < 5; ++i) {
test.CreateAndProcessBlock({}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey()));
Expand Down
41 changes: 41 additions & 0 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <policy/policy.h>
#include <policy/rbf.h>
#include <primitives/transaction.h>
#include <rpc/rawtransaction.h>
#include <rpc/server.h>
#include <rpc/util.h>
#include <script/descriptor.h>
Expand Down Expand Up @@ -116,6 +117,43 @@ static int ComputeNextBlockAndDepth(const CBlockIndex* tip, const CBlockIndex* b
return blockindex == tip ? 1 : -1;
}


UniValue AuxpowToJSON(const CAuxPow& auxpow)
{
UniValue result(UniValue::VOBJ);

{
UniValue tx(UniValue::VOBJ);
tx.pushKV("hex", EncodeHexTx(*auxpow.coinbaseTx));
TxToJSON(*auxpow.coinbaseTx, auxpow.parentBlock.GetHash(), tx);
result.pushKV("tx", tx);
}

// FIXME: We have a compatibility issue where the "index" field is no longer available in 1.21
result.pushKV("chainindex", auxpow.nChainIndex);

{
UniValue branch(UniValue::VARR);
for (const auto& node : auxpow.vMerkleBranch)
branch.push_back(node.GetHex());
result.pushKV("merklebranch", branch);
}

{
UniValue branch(UniValue::VARR);
for (const auto& node : auxpow.vChainMerkleBranch)
branch.push_back(node.GetHex());
result.pushKV("chainmerklebranch", branch);
}

CDataStream ssParent(SER_NETWORK, PROTOCOL_VERSION);
ssParent << auxpow.parentBlock;
const std::string strHex = HexStr(ssParent);
result.pushKV("parentblock", strHex);

return result;
}

UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex)
{
// Serialize passed information without accessing chain state of the active chain!
Expand Down Expand Up @@ -183,6 +221,9 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIn
result.pushKV("chainwork", blockindex->nChainWork.GetHex());
result.pushKV("nTx", (uint64_t)blockindex->nTx);

if (block.auxpow)
result.pushKV("auxpow", AuxpowToJSON(*block.auxpow));

if (blockindex->pprev)
result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex());
if (pnext)
Expand Down
Loading

0 comments on commit f89ad55

Please sign in to comment.