aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Winget <tewinget@gmail.com>2015-04-22 04:36:39 -0400
committerThomas Winget <tewinget@gmail.com>2015-04-22 04:36:39 -0400
commit2717883dbaa6339ea3eb5e685852c0a40351aad9 (patch)
tree3c16dff41e195513880a1ead4b36fccecc5a64ad
parentupdate lmdb64 (diff)
downloadmonero-2717883dbaa6339ea3eb5e685852c0a40351aad9.tar.xz
DNS Checkpoint updating-related fixes/changes
Only one thread will be doing the updating. Two valid responses must match, and the first two that match will be used.
-rw-r--r--src/cryptonote_core/checkpoints_create.cpp74
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp4
-rw-r--r--src/cryptonote_core/cryptonote_core.h2
3 files changed, 72 insertions, 8 deletions
diff --git a/src/cryptonote_core/checkpoints_create.cpp b/src/cryptonote_core/checkpoints_create.cpp
index 43f926682..6f22e596d 100644
--- a/src/cryptonote_core/checkpoints_create.cpp
+++ b/src/cryptonote_core/checkpoints_create.cpp
@@ -35,6 +35,30 @@
#include <random>
#include "storages/portable_storage_template_helper.h" // epee json include
+namespace
+{
+ bool dns_records_match(const std::vector<std::string>& a, const std::vector<std::string>& b)
+ {
+ if (a.size() != b.size()) return false;
+
+ for (const auto& record_in_a : a)
+ {
+ bool ok = false;
+ for (const auto& record_in_b : b)
+ {
+ if (record_in_a == record_in_b)
+ {
+ ok = true;
+ break;
+ }
+ }
+ if (!ok) return false;
+ }
+
+ return true;
+ }
+} // anonymous namespace
+
namespace cryptonote
{
@@ -127,14 +151,16 @@ bool load_checkpoints_from_dns(cryptonote::checkpoints& checkpoints, bool testne
, "testpoints.moneropulse.net"
, "testpoints.moneropulse.co"
};
- bool avail, valid;
- std::vector<std::string> records;
+
+ std::vector<std::vector<std::string> > records;
+ records.resize(dns_urls.size());
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dis(0, dns_urls.size() - 1);
size_t first_index = dis(gen);
+ bool avail, valid;
size_t cur_index = first_index;
do
{
@@ -148,7 +174,7 @@ bool load_checkpoints_from_dns(cryptonote::checkpoints& checkpoints, bool testne
url = dns_urls[cur_index];
}
- records = tools::DNSResolver::instance().get_txt_record(url, avail, valid);
+ records[cur_index] = tools::DNSResolver::instance().get_txt_record(url, avail, valid);
if (!avail)
{
LOG_PRINT_L2("DNSSEC not available for checkpoint update at URL: " << url << ", skipping.");
@@ -158,26 +184,58 @@ bool load_checkpoints_from_dns(cryptonote::checkpoints& checkpoints, bool testne
LOG_PRINT_L2("DNSSEC validation failed for checkpoint update at URL: " << url << ", skipping.");
}
- if (records.size() == 0 || !avail || !valid)
+ if (records[cur_index].size() == 0 || !avail || !valid)
{
cur_index++;
if (cur_index == dns_urls.size())
{
cur_index = 0;
}
- records.clear();
+ records[cur_index].clear();
continue;
}
break;
} while (cur_index != first_index);
- if (records.size() == 0)
+ size_t num_valid_records = 0;
+
+ for( const auto& record_set : records)
+ {
+ if (record_set.size() != 0)
+ {
+ num_valid_records++;
+ }
+ }
+
+ if (num_valid_records < 2)
+ {
+ LOG_PRINT_L0("WARNING: no two valid MoneroPulse DNS checkpoint records were received");
+ return true;
+ }
+
+ int good_records_index = -1;
+ for (size_t i = 0; i < records.size() - 1; ++i)
+ {
+ if (records[i].size() == 0) continue;
+
+ for (size_t j = i + 1; j < records.size(); ++j)
+ {
+ if (dns_records_match(records[i], records[j]))
+ {
+ good_records_index = i;
+ break;
+ }
+ }
+ if (good_records_index >= 0) break;
+ }
+
+ if (good_records_index < 0)
{
- LOG_PRINT_L0("WARNING: All MoneroPulse checkpoint URLs failed DNSSEC validation and/or returned no records");
+ LOG_PRINT_L0("WARNING: no two MoneroPulse DNS checkpoint records matched");
return true;
}
- for (auto& record : records)
+ for (auto& record : records[good_records_index])
{
auto pos = record.find(":");
if (pos != std::string::npos)
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index f6eaff2b1..78d034e7a 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -100,6 +100,8 @@ namespace cryptonote
{
if (m_testnet) return true;
+ if (m_checkpoints_updating.test_and_set()) return true;
+
bool res = true;
if (time(NULL) - m_last_dns_checkpoints_update >= 3600)
{
@@ -113,6 +115,8 @@ namespace cryptonote
m_last_json_checkpoints_update = time(NULL);
}
+ m_checkpoints_updating.clear();
+
// if anything fishy happened getting new checkpoints, bring down the house
if (!res)
{
diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h
index 973f01272..51584dbcf 100644
--- a/src/cryptonote_core/cryptonote_core.h
+++ b/src/cryptonote_core/cryptonote_core.h
@@ -189,6 +189,8 @@ namespace cryptonote
std::string m_checkpoints_path;
time_t m_last_dns_checkpoints_update;
time_t m_last_json_checkpoints_update;
+
+ std::atomic_flag m_checkpoints_updating;
};
}