aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/CMakeLists.txt6
-rw-r--r--src/common/aligned.c2
-rw-r--r--src/common/apply_permutation.h2
-rw-r--r--src/common/base58.cpp2
-rw-r--r--src/common/base58.h2
-rw-r--r--src/common/boost_serialization_helper.h2
-rw-r--r--src/common/command_line.cpp2
-rw-r--r--src/common/command_line.h2
-rw-r--r--src/common/common_fwd.h2
-rw-r--r--src/common/compat/glibc_compat.cpp2
-rw-r--r--src/common/dns_utils.cpp50
-rw-r--r--src/common/dns_utils.h2
-rw-r--r--src/common/download.cpp6
-rw-r--r--src/common/download.h2
-rw-r--r--src/common/http_connection.h2
-rw-r--r--src/common/i18n.cpp16
-rw-r--r--src/common/i18n.h2
-rw-r--r--src/common/json_util.h2
-rw-r--r--src/common/notify.cpp29
-rw-r--r--src/common/notify.h2
-rw-r--r--src/common/password.cpp2
-rw-r--r--src/common/password.h2
-rw-r--r--src/common/perf_timer.cpp2
-rw-r--r--src/common/perf_timer.h3
-rw-r--r--src/common/pod-class.h2
-rw-r--r--src/common/pruning.cpp116
-rw-r--r--src/common/pruning.h52
-rw-r--r--src/common/rpc_client.h2
-rw-r--r--src/common/scoped_message_writer.h2
-rw-r--r--src/common/sfinae_helpers.h2
-rw-r--r--src/common/spawn.cpp7
-rw-r--r--src/common/stack_trace.cpp2
-rw-r--r--src/common/stack_trace.h2
-rw-r--r--src/common/threadpool.cpp2
-rw-r--r--src/common/threadpool.h2
-rw-r--r--src/common/timings.cc125
-rw-r--r--src/common/timings.h34
-rw-r--r--src/common/unordered_containers_boost_serialization.h2
-rw-r--r--src/common/updates.cpp2
-rw-r--r--src/common/updates.h2
-rw-r--r--src/common/util.cpp2
-rw-r--r--src/common/util.h2
-rw-r--r--src/common/varint.h4
43 files changed, 454 insertions, 56 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 3b1eb6d23..f06737b31 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2014-2018, The Monero Project
+# Copyright (c) 2014-2019, The Monero Project
#
# All rights reserved.
#
@@ -40,10 +40,12 @@ set(common_sources
notify.cpp
password.cpp
perf_timer.cpp
+ pruning.cpp
spawn.cpp
threadpool.cpp
updates.cpp
aligned.c
+ timings.cc
combinator.cpp)
if (STACK_TRACE)
@@ -69,6 +71,7 @@ set(common_private_headers
http_connection.h
notify.h
pod-class.h
+ pruning.h
rpc_client.h
scoped_message_writer.h
unordered_containers_boost_serialization.h
@@ -82,6 +85,7 @@ set(common_private_headers
threadpool.h
updates.h
aligned.h
+ timings.h
combinator.h)
monero_private_headers(common
diff --git a/src/common/aligned.c b/src/common/aligned.c
index 763dfd0e7..6982409f7 100644
--- a/src/common/aligned.c
+++ b/src/common/aligned.c
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2018, The Monero Project
+// Copyright (c) 2017-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/apply_permutation.h b/src/common/apply_permutation.h
index ff346bab1..a4b2c8b78 100644
--- a/src/common/apply_permutation.h
+++ b/src/common/apply_permutation.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2018, The Monero Project
+// Copyright (c) 2017-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/base58.cpp b/src/common/base58.cpp
index 3562af486..ac1bf4b29 100644
--- a/src/common/base58.cpp
+++ b/src/common/base58.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/base58.h b/src/common/base58.h
index 69611859d..6bf2c3bb7 100644
--- a/src/common/base58.h
+++ b/src/common/base58.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/boost_serialization_helper.h b/src/common/boost_serialization_helper.h
index 3f5c623f8..2280f3312 100644
--- a/src/common/boost_serialization_helper.h
+++ b/src/common/boost_serialization_helper.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/command_line.cpp b/src/common/command_line.cpp
index 35135ea18..cae744ea5 100644
--- a/src/common/command_line.cpp
+++ b/src/common/command_line.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/command_line.h b/src/common/command_line.h
index 3a869bb26..b5e3d94a7 100644
--- a/src/common/command_line.h
+++ b/src/common/command_line.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/common_fwd.h b/src/common/common_fwd.h
index 2924d9cbe..7eaa6cdee 100644
--- a/src/common/common_fwd.h
+++ b/src/common/common_fwd.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/compat/glibc_compat.cpp b/src/common/compat/glibc_compat.cpp
index bf567987d..435e7930f 100644
--- a/src/common/compat/glibc_compat.cpp
+++ b/src/common/compat/glibc_compat.cpp
@@ -82,7 +82,7 @@ __explicit_bzero_chk (void *dst, size_t len, size_t dstlen)
#undef glob
extern "C" int glob_old(const char * pattern, int flags, int (*errfunc) (const char *epath, int eerrno), glob_t *pglob);
#ifdef __i386__
-__asm__(".symver glob_old,glob@GLIBC_2.1");
+__asm__(".symver glob_old,glob@GLIBC_2.0");
#elif defined(__amd64__)
__asm__(".symver glob_old,glob@GLIBC_2.2.5");
#elif defined(__arm__)
diff --git a/src/common/dns_utils.cpp b/src/common/dns_utils.cpp
index 417b5b4ac..711a8ba30 100644
--- a/src/common/dns_utils.cpp
+++ b/src/common/dns_utils.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
@@ -232,13 +232,24 @@ public:
char *str;
};
+static void add_anchors(ub_ctx *ctx)
+{
+ const char * const *ds = ::get_builtin_ds();
+ while (*ds)
+ {
+ MINFO("adding trust anchor: " << *ds);
+ ub_ctx_add_ta(ctx, string_copy(*ds++));
+ }
+}
+
DNSResolver::DNSResolver() : m_data(new DNSResolverData())
{
int use_dns_public = 0;
std::vector<std::string> dns_public_addr;
- if (auto res = getenv("DNS_PUBLIC"))
+ const char *DNS_PUBLIC = getenv("DNS_PUBLIC");
+ if (DNS_PUBLIC)
{
- dns_public_addr = tools::dns_utils::parse_dns_public(res);
+ dns_public_addr = tools::dns_utils::parse_dns_public(DNS_PUBLIC);
if (!dns_public_addr.empty())
{
MGINFO("Using public DNS server(s): " << boost::join(dns_public_addr, ", ") << " (TCP)");
@@ -266,11 +277,28 @@ DNSResolver::DNSResolver() : m_data(new DNSResolverData())
ub_ctx_hosts(m_data->m_ub_context, NULL);
}
- const char * const *ds = ::get_builtin_ds();
- while (*ds)
+ add_anchors(m_data->m_ub_context);
+
+ if (!DNS_PUBLIC)
{
- MINFO("adding trust anchor: " << *ds);
- ub_ctx_add_ta(m_data->m_ub_context, string_copy(*ds++));
+ // if no DNS_PUBLIC specified, we try a lookup to what we know
+ // should be a valid DNSSEC record, and switch to known good
+ // DNSSEC resolvers if verification fails
+ bool available, valid;
+ static const char *probe_hostname = "updates.moneropulse.org";
+ auto records = get_txt_record(probe_hostname, available, valid);
+ if (!valid)
+ {
+ MINFO("Failed to verify DNSSEC record from " << probe_hostname << ", falling back to TCP with well known DNSSEC resolvers");
+ ub_ctx_delete(m_data->m_ub_context);
+ m_data->m_ub_context = ub_ctx_create();
+ add_anchors(m_data->m_ub_context);
+ dns_public_addr = tools::dns_utils::parse_dns_public(DNS_PUBLIC);
+ for (const auto &ip: dns_public_addr)
+ ub_ctx_set_fwd(m_data->m_ub_context, string_copy(ip.c_str()));
+ ub_ctx_set_option(m_data->m_ub_context, string_copy("do-udp:"), string_copy("no"));
+ ub_ctx_set_option(m_data->m_ub_context, string_copy("do-tcp:"), string_copy("yes"));
+ }
}
}
@@ -514,12 +542,12 @@ bool load_txt_records_from_dns(std::vector<std::string> &good_records, const std
if (!avail[cur_index])
{
records[cur_index].clear();
- LOG_PRINT_L2("DNSSEC not available for checkpoint update at URL: " << url << ", skipping.");
+ LOG_PRINT_L2("DNSSEC not available for hostname: " << url << ", skipping.");
}
if (!valid[cur_index])
{
records[cur_index].clear();
- LOG_PRINT_L2("DNSSEC validation failed for checkpoint update at URL: " << url << ", skipping.");
+ LOG_PRINT_L2("DNSSEC validation failed for hostname: " << url << ", skipping.");
}
cur_index++;
@@ -541,7 +569,7 @@ bool load_txt_records_from_dns(std::vector<std::string> &good_records, const std
if (num_valid_records < 2)
{
- LOG_PRINT_L0("WARNING: no two valid MoneroPulse DNS checkpoint records were received");
+ LOG_PRINT_L0("WARNING: no two valid DNS TXT records were received");
return false;
}
@@ -563,7 +591,7 @@ bool load_txt_records_from_dns(std::vector<std::string> &good_records, const std
if (good_records_index < 0)
{
- LOG_PRINT_L0("WARNING: no two MoneroPulse DNS checkpoint records matched");
+ LOG_PRINT_L0("WARNING: no two DNS TXT records matched");
return false;
}
diff --git a/src/common/dns_utils.h b/src/common/dns_utils.h
index 3a6ef68a1..a6bc7463a 100644
--- a/src/common/dns_utils.h
+++ b/src/common/dns_utils.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/download.cpp b/src/common/download.cpp
index 58ce0595f..f07d6798d 100644
--- a/src/common/download.cpp
+++ b/src/common/download.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2018, The Monero Project
+// Copyright (c) 2017-2019, The Monero Project
//
// All rights reserved.
//
@@ -179,8 +179,8 @@ namespace tools
lock.unlock();
- bool ssl = u_c.schema == "https";
- uint16_t port = u_c.port ? u_c.port : ssl ? 443 : 80;
+ epee::net_utils::ssl_support_t ssl = u_c.schema == "https" ? epee::net_utils::ssl_support_t::e_ssl_support_enabled : epee::net_utils::ssl_support_t::e_ssl_support_disabled;
+ uint16_t port = u_c.port ? u_c.port : ssl == epee::net_utils::ssl_support_t::e_ssl_support_enabled ? 443 : 80;
MDEBUG("Connecting to " << u_c.host << ":" << port);
client.set_server(u_c.host, std::to_string(port), boost::none, ssl);
if (!client.connect(std::chrono::seconds(30)))
diff --git a/src/common/download.h b/src/common/download.h
index 3097394bc..f8656a59c 100644
--- a/src/common/download.h
+++ b/src/common/download.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2018, The Monero Project
+// Copyright (c) 2017-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/http_connection.h b/src/common/http_connection.h
index 554dd832b..6b4294802 100644
--- a/src/common/http_connection.h
+++ b/src/common/http_connection.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/i18n.cpp b/src/common/i18n.cpp
index ffe8d8b52..9ac347263 100644
--- a/src/common/i18n.cpp
+++ b/src/common/i18n.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
@@ -38,6 +38,8 @@
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "i18n"
+#define MAX_LANGUAGE_SIZE 16
+
static const unsigned char qm_magic[16] = {0x3c, 0xb8, 0x64, 0x18, 0xca, 0xef, 0x9c, 0x95, 0xcd, 0x21, 0x1c, 0xbf, 0x60, 0xa1, 0xbd, 0xdd};
static std::map<std::string,std::string> i18n_entries;
@@ -62,7 +64,19 @@ std::string i18n_get_language()
std::string language = e;
language = language.substr(0, language.find("."));
+ language = language.substr(0, language.find("@"));
+
+ // check valid values
+ for (char c: language)
+ if (!strchr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-.@", c))
+ return "en";
+
std::transform(language.begin(), language.end(), language.begin(), tolower);
+ if (language.size() > MAX_LANGUAGE_SIZE)
+ {
+ i18n_log("Language from LANG/LC_ALL suspiciously long, defaulting to en");
+ return "en";
+ }
return language;
}
diff --git a/src/common/i18n.h b/src/common/i18n.h
index d21d00275..82a07410d 100644
--- a/src/common/i18n.h
+++ b/src/common/i18n.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/json_util.h b/src/common/json_util.h
index c320c3956..96f4b90e6 100644
--- a/src/common/json_util.h
+++ b/src/common/json_util.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2018, The Monero Project
+// Copyright (c) 2016-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/notify.cpp b/src/common/notify.cpp
index cadc68ea7..e2df5096d 100644
--- a/src/common/notify.cpp
+++ b/src/common/notify.cpp
@@ -27,11 +27,15 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/algorithm/string.hpp>
+#include <stdarg.h>
#include "misc_log_ex.h"
#include "file_io_utils.h"
#include "spawn.h"
#include "notify.h"
+#undef MONERO_DEFAULT_LOG_CATEGORY
+#define MONERO_DEFAULT_LOG_CATEGORY "notify"
+
namespace tools
{
@@ -44,17 +48,34 @@ Notify::Notify(const char *spec)
{
CHECK_AND_ASSERT_THROW_MES(spec, "Null spec");
- boost::split(args, spec, boost::is_any_of(" "));
+ boost::split(args, spec, boost::is_any_of(" \t"), boost::token_compress_on);
CHECK_AND_ASSERT_THROW_MES(args.size() > 0, "Failed to parse spec");
+ if (strchr(spec, '\'') || strchr(spec, '\"') || strchr(spec, '\\'))
+ MWARNING("A notification spec contains a quote or backslash: note that these are handled verbatim, which may not be the intent");
filename = args[0];
CHECK_AND_ASSERT_THROW_MES(epee::file_io_utils::is_file_exist(filename), "File not found: " << filename);
}
-int Notify::notify(const char *parameter)
+static void replace(std::vector<std::string> &v, const char *tag, const char *s)
+{
+ for (std::string &str: v)
+ boost::replace_all(str, tag, s);
+}
+
+int Notify::notify(const char *tag, const char *s, ...)
{
std::vector<std::string> margs = args;
- for (std::string &s: margs)
- boost::replace_all(s, "%s", parameter);
+
+ replace(margs, tag, s);
+
+ va_list ap;
+ va_start(ap, s);
+ while ((tag = va_arg(ap, const char*)))
+ {
+ s = va_arg(ap, const char*);
+ replace(margs, tag, s);
+ }
+ va_end(ap);
return tools::spawn(filename.c_str(), margs, false);
}
diff --git a/src/common/notify.h b/src/common/notify.h
index 81aacebb0..f813e8def 100644
--- a/src/common/notify.h
+++ b/src/common/notify.h
@@ -39,7 +39,7 @@ class Notify
public:
Notify(const char *spec);
- int notify(const char *parameter);
+ int notify(const char *tag, const char *s, ...);
private:
std::string filename;
diff --git a/src/common/password.cpp b/src/common/password.cpp
index 5f5cb800a..03d13db42 100644
--- a/src/common/password.cpp
+++ b/src/common/password.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/password.h b/src/common/password.h
index beb98283b..2837c70f3 100644
--- a/src/common/password.h
+++ b/src/common/password.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/perf_timer.cpp b/src/common/perf_timer.cpp
index 3e1357833..dda498088 100644
--- a/src/common/perf_timer.cpp
+++ b/src/common/perf_timer.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2018, The Monero Project
+// Copyright (c) 2016-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/perf_timer.h b/src/common/perf_timer.h
index d859cf576..717391623 100644
--- a/src/common/perf_timer.h
+++ b/src/common/perf_timer.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2018, The Monero Project
+// Copyright (c) 2016-2019, The Monero Project
//
// All rights reserved.
//
@@ -53,6 +53,7 @@ public:
void resume();
void reset();
uint64_t value() const;
+ operator uint64_t() const { return value(); }
protected:
uint64_t ticks;
diff --git a/src/common/pod-class.h b/src/common/pod-class.h
index 5f6709eef..200647590 100644
--- a/src/common/pod-class.h
+++ b/src/common/pod-class.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/pruning.cpp b/src/common/pruning.cpp
new file mode 100644
index 000000000..442b24e4e
--- /dev/null
+++ b/src/common/pruning.cpp
@@ -0,0 +1,116 @@
+// Copyright (c) 2018, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "cryptonote_config.h"
+#include "misc_log_ex.h"
+#include "crypto/crypto.h"
+#include "pruning.h"
+
+namespace tools
+{
+
+uint32_t make_pruning_seed(uint32_t stripe, uint32_t log_stripes)
+{
+ CHECK_AND_ASSERT_THROW_MES(log_stripes <= PRUNING_SEED_LOG_STRIPES_MASK, "log_stripes out of range");
+ CHECK_AND_ASSERT_THROW_MES(stripe > 0 && stripe <= (1ul << log_stripes), "stripe out of range");
+ return (log_stripes << PRUNING_SEED_LOG_STRIPES_SHIFT) | ((stripe - 1) << PRUNING_SEED_STRIPE_SHIFT);
+}
+
+bool has_unpruned_block(uint64_t block_height, uint64_t blockchain_height, uint32_t pruning_seed)
+{
+ const uint32_t stripe = get_pruning_stripe(pruning_seed);
+ if (stripe == 0)
+ return true;
+ const uint32_t log_stripes = get_pruning_log_stripes(pruning_seed);
+ uint32_t block_stripe = get_pruning_stripe(block_height, blockchain_height, log_stripes);
+ return block_stripe == 0 || block_stripe == stripe;
+}
+
+uint32_t get_pruning_stripe(uint64_t block_height, uint64_t blockchain_height, uint32_t log_stripes)
+{
+ if (block_height + CRYPTONOTE_PRUNING_TIP_BLOCKS >= blockchain_height)
+ return 0;
+ return ((block_height / CRYPTONOTE_PRUNING_STRIPE_SIZE) & (uint64_t)((1ul << log_stripes) - 1)) + 1;
+}
+
+uint32_t get_pruning_seed(uint64_t block_height, uint64_t blockchain_height, uint32_t log_stripes)
+{
+ const uint32_t stripe = get_pruning_stripe(block_height, blockchain_height, log_stripes);
+ if (stripe == 0)
+ return 0;
+ return make_pruning_seed(stripe, log_stripes);
+}
+
+uint64_t get_next_unpruned_block_height(uint64_t block_height, uint64_t blockchain_height, uint32_t pruning_seed)
+{
+ CHECK_AND_ASSERT_MES(block_height <= CRYPTONOTE_MAX_BLOCK_NUMBER+1, block_height, "block_height too large");
+ CHECK_AND_ASSERT_MES(blockchain_height <= CRYPTONOTE_MAX_BLOCK_NUMBER+1, block_height, "blockchain_height too large");
+ const uint32_t stripe = get_pruning_stripe(pruning_seed);
+ if (stripe == 0)
+ return block_height;
+ if (block_height + CRYPTONOTE_PRUNING_TIP_BLOCKS >= blockchain_height)
+ return block_height;
+ const uint32_t seed_log_stripes = get_pruning_log_stripes(pruning_seed);
+ const uint64_t log_stripes = seed_log_stripes ? seed_log_stripes : CRYPTONOTE_PRUNING_LOG_STRIPES;
+ const uint64_t mask = (1ul << log_stripes) - 1;
+ const uint32_t block_pruning_stripe = ((block_height / CRYPTONOTE_PRUNING_STRIPE_SIZE) & mask) + 1;
+ if (block_pruning_stripe == stripe)
+ return block_height;
+ const uint64_t cycles = ((block_height / CRYPTONOTE_PRUNING_STRIPE_SIZE) >> log_stripes);
+ const uint64_t cycle_start = cycles + ((stripe > block_pruning_stripe) ? 0 : 1);
+ const uint64_t h = cycle_start * (CRYPTONOTE_PRUNING_STRIPE_SIZE << log_stripes) + (stripe - 1) * CRYPTONOTE_PRUNING_STRIPE_SIZE;
+ if (h + CRYPTONOTE_PRUNING_TIP_BLOCKS > blockchain_height)
+ return blockchain_height < CRYPTONOTE_PRUNING_TIP_BLOCKS ? 0 : blockchain_height - CRYPTONOTE_PRUNING_TIP_BLOCKS;
+ CHECK_AND_ASSERT_MES(h >= block_height, block_height, "h < block_height, unexpected");
+ return h;
+}
+
+uint64_t get_next_pruned_block_height(uint64_t block_height, uint64_t blockchain_height, uint32_t pruning_seed)
+{
+ const uint32_t stripe = get_pruning_stripe(pruning_seed);
+ if (stripe == 0)
+ return blockchain_height;
+ if (block_height + CRYPTONOTE_PRUNING_TIP_BLOCKS >= blockchain_height)
+ return blockchain_height;
+ const uint32_t seed_log_stripes = get_pruning_log_stripes(pruning_seed);
+ const uint64_t log_stripes = seed_log_stripes ? seed_log_stripes : CRYPTONOTE_PRUNING_LOG_STRIPES;
+ const uint64_t mask = (1ul << log_stripes) - 1;
+ const uint32_t block_pruning_seed = ((block_height / CRYPTONOTE_PRUNING_STRIPE_SIZE) & mask) + 1;
+ if (block_pruning_seed != stripe)
+ return block_height;
+ const uint32_t next_stripe = 1 + (block_pruning_seed & mask);
+ return get_next_unpruned_block_height(block_height, blockchain_height, tools::make_pruning_seed(next_stripe, log_stripes));
+}
+
+uint32_t get_random_stripe()
+{
+ return 1 + crypto::rand<uint8_t>() % (1ul << CRYPTONOTE_PRUNING_LOG_STRIPES);
+}
+
+}
+
diff --git a/src/common/pruning.h b/src/common/pruning.h
new file mode 100644
index 000000000..3fac3c0fa
--- /dev/null
+++ b/src/common/pruning.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2018, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#pragma once
+
+#include <stdint.h>
+
+namespace tools
+{
+ static constexpr uint32_t PRUNING_SEED_LOG_STRIPES_SHIFT = 7;
+ static constexpr uint32_t PRUNING_SEED_LOG_STRIPES_MASK = 0x7;
+ static constexpr uint32_t PRUNING_SEED_STRIPE_SHIFT = 0;
+ static constexpr uint32_t PRUNING_SEED_STRIPE_MASK = 0x7f;
+
+ constexpr inline uint32_t get_pruning_log_stripes(uint32_t pruning_seed) { return (pruning_seed >> PRUNING_SEED_LOG_STRIPES_SHIFT) & PRUNING_SEED_LOG_STRIPES_MASK; }
+ inline uint32_t get_pruning_stripe(uint32_t pruning_seed) { if (pruning_seed == 0) return 0; return 1 + ((pruning_seed >> PRUNING_SEED_STRIPE_SHIFT) & PRUNING_SEED_STRIPE_MASK); }
+
+ uint32_t make_pruning_seed(uint32_t stripe, uint32_t log_stripes);
+
+ bool has_unpruned_block(uint64_t block_height, uint64_t blockchain_height, uint32_t pruning_seed);
+ uint32_t get_pruning_stripe(uint64_t block_height, uint64_t blockchain_height, uint32_t log_stripes);
+ uint32_t get_pruning_seed(uint64_t block_height, uint64_t blockchain_height, uint32_t log_stripes);
+ uint64_t get_next_unpruned_block_height(uint64_t block_height, uint64_t blockchain_height, uint32_t pruning_seed);
+ uint64_t get_next_pruned_block_height(uint64_t block_height, uint64_t blockchain_height, uint32_t pruning_seed);
+ uint32_t get_random_stripe();
+}
+
diff --git a/src/common/rpc_client.h b/src/common/rpc_client.h
index 9665966ae..cb5f79da8 100644
--- a/src/common/rpc_client.h
+++ b/src/common/rpc_client.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/scoped_message_writer.h b/src/common/scoped_message_writer.h
index 42f439ad8..546377392 100644
--- a/src/common/scoped_message_writer.h
+++ b/src/common/scoped_message_writer.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/sfinae_helpers.h b/src/common/sfinae_helpers.h
index fa5052a2e..e9a98bb63 100644
--- a/src/common/sfinae_helpers.h
+++ b/src/common/sfinae_helpers.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2018, The Monero Project
+// Copyright (c) 2016-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/spawn.cpp b/src/common/spawn.cpp
index b2d03f62f..9a7e75d41 100644
--- a/src/common/spawn.cpp
+++ b/src/common/spawn.cpp
@@ -42,6 +42,9 @@
#include "util.h"
#include "spawn.h"
+#undef MONERO_DEFAULT_LOG_CATEGORY
+#define MONERO_DEFAULT_LOG_CATEGORY "spawn"
+
namespace tools
{
@@ -88,7 +91,7 @@ int spawn(const char *filename, const std::vector<std::string>& args, bool wait)
MINFO("Child exited with " << exitCode);
return static_cast<int>(exitCode);
#else
- char **argv = (char**)alloca(sizeof(char*) * (args.size() + 1));
+ std::vector<char*> argv(args.size() + 1);
for (size_t n = 0; n < args.size(); ++n)
argv[n] = (char*)args[n].c_str();
argv[args.size()] = NULL;
@@ -106,7 +109,7 @@ int spawn(const char *filename, const std::vector<std::string>& args, bool wait)
tools::closefrom(3);
close(0);
char *envp[] = {NULL};
- execve(filename, argv, envp);
+ execve(filename, argv.data(), envp);
MERROR("Failed to execve: " << strerror(errno));
return -1;
}
diff --git a/src/common/stack_trace.cpp b/src/common/stack_trace.cpp
index 141621427..8d4f8c6f1 100644
--- a/src/common/stack_trace.cpp
+++ b/src/common/stack_trace.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2018, The Monero Project
+// Copyright (c) 2016-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/stack_trace.h b/src/common/stack_trace.h
index 272fb89ae..ae6573885 100644
--- a/src/common/stack_trace.h
+++ b/src/common/stack_trace.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2018, The Monero Project
+// Copyright (c) 2016-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/threadpool.cpp b/src/common/threadpool.cpp
index cbf7163c5..2748c798c 100644
--- a/src/common/threadpool.cpp
+++ b/src/common/threadpool.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2018, The Monero Project
+// Copyright (c) 2017-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/threadpool.h b/src/common/threadpool.h
index a43e38a76..5e490ee7d 100644
--- a/src/common/threadpool.h
+++ b/src/common/threadpool.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2018, The Monero Project
+// Copyright (c) 2017-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/timings.cc b/src/common/timings.cc
new file mode 100644
index 000000000..612ac2cc6
--- /dev/null
+++ b/src/common/timings.cc
@@ -0,0 +1,125 @@
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <algorithm>
+#include <boost/algorithm/string.hpp>
+#include "misc_log_ex.h"
+#include "timings.h"
+
+#define N_EXPECTED_FIELDS (8+11)
+
+TimingsDatabase::TimingsDatabase()
+{
+}
+
+TimingsDatabase::TimingsDatabase(const std::string &filename):
+ filename(filename)
+{
+ load();
+}
+
+TimingsDatabase::~TimingsDatabase()
+{
+ save();
+}
+
+bool TimingsDatabase::load()
+{
+ instances.clear();
+
+ if (filename.empty())
+ return true;
+
+ FILE *f = fopen(filename.c_str(), "r");
+ if (!f)
+ {
+ MDEBUG("Failed to load timings file " << filename << ": " << strerror(errno));
+ return false;
+ }
+ while (1)
+ {
+ char s[4096];
+ if (!fgets(s, sizeof(s), f))
+ break;
+ char *tab = strchr(s, '\t');
+ if (!tab)
+ {
+ MWARNING("Bad format: no tab found");
+ continue;
+ }
+ const std::string name = std::string(s, tab - s);
+ std::vector<std::string> fields;
+ char *ptr = tab + 1;
+ boost::split(fields, ptr, boost::is_any_of(" "));
+ if (fields.size() != N_EXPECTED_FIELDS)
+ {
+ MERROR("Bad format: wrong number of fields: got " << fields.size() << " expected " << N_EXPECTED_FIELDS);
+ continue;
+ }
+
+ instance i;
+
+ unsigned int idx = 0;
+ i.t = atoi(fields[idx++].c_str());
+ i.npoints = atoi(fields[idx++].c_str());
+ i.min = atof(fields[idx++].c_str());
+ i.max = atof(fields[idx++].c_str());
+ i.mean = atof(fields[idx++].c_str());
+ i.median = atof(fields[idx++].c_str());
+ i.stddev = atof(fields[idx++].c_str());
+ i.npskew = atof(fields[idx++].c_str());
+ i.deciles.reserve(11);
+ for (int n = 0; n < 11; ++n)
+ {
+ i.deciles.push_back(atoi(fields[idx++].c_str()));
+ }
+ instances.insert(std::make_pair(name, i));
+ }
+ fclose(f);
+ return true;
+}
+
+bool TimingsDatabase::save()
+{
+ if (filename.empty())
+ return true;
+
+ FILE *f = fopen(filename.c_str(), "w");
+ if (!f)
+ {
+ MERROR("Failed to write to file " << filename << ": " << strerror(errno));
+ return false;
+ }
+ for (const auto &i: instances)
+ {
+ fprintf(f, "%s", i.first.c_str());
+ fprintf(f, "\t%lu", (unsigned long)i.second.t);
+ fprintf(f, " %zu", i.second.npoints);
+ fprintf(f, " %f", i.second.min);
+ fprintf(f, " %f", i.second.max);
+ fprintf(f, " %f", i.second.mean);
+ fprintf(f, " %f", i.second.median);
+ fprintf(f, " %f", i.second.stddev);
+ fprintf(f, " %f", i.second.npskew);
+ for (uint64_t v: i.second.deciles)
+ fprintf(f, " %lu", (unsigned long)v);
+ fputc('\n', f);
+ }
+ fclose(f);
+ return true;
+}
+
+std::vector<TimingsDatabase::instance> TimingsDatabase::get(const char *name) const
+{
+ std::vector<instance> ret;
+ auto range = instances.equal_range(name);
+ for (auto i = range.first; i != range.second; ++i)
+ ret.push_back(i->second);
+ std::sort(ret.begin(), ret.end(), [](const instance &e0, const instance &e1){ return e0.t < e1.t; });
+ return ret;
+}
+
+void TimingsDatabase::add(const char *name, const instance &i)
+{
+ instances.insert(std::make_pair(name, i));
+}
diff --git a/src/common/timings.h b/src/common/timings.h
new file mode 100644
index 000000000..fb905611f
--- /dev/null
+++ b/src/common/timings.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+#include <map>
+
+class TimingsDatabase
+{
+public:
+ struct instance
+ {
+ time_t t;
+ size_t npoints;
+ double min, max, mean, median, stddev, npskew;
+ std::vector<uint64_t> deciles;
+ };
+
+public:
+ TimingsDatabase();
+ TimingsDatabase(const std::string &filename);
+ ~TimingsDatabase();
+
+ std::vector<instance> get(const char *name) const;
+ void add(const char *name, const instance &data);
+
+private:
+ bool load();
+ bool save();
+
+private:
+ std::string filename;
+ std::multimap<std::string, instance> instances;
+};
diff --git a/src/common/unordered_containers_boost_serialization.h b/src/common/unordered_containers_boost_serialization.h
index d78dc6a30..74e2c3f81 100644
--- a/src/common/unordered_containers_boost_serialization.h
+++ b/src/common/unordered_containers_boost_serialization.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/updates.cpp b/src/common/updates.cpp
index 9f12f8dbc..0bc6ff63c 100644
--- a/src/common/updates.cpp
+++ b/src/common/updates.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2018, The Monero Project
+// Copyright (c) 2017-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/updates.h b/src/common/updates.h
index 6ec22f183..8fda6d207 100644
--- a/src/common/updates.h
+++ b/src/common/updates.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2018, The Monero Project
+// Copyright (c) 2017-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/util.cpp b/src/common/util.cpp
index 28745eea4..80b8a9e81 100644
--- a/src/common/util.cpp
+++ b/src/common/util.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/util.h b/src/common/util.h
index d5aca15d1..ef2305bf4 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/src/common/varint.h b/src/common/varint.h
index 151d13dbf..a0d79be28 100644
--- a/src/common/varint.h
+++ b/src/common/varint.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
@@ -123,6 +123,6 @@ namespace tools {
*/
template<typename InputIt, typename T>
int read_varint(InputIt &&first, InputIt &&last, T &i) {
- return read_varint<std::numeric_limits<T>::digits, InputIt, T>(std::move(first), std::move(last), i);
+ return read_varint<std::numeric_limits<T>::digits>(std::forward<InputIt>(first), std::forward<InputIt>(last), i);
}
}