upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 15805ca..dbb2c41 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -49,6 +49,15 @@ uint256 hashGenesisMerkleRoot("0x1a45b4482532abb29b10e234d3f13132230525a339ecea9
49CBlockIndex* pindexGenesisBlock = NULL; 49CBlockIndex* pindexGenesisBlock = NULL;
50int nBestHeight = -1; 50int nBestHeight = -1;
51uint256 hashBestChain = 0; 51uint256 hashBestChain = 0;
52// Blocks at the tip to re-verify on startup. 0 means the whole chain. 288 is
53// about ten hours at a two-minute target -- far enough back to catch a bad tip,
54// short enough that startup does not pay a RandomX hash per block for the whole
55// history. /checkblocks=N overrides it.
56int nCheckBlocksOnLoad = 288;
57// Set by CTxDB::LoadBlockIndex when the tail of the chain fails verification.
58// The repair runs in LoadBlockIndex() below, once that read-only handle and its
59// cursor are closed.
60CBlockIndex* pindexBadChainFork = NULL;
52CBlockIndex* pindexBest = NULL; 61CBlockIndex* pindexBest = NULL;
53 62
54map<uint256, CBlock*> mapOrphanBlocks; 63map<uint256, CBlock*> mapOrphanBlocks;
@@ -1577,6 +1586,72 @@ bool LoadBlockIndex(bool fAllowNew)
1577 return false; 1586 return false;
1578 txdb.Close(); 1587 txdb.Close();
1579 1588
1589 // Repair a bad tip found during verification.
1590 //
1591 // This has to happen after the handle above is closed. CTxDB::LoadBlockIndex
1592 // walks the index with a cursor it never closes, so it is still holding read
1593 // locks -- a write transaction opened alongside it waits on them forever.
1594 // Measured, not guessed: the node came up, printed the diagnosis, and hung
1595 // there with nothing in any log.
1596 if (pindexBadChainFork)
1597 {
1598 CBlockIndex* pindexFork = pindexBadChainFork;
1599 pindexBadChainFork = NULL;
1600
1601 printf("LoadBlockIndex() : *** moving best chain back to height %d, discarding %d block(s)\n",
1602 pindexFork->nHeight, nBestHeight - pindexFork->nHeight);
1603
1604 vector<CBlockIndex*> vDisconnect;
1605 for (CBlockIndex* pindex = pindexBest; pindex && pindex != pindexFork; pindex = pindex->pprev)
1606 vDisconnect.push_back(pindex);
1607
1608 bool fRolledBack = false;
1609 try
1610 {
1611 CTxDB txdbWrite;
1612 txdbWrite.TxnBegin();
1613 foreach(CBlockIndex* pindex, vDisconnect)
1614 {
1615 CBlock block;
1616 if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos, true))
1617 throw runtime_error("ReadFromDisk for disconnect failed");
1618 if (!block.DisconnectBlock(txdbWrite, pindex))
1619 throw runtime_error("DisconnectBlock failed");
1620 }
1621 if (!txdbWrite.WriteHashBestChain(pindexFork->GetBlockHash()))
1622 throw runtime_error("WriteHashBestChain failed");
1623 txdbWrite.TxnCommit();
1624 txdbWrite.Close();
1625 fRolledBack = true;
1626 }
1627 catch (const std::exception& e)
1628 {
1629 printf("LoadBlockIndex() : rollback failed: %s\n", e.what());
1630 }
1631 catch (...)
1632 {
1633 printf("LoadBlockIndex() : rollback failed\n");
1634 }
1635
1636 if (fRolledBack)
1637 {
1638 foreach(CBlockIndex* pindex, vDisconnect)
1639 if (pindex->pprev)
1640 pindex->pprev->pnext = NULL;
1641
1642 pindexBest = pindexFork;
1643 hashBestChain = pindexBest->GetBlockHash();
1644 nBestHeight = pindexBest->nHeight;
1645 printf("LoadBlockIndex() : now at height %d, will re-download from peers\n", nBestHeight);
1646 }
1647 else
1648 {
1649 // Start anyway. The operator needs a running node to read this from.
1650 printf("LoadBlockIndex() : *** still on the bad chain at height %d -- back up the data directory and report this\n",
1651 nBestHeight);
1652 }
1653 }
1654
1580 // 1655 //
1581 // Init with genesis block 1656 // Init with genesis block
1582 // 1657 //