txindex: use a new block locator for downgrade safety

The hashed txindex entries cannot be found by older nodes. Record sync
progress under a new locator key so a downgraded node will not rely on
entries indexed by upgraded nodes, and instead continue syncing from the
legacy locator.
This commit is contained in:
Andrew Toth
2026-06-23 18:33:20 -04:00
parent 4b08baed72
commit 42771e7998
2 changed files with 22 additions and 2 deletions

View File

@@ -66,13 +66,14 @@ protected:
public:
DB(const fs::path& path, size_t n_cache_size,
bool f_memory = false, bool f_wipe = false, bool f_obfuscate = false, bool f_bloom = true);
virtual ~DB() = default;
/// Read block locator of the chain that the index is in sync with.
/// Note, the returned locator will be empty if no record exists.
CBlockLocator ReadBestBlock() const;
virtual CBlockLocator ReadBestBlock() const;
/// Write block locator of the chain that the index is in sync with.
void WriteBestBlock(CDBBatch& batch, const CBlockLocator& locator);
virtual void WriteBestBlock(CDBBatch& batch, const CBlockLocator& locator);
};
private:

View File

@@ -30,6 +30,7 @@
#include <vector>
constexpr uint8_t DB_TXINDEX{'t'};
const std::string DB_BEST_BLOCK_V2{"best_block_v2"};
std::unique_ptr<TxIndex> g_txindex;
@@ -46,6 +47,9 @@ public:
/// Write a batch of transaction positions to the DB.
void WriteTxs(const std::vector<std::pair<Txid, CDiskTxPos>>& v_pos);
CBlockLocator ReadBestBlock() const override;
void WriteBestBlock(CDBBatch& batch, const CBlockLocator& locator) override;
};
TxIndex::DB::DB(size_t n_cache_size, bool f_memory, bool f_wipe) :
@@ -57,6 +61,21 @@ bool TxIndex::DB::ReadTxPos(const Txid& txid, CDiskTxPos& pos) const
return Read(std::make_pair(DB_TXINDEX, txid.ToUint256()), pos);
}
CBlockLocator TxIndex::DB::ReadBestBlock() const
{
CBlockLocator locator;
if (Read(DB_BEST_BLOCK_V2, locator)) {
return locator;
}
// If we don't have a locator yet, start from the legacy best block.
return BaseIndex::DB::ReadBestBlock();
}
void TxIndex::DB::WriteBestBlock(CDBBatch& batch, const CBlockLocator& locator)
{
batch.Write(DB_BEST_BLOCK_V2, locator);
}
void TxIndex::DB::WriteTxs(const std::vector<std::pair<Txid, CDiskTxPos>>& v_pos)
{
CDBBatch batch(*this);