Skip to content

Commit 3d29b6c

Browse files
Merge #6579: chore: drop legacy CDeterministicMNState formats, evodb upgrade logic
39f76c8 chore: drop legacy `CDeterministicMNState` formats, evodb upgrade logic (Kittywhiskers Van Gogh) Pull request description: ## Additional Information * `CDeterministicMNState_`{`Oldformat`, `mntype_format`} was introduced in [dash#5039](#5039) and [dash#5403](#5403), included in Dash Core v19 and v20 respectively. The above change has been in the codebase for more than two major releases and does not concern databases with a long shelf life (like wallets), this pull request removes them entirely. ## Breaking Changes Users upgrading from these versions are now expected to `-reindex`. ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)** - [x] I have added or updated relevant unit/integration/functional/e2e tests **(note: N/A)** - [x] I have made corresponding changes to the documentation **(note: N/A)** - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: UdjinM6: utACK 39f76c8 knst: utACK 39f76c8 Tree-SHA512: 3fabe0aeb7f3d01a858b0b19d49a22523f462157597a1ade93181288e4ba7b133a5ee9272a8abe41e40cff177c0ddf94123274f0427693db6fdb90c4b8e613fa
2 parents 745b4e0 + 39f76c8 commit 3d29b6c

File tree

7 files changed

+12
-405
lines changed

7 files changed

+12
-405
lines changed

doc/release-notes-6579.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Notable Changes
2+
---------------
3+
4+
* Dash Core will no longer migrate EvoDb databases generated in v19 and v20, users upgrading
5+
from these versions are recommended to run `-reindex` to rebuild all databases and indexes.

src/evo/deterministicmns.cpp

Lines changed: 0 additions & 232 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,238 +1199,6 @@ void CDeterministicMNManager::CleanupCache(int nHeight)
11991199
return erased;
12001200
}
12011201

1202-
bool CDeterministicMNManager::MigrateDBIfNeeded()
1203-
{
1204-
static const std::string DB_OLD_LIST_SNAPSHOT = "dmn_S";
1205-
static const std::string DB_OLD_LIST_DIFF = "dmn_D";
1206-
static const std::string DB_OLD_BEST_BLOCK = "b_b2";
1207-
static const std::string DB_OLD_BEST_BLOCK2 = "b_b3";
1208-
const auto& consensusParams = Params().GetConsensus();
1209-
1210-
LOCK(cs_main);
1211-
1212-
LogPrintf("CDeterministicMNManager::%s -- upgrading DB to migrate MN type\n", __func__);
1213-
1214-
if (m_chainstate.m_chain.Tip() == nullptr) {
1215-
// should have no records
1216-
LogPrintf("CDeterministicMNManager::%s -- Chain empty. evoDB:%d.\n", __func__, m_evoDb.IsEmpty());
1217-
return m_evoDb.IsEmpty();
1218-
}
1219-
1220-
if (m_evoDb.GetRawDB().Exists(EVODB_BEST_BLOCK) || m_evoDb.GetRawDB().Exists(DB_OLD_BEST_BLOCK2)) {
1221-
if (EraseOldDBData(m_evoDb.GetRawDB(), {DB_OLD_LIST_DIFF, DB_OLD_LIST_SNAPSHOT})) {
1222-
// we messed up, make sure this time we actually drop old data
1223-
LogPrintf("CDeterministicMNManager::%s -- migration already done. cleaned old data.\n", __func__);
1224-
m_evoDb.GetRawDB().CompactFull();
1225-
LogPrintf("CDeterministicMNManager::%s -- done compacting database\n", __func__);
1226-
// flush it to disk
1227-
if (!m_evoDb.CommitRootTransaction()) {
1228-
LogPrintf("CDeterministicMNManager::%s -- failed to commit to evoDB\n", __func__);
1229-
return false;
1230-
}
1231-
} else {
1232-
LogPrintf("CDeterministicMNManager::%s -- migration already done. skipping.\n", __func__);
1233-
}
1234-
return true;
1235-
}
1236-
1237-
// Removing the old EVODB_BEST_BLOCK value early results in older version to crash immediately, even if the upgrade
1238-
// process is cancelled in-between. But if the new version sees that the old EVODB_BEST_BLOCK is already removed,
1239-
// then we must assume that the upgrade process was already running before but was interrupted.
1240-
if (m_chainstate.m_chain.Height() > 1 && !m_evoDb.GetRawDB().Exists(DB_OLD_BEST_BLOCK)) {
1241-
LogPrintf("CDeterministicMNManager::%s -- previous migration attempt failed.\n", __func__);
1242-
return false;
1243-
}
1244-
m_evoDb.GetRawDB().Erase(DB_OLD_BEST_BLOCK);
1245-
1246-
if (!DeploymentActiveAt(*m_chainstate.m_chain.Tip(), consensusParams, Consensus::DEPLOYMENT_DIP0003)) {
1247-
// not reached DIP3 height yet, so no upgrade needed
1248-
LogPrintf("CDeterministicMNManager::%s -- migration not needed. dip3 not reached\n", __func__);
1249-
auto dbTx = m_evoDb.BeginTransaction();
1250-
m_evoDb.WriteBestBlock(m_chainstate.m_chain.Tip()->GetBlockHash());
1251-
dbTx->Commit();
1252-
if (!m_evoDb.CommitRootTransaction()) {
1253-
LogPrintf("CDeterministicMNManager::%s -- failed to commit to evoDB\n", __func__);
1254-
return false;
1255-
}
1256-
return true;
1257-
}
1258-
1259-
if (DeploymentActiveAt(*m_chainstate.m_chain.Tip(), consensusParams, Consensus::DEPLOYMENT_V19)) {
1260-
// too late
1261-
LogPrintf("CDeterministicMNManager::%s -- migration is not possible\n", __func__);
1262-
return false;
1263-
}
1264-
1265-
1266-
CDBBatch batch(m_evoDb.GetRawDB());
1267-
1268-
for (const auto nHeight : irange::range(Params().GetConsensus().DIP0003Height, m_chainstate.m_chain.Height() + 1)) {
1269-
auto pindex = m_chainstate.m_chain[nHeight];
1270-
// Unserialise CDeterministicMNListDiff using MN_OLD_FORMAT and set it's type to the default value TYPE_REGULAR_MASTERNODE
1271-
// It will be later written with format MN_CURRENT_FORMAT which includes the type field and MN state bls version.
1272-
CDataStream diff_data(SER_DISK, CLIENT_VERSION);
1273-
if (!m_evoDb.GetRawDB().ReadDataStream(std::make_pair(DB_OLD_LIST_DIFF, pindex->GetBlockHash()), diff_data)) {
1274-
LogPrintf("CDeterministicMNManager::%s -- missing CDeterministicMNListDiff at height %d\n", __func__, nHeight);
1275-
return false;
1276-
}
1277-
CDeterministicMNListDiff mndiff;
1278-
mndiff.Unserialize(diff_data, CDeterministicMN::MN_OLD_FORMAT);
1279-
batch.Write(std::make_pair(DB_LIST_DIFF, pindex->GetBlockHash()), mndiff);
1280-
CDataStream snapshot_data(SER_DISK, CLIENT_VERSION);
1281-
if (!m_evoDb.GetRawDB().ReadDataStream(std::make_pair(DB_OLD_LIST_SNAPSHOT, pindex->GetBlockHash()), snapshot_data)) {
1282-
// it's ok, we write snapshots every DISK_SNAPSHOT_PERIOD blocks only
1283-
continue;
1284-
}
1285-
CDeterministicMNList mnList;
1286-
mnList.Unserialize(snapshot_data, CDeterministicMN::MN_OLD_FORMAT);
1287-
batch.Write(std::make_pair(DB_LIST_SNAPSHOT, pindex->GetBlockHash()), mnList);
1288-
m_evoDb.GetRawDB().WriteBatch(batch);
1289-
batch.Clear();
1290-
LogPrintf("CDeterministicMNManager::%s -- wrote snapshot at height %d\n", __func__, nHeight);
1291-
}
1292-
1293-
m_evoDb.GetRawDB().WriteBatch(batch);
1294-
1295-
// Writing EVODB_BEST_BLOCK (which is b_b4 now) marks the DB as upgraded
1296-
auto dbTx = m_evoDb.BeginTransaction();
1297-
m_evoDb.WriteBestBlock(m_chainstate.m_chain.Tip()->GetBlockHash());
1298-
dbTx->Commit();
1299-
1300-
LogPrintf("CDeterministicMNManager::%s -- done migrating\n", __func__);
1301-
1302-
if (EraseOldDBData(m_evoDb.GetRawDB(), {DB_OLD_LIST_DIFF, DB_OLD_LIST_SNAPSHOT})) {
1303-
LogPrintf("CDeterministicMNManager::%s -- done cleaning old data\n", __func__);
1304-
}
1305-
1306-
m_evoDb.GetRawDB().CompactFull();
1307-
1308-
LogPrintf("CDeterministicMNManager::%s -- done compacting database\n", __func__);
1309-
1310-
// flush it to disk
1311-
if (!m_evoDb.CommitRootTransaction()) {
1312-
LogPrintf("CDeterministicMNManager::%s -- failed to commit to evoDB\n", __func__);
1313-
return false;
1314-
}
1315-
1316-
return true;
1317-
}
1318-
1319-
bool CDeterministicMNManager::MigrateDBIfNeeded2()
1320-
{
1321-
static const std::string DB_OLD_LIST_SNAPSHOT = "dmn_S2";
1322-
static const std::string DB_OLD_LIST_DIFF = "dmn_D2";
1323-
static const std::string DB_OLD_BEST_BLOCK = "b_b3";
1324-
const auto& consensusParams = Params().GetConsensus();
1325-
1326-
LOCK(cs_main);
1327-
1328-
LogPrintf("CDeterministicMNManager::%s -- upgrading DB to migrate MN state bls version\n", __func__);
1329-
1330-
if (m_chainstate.m_chain.Tip() == nullptr) {
1331-
// should have no records
1332-
LogPrintf("CDeterministicMNManager::%s -- Chain empty. evoDB:%d.\n", __func__, m_evoDb.IsEmpty());
1333-
return m_evoDb.IsEmpty();
1334-
}
1335-
1336-
if (m_evoDb.GetRawDB().Exists(EVODB_BEST_BLOCK)) {
1337-
if (EraseOldDBData(m_evoDb.GetRawDB(), {DB_OLD_LIST_DIFF, DB_OLD_LIST_SNAPSHOT})) {
1338-
// we messed up, make sure this time we actually drop old data
1339-
LogPrintf("CDeterministicMNManager::%s -- migration already done. cleaned old data.\n", __func__);
1340-
m_evoDb.GetRawDB().CompactFull();
1341-
LogPrintf("CDeterministicMNManager::%s -- done compacting database\n", __func__);
1342-
// flush it to disk
1343-
if (!m_evoDb.CommitRootTransaction()) {
1344-
LogPrintf("CDeterministicMNManager::%s -- failed to commit to evoDB\n", __func__);
1345-
return false;
1346-
}
1347-
} else {
1348-
LogPrintf("CDeterministicMNManager::%s -- migration already done. skipping.\n", __func__);
1349-
}
1350-
return true;
1351-
}
1352-
1353-
// Removing the old EVODB_BEST_BLOCK value early results in older version to crash immediately, even if the upgrade
1354-
// process is cancelled in-between. But if the new version sees that the old EVODB_BEST_BLOCK is already removed,
1355-
// then we must assume that the upgrade process was already running before but was interrupted.
1356-
if (m_chainstate.m_chain.Height() > 1 && !m_evoDb.GetRawDB().Exists(DB_OLD_BEST_BLOCK)) {
1357-
LogPrintf("CDeterministicMNManager::%s -- previous migration attempt failed.\n", __func__);
1358-
return false;
1359-
}
1360-
m_evoDb.GetRawDB().Erase(DB_OLD_BEST_BLOCK);
1361-
1362-
if (!DeploymentActiveAt(*m_chainstate.m_chain.Tip(), consensusParams, Consensus::DEPLOYMENT_DIP0003)) {
1363-
// not reached DIP3 height yet, so no upgrade needed
1364-
LogPrintf("CDeterministicMNManager::%s -- migration not needed. dip3 not reached\n", __func__);
1365-
auto dbTx = m_evoDb.BeginTransaction();
1366-
m_evoDb.WriteBestBlock(m_chainstate.m_chain.Tip()->GetBlockHash());
1367-
dbTx->Commit();
1368-
if (!m_evoDb.CommitRootTransaction()) {
1369-
LogPrintf("CDeterministicMNManager::%s -- failed to commit to evoDB\n", __func__);
1370-
return false;
1371-
}
1372-
return true;
1373-
}
1374-
1375-
if (DeploymentActiveAt(*m_chainstate.m_chain.Tip(), consensusParams, Consensus::DEPLOYMENT_V19)) {
1376-
// too late
1377-
LogPrintf("CDeterministicMNManager::%s -- migration is not possible\n", __func__);
1378-
return false;
1379-
}
1380-
1381-
CDBBatch batch(m_evoDb.GetRawDB());
1382-
1383-
for (const auto nHeight : irange::range(Params().GetConsensus().DIP0003Height, m_chainstate.m_chain.Height() + 1)) {
1384-
auto pindex = m_chainstate.m_chain[nHeight];
1385-
// Unserialise CDeterministicMNListDiff using MN_TYPE_FORMAT and set MN state bls version to LEGACY_BLS_VERSION.
1386-
// It will be later written with format MN_CURRENT_FORMAT which includes the type field.
1387-
CDataStream diff_data(SER_DISK, CLIENT_VERSION);
1388-
if (!m_evoDb.GetRawDB().ReadDataStream(std::make_pair(DB_OLD_LIST_DIFF, pindex->GetBlockHash()), diff_data)) {
1389-
LogPrintf("CDeterministicMNManager::%s -- missing CDeterministicMNListDiff at height %d\n", __func__, nHeight);
1390-
return false;
1391-
}
1392-
CDeterministicMNListDiff mndiff;
1393-
mndiff.Unserialize(diff_data, CDeterministicMN::MN_TYPE_FORMAT);
1394-
batch.Write(std::make_pair(DB_LIST_DIFF, pindex->GetBlockHash()), mndiff);
1395-
CDataStream snapshot_data(SER_DISK, CLIENT_VERSION);
1396-
if (!m_evoDb.GetRawDB().ReadDataStream(std::make_pair(DB_OLD_LIST_SNAPSHOT, pindex->GetBlockHash()), snapshot_data)) {
1397-
// it's ok, we write snapshots every DISK_SNAPSHOT_PERIOD blocks only
1398-
continue;
1399-
}
1400-
CDeterministicMNList mnList;
1401-
mnList.Unserialize(snapshot_data, CDeterministicMN::MN_TYPE_FORMAT);
1402-
batch.Write(std::make_pair(DB_LIST_SNAPSHOT, pindex->GetBlockHash()), mnList);
1403-
m_evoDb.GetRawDB().WriteBatch(batch);
1404-
batch.Clear();
1405-
LogPrintf("CDeterministicMNManager::%s -- wrote snapshot at height %d\n", __func__, nHeight);
1406-
}
1407-
1408-
m_evoDb.GetRawDB().WriteBatch(batch);
1409-
1410-
// Writing EVODB_BEST_BLOCK (which is b_b4 now) marks the DB as upgraded
1411-
auto dbTx = m_evoDb.BeginTransaction();
1412-
m_evoDb.WriteBestBlock(m_chainstate.m_chain.Tip()->GetBlockHash());
1413-
dbTx->Commit();
1414-
1415-
LogPrintf("CDeterministicMNManager::%s -- done migrating\n", __func__);
1416-
1417-
if (EraseOldDBData(m_evoDb.GetRawDB(), {DB_OLD_LIST_DIFF, DB_OLD_LIST_SNAPSHOT})) {
1418-
LogPrintf("CDeterministicMNManager::%s -- done cleaning old data\n", __func__);
1419-
}
1420-
1421-
m_evoDb.GetRawDB().CompactFull();
1422-
1423-
LogPrintf("CDeterministicMNManager::%s -- done compacting database\n", __func__);
1424-
1425-
// flush it to disk
1426-
if (!m_evoDb.CommitRootTransaction()) {
1427-
LogPrintf("CDeterministicMNManager::%s -- failed to commit to evoDB\n", __func__);
1428-
return false;
1429-
}
1430-
1431-
return true;
1432-
}
1433-
14341202
template <typename ProTx>
14351203
static bool CheckService(const ProTx& proTx, TxValidationState& state)
14361204
{

src/evo/deterministicmns.h

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ class CDeterministicMN
4646
uint64_t internalId{std::numeric_limits<uint64_t>::max()};
4747

4848
public:
49-
static constexpr uint16_t MN_OLD_FORMAT = 0;
50-
static constexpr uint16_t MN_TYPE_FORMAT = 1;
5149
static constexpr uint16_t MN_VERSION_FORMAT = 2;
5250
static constexpr uint16_t MN_CURRENT_FORMAT = MN_VERSION_FORMAT;
5351

@@ -75,29 +73,19 @@ class CDeterministicMN
7573
template <typename Stream, typename Operation>
7674
inline void SerializationOp(Stream& s, Operation ser_action, const uint8_t format_version)
7775
{
76+
// We no longer support EvoDB formats below MN_VERSION_FORMAT
77+
if (format_version < MN_VERSION_FORMAT) {
78+
throw std::ios_base::failure("EvoDb too old, run Dash Core with -reindex to rebuild");
79+
}
7880
READWRITE(proTxHash);
7981
READWRITE(VARINT(internalId));
8082
READWRITE(collateralOutpoint);
8183
READWRITE(nOperatorReward);
82-
// We need to read CDeterministicMNState using the old format only when called with MN_OLD_FORMAT or MN_TYPE_FORMAT on Unserialize()
83-
// Serialisation (writing) will be done always using new format
84-
if (ser_action.ForRead() && format_version == MN_OLD_FORMAT) {
85-
CDeterministicMNState_Oldformat old_state;
86-
READWRITE(old_state);
87-
pdmnState = std::make_shared<const CDeterministicMNState>(old_state);
88-
} else if (ser_action.ForRead() && format_version == MN_TYPE_FORMAT) {
89-
CDeterministicMNState_mntype_format old_state;
90-
READWRITE(old_state);
91-
pdmnState = std::make_shared<const CDeterministicMNState>(old_state);
92-
} else {
93-
READWRITE(pdmnState);
94-
}
95-
// We need to read/write nType if:
96-
// format_version is set to MN_TYPE_FORMAT (For writing (serialisation) it is always the case) Needed for the MNLISTDIFF Migration in evoDB
84+
READWRITE(pdmnState);
9785
// We can't know if we are serialising for the Disk or for the Network here (s.GetType() is not accessible)
9886
// Therefore if s.GetVersion() == CLIENT_VERSION -> Then we know we are serialising for the Disk
9987
// Otherwise, we can safely check with protocol versioning logic so we won't break old clients
100-
if (format_version >= MN_TYPE_FORMAT && (s.GetVersion() == CLIENT_VERSION || s.GetVersion() >= DMN_TYPE_PROTO_VERSION)) {
88+
if (s.GetVersion() == CLIENT_VERSION || s.GetVersion() >= DMN_TYPE_PROTO_VERSION) {
10189
READWRITE(nType);
10290
} else {
10391
nType = MnType::Regular;
@@ -221,15 +209,9 @@ class CDeterministicMNList
221209

222210
SerializationOpBase(s, CSerActionUnserialize());
223211

224-
bool evodb_migration = (format_version == CDeterministicMN::MN_OLD_FORMAT || format_version == CDeterministicMN::MN_TYPE_FORMAT);
225212
size_t cnt = ReadCompactSize(s);
226213
for (size_t i = 0; i < cnt; i++) {
227-
if (evodb_migration) {
228-
const auto dmn = std::make_shared<CDeterministicMN>(deserialize, s, format_version);
229-
mnMap = mnMap.set(dmn->proTxHash, dmn);
230-
} else {
231-
AddMN(std::make_shared<CDeterministicMN>(deserialize, s, format_version), false);
232-
}
214+
AddMN(std::make_shared<CDeterministicMN>(deserialize, s, format_version), false);
233215
}
234216
}
235217

@@ -620,9 +602,6 @@ class CDeterministicMNManager
620602
// Test if given TX is a ProRegTx which also contains the collateral at index n
621603
static bool IsProTxWithCollateral(const CTransactionRef& tx, uint32_t n);
622604

623-
bool MigrateDBIfNeeded();
624-
bool MigrateDBIfNeeded2();
625-
626605
void DoMaintenance() EXCLUSIVE_LOCKS_REQUIRED(!cs);
627606

628607
private:

0 commit comments

Comments
 (0)