diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index d17c25a2e..a1ebe1a6c 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -33,12 +33,8 @@ static const int CONTINUE_EXECUTION=-1; // To fix the chainActive not defined error. CChain chainActive; -struct BlockHasher -{ - size_t operator()(const uint256& hash) const { return hash.GetCheapHash(); } -}; -typedef std::unordered_map BlockMap; -BlockMap mapBlockIndex; +typedef std::map BlockSeedHeightMap; +BlockSeedHeightMap mapBlockSeedHeight; // // This function returns either one of EXIT_ codes when it's expected to stop the process or diff --git a/src/cn_utils/crypto/hash-ops.h b/src/cn_utils/crypto/hash-ops.h index 416b9acf3..e03c14cc9 100644 --- a/src/cn_utils/crypto/hash-ops.h +++ b/src/cn_utils/crypto/hash-ops.h @@ -93,5 +93,6 @@ void rx_slow_hash_allocate_state(void); void rx_slow_hash_free_state(void); uint64_t rx_seedheight(const uint64_t height); void rx_seedheights(const uint64_t height, uint64_t *seed_height, uint64_t *next_height); +int is_a_seed_height(const uint64_t height); void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const char *seedhash, const void *data, size_t length, char *hash, int miners, int is_alt); void rx_reorg(const uint64_t split_height); diff --git a/src/cn_utils/crypto/rx-slow-hash.c b/src/cn_utils/crypto/rx-slow-hash.c index 2854c8e78..7af5c18d6 100644 --- a/src/cn_utils/crypto/rx-slow-hash.c +++ b/src/cn_utils/crypto/rx-slow-hash.c @@ -139,6 +139,11 @@ void rx_seedheights(const uint64_t height, uint64_t *seedheight, uint64_t *nexth *nextheight = rx_seedheight(height + SEEDHASH_EPOCH_LAG); } +int is_a_seed_height(const uint64_t height) { + uint64_t next_seed_hegith = rx_seedheight(height + SEEDHASH_EPOCH_LAG + 1); + return (height == next_seed_hegith); +} + typedef struct seedinfo { randomx_cache *si_cache; unsigned long si_start; diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 7f5db08c1..d1baa2b47 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -17,50 +17,14 @@ extern "C" void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height); extern "C" void cn_fast_hash(const void *data, size_t length, char *hash); -namespace -{ - boost::mutex max_concurrency_lock; - unsigned max_concurrency = boost::thread::hardware_concurrency(); -} - -void set_max_concurrency(unsigned n) -{ - if (n < 1) - n = boost::thread::hardware_concurrency(); - unsigned hwc = boost::thread::hardware_concurrency(); - if (n > hwc) - n = hwc; - boost::lock_guard lock(max_concurrency_lock); - max_concurrency = n; -} - -unsigned get_max_concurrency() -{ - boost::lock_guard lock(max_concurrency_lock); - return max_concurrency; -} - static uint256 cn_get_block_hash_by_height(uint64_t seed_height, char cnHash[32]) { CBlockIndex* pblockindex = chainActive[seed_height]; if (pblockindex == NULL) { // This will only happens during initial block download. - static std::map mapBlockHeight; - std::map::iterator iter = mapBlockHeight.find(seed_height); - if (iter != mapBlockHeight.end()) { - pblockindex = iter->second; - } else { - for (const std::pair& item : mapBlockIndex) - { - CBlockIndex* pindex = item.second; - if (pindex->nNonce == seed_height) { - pblockindex = pindex; - mapBlockHeight.insert(std::make_pair(seed_height, pindex)); - break; - } - } - } + pblockindex = mapBlockSeedHeight.find(seed_height)->second; } + assert(pblockindex != NULL); uint256 blockHash = pblockindex->GetBlockHash(); const unsigned char* pHash = blockHash.begin(); for (int j = 31; j >= 0; j--) { @@ -109,7 +73,7 @@ uint256 CBlockHeader::GetPoWHash() const char cnHash[32]; seed_height = crypto::rx_seedheight(height); cn_get_block_hash_by_height(seed_height, cnHash); - crypto::rx_slow_hash(height, seed_height, cnHash, blob.data(), blob.size(), BEGIN(thash), get_max_concurrency(), 0); + crypto::rx_slow_hash(height, seed_height, cnHash, blob.data(), blob.size(), BEGIN(thash), 0, 0); } else { cn_slow_hash(blob.data(), blob.size(), BEGIN(thash), cnHeader.major_version - 6, 0, height); } diff --git a/src/validation.cpp b/src/validation.cpp index 3283d4bf7..aead72147 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -154,6 +154,7 @@ public: CChain chainActive; BlockMap mapBlockIndex; std::multimap mapBlocksUnlinked; + BlockSeedHeightMap mapBlockSeedHeight; CBlockIndex *pindexBestInvalid = nullptr; bool LoadBlockIndex(const Consensus::Params& consensus_params, CBlockTreeDB& blocktree); @@ -206,6 +207,7 @@ private: CCriticalSection cs_main; BlockMap& mapBlockIndex = g_chainstate.mapBlockIndex; +BlockSeedHeightMap& mapBlockSeedHeight = g_chainstate.mapBlockSeedHeight; CChain& chainActive = g_chainstate.chainActive; CBlockIndex *pindexBestHeader = nullptr; CWaitableCriticalSection csBestBlock; @@ -2880,6 +2882,10 @@ CBlockIndex* CChainState::AddToBlockIndex(const CBlockHeader& block) // to avoid miners withholding blocks but broadcasting headers, to get a // competitive advantage. pindexNew->nSequenceId = 0; + uint64_t height = block.nNonce; + if (crypto::is_a_seed_height(height)) { + mapBlockSeedHeight.insert(std::make_pair(height, pindexNew)); + } BlockMap::iterator mi = mapBlockIndex.insert(std::make_pair(hash, pindexNew)).first; pindexNew->phashBlock = &((*mi).first); BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock); diff --git a/src/validation.h b/src/validation.h index c0d64534c..1c102c4b4 100644 --- a/src/validation.h +++ b/src/validation.h @@ -161,6 +161,8 @@ extern CBlockPolicyEstimator feeEstimator; extern CTxMemPool mempool; typedef std::unordered_map BlockMap; extern BlockMap& mapBlockIndex; +typedef std::map BlockSeedHeightMap; +extern BlockSeedHeightMap& mapBlockSeedHeight; extern uint64_t nLastBlockTx; extern uint64_t nLastBlockWeight; extern const std::string strMessageMagic; @@ -221,7 +223,7 @@ static const unsigned int DEFAULT_CHECKLEVEL = 3; // Setting the target to > than 550MB will make it likely we can respect the target. static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024; -/** +/** * Process an incoming block. This only returns after the best known valid * block is made active. Note that it does not, however, guarantee that the * specific block passed to it has been checked for validity! @@ -232,7 +234,7 @@ static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024; * * Note that we guarantee that either the proof-of-work is valid on pblock, or * (and possibly also) BlockChecked will have been called. - * + * * Call without cs_main held. * * @param[in] pblock The block we want to process. @@ -358,7 +360,7 @@ bool CheckSequenceLocks(const CTransaction &tx, int flags, LockPoints* lp = null /** * Closure representing one script verification - * Note that this stores references to the spending transaction + * Note that this stores references to the spending transaction */ class CScriptCheck {