Browse Source

Upgrade from per-tx database to per-txout

0.15
Pieter Wuille 7 years ago
parent
commit
8b25d2c0ce
  1. 1
      src/coins.h
  2. 6
      src/init.cpp
  3. 45
      src/txdb.cpp
  4. 2
      src/txdb.h

1
src/coins.h

@ -82,6 +82,7 @@ public: @@ -82,6 +82,7 @@ public:
}
};
//! Legacy class to deserialize pre-pertxout database entries without reindex.
class CCoins
{
public:

6
src/init.cpp

@ -1455,6 +1455,12 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) @@ -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 (fPruneMode)
CleanupBlockRevFiles();
} else {
// If necessary, upgrade from older database format.
if (!pcoinsdbview->Upgrade()) {
strLoadError = _("Error upgrading chainstate database");
break;
}
}
if (!LoadBlockIndex(chainparams)) {

45
src/txdb.cpp

@ -252,3 +252,48 @@ bool CBlockTreeDB::LoadBlockIndexGuts(std::function<CBlockIndex*(const uint256&) @@ -252,3 +252,48 @@ bool CBlockTreeDB::LoadBlockIndexGuts(std::function<CBlockIndex*(const uint256&)
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;
}

2
src/txdb.h

@ -77,6 +77,8 @@ public: @@ -77,6 +77,8 @@ public:
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) 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;
};

Loading…
Cancel
Save