diff options
Diffstat (limited to 'src/cryptonote_core/blockchain_storage.cpp')
| -rw-r--r-- | src/cryptonote_core/blockchain_storage.cpp | 80 |
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; +} |
