mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 20:12:57 +01:00
Merge #9490: Replace FindLatestBefore used by importmuti with FindEarliestAtLeast.
4b06e41
Add unit test for FindEarliestAtLeast (Suhas Daftuar)997a98a
Replace FindLatestBefore used by importmuti with FindEarliestAtLeast. (Gregory Maxwell)
This commit is contained in:
commit
e126d0c12c
@ -61,10 +61,10 @@ const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const {
|
|||||||
return pindex;
|
return pindex;
|
||||||
}
|
}
|
||||||
|
|
||||||
CBlockIndex* CChain::FindLatestBefore(int64_t nTime) const
|
CBlockIndex* CChain::FindEarliestAtLeast(int64_t nTime) const
|
||||||
{
|
{
|
||||||
std::vector<CBlockIndex*>::const_iterator lower = std::lower_bound(vChain.begin(), vChain.end(), nTime,
|
std::vector<CBlockIndex*>::const_iterator lower = std::lower_bound(vChain.begin(), vChain.end(), nTime,
|
||||||
[](CBlockIndex* pBlock, const int64_t& time) -> bool { return pBlock->GetBlockTime() < time; });
|
[](CBlockIndex* pBlock, const int64_t& time) -> bool { return pBlock->GetBlockTimeMax() < time; });
|
||||||
return (lower == vChain.end() ? NULL : *lower);
|
return (lower == vChain.end() ? NULL : *lower);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
src/chain.h
13
src/chain.h
@ -202,6 +202,9 @@ public:
|
|||||||
//! (memory only) Sequential id assigned to distinguish order in which blocks are received.
|
//! (memory only) Sequential id assigned to distinguish order in which blocks are received.
|
||||||
int32_t nSequenceId;
|
int32_t nSequenceId;
|
||||||
|
|
||||||
|
//! (memory only) Maximum nTime in the chain upto and including this block.
|
||||||
|
unsigned int nTimeMax;
|
||||||
|
|
||||||
void SetNull()
|
void SetNull()
|
||||||
{
|
{
|
||||||
phashBlock = NULL;
|
phashBlock = NULL;
|
||||||
@ -216,6 +219,7 @@ public:
|
|||||||
nChainTx = 0;
|
nChainTx = 0;
|
||||||
nStatus = 0;
|
nStatus = 0;
|
||||||
nSequenceId = 0;
|
nSequenceId = 0;
|
||||||
|
nTimeMax = 0;
|
||||||
|
|
||||||
nVersion = 0;
|
nVersion = 0;
|
||||||
hashMerkleRoot = uint256();
|
hashMerkleRoot = uint256();
|
||||||
@ -281,6 +285,11 @@ public:
|
|||||||
return (int64_t)nTime;
|
return (int64_t)nTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t GetBlockTimeMax() const
|
||||||
|
{
|
||||||
|
return (int64_t)nTimeMax;
|
||||||
|
}
|
||||||
|
|
||||||
enum { nMedianTimeSpan=11 };
|
enum { nMedianTimeSpan=11 };
|
||||||
|
|
||||||
int64_t GetMedianTimePast() const
|
int64_t GetMedianTimePast() const
|
||||||
@ -461,8 +470,8 @@ public:
|
|||||||
/** Find the last common block between this chain and a block index entry. */
|
/** Find the last common block between this chain and a block index entry. */
|
||||||
const CBlockIndex *FindFork(const CBlockIndex *pindex) const;
|
const CBlockIndex *FindFork(const CBlockIndex *pindex) const;
|
||||||
|
|
||||||
/** Find the most recent block with timestamp lower than the given. */
|
/** Find the earliest block with timestamp equal or greater than the given. */
|
||||||
CBlockIndex* FindLatestBefore(int64_t nTime) const;
|
CBlockIndex* FindEarliestAtLeast(int64_t nTime) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BITCOIN_CHAIN_H
|
#endif // BITCOIN_CHAIN_H
|
||||||
|
@ -839,9 +839,9 @@ UniValue pruneblockchain(const JSONRPCRequest& request)
|
|||||||
// Height value more than a billion is too high to be a block height, and
|
// Height value more than a billion is too high to be a block height, and
|
||||||
// too low to be a block time (corresponds to timestamp from Sep 2001).
|
// too low to be a block time (corresponds to timestamp from Sep 2001).
|
||||||
if (heightParam > 1000000000) {
|
if (heightParam > 1000000000) {
|
||||||
CBlockIndex* pindex = chainActive.FindLatestBefore(heightParam);
|
CBlockIndex* pindex = chainActive.FindEarliestAtLeast(heightParam);
|
||||||
if (!pindex) {
|
if (!pindex) {
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Could not find block before specified timestamp.");
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "Could not find block with at least the specified timestamp.");
|
||||||
}
|
}
|
||||||
heightParam = pindex->nHeight;
|
heightParam = pindex->nHeight;
|
||||||
}
|
}
|
||||||
|
@ -100,4 +100,47 @@ BOOST_AUTO_TEST_CASE(getlocator_test)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(findearliestatleast_test)
|
||||||
|
{
|
||||||
|
std::vector<uint256> vHashMain(100000);
|
||||||
|
std::vector<CBlockIndex> vBlocksMain(100000);
|
||||||
|
for (unsigned int i=0; i<vBlocksMain.size(); i++) {
|
||||||
|
vHashMain[i] = ArithToUint256(i); // Set the hash equal to the height
|
||||||
|
vBlocksMain[i].nHeight = i;
|
||||||
|
vBlocksMain[i].pprev = i ? &vBlocksMain[i - 1] : NULL;
|
||||||
|
vBlocksMain[i].phashBlock = &vHashMain[i];
|
||||||
|
vBlocksMain[i].BuildSkip();
|
||||||
|
if (i < 10) {
|
||||||
|
vBlocksMain[i].nTime = i;
|
||||||
|
vBlocksMain[i].nTimeMax = i;
|
||||||
|
} else {
|
||||||
|
// randomly choose something in the range [MTP, MTP*2]
|
||||||
|
int64_t medianTimePast = vBlocksMain[i].GetMedianTimePast();
|
||||||
|
int r = insecure_rand() % medianTimePast;
|
||||||
|
vBlocksMain[i].nTime = r + medianTimePast;
|
||||||
|
vBlocksMain[i].nTimeMax = std::max(vBlocksMain[i].nTime, vBlocksMain[i-1].nTimeMax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check that we set nTimeMax up correctly.
|
||||||
|
unsigned int curTimeMax = 0;
|
||||||
|
for (unsigned int i=0; i<vBlocksMain.size(); ++i) {
|
||||||
|
curTimeMax = std::max(curTimeMax, vBlocksMain[i].nTime);
|
||||||
|
BOOST_CHECK(curTimeMax == vBlocksMain[i].nTimeMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a CChain for the main branch.
|
||||||
|
CChain chain;
|
||||||
|
chain.SetTip(&vBlocksMain.back());
|
||||||
|
|
||||||
|
// Verify that FindEarliestAtLeast is correct.
|
||||||
|
for (unsigned int i=0; i<10000; ++i) {
|
||||||
|
// Pick a random element in vBlocksMain.
|
||||||
|
int r = insecure_rand() % vBlocksMain.size();
|
||||||
|
int64_t test_time = vBlocksMain[r].nTime;
|
||||||
|
CBlockIndex *ret = chain.FindEarliestAtLeast(test_time);
|
||||||
|
BOOST_CHECK(ret->nTimeMax >= test_time);
|
||||||
|
BOOST_CHECK((ret->pprev==NULL) || ret->pprev->nTimeMax < test_time);
|
||||||
|
BOOST_CHECK(vBlocksMain[r].GetAncestor(ret->nHeight) == ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
@ -2611,6 +2611,7 @@ CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
|
|||||||
pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
|
pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
|
||||||
pindexNew->BuildSkip();
|
pindexNew->BuildSkip();
|
||||||
}
|
}
|
||||||
|
pindexNew->nTimeMax = (pindexNew->pprev ? std::max(pindexNew->pprev->nTimeMax, pindexNew->nTime) : pindexNew->nTime);
|
||||||
pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew);
|
pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew);
|
||||||
pindexNew->RaiseValidity(BLOCK_VALID_TREE);
|
pindexNew->RaiseValidity(BLOCK_VALID_TREE);
|
||||||
if (pindexBestHeader == NULL || pindexBestHeader->nChainWork < pindexNew->nChainWork)
|
if (pindexBestHeader == NULL || pindexBestHeader->nChainWork < pindexNew->nChainWork)
|
||||||
@ -3432,6 +3433,7 @@ bool static LoadBlockIndexDB(const CChainParams& chainparams)
|
|||||||
{
|
{
|
||||||
CBlockIndex* pindex = item.second;
|
CBlockIndex* pindex = item.second;
|
||||||
pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex);
|
pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex);
|
||||||
|
pindex->nTimeMax = (pindex->pprev ? std::max(pindex->pprev->nTimeMax, pindex->nTime) : pindex->nTime);
|
||||||
// We can link the chain of blocks for which we've received transactions at some point.
|
// We can link the chain of blocks for which we've received transactions at some point.
|
||||||
// Pruned nodes may have deleted the block.
|
// Pruned nodes may have deleted the block.
|
||||||
if (pindex->nTx > 0) {
|
if (pindex->nTx > 0) {
|
||||||
|
@ -1048,8 +1048,8 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fRescan && fRunScan && requests.size() && nLowestTimestamp <= chainActive.Tip()->GetBlockTime()) {
|
if (fRescan && fRunScan && requests.size() && nLowestTimestamp <= chainActive.Tip()->GetBlockTimeMax()) {
|
||||||
CBlockIndex* pindex = nLowestTimestamp > minimumTimestamp ? chainActive.FindLatestBefore(nLowestTimestamp) : chainActive.Genesis();
|
CBlockIndex* pindex = nLowestTimestamp > minimumTimestamp ? chainActive.FindEarliestAtLeast(nLowestTimestamp) : chainActive.Genesis();
|
||||||
|
|
||||||
if (pindex) {
|
if (pindex) {
|
||||||
pwalletMain->ScanForWalletTransactions(pindex, true);
|
pwalletMain->ScanForWalletTransactions(pindex, true);
|
||||||
|
Loading…
Reference in New Issue
Block a user