Upgrade from per-tx database to per-txout
This commit is contained in:
parent
b2af357f39
commit
8b25d2c0ce
4 changed files with 54 additions and 0 deletions
|
@ -82,6 +82,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! Legacy class to deserialize pre-pertxout database entries without reindex.
|
||||||
class CCoins
|
class CCoins
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -1455,6 +1455,12 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||||
//If we're reindexing in prune mode, wipe away unusable block files and all undo data files
|
//If we're reindexing in prune mode, wipe away unusable block files and all undo data files
|
||||||
if (fPruneMode)
|
if (fPruneMode)
|
||||||
CleanupBlockRevFiles();
|
CleanupBlockRevFiles();
|
||||||
|
} else {
|
||||||
|
// If necessary, upgrade from older database format.
|
||||||
|
if (!pcoinsdbview->Upgrade()) {
|
||||||
|
strLoadError = _("Error upgrading chainstate database");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!LoadBlockIndex(chainparams)) {
|
if (!LoadBlockIndex(chainparams)) {
|
||||||
|
|
45
src/txdb.cpp
45
src/txdb.cpp
|
@ -252,3 +252,48 @@ bool CBlockTreeDB::LoadBlockIndexGuts(std::function<CBlockIndex*(const uint256&)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Upgrade the database from older formats.
|
||||||
|
*
|
||||||
|
* Currently implemented: from the per-tx utxo model (0.8..0.14.x) to per-txout.
|
||||||
|
*/
|
||||||
|
bool CCoinsViewDB::Upgrade() {
|
||||||
|
std::unique_ptr<CDBIterator> pcursor(db.NewIterator());
|
||||||
|
pcursor->Seek(std::make_pair(DB_COINS, uint256()));
|
||||||
|
if (!pcursor->Valid()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogPrintf("Upgrading database...\n");
|
||||||
|
size_t batch_size = 1 << 24;
|
||||||
|
CDBBatch batch(db);
|
||||||
|
while (pcursor->Valid()) {
|
||||||
|
boost::this_thread::interruption_point();
|
||||||
|
std::pair<unsigned char, uint256> key;
|
||||||
|
if (pcursor->GetKey(key) && key.first == DB_COINS) {
|
||||||
|
CCoins old_coins;
|
||||||
|
if (!pcursor->GetValue(old_coins)) {
|
||||||
|
return error("%s: cannot parse CCoins record", __func__);
|
||||||
|
}
|
||||||
|
COutPoint outpoint(key.second, 0);
|
||||||
|
for (size_t i = 0; i < old_coins.vout.size(); ++i) {
|
||||||
|
if (!old_coins.vout[i].IsNull() && !old_coins.vout[i].scriptPubKey.IsUnspendable()) {
|
||||||
|
Coin newcoin(std::move(old_coins.vout[i]), old_coins.nHeight, old_coins.fCoinBase);
|
||||||
|
outpoint.n = i;
|
||||||
|
CoinEntry entry(&outpoint);
|
||||||
|
batch.Write(entry, newcoin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
batch.Erase(key);
|
||||||
|
if (batch.SizeEstimate() > batch_size) {
|
||||||
|
db.WriteBatch(batch);
|
||||||
|
batch.Clear();
|
||||||
|
}
|
||||||
|
pcursor->Next();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
db.WriteBatch(batch);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -77,6 +77,8 @@ public:
|
||||||
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override;
|
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override;
|
||||||
CCoinsViewCursor *Cursor() const override;
|
CCoinsViewCursor *Cursor() const override;
|
||||||
|
|
||||||
|
//! Attempt to update from an older database format. Returns whether an error occurred.
|
||||||
|
bool Upgrade();
|
||||||
size_t EstimateSize() const override;
|
size_t EstimateSize() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue