diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/auxpow.h | 4 | ||||
| -rw-r--r-- | src/chainparams.cpp | 10 | ||||
| -rw-r--r-- | src/dogecoin.cpp | 51 | ||||
| -rw-r--r-- | src/dogecoin.h | 10 | ||||
| -rw-r--r-- | src/init.cpp | 2 | ||||
| -rw-r--r-- | src/main.cpp | 61 | ||||
| -rw-r--r-- | src/main.h | 8 | ||||
| -rw-r--r-- | src/miner.cpp | 6 | ||||
| -rw-r--r-- | src/miner.h | 1 | ||||
| -rw-r--r-- | src/primitives/block.h | 2 | ||||
| -rw-r--r-- | src/primitives/pureheader.cpp | 8 | ||||
| -rw-r--r-- | src/primitives/pureheader.h | 42 | ||||
| -rw-r--r-- | src/rpcblockchain.cpp | 9 | ||||
| -rw-r--r-- | src/rpcmining.cpp | 66 | ||||
| -rw-r--r-- | src/test/auxpow_tests.cpp | 39 |
15 files changed, 160 insertions, 159 deletions
diff --git a/src/auxpow.h b/src/auxpow.h index 26cc05f98..dda550a01 100644 --- a/src/auxpow.h +++ b/src/auxpow.h @@ -154,9 +154,9 @@ public: * @return The parent block hash. */ inline uint256 - getParentBlockHash() const + getParentBlockPoWHash() const { - return parentBlock.GetHash(); + return parentBlock.GetPoWHash(); } /** diff --git a/src/chainparams.cpp b/src/chainparams.cpp index b573aa80a..8a5e613c7 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -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; diff --git a/src/dogecoin.cpp b/src/dogecoin.cpp index e946acad6..dd394d5b4 100644 --- a/src/dogecoin.cpp +++ b/src/dogecoin.cpp @@ -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; diff --git a/src/dogecoin.h b/src/dogecoin.h index cedbfac78..edc07b5f5 100644 --- a/src/dogecoin.h +++ b/src/dogecoin.h @@ -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); diff --git a/src/init.cpp b/src/init.cpp index 7bb7b183f..0923dcb3a 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -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 diff --git a/src/main.cpp b/src/main.cpp index 4046330e9..39b97d1d6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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; } diff --git a/src/main.h b/src/main.h index 2cb3752ef..d09540aa4 100644 --- a/src/main.h +++ b/src/main.h @@ -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); diff --git a/src/miner.cpp b/src/miner.cpp index a6ed42d00..f83f43ceb 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -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)); diff --git a/src/miner.h b/src/miner.h index 46bed944d..c6a4acc2e 100644 --- a/src/miner.h +++ b/src/miner.h @@ -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 diff --git a/src/primitives/block.h b/src/primitives/block.h index ef2b19010..d59ac4427 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -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()) diff --git a/src/primitives/pureheader.cpp b/src/primitives/pureheader.cpp index c90d5fd8e..94f14499b 100644 --- a/src/primitives/pureheader.cpp +++ b/src/primitives/pureheader.cpp @@ -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); diff --git a/src/primitives/pureheader.h b/src/primitives/pureheader.h index 449ebbff0..0e4385e6e 100644 --- a/src/primitives/pureheader.h +++ b/src/primitives/pureheader.h @@ -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() @@ -46,29 +46,12 @@ public: } /** - * 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); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 3d4cfcd21..e4ef47884 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -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())); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 3639ac931..7eee8bb05 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -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 diff --git a/src/test/auxpow_tests.cpp b/src/test/auxpow_tests.cpp index 1630d000d..566c88feb 100644 --- a/src/test/auxpow_tests.cpp +++ b/src/test/auxpow_tests.cpp @@ -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)); } /* ************************************************************************** */ |