aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core/blockchain_storage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptonote_core/blockchain_storage.cpp')
-rw-r--r--src/cryptonote_core/blockchain_storage.cpp80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/cryptonote_core/blockchain_storage.cpp b/src/cryptonote_core/blockchain_storage.cpp
index e664a39c5..6f1b4121c 100644
--- a/src/cryptonote_core/blockchain_storage.cpp
+++ b/src/cryptonote_core/blockchain_storage.cpp
@@ -47,6 +47,7 @@
#include "common/boost_serialization_helper.h"
#include "warnings.h"
#include "crypto/hash.h"
+#include "cryptonote_core/checkpoints_create.h"
//#include "serialization/json_archive.h"
using namespace cryptonote;
@@ -441,6 +442,13 @@ difficulty_type blockchain_storage::get_difficulty_for_next_block()
bool blockchain_storage::rollback_blockchain_switching(std::list<block>& original_chain, size_t rollback_height)
{
CRITICAL_REGION_LOCAL(m_blockchain_lock);
+
+ // fail if rollback_height passed is too high
+ if (rollback_height > m_blocks.size())
+ {
+ return true;
+ }
+
//remove failed subchain
for(size_t i = m_blocks.size()-1; i >=rollback_height; i--)
{
@@ -1773,3 +1781,75 @@ bool blockchain_storage::add_new_block(const block& bl_, block_verification_cont
return handle_block_to_main_chain(bl, id, bvc);
}
+//------------------------------------------------------------------
+void blockchain_storage::check_against_checkpoints(checkpoints& points, bool enforce)
+{
+ const auto& pts = points.get_points();
+
+ for (const auto& pt : pts)
+ {
+ // if the checkpoint is for a block we don't have yet, move on
+ if (pt.first >= m_blocks.size())
+ {
+ continue;
+ }
+
+ if (!m_checkpoints.check_block(pt.first, get_block_hash(m_blocks[pt.first].bl)))
+ {
+ // if asked to enforce checkpoints, roll back to a couple of blocks before the checkpoint
+ if (enforce)
+ {
+ LOG_ERROR("Checkpoint failed when adding new checkpoints, rolling back!");
+ std::list<block> empty;
+ rollback_blockchain_switching(empty, pt.first - 2);
+ }
+ else
+ {
+ LOG_ERROR("Checkpoint failed when adding new checkpoints, this could be very bad.");
+ }
+ }
+ }
+}
+//------------------------------------------------------------------
+// returns false if any of the checkpoints loading returns false.
+// That should happen only if a checkpoint is added that conflicts
+// with an existing checkpoint.
+bool blockchain_storage::update_checkpoints(const std::string& file_path, bool check_dns)
+{
+ if (!cryptonote::load_checkpoints_from_json(m_checkpoints, file_path))
+ {
+ return false;
+ }
+
+ // if we're checking both dns and json, load checkpoints from dns.
+ // if we're not hard-enforcing dns checkpoints, handle accordingly
+ if (m_enforce_dns_checkpoints && check_dns)
+ {
+ if (!cryptonote::load_checkpoints_from_dns(m_checkpoints))
+ {
+ return false;
+ }
+ }
+ else if (check_dns)
+ {
+ checkpoints dns_points;
+ cryptonote::load_checkpoints_from_dns(dns_points);
+ if (m_checkpoints.check_for_conflicts(dns_points))
+ {
+ check_against_checkpoints(dns_points, false);
+ }
+ else
+ {
+ LOG_PRINT_L0("One or more checkpoints fetched from DNS conflicted with existing checkpoints!");
+ }
+ }
+
+ check_against_checkpoints(m_checkpoints, true);
+
+ return true;
+}
+//------------------------------------------------------------------
+void blockchain_storage::set_enforce_dns_checkpoints(bool enforce_checkpoints)
+{
+ m_enforce_dns_checkpoints = enforce_checkpoints;
+}