mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 20:12:57 +01:00
Fall back to ReadBlockFromDisk when blockTxs is not filled yet (#2908)
* Fall back to ReadBlockFromDisk when blockTxs is not filled yet This handles the case where a MN is freshly started and SyncTransaction was not been called for older transactions/blocks. * Also update txFirstSeenTime * Properly handle txids == nullptr
This commit is contained in:
parent
4dc5c0e9ed
commit
56f31195d2
@ -301,17 +301,10 @@ void CChainLocksHandler::TrySignChainTip()
|
||||
break;
|
||||
}
|
||||
|
||||
decltype(blockTxs.begin()->second) txids;
|
||||
{
|
||||
LOCK(cs);
|
||||
auto it = blockTxs.find(pindexWalk->GetBlockHash());
|
||||
if (it == blockTxs.end()) {
|
||||
// this should actually not happen as NewPoWValidBlock should have been called before
|
||||
LogPrint("chainlocks", "CChainLocksHandler::%s -- blockTxs for %s not found\n", __func__,
|
||||
pindexWalk->GetBlockHash().ToString());
|
||||
return;
|
||||
}
|
||||
txids = it->second;
|
||||
auto txids = GetBlockTxs(pindexWalk->GetBlockHash());
|
||||
if (!txids) {
|
||||
pindexWalk = pindexWalk->pprev;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto& txid : *txids) {
|
||||
@ -382,6 +375,55 @@ void CChainLocksHandler::SyncTransaction(const CTransaction& tx, const CBlockInd
|
||||
}
|
||||
}
|
||||
|
||||
CChainLocksHandler::BlockTxs::mapped_type CChainLocksHandler::GetBlockTxs(const uint256& blockHash)
|
||||
{
|
||||
AssertLockNotHeld(cs);
|
||||
AssertLockNotHeld(cs_main);
|
||||
|
||||
CChainLocksHandler::BlockTxs::mapped_type ret;
|
||||
|
||||
{
|
||||
LOCK(cs);
|
||||
auto it = blockTxs.find(blockHash);
|
||||
if (it != blockTxs.end()) {
|
||||
ret = it->second;
|
||||
}
|
||||
}
|
||||
if (!ret) {
|
||||
// This should only happen when freshly started.
|
||||
// If running for some time, SyncTransaction should have been called before which fills blockTxs.
|
||||
LogPrint("chainlocks", "CChainLocksHandler::%s -- blockTxs for %s not found. Trying ReadBlockFromDisk\n", __func__,
|
||||
blockHash.ToString());
|
||||
|
||||
uint32_t blockTime;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
auto pindex = mapBlockIndex.at(blockHash);
|
||||
CBlock block;
|
||||
if (!ReadBlockFromDisk(block, pindex, Params().GetConsensus())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ret = std::make_shared<std::unordered_set<uint256, StaticSaltedHasher>>();
|
||||
for (auto& tx : block.vtx) {
|
||||
if (tx->IsCoinBase() || tx->vin.empty()) {
|
||||
continue;
|
||||
}
|
||||
ret->emplace(tx->GetHash());
|
||||
}
|
||||
|
||||
blockTime = block.nTime;
|
||||
}
|
||||
|
||||
LOCK(cs);
|
||||
blockTxs.emplace(blockHash, ret);
|
||||
for (auto& txid : *ret) {
|
||||
txFirstSeenTime.emplace(txid, blockTime);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CChainLocksHandler::IsTxSafeForMining(const uint256& txid)
|
||||
{
|
||||
if (!sporkManager.IsSporkActive(SPORK_3_INSTANTSEND_BLOCK_FILTERING)) {
|
||||
|
@ -68,7 +68,8 @@ private:
|
||||
uint256 lastSignedMsgHash;
|
||||
|
||||
// We keep track of txids from recently received blocks so that we can check if all TXs got ixlocked
|
||||
std::unordered_map<uint256, std::shared_ptr<std::unordered_set<uint256, StaticSaltedHasher>>> blockTxs;
|
||||
typedef std::unordered_map<uint256, std::shared_ptr<std::unordered_set<uint256, StaticSaltedHasher>>> BlockTxs;
|
||||
BlockTxs blockTxs;
|
||||
std::unordered_map<uint256, int64_t> txFirstSeenTime;
|
||||
|
||||
std::map<uint256, int64_t> seenChainLocks;
|
||||
@ -107,6 +108,8 @@ private:
|
||||
|
||||
void DoInvalidateBlock(const CBlockIndex* pindex, bool activateBestChain);
|
||||
|
||||
BlockTxs::mapped_type GetBlockTxs(const uint256& blockHash);
|
||||
|
||||
void Cleanup();
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user