Make difficulty 128 bit instead of 64 bit
Based on Boolberry work by: jahrsg <jahr@jahr.me> cr.zoidberg <crypto.zoidberg@gmail.com>
This commit is contained in:
@@ -54,7 +54,7 @@ using epee::string_tools::pod_to_hex;
|
||||
using namespace crypto;
|
||||
|
||||
// Increase when the DB structure changes
|
||||
#define VERSION 4
|
||||
#define VERSION 5
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -274,7 +274,7 @@ typedef struct mdb_block_info_1
|
||||
uint64_t bi_timestamp;
|
||||
uint64_t bi_coins;
|
||||
uint64_t bi_weight; // a size_t really but we need 32-bit compat
|
||||
difficulty_type bi_diff;
|
||||
uint64_t bi_diff;
|
||||
crypto::hash bi_hash;
|
||||
} mdb_block_info_1;
|
||||
|
||||
@@ -284,7 +284,7 @@ typedef struct mdb_block_info_2
|
||||
uint64_t bi_timestamp;
|
||||
uint64_t bi_coins;
|
||||
uint64_t bi_weight; // a size_t really but we need 32-bit compat
|
||||
difficulty_type bi_diff;
|
||||
uint64_t bi_diff;
|
||||
crypto::hash bi_hash;
|
||||
uint64_t bi_cum_rct;
|
||||
} mdb_block_info_2;
|
||||
@@ -295,13 +295,26 @@ typedef struct mdb_block_info_3
|
||||
uint64_t bi_timestamp;
|
||||
uint64_t bi_coins;
|
||||
uint64_t bi_weight; // a size_t really but we need 32-bit compat
|
||||
difficulty_type bi_diff;
|
||||
uint64_t bi_diff;
|
||||
crypto::hash bi_hash;
|
||||
uint64_t bi_cum_rct;
|
||||
uint64_t bi_long_term_block_weight;
|
||||
} mdb_block_info_3;
|
||||
|
||||
typedef mdb_block_info_3 mdb_block_info;
|
||||
typedef struct mdb_block_info_4
|
||||
{
|
||||
uint64_t bi_height;
|
||||
uint64_t bi_timestamp;
|
||||
uint64_t bi_coins;
|
||||
uint64_t bi_weight; // a size_t really but we need 32-bit compat
|
||||
uint64_t bi_diff_lo;
|
||||
uint64_t bi_diff_hi;
|
||||
crypto::hash bi_hash;
|
||||
uint64_t bi_cum_rct;
|
||||
uint64_t bi_long_term_block_weight;
|
||||
} mdb_block_info_4;
|
||||
|
||||
typedef mdb_block_info_4 mdb_block_info;
|
||||
|
||||
typedef struct blk_height {
|
||||
crypto::hash bh_hash;
|
||||
@@ -757,7 +770,8 @@ void BlockchainLMDB::add_block(const block& blk, size_t block_weight, uint64_t l
|
||||
bi.bi_timestamp = blk.timestamp;
|
||||
bi.bi_coins = coins_generated;
|
||||
bi.bi_weight = block_weight;
|
||||
bi.bi_diff = cumulative_difficulty;
|
||||
bi.bi_diff_hi = (cumulative_difficulty >> 64).convert_to<uint64_t>();
|
||||
bi.bi_diff_lo = (cumulative_difficulty << 64 >> 64).convert_to<uint64_t>();
|
||||
bi.bi_hash = blk_hash;
|
||||
bi.bi_cum_rct = num_rct_outs;
|
||||
if (blk.major_version >= 4)
|
||||
@@ -2527,7 +2541,9 @@ difficulty_type BlockchainLMDB::get_block_cumulative_difficulty(const uint64_t&
|
||||
throw0(DB_ERROR("Error attempting to retrieve a cumulative difficulty from the db"));
|
||||
|
||||
mdb_block_info *bi = (mdb_block_info *)result.mv_data;
|
||||
difficulty_type ret = bi->bi_diff;
|
||||
difficulty_type ret = bi->bi_diff_hi;
|
||||
ret <<= 64;
|
||||
ret |= bi->bi_diff_lo;
|
||||
TXN_POSTFIX_RDONLY();
|
||||
return ret;
|
||||
}
|
||||
@@ -5040,6 +5056,133 @@ void BlockchainLMDB::migrate_3_4()
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
void BlockchainLMDB::migrate_4_5()
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
uint64_t i;
|
||||
int result;
|
||||
mdb_txn_safe txn(false);
|
||||
MDB_val k, v;
|
||||
char *ptr;
|
||||
|
||||
MGINFO_YELLOW("Migrating blockchain from DB version 4 to 5 - this may take a while:");
|
||||
|
||||
do {
|
||||
LOG_PRINT_L1("migrating block info:");
|
||||
|
||||
result = mdb_txn_begin(m_env, NULL, 0, txn);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", result).c_str()));
|
||||
|
||||
MDB_stat db_stats;
|
||||
if ((result = mdb_stat(txn, m_blocks, &db_stats)))
|
||||
throw0(DB_ERROR(lmdb_error("Failed to query m_blocks: ", result).c_str()));
|
||||
const uint64_t blockchain_height = db_stats.ms_entries;
|
||||
|
||||
/* the block_info table name is the same but the old version and new version
|
||||
* have incompatible data. Create a new table. We want the name to be similar
|
||||
* to the old name so that it will occupy the same location in the DB.
|
||||
*/
|
||||
MDB_dbi o_block_info = m_block_info;
|
||||
lmdb_db_open(txn, "block_infn", MDB_INTEGERKEY | MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_block_info, "Failed to open db handle for block_infn");
|
||||
mdb_set_dupsort(txn, m_block_info, compare_uint64);
|
||||
|
||||
|
||||
MDB_cursor *c_blocks;
|
||||
result = mdb_cursor_open(txn, m_blocks, &c_blocks);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to open a cursor for blocks: ", result).c_str()));
|
||||
|
||||
MDB_cursor *c_old, *c_cur;
|
||||
i = 0;
|
||||
while(1) {
|
||||
if (!(i % 1000)) {
|
||||
if (i) {
|
||||
LOGIF(el::Level::Info) {
|
||||
std::cout << i << " / " << blockchain_height << " \r" << std::flush;
|
||||
}
|
||||
txn.commit();
|
||||
result = mdb_txn_begin(m_env, NULL, 0, txn);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", result).c_str()));
|
||||
}
|
||||
result = mdb_cursor_open(txn, m_block_info, &c_cur);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to open a cursor for block_infn: ", result).c_str()));
|
||||
result = mdb_cursor_open(txn, o_block_info, &c_old);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to open a cursor for block_info: ", result).c_str()));
|
||||
if (!i) {
|
||||
MDB_stat db_stat;
|
||||
result = mdb_stat(txn, m_block_info, &db_stats);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to query m_block_info: ", result).c_str()));
|
||||
i = db_stats.ms_entries;
|
||||
}
|
||||
}
|
||||
result = mdb_cursor_get(c_old, &k, &v, MDB_NEXT);
|
||||
if (result == MDB_NOTFOUND) {
|
||||
txn.commit();
|
||||
break;
|
||||
}
|
||||
else if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to get a record from block_info: ", result).c_str()));
|
||||
const mdb_block_info_3 *bi_old = (const mdb_block_info_3*)v.mv_data;
|
||||
mdb_block_info_4 bi;
|
||||
bi.bi_height = bi_old->bi_height;
|
||||
bi.bi_timestamp = bi_old->bi_timestamp;
|
||||
bi.bi_coins = bi_old->bi_coins;
|
||||
bi.bi_weight = bi_old->bi_weight;
|
||||
bi.bi_diff_lo = bi_old->bi_diff;
|
||||
bi.bi_diff_hi = 0;
|
||||
bi.bi_hash = bi_old->bi_hash;
|
||||
bi.bi_cum_rct = bi_old->bi_cum_rct;
|
||||
bi.bi_long_term_block_weight = bi_old->bi_long_term_block_weight;
|
||||
|
||||
MDB_val_set(nv, bi);
|
||||
result = mdb_cursor_put(c_cur, (MDB_val *)&zerokval, &nv, MDB_APPENDDUP);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to put a record into block_infn: ", result).c_str()));
|
||||
/* we delete the old records immediately, so the overall DB and mapsize should not grow.
|
||||
* This is a little slower than just letting mdb_drop() delete it all at the end, but
|
||||
* it saves a significant amount of disk space.
|
||||
*/
|
||||
result = mdb_cursor_del(c_old, 0);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to delete a record from block_info: ", result).c_str()));
|
||||
i++;
|
||||
}
|
||||
|
||||
result = mdb_txn_begin(m_env, NULL, 0, txn);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", result).c_str()));
|
||||
/* Delete the old table */
|
||||
result = mdb_drop(txn, o_block_info, 1);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to delete old block_info table: ", result).c_str()));
|
||||
|
||||
RENAME_DB("block_infn");
|
||||
mdb_dbi_close(m_env, m_block_info);
|
||||
|
||||
lmdb_db_open(txn, "block_info", MDB_INTEGERKEY | MDB_CREATE | MDB_DUPSORT | MDB_DUPFIXED, m_block_info, "Failed to open db handle for block_infn");
|
||||
mdb_set_dupsort(txn, m_block_info, compare_uint64);
|
||||
|
||||
txn.commit();
|
||||
} while(0);
|
||||
|
||||
uint32_t version = 5;
|
||||
v.mv_data = (void *)&version;
|
||||
v.mv_size = sizeof(version);
|
||||
MDB_val_str(vk, "version");
|
||||
result = mdb_txn_begin(m_env, NULL, 0, txn);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to create a transaction for the db: ", result).c_str()));
|
||||
result = mdb_put(txn, m_properties, &vk, &v, 0);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to update version for the db: ", result).c_str()));
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
void BlockchainLMDB::migrate(const uint32_t oldversion)
|
||||
{
|
||||
if (oldversion < 1)
|
||||
@@ -5050,6 +5193,8 @@ void BlockchainLMDB::migrate(const uint32_t oldversion)
|
||||
migrate_2_3();
|
||||
if (oldversion < 4)
|
||||
migrate_3_4();
|
||||
if (oldversion < 5)
|
||||
migrate_4_5();
|
||||
}
|
||||
|
||||
} // namespace cryptonote
|
||||
|
||||
@@ -418,6 +418,9 @@ private:
|
||||
// migrate from DB version 3 to 4
|
||||
void migrate_3_4();
|
||||
|
||||
// migrate from DB version 4 to 5
|
||||
void migrate_4_5();
|
||||
|
||||
void cleanup_batch();
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user