Adapt AuxPoW to Dogecoin

Changed AuxPoW parent block hashing to use Scrypt rather than SHA256 hash.
Update chain parameters to match Dogecoin
Move CheckProofOfWork into dogecoin.cpp and rename it to CheckAuxPowProofOfWork.
Add operator overrides to CBlockVersion so that naive usage operates on the underlying version without chain ID or flags.
Modify RPC mining to more closely match existing submitblock() structure
This commit is contained in:
Ross Nicoll 2015-07-05 17:45:38 +01:00
parent eabf633f13
commit c453bcc9e5
15 changed files with 160 additions and 159 deletions

View file

@ -154,9 +154,9 @@ public:
* @return The parent block hash.
*/
inline uint256
getParentBlockHash() const
getParentBlockPoWHash() const
{
return parentBlock.GetHash();
return parentBlock.GetPoWHash();
}
/**

View file

@ -39,10 +39,10 @@ public:
consensus.nPowTargetTimespan = 4 * 60 * 60; // pre-digishield: 4 hours
consensus.nPowTargetSpacing = 60; // 1 minute
consensus.fPowAllowMinDifficultyBlocks = false;
consensus.nAuxpowChainId = 0x0001;
consensus.nAuxpowStartHeight = 19200;
consensus.nAuxpowChainId = 0x0062; // 98 - Josh Wise!
consensus.nAuxpowStartHeight = 371337;
consensus.fStrictChainId = true;
consensus.nLegacyBlocksBefore = 19200;
consensus.nLegacyBlocksBefore = 371337;
/**
* The message start string is designed to be unlikely to occur in normal data.
* The characters are rarely used upper ASCII, not valid as UTF-8, and produce
@ -152,9 +152,9 @@ public:
consensus.nMajorityRejectBlockOutdated = 75;
consensus.nMajorityWindow = 100;
consensus.fPowAllowMinDifficultyBlocks = true;
consensus.nAuxpowStartHeight = 0;
consensus.nAuxpowStartHeight = 158100;
consensus.fStrictChainId = false;
consensus.nLegacyBlocksBefore = -1;
consensus.nLegacyBlocksBefore = 158100;
pchMessageStart[0] = 0xfc;
pchMessageStart[1] = 0xc1;

View file

@ -21,9 +21,9 @@ unsigned int CalculateDogecoinNextWorkRequired(const CBlockIndex* pindexLast, in
int nHeight = pindexLast->nHeight + 1;
bool fNewDifficultyProtocol = (nHeight >= 145000);
// bool fNewDifficultyProtocol = (nHeight >= params.GetDigiShieldForkBlock());
const int64_t retargetTimespan = fNewDifficultyProtocol
? 60 // params.DigiShieldTargetTimespan()
: params.nPowTargetTimespan;
const int64_t retargetTimespan = fNewDifficultyProtocol ? 60 // params.DigiShieldTargetTimespan()
:
params.nPowTargetTimespan;
const int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
int64_t nModulatedTimespan = nActualTimespan;
@ -75,6 +75,51 @@ unsigned int CalculateDogecoinNextWorkRequired(const CBlockIndex* pindexLast, in
return bnNew.GetCompact();
}
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.nVersion.IsLegacy() && params.fStrictChainId && block.nVersion.GetChainId() != params.nAuxpowChainId)
return error("%s : block does not have our chain ID"
" (got %d, expected %d, full nVersion %d)",
__func__,
block.nVersion.GetChainId(),
params.nAuxpowChainId,
block.nVersion.GetFullVersion());
/* If there is no auxpow, just check the block hash. */
if (!block.auxpow) {
if (block.nVersion.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.nVersion.IsAuxpow())
return error("%s : auxpow on block with non-auxpow version", __func__);
/* Temporary check: Disallow parent blocks with auxpow version. This is
for compatibility with the old client. */
/* FIXME: Remove this check with a hardfork later on. */
if (block.auxpow->getParentBlock().nVersion.IsAuxpow())
return error("%s : auxpow parent block has auxpow version", __func__);
if (!block.auxpow->check(block.GetHash(), block.nVersion.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;
}
CAmount GetDogecoinBlockSubsidy(int nHeight, const Consensus::Params& consensusParams, uint256 prevHash)
{
int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;

View file

@ -2,9 +2,17 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "amount.h"
#include "chain.h"
#include "chainparams.h"
#include "amount.h"
CAmount GetDogecoinBlockSubsidy(int nHeight, const Consensus::Params& consensusParams, uint256 prevHash);
unsigned int CalculateDogecoinNextWorkRequired(const CBlockIndex* pindexLast, int64_t nLastRetargetTime, const Consensus::Params& 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);

View file

@ -154,7 +154,6 @@ void Shutdown()
mempool.AddTransactionsUpdated(1);
StopRPCThreads();
#ifdef ENABLE_WALLET
ShutdownRPCMining();
if (pwalletMain)
pwalletMain->Flush(false);
GenerateBitcoins(false, NULL, 0);
@ -1433,7 +1432,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (pwalletMain)
GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 1));
InitRPCMining ();
#endif
// ********************************************************* Step 11: finished

View file

@ -1139,51 +1139,6 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock
// CBlock and CBlockIndex
//
bool CheckProofOfWork(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.nVersion.IsLegacy() && params.fStrictChainId
&& block.nVersion.GetChainId() != params.nAuxpowChainId)
return error("%s : block does not have our chain ID"
" (got %d, expected %d, full nVersion %d)",
__func__, block.nVersion.GetChainId(),
params.nAuxpowChainId, block.nVersion.GetFullVersion());
/* If there is no auxpow, just check the block hash. */
if (!block.auxpow)
{
if (block.nVersion.IsAuxpow())
return error("%s : no auxpow on block with auxpow version",
__func__);
if (!CheckProofOfWork(block.GetHash(), block.nBits, params))
return error("%s : non-AUX proof of work failed", __func__);
return true;
}
/* We have auxpow. Check it. */
if (!block.nVersion.IsAuxpow())
return error("%s : auxpow on block with non-auxpow version", __func__);
/* Temporary check: Disallow parent blocks with auxpow version. This is
for compatibility with the old client. */
/* FIXME: Remove this check with a hardfork later on. */
if (block.auxpow->getParentBlock().nVersion.IsAuxpow())
return error("%s : auxpow parent block has auxpow version", __func__);
if (!block.auxpow->check(block.GetHash(), block.nVersion.GetChainId(), params))
return error("%s : AUX POW is not valid", __func__);
if (!CheckProofOfWork(block.auxpow->getParentBlockHash(), block.nBits, params))
return error("%s : AUX proof of work failed", __func__);
return true;
}
bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart)
{
// Open history file to append
@ -1227,7 +1182,7 @@ static bool ReadBlockOrHeader(T& block, const CDiskBlockPos& pos)
}
// Check the header
if (!CheckProofOfWork(block, Params().GetConsensus()))
if (!CheckAuxPowProofOfWork(block, Params().GetConsensus()))
return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
return true;
@ -1895,7 +1850,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE;
// Start enforcing the DERSIG (BIP66) rules, for block.nVersion=3 blocks, when 75% of the network has upgraded:
if (block.nVersion.GetBaseVersion() >= 3 && IsSuperMajority(3, pindex->pprev, chainparams.GetConsensus().nMajorityEnforceBlockUpgrade, chainparams.GetConsensus())) {
if (block.nVersion >= 3 && IsSuperMajority(3, pindex->pprev, chainparams.GetConsensus().nMajorityEnforceBlockUpgrade, chainparams.GetConsensus())) {
flags |= SCRIPT_VERIFY_DERSIG;
}
@ -2157,7 +2112,7 @@ void static UpdateTip(CBlockIndex *pindexNew) {
const CBlockIndex* pindex = chainActive.Tip();
for (int i = 0; i < 100 && pindex != NULL; i++)
{
if (pindex->nVersion.GetBaseVersion() > CBlock::CURRENT_VERSION)
if (pindex->nVersion > CBlock::CURRENT_VERSION)
++nUpgraded;
pindex = pindex->pprev;
}
@ -2712,7 +2667,7 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne
bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW)
{
// Check proof of work matches claimed amount
if (fCheckPOW && !CheckProofOfWork(block, Params().GetConsensus()))
if (fCheckPOW && !CheckAuxPowProofOfWork(block, Params().GetConsensus()))
return state.DoS(50, error("CheckBlockHeader(): proof of work failed"),
REJECT_INVALID, "high-hash");
@ -2827,12 +2782,12 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
}
// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
if (block.nVersion.GetBaseVersion() < 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams))
if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams))
return state.Invalid(error("%s: rejected nVersion=1 block", __func__),
REJECT_OBSOLETE, "bad-version");
// Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded:
if (block.nVersion.GetBaseVersion() < 3 && IsSuperMajority(3, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams))
if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams))
return state.Invalid(error("%s : rejected nVersion=2 block", __func__),
REJECT_OBSOLETE, "bad-version");
@ -2852,7 +2807,7 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
// Enforce block.nVersion=2 rule that the coinbase starts with serialized block height
// if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet):
if (block.nVersion.GetBaseVersion() >= 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams))
if (block.nVersion >= 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams))
{
CScript expect = CScript() << nHeight;
if (block.vtx[0].vin[0].scriptSig.size() < expect.size() ||
@ -2970,7 +2925,7 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned
unsigned int nFound = 0;
for (int i = 0; i < consensusParams.nMajorityWindow && nFound < nRequired && pstart != NULL; i++)
{
if (pstart->nVersion.GetBaseVersion() >= minVersion)
if (pstart->nVersion >= minVersion)
++nFound;
pstart = pstart->pprev;
}

View file

@ -404,14 +404,6 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn
/** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */
bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex *pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true);
/**
* 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 CheckProofOfWork(const CBlockHeader& block, const Consensus::Params& params);
/** Store block on disk. If dbp is non-NULL, the file is known to already reside on disk */
bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex **pindex, bool fRequested, CDiskBlockPos* dbp);
bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL);

View file

@ -102,12 +102,12 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
CBlock *pblock = &pblocktemplate->block; // pointer for convenience
/* Initialise the block version. */
pblock->nVersion.SetBaseVersion(CBlockHeader::CURRENT_VERSION);
pblock->nVersion = CBlockHeader::CURRENT_VERSION;
// -regtest only: allow overriding block.nVersion with
// -blockversion=N to test forking scenarios
if (Params().MineBlocksOnDemand())
pblock->nVersion.SetBaseVersion(GetArg("-blockversion", pblock->nVersion.GetBaseVersion()));
pblock->nVersion = GetArg("-blockversion", pblock->nVersion);
// Create coinbase tx
CMutableTransaction txNew;
@ -420,7 +420,7 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey)
return CreateNewBlock(scriptPubKey);
}
bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
{
LogPrintf("%s\n", pblock->ToString());
LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue));

View file

@ -31,6 +31,5 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey);
/** Modify the extranonce in a block */
void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev);
bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
#endif // BITCOIN_MINER_H

View file

@ -37,7 +37,7 @@ public:
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(*(CPureBlockHeader*)this);
nVersion = this->nVersion.GetBaseVersion();
nVersion = this->nVersion;
if (this->nVersion.IsAuxpow()) {
if (ser_action.ForRead())

View file

@ -10,14 +10,6 @@
#include "hash.h"
#include "utilstrencodings.h"
void CBlockVersion::SetBaseVersion(int32_t nBaseVersion)
{
assert(nBaseVersion >= 1 && nBaseVersion < VERSION_AUXPOW);
assert(!IsAuxpow());
const int32_t nChainId = Params().GetConsensus().nAuxpowChainId;
nVersion = nBaseVersion | (nChainId * VERSION_CHAIN_START);
}
uint256 CPureBlockHeader::GetHash() const
{
return SerializeHash(*this);

View file

@ -24,7 +24,7 @@ private:
static const int32_t VERSION_CHAIN_START = (1 << 16);
/** The version as integer. Should not be accessed directly. */
int32_t nVersion;
int nVersion;
public:
inline CBlockVersion()
@ -45,30 +45,13 @@ public:
nVersion = 0;
}
/**
* Extract the base version (without modifiers and chain ID).
* @return The base version./
*/
inline int32_t GetBaseVersion() const
{
return nVersion % VERSION_AUXPOW;
}
/**
* Set the base version (apart from chain ID and auxpow flag) to
* the one given. This should only be called when auxpow is not yet
* set, to initialise a block!
* @param nBaseVersion The base version.
*/
void SetBaseVersion(int32_t nBaseVersion);
/**
* Extract the chain ID.
* @return The chain ID encoded in the version.
*/
inline int32_t GetChainId() const
{
return nVersion / VERSION_CHAIN_START;
return nVersion >> 16;
}
/**
@ -123,12 +106,27 @@ public:
/**
* Check whether this is a "legacy" block without chain ID.
* @return True iff it is.
* @return True if it is.
*/
inline bool IsLegacy() const
{
return nVersion == 1;
return nVersion == 1
|| (nVersion == 2 && GetChainId() == 0);
}
CBlockVersion& operator=(const int nBaseVersion)
{
nVersion = (nBaseVersion & 0x000000ff) | (nVersion & 0xffffff00);
return *this;
}
operator int() { return nVersion & 0x000000ff; }
friend inline bool operator==(const CBlockVersion a, const int b) { return (a.nVersion & 0x000000ff) == b; }
friend inline bool operator!=(const CBlockVersion a, const int b) { return (a.nVersion & 0x000000ff) != b; }
friend inline bool operator>(const CBlockVersion a, const int b) { return (a.nVersion & 0x000000ff) > b; }
friend inline bool operator<(const CBlockVersion a, const int b) { return (a.nVersion & 0x000000ff) < b; }
friend inline bool operator>=(const CBlockVersion a, const int b) { return (a.nVersion & 0x000000ff) >= b; }
friend inline bool operator<=(const CBlockVersion a, const int b) { return (a.nVersion & 0x000000ff) <= b; }
};
/**
@ -161,7 +159,7 @@ public:
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
{
READWRITE(this->nVersion);
nVersion = this->nVersion.GetBaseVersion();
nVersion = this->nVersion;
READWRITE(hashPrevBlock);
READWRITE(hashMerkleRoot);
READWRITE(nTime);

View file

@ -6,6 +6,7 @@
#include "checkpoints.h"
#include "consensus/validation.h"
#include "core_io.h"
#include "dogecoin.h"
#include "main.h"
#include "primitives/transaction.h"
#include "rpcserver.h"
@ -53,7 +54,7 @@ double GetDifficulty(const CBlockIndex* blockindex)
return dDiff;
}
static Object AuxpowToJSON(const CAuxPow& auxpow)
static Object auxpowToJSON(const CAuxPow& auxpow)
{
Object tx;
tx.push_back(Pair("hex", EncodeHexTx(auxpow)));
@ -65,12 +66,12 @@ static Object AuxpowToJSON(const CAuxPow& auxpow)
result.push_back(Pair("chainindex", auxpow.nChainIndex));
Array branch;
BOOST_FOREACH(const uint256& node, auxpow.vMerkleBranch)
BOOST_FOREACH (const uint256& node, auxpow.vMerkleBranch)
branch.push_back(node.GetHex());
result.push_back(Pair("merklebranch", branch));
branch.clear();
BOOST_FOREACH(const uint256& node, auxpow.vChainMerkleBranch)
BOOST_FOREACH (const uint256& node, auxpow.vChainMerkleBranch)
branch.push_back(node.GetHex());
result.push_back(Pair("chainmerklebranch", branch));
@ -115,7 +116,7 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDe
result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex()));
if (block.auxpow)
result.push_back(Pair("auxpow", AuxpowToJSON(*block.auxpow)));
result.push_back(Pair("auxpow", auxpowToJSON(*block.auxpow)));
if (blockindex->pprev)
result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()));

View file

@ -8,6 +8,7 @@
#include "consensus/consensus.h"
#include "consensus/validation.h"
#include "core_io.h"
#include "dogecoin.h"
#include "init.h"
#include "main.h"
#include "miner.h"
@ -30,30 +31,6 @@
using namespace json_spirit;
using namespace std;
#ifdef ENABLE_WALLET
// Key used by getwork miners.
// Allocated in InitRPCMining, free'd in ShutdownRPCMining
static CReserveKey* pminingKey = NULL;
void InitRPCMining()
{
if (!pwalletMain)
return;
// getwork/getblocktemplate mining rewards paid here:
pminingKey = new CReserveKey(pwalletMain);
}
void ShutdownRPCMining()
{
if (!pminingKey)
return;
delete pminingKey;
pminingKey = NULL;
}
#endif // ENABLE_WALLET
/**
* Return average network hashes per second based on the last 'lookup' blocks,
* or from the last difficulty change if 'lookup' is nonpositive.
@ -182,7 +159,7 @@ Value generate(const Array& params, bool fHelp)
LOCK(cs_main);
IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce);
}
while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) {
while (!CheckProofOfWork(pblock->GetPoWHash(), pblock->nBits, Params().GetConsensus())) {
// Yes, there is a chance every nonce could fail to satisfy the -regtest
// target -- 1 in 2^(2^32). That ain't gonna happen.
++pblock->nNonce;
@ -787,7 +764,6 @@ Value getauxblock(const Array& params, bool fHelp)
if (pwalletMain == NULL)
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found (disabled)");
assert (pminingKey);
if (vNodes.empty() && !Params().MineBlocksOnDemand())
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED,
@ -822,6 +798,7 @@ Value getauxblock(const Array& params, bool fHelp)
static uint64_t nStart;
static CBlockTemplate* pblocktemplate;
static unsigned nExtraNonce = 0;
CReserveKey reservekey(pwalletMain);
// Update block
{
@ -840,7 +817,7 @@ Value getauxblock(const Array& params, bool fHelp)
}
// Create new block with nonce = 0 and extraNonce = 1
pblocktemplate = CreateNewBlockWithKey(*pminingKey);
pblocktemplate = CreateNewBlockWithKey(reservekey);
if (!pblocktemplate)
throw JSONRPCError(RPC_OUT_OF_MEMORY, "out of memory");
@ -900,6 +877,39 @@ Value getauxblock(const Array& params, bool fHelp)
block.SetAuxpow(new CAuxPow(pow));
assert(block.GetHash() == hash);
return ProcessBlockFound(&block, *pwalletMain, *pminingKey);
// This is a straight cut & paste job from submitblock()
bool fBlockPresent = false;
{
LOCK(cs_main);
BlockMap::iterator mi = mapBlockIndex.find(hash);
if (mi != mapBlockIndex.end()) {
CBlockIndex *pindex = mi->second;
if (pindex->IsValid(BLOCK_VALID_SCRIPTS))
return "duplicate";
if (pindex->nStatus & BLOCK_FAILED_MASK)
return "duplicate-invalid";
// Otherwise, we might only have the header - process the block before returning
fBlockPresent = true;
}
}
CValidationState state;
submitblock_StateCatcher sc(block.GetHash());
RegisterValidationInterface(&sc);
bool fAccepted = ProcessNewBlock(state, NULL, &block, true, NULL);
UnregisterValidationInterface(&sc);
if (fBlockPresent)
{
if (fAccepted && !sc.found)
return "duplicate-inconclusive";
return "duplicate";
}
if (fAccepted)
{
if (!sc.found)
return "inconclusive";
state = sc.state;
}
return BIP22ValidationResult(state);
}
#endif // ENABLE_WALLET

View file

@ -5,6 +5,7 @@
#include "auxpow.h"
#include "chainparams.h"
#include "coins.h"
#include "dogecoin.h"
#include "main.h"
#include "uint256.h"
#include "primitives/block.h"
@ -110,7 +111,7 @@ public:
CAuxpowBuilder::CAuxpowBuilder(int baseVersion, int chainId)
: auxpowChainIndex(-1)
{
parentBlock.nVersion.SetBaseVersion(baseVersion);
parentBlock.nVersion = baseVersion;
parentBlock.nVersion.SetChainId(chainId);
}
@ -330,7 +331,7 @@ mineBlock(CBlockHeader& block, bool ok, int nBits = -1)
block.nNonce = 0;
while (true) {
const bool nowOk = (UintToArith256(block.GetHash()) <= target);
const bool nowOk = (UintToArith256(block.GetPoWHash()) <= target);
if ((ok && nowOk) || (!ok && !nowOk))
break;
@ -338,9 +339,9 @@ mineBlock(CBlockHeader& block, bool ok, int nBits = -1)
}
if (ok)
BOOST_CHECK(CheckProofOfWork(block.GetHash(), nBits, Params().GetConsensus()));
BOOST_CHECK(CheckProofOfWork(block.GetPoWHash(), nBits, Params().GetConsensus()));
else
BOOST_CHECK(!CheckProofOfWork(block.GetHash(), nBits, Params().GetConsensus()));
BOOST_CHECK(!CheckProofOfWork(block.GetPoWHash(), nBits, Params().GetConsensus()));
}
BOOST_AUTO_TEST_CASE(auxpow_pow)
@ -357,20 +358,22 @@ BOOST_AUTO_TEST_CASE(auxpow_pow)
block.nVersion.SetGenesisVersion(1);
mineBlock(block, true);
BOOST_CHECK(CheckProofOfWork(block, params));
BOOST_CHECK(CheckAuxPowProofOfWork(block, params));
block.nVersion.SetGenesisVersion(2);
// Dogecoin block version 2 can be both AuxPoW and regular, so test 3
block.nVersion.SetGenesisVersion(3);
mineBlock(block, true);
BOOST_CHECK(!CheckProofOfWork(block, params));
BOOST_CHECK(!CheckAuxPowProofOfWork(block, params));
block.nVersion.SetBaseVersion(2);
block.nVersion = 2;
block.nVersion.SetChainId(params.nAuxpowChainId);
mineBlock(block, true);
BOOST_CHECK(CheckProofOfWork(block, params));
BOOST_CHECK(CheckAuxPowProofOfWork(block, params));
block.nVersion.SetChainId(params.nAuxpowChainId + 1);
mineBlock(block, true);
BOOST_CHECK(!CheckProofOfWork(block, params));
BOOST_CHECK(!CheckAuxPowProofOfWork(block, params));
/* Check the case when the block does not have auxpow (this is true
right now). */
@ -378,13 +381,13 @@ BOOST_AUTO_TEST_CASE(auxpow_pow)
block.nVersion.SetChainId(params.nAuxpowChainId);
block.nVersion.SetAuxpow(true);
mineBlock(block, true);
BOOST_CHECK(!CheckProofOfWork(block, params));
BOOST_CHECK(!CheckAuxPowProofOfWork(block, params));
block.nVersion.SetAuxpow(false);
mineBlock(block, true);
BOOST_CHECK(CheckProofOfWork(block, params));
BOOST_CHECK(CheckAuxPowProofOfWork(block, params));
mineBlock(block, false);
BOOST_CHECK(!CheckProofOfWork(block, params));
BOOST_CHECK(!CheckAuxPowProofOfWork(block, params));
/* ****************************************** */
/* Check the case that the block has auxpow. */
@ -404,10 +407,10 @@ BOOST_AUTO_TEST_CASE(auxpow_pow)
builder.setCoinbase(CScript() << data);
mineBlock(builder.parentBlock, false, block.nBits);
block.SetAuxpow(new CAuxPow(builder.get()));
BOOST_CHECK(!CheckProofOfWork(block, params));
BOOST_CHECK(!CheckAuxPowProofOfWork(block, params));
mineBlock(builder.parentBlock, true, block.nBits);
block.SetAuxpow(new CAuxPow(builder.get()));
BOOST_CHECK(CheckProofOfWork(block, params));
BOOST_CHECK(CheckAuxPowProofOfWork(block, params));
/* Mismatch between auxpow being present and block.nVersion. Note that
block.SetAuxpow sets also the version and that we want to ensure
@ -423,7 +426,7 @@ BOOST_AUTO_TEST_CASE(auxpow_pow)
BOOST_CHECK(hashAux != block.GetHash());
block.nVersion.SetAuxpow(false);
BOOST_CHECK(hashAux == block.GetHash());
BOOST_CHECK(!CheckProofOfWork(block, params));
BOOST_CHECK(!CheckAuxPowProofOfWork(block, params));
/* Modifying the block invalidates the PoW. */
block.nVersion.SetAuxpow(true);
@ -432,9 +435,9 @@ BOOST_AUTO_TEST_CASE(auxpow_pow)
builder.setCoinbase(CScript() << data);
mineBlock(builder.parentBlock, true, block.nBits);
block.SetAuxpow(new CAuxPow(builder.get()));
BOOST_CHECK(CheckProofOfWork(block, params));
BOOST_CHECK(CheckAuxPowProofOfWork(block, params));
tamperWith(block.hashMerkleRoot);
BOOST_CHECK(!CheckProofOfWork(block, params));
BOOST_CHECK(!CheckAuxPowProofOfWork(block, params));
}
/* ************************************************************************** */