aboutsummaryrefslogtreecommitdiff
path: root/src/blockchain_db
diff options
context:
space:
mode:
Diffstat (limited to 'src/blockchain_db')
-rw-r--r--src/blockchain_db/blockchain_db.h10
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.cpp38
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.h2
-rw-r--r--src/blockchain_db/testdb.h1
4 files changed, 51 insertions, 0 deletions
diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h
index 3e2387da4..8cf84ef4f 100644
--- a/src/blockchain_db/blockchain_db.h
+++ b/src/blockchain_db/blockchain_db.h
@@ -1039,6 +1039,16 @@ public:
virtual difficulty_type get_block_difficulty(const uint64_t& height) const = 0;
/**
+ * @brief correct blocks cumulative difficulties that were incorrectly calculated due to the 'difficulty drift' bug
+ *
+ * If the block does not exist, the subclass should throw BLOCK_DNE
+ *
+ * @param start_height the height where the drift starts
+ * @param new_cumulative_difficulties new cumulative difficulties to be stored
+ */
+ virtual void correct_block_cumulative_difficulties(const uint64_t& start_height, const std::vector<difficulty_type>& new_cumulative_difficulties) = 0;
+
+ /**
* @brief fetch a block's already generated coins
*
* The subclass should return the total coins generated as of the block
diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp
index 5cec8879d..db19fb1a7 100644
--- a/src/blockchain_db/lmdb/db_lmdb.cpp
+++ b/src/blockchain_db/lmdb/db_lmdb.cpp
@@ -2750,6 +2750,44 @@ difficulty_type BlockchainLMDB::get_block_difficulty(const uint64_t& height) con
return diff1 - diff2;
}
+void BlockchainLMDB::correct_block_cumulative_difficulties(const uint64_t& start_height, const std::vector<difficulty_type>& new_cumulative_difficulties)
+{
+ LOG_PRINT_L3("BlockchainLMDB::" << __func__);
+ check_open();
+ mdb_txn_cursors *m_cursors = &m_wcursors;
+
+ int result = 0;
+ block_wtxn_start();
+ CURSOR(block_info)
+
+ const uint64_t bc_height = height();
+ if (start_height + new_cumulative_difficulties.size() != bc_height)
+ {
+ block_wtxn_abort();
+ throw0(DB_ERROR("Incorrect new_cumulative_difficulties size"));
+ }
+
+ for (uint64_t height = start_height; height < bc_height; ++height)
+ {
+ MDB_val_set(key, height);
+ result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &key, MDB_GET_BOTH);
+ if (result)
+ throw1(BLOCK_DNE(lmdb_error("Failed to get block info: ", result).c_str()));
+
+ mdb_block_info bi = *(mdb_block_info*)key.mv_data;
+ const difficulty_type d = new_cumulative_difficulties[height - start_height];
+ bi.bi_diff_hi = ((d >> 64) & 0xffffffffffffffff).convert_to<uint64_t>();
+ bi.bi_diff_lo = (d & 0xffffffffffffffff).convert_to<uint64_t>();
+
+ MDB_val_set(key2, height);
+ MDB_val_set(val, bi);
+ result = mdb_cursor_put(m_cur_block_info, &key2, &val, MDB_CURRENT);
+ if (result)
+ throw0(DB_ERROR(lmdb_error("Failed to overwrite block info to db transaction: ", result).c_str()));
+ }
+ block_wtxn_stop();
+}
+
uint64_t BlockchainLMDB::get_block_already_generated_coins(const uint64_t& height) const
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h
index 6ddeed671..0213c1342 100644
--- a/src/blockchain_db/lmdb/db_lmdb.h
+++ b/src/blockchain_db/lmdb/db_lmdb.h
@@ -229,6 +229,8 @@ public:
virtual difficulty_type get_block_difficulty(const uint64_t& height) const;
+ virtual void correct_block_cumulative_difficulties(const uint64_t& start_height, const std::vector<difficulty_type>& new_cumulative_difficulties);
+
virtual uint64_t get_block_already_generated_coins(const uint64_t& height) const;
virtual uint64_t get_block_long_term_weight(const uint64_t& height) const;
diff --git a/src/blockchain_db/testdb.h b/src/blockchain_db/testdb.h
index 638dd3b37..da8ce943f 100644
--- a/src/blockchain_db/testdb.h
+++ b/src/blockchain_db/testdb.h
@@ -82,6 +82,7 @@ public:
virtual std::vector<uint64_t> get_block_weights(uint64_t start_height, size_t count) const override { return {}; }
virtual cryptonote::difficulty_type get_block_cumulative_difficulty(const uint64_t& height) const override { return 10; }
virtual cryptonote::difficulty_type get_block_difficulty(const uint64_t& height) const override { return 0; }
+ virtual void correct_block_cumulative_difficulties(const uint64_t& start_height, const std::vector<difficulty_type>& new_cumulative_difficulties) override {}
virtual uint64_t get_block_already_generated_coins(const uint64_t& height) const override { return 10000000000; }
virtual uint64_t get_block_long_term_weight(const uint64_t& height) const override { return 128; }
virtual std::vector<uint64_t> get_long_term_block_weights(uint64_t start_height, size_t count) const override { return {}; }