Commit graph

654 commits

Author SHA1 Message Date
Doyle
62fe4db413 config: Convert DIFFICULTY_BLOCKS_V2 to TARGET_BLOCK_TIME 2020-08-18 11:59:53 +10:00
Doyle
a62ff316e3 Pulse: Queue Block Gen code review
- Rename find_named_argument -> find_prefixed_value
- Update get_current_blockchain_height() comment to specify ability to lock
- Update memcmp(address1, address2) to address1 == address2
- Make create_next_miner_block_template call create_miner_block_template
- Update LMQ x25519 keys only when key has changed
- construct_miner_tx: Use C++17 features
- Pulse: Add log category "Pulse"
- Pulse: Check shutdown before blockchain height
- Pulse: Use get_human_readable_timespan
- Pulse: Switch to MINFO, enable with --log-level +pulse:DEBUG
- Pulse: Add height into context
- Pulse: Remove some default switch cases hiding compiler warnings
- SN: Update hardcoded '9' literals to network_version_9_service_nodes
- Core: Use using namespace std::literals
- Miner: Change num_blocks availability to debug
- RPC: Gate test rpc commands to != MAINNET
- Wallet: Store wallet before deinitialization instead of refresh
2020-08-18 11:59:53 +10:00
Doyle
9a5889b68b miner: Allow setting num_blocks param, used named arguments 2020-08-18 11:59:53 +10:00
Doyle
0a4d8319b7 Pulse: Pass std::seed_seq to mt19937_64 2020-08-18 11:59:53 +10:00
Jason Rhinelander
ef91df6af0 Rename stagenet to devnet 2020-08-17 02:54:43 -03:00
Jason Rhinelander
a4e3d0c4e2 Work around gcc-8 compiler segfault
Also slightly simplifies the code by avoiding a local static variable
(which are quite expensive) in favour of a static global variable.
2020-08-11 11:18:31 -03:00
Jason Rhinelander
b433bfe2f9 Compilation fixes/warnings
- Add missing <thread> header to util.cpp
- Remove `std::move()` on return value preventing RVO
- Remove debugging warning
2020-08-07 17:14:03 -03:00
Jason Rhinelander
34ced75056 Split http_server into server + base class
The base class contains the common functionality that will also be used
by the wallet rpc server.
2020-08-07 17:14:03 -03:00
Jason Rhinelander
2083c58d35 wallet_api updates
- updates to use rpc::http_client instead of epee
- simplifies a bunch of json_rpc calls
- removes update checking
- fixes various other random compilation issues
2020-08-07 17:14:03 -03:00
Jason Rhinelander
251365122b Add tools::type_to_hex
This does the opposite of tools::hex_to_type: it converts the data
inside a (simple) type to hex.
2020-08-07 17:14:03 -03:00
Jason Rhinelander
fb0aff57f6 Replace epee http client with curl-based client
In short: epee's http client is garbage, standard violating, and
unreliable.

This completely removes the epee http client support and replaces it
with cpr, a curl-based C++ wrapper.  rpc/http_client.h wraps cpr for RPC
requests specifically, but it is also usable directly.

This replacement has a number of advantages:

- requests are considerably more reliable.  The epee http client code
  assumes that a connection will be kept alive forever, and returns a
  failure if a connection is ever closed.  This results in some very
  annoying things: for example, preparing a transaction and then waiting
  a long tim before confirming it will usually result in an error
  communication with the daemon.  This is just terribly behaviour: the
  right thing to do on a connection failure is to resubmit the request.

- epee's http client is broken in lots of other ways: for example, it
  tries throwing SSL at the port to see if it is HTTPS, but this is
  protocol violating and just breaks (with a several second timeout) on
  anything that *isn't* epee http server (for example, when lokid is
  behind a proxying server).

- even when it isn't doing the above, the client breaks in other ways:
  for example, there is a comment (replaced in this PR) in the Trezor PR
  code that forces a connection close after every request because epee's
  http client doesn't do proper keep-alive request handling.

- it seems noticeably faster to me in practical use in this PR; both
  simple requests (for example, when running `lokid status`) and
  wallet<->daemon connections are faster, probably because of crappy
  code in epee.  (I think this is also related to the throw-ssl-at-it
  junk above: the epee client always generates an ssl certificate during
  static initialization because it might need one at some point).

- significantly reduces the amount of code we have to maintain.

- removes all the epee ssl option code: curl can handle all of that just
  fine.

- removes the epee socks proxy code; curl can handle that just fine.
  (And can do more: it also supports using HTTP/HTTPS proxies).

- When a cli wallet connection fails we know show why it failed (which
  now is an error message from curl), which could have all sorts of
  reasons like hostname resolution failure, bad ssl certificate, etc.
  Previously you just got a useless generic error that tells you
  nothing.

Other related changes in this PR:

- Drops the check-for-update and download-update code.  To the best of
my knowledge these have never been supported in loki-core and so it
didn't seem worth the trouble to convert them to use cpr for the
requests.

- Cleaned up node_rpc_proxy return values: there was an inconsistent mix
  of ways to return errors and how the returned strings were handled.
  Instead this cleans it up to return a pair<bool, val>, which (with
  C++17) can be transparently captured as:

    auto [success, val] = node.whatever(req);

  This drops the failure message string, but it was almost always set to
  something fairly useless (if we want to resurrect it we could easily
  change the first element to be a custom type with a bool operator for
  success, and a `.error` attribute containing some error string, but
  for the most part the current code wasn't doing much useful with the
  failure string).

- changed local detection (for automatic trusted daemon determination)
  to just look for localhost, and to not try to resolve anything.
  Trusting non-public IPs does not work well (e.g. with lokinet where
  all .loki addresses resolve to a local IP).

- ssl fingerprint option is removed; this isn't supported by curl
  (because it is essentially just duplicating what a custom cainfo
  bundle does)

- --daemon-ssl-allow-chained is removed; it wasn't a useful option (if
  you don't want chaining, don't specify a cainfo chain).

- --daemon-address is now a URL instead of just host:port.  (If you omit
  the protocol, http:// is prepended).

- --daemon-host and --daemon-port are now deprecated and produce a
  warning (in simplewallet) if used; the replacement is to use
  --daemon-address.

- --daemon-ssl is deprecated; specify --daemon-address=https://whatever
  instead.

- the above three are now hidden from --help

- reordered the wallet connection options to make more logical sense.
2020-08-07 17:14:03 -03:00
Jason Rhinelander
fe41f08516 Simplify get_human_readable_bytes (avoids boost)
The code here was convoluted; simplified it and avoided needing
boost::format.
2020-08-07 17:14:02 -03:00
Jason Rhinelander
ea9eeab899 Simplify is_local_address to just look for localhost
Doing a DNS resolution here seems like overkill, and even if you get a
resolution to a non-public IP that doesn't mean it's local/trusted (for
example, you could resolve a .loki address, get 10.0.0.3, and then
specify that).  So just hard-code common ways of specifying localhost
instead, which is really the main point of this.
2020-08-07 17:14:02 -03:00
Jason Rhinelander
43f2dfba50 Windows fixes
- Add libuv submodule (only needed and built on Windows)

- Temporarily switch uWebSockets to my github repo: I submitted some
mingw compilation fixes upstream; as soon as a new upstream release
comes out we will switch this back to the upstream repo.

- Switch BOOST_SCOPE_EXIT to LOKI_DEFER

- Don't compile `closefrom()` on Windows (it isn't used, and generates
an unused function warning).
2020-08-07 17:14:02 -03:00
Jason Rhinelander
42a7e83c33 Replace epee http rpc server with uWebSockets
This replaces the NIH epee http server which does not work all that well
with an external C++ library called uWebSockets.  Fundamentally this
gives the following advantages:

- Much less code to maintain
- Just one thread for handling HTTP connections versus epee's pool of
threads
- Uses existing LokiMQ job server and existing thread pool for handling
the actual tasks; they are processed/scheduled in the same "rpc" or
"admin" queues as lokimq rpc calls.  One notable benefit is that "admin"
rpc commands get their own queue (and thus cannot be delayed by long rpc
commands).  Currently the lokimq threads and the http rpc thread pool
and the p2p thread pool and the job queue thread pool and the dns lookup
thread pool and... are *all* different thread pools; this is a step
towards consolidating them.
- Very little mutex contention (which has been a major problem with epee
RPC in the past): there is one mutex (inside uWebSockets) for putting
responses back into the thread managing the connection; everything
internally gets handled through (lock-free) lokimq inproc sockets.
- Faster RPC performance on average, and much better worst case
performance.  Epee's http interface seems to have some race condition
that ocassionally stalls a request (even a very simple one) for a dozen
or more seconds for no good reason.
- Long polling gets redone here to no longer need threads; instead we
just store the request and respond when the thread pool, or else in a
timer (that runs once/second) for timing out long polls.

---

The basic idea of how this works from a high level:

We launch a single thread to handle HTTP RPC requests and response data.
This uWebSockets thread is essentially running an event loop: it never
actually handles any logic; it only serves to shuttle data that arrives
in a request to some other thread, and then, at some later point, to
send some reply back to that waiting connection.  Everything is
asynchronous and non-blocking here: the basic uWebSockets event loop
just operates as things arrive, passes it off immediately, and goes back
to waiting for the next thing to arrive.

The basic flow is like this:

    0. uWS thread -- listens on localhost:22023
    1. uWS thread -- incoming request on localhost:22023
    2. uWS thread -- fires callback, which injects the task into the LokiMQ job queue
    3. LMQ main loop -- schedules it as an RPC job
    4. LMQ rpc thread -- Some LokiMQ thread runs it, gets the result
    5. LMQ rpc thread -- Result gets queued up for the uWS thread
    6. uWS thread -- takes the request and starts sending it
       (asynchronously) back to the requestor.

In more detail:

uWebSockets has registered has registered handlers for non-jsonrpc
requests (legacy JSON or binary).  If the port is restricted then admin
commands get mapped to a "Access denied" response handler, otherwise
public commands (and admin commands on an unrestricted port) go to the
rpc command handler.

POST requests to /json_rpc have their own handler; this is a little
different than the above because it has to parse the request before it
can determine whether it is allowed or not, but once this is done it
continues roughly the same as legacy/binary requests.

uWebSockets then listens on the given IP/port for new incoming requests,
and starts listening for requests in a thread (we own this thread).
When a request arrives, it fires the event handler for that request.
(This may happen multiple times, if the client is sending a bunch of
data in a POST request).  Once we have the full request, we then queue
the job in LokiMQ, putting it in the "rpc" or "admin" command
categories.  (The one practical different here is that "admin" is
configured to be allowed to start up its own thread if all other threads
are busy, while "rpc" commands are prioritized along with everything
else.)  LokiMQ then schedules this, along with native LokiMQ "rpc." or
"admin." requests.

When a LMQ worker thread becomes available, the RPC command gets called
in it and runs.  Whatever output it produces (or error message, if it
throws) then gets wrapped up in jsonrpc boilerplate (if necessary), and
delivered to the uWebSockets thread to be sent in reply to that request.

uWebSockets picks up the data and sends whatever it can without
blocking, then buffers whatever it couldn't send to be sent again in a
later event loop iteration once the requestor can accept more data.
(This part is outside lokid; we only have to give uWS the data and let
it worry about delivery).

---

PR specifics:

Things removed from this PR:

1. ssl settings; with this PR the HTTP RPC interface is plain-text.  The
previous default generated a self-signed certificate for the server on
startup and then the client accepted any certificate.  This is actually
*worse* than unencrypted because it is entirely MITM-readable and yet
might make people think that their RPC communication is encrypted, and
setting up actual certificates is difficult enough that I think most
people don't bother.

uWebSockets *does* support HTTPS, and we could glue the existing options
into it, but I'm not convinced it's worthwhile: it works much better to
put HTTPS in a front-end proxy holding the certificate that proxies
requests to the backend (which can then listen in restricted mode on
some localhost port).  One reason this is better is that it is much
easier to reload and/or restart such a front-end server, while
certificate updates with lokid require a full restart.  Another reason
is that you get an error page instead of a timeout if something is wrong
with the backend.  Finally we also save having to generate a temporary
certificate on *every* lokid invocation.

2. HTTP Digest authentication.  Digest authentication is obsolete (and
was already obsolete when it got added to Monero).  HTTP-Digest was
originally an attempt to provide a password authentication mechanism
that does not leak the password in transit, but still required that the
server know the password.  It only has marginal value against replay
attacks, and is made entirely obsolete by sending traffic over HTTPS
instead.  No client out there supports Digest but *not* Basic auth, and
so given the limited usefulness it seems pointless to support more than
Basic auth for HTTP RPC login.

What's worse is that epee's HTTP Digest authentication is a terrible
implementation: it uses boost::spirit -- a recursive descent parser
meant for building complex language grammars -- just to parse a single
HTTP header for Digest auth.  This is a big load of crap that should
never have been accepted upstream, and that we should get rid of (even
if we wanted to support Digest auth it takes less than 100 lines of code
to do it when *not* using a recursive descent parser).
2020-08-07 17:14:02 -03:00
Jason Rhinelander
463b2cbf01 Add simple delimiter joining string function
Because:

    boost::join(v | boost::adaptors::transformed([](uint64_t out){return std::to_string(out);}), " ")

is ugly as sin, while:

    tools::join(" ", v)

is nice and simple.

Also removes a few unnecessary boost iterator adaptor includes and uses.
2020-08-07 17:14:02 -03:00
Jason Rhinelander
d10c08d15c Remove long-obsolete compiler workaround 2020-07-21 21:53:27 -03:00
Jason Rhinelander
5da9b81e4d Fix hex_to_type and add a unit test for it 2020-07-02 12:56:37 -03:00
Jason Rhinelander
07293ebf60 Address PR feedback 2020-07-02 12:56:37 -03:00
Jason Rhinelander
d667ff2edd Windows compilation fixes 2020-07-02 12:55:28 -03:00
Jason Rhinelander
f09857de2b More string_view (mostly in wallet code)
This started out with a few string_view simplifications, but unwinding
the string_view calls resulted in quite a few changes.

- use constexpr string_view instead of macros for constants

- use constexpr ints for other macros instead of constants (to be
consistent with the string_view constexprs); also eliminated a couple of
unused variables.

- convert amount parsing to string_view, and rewrite it with comments to
be far less confusing.  (Previously it was remove a "." from a string,
chopping 0s off the end then putting them back on which was hard to
follow).

- fixed some not-quite-right amount parsing unit tests

- replace a bunch of string code (including lots of code allocating new
strings with .substr on a string) with std::string_view.

- avoid using C functions for strings

- convert epee http uri conversion methods to string_view (and fix one
typoed func name "conver" -> "convert")

- Add a `tools::hex_to_type` that converts hex directly into a (simple)
type, with hex and length verification for the type, and use it to
eliminate a bunch of intermediate std::string conversions.

- Convert a bunch of error-prone raw pointer string appends into
more type-safe `tools::view_guts(val)` calls.  (In particular view_guts
always gets the sizeof() correct, while the individual call could easily
put the wrong type in the `sizeof()`).
2020-07-02 12:55:28 -03:00
Jason Rhinelander
48a0dc9eef More string_view niceties
- Adds a tools::trim that operates on a string_view to replace boost
string trim usage.

- Replaces some boost::split's with tools::split's

- updates vercmp to operate on string_views instead of c strings
2020-07-02 12:52:13 -03:00
Jason Rhinelander
24f084a73c Miscellaneous header updates via iwyu
Adds some missing required headers and removes some unnecessary ones.
2020-07-02 12:52:13 -03:00
Jason Rhinelander
6f3d3edd0d Use string_view for address lookups
Also DRY out a bunch of identical address-from-string code blocks.
2020-07-02 12:52:13 -03:00
Jason Rhinelander
29b18f6cc3 DNS: async multi-address lookup
Add a multi-address lookup mode to the unbound lookup code and remove
the gross code in net_node.inl that creates one thread per address.
(And worse, tries to use boost thread interruption which cannot work at
all since any such interruption is voluntary and won't do anything to a
thread that is stalled waiting for a synchronous libunbound lookup).

The replacement has unbound create and manage a single thread for async
lookups then waits up to the given timeout for results.

Currently this code isn't actually used because our seed node DNS list
is empty, but this lets us eliminate a boost::thread dependency while
not removing the feature (also includes a test case).
2020-07-02 12:52:13 -03:00
Jason Rhinelander
723d66ad59 Miscellaneous fixes
Adds a small handful of missing headers, signature updates, etc. to make
it compile again.
2020-07-02 12:52:13 -03:00
Jason Rhinelander
237f71396b fix: performance stats 2020-07-02 12:52:13 -03:00
Jason Rhinelander
89afcad468 Post-merge: locks/mutexes
Replaces boost mutexes/locks added upstream with std::equivalents.
2020-07-02 12:52:13 -03:00
Jason Rhinelander
05f0572155 Replace loki::clamp_u64 backport with std::clamp 2020-07-02 12:52:13 -03:00
Jason Rhinelander
515b96e20b Replace (most) boost::thread with std::thread
This removes some boost thread interruption code, but that code is
highly unlikely to have done anything: you cannot preemptively interrupt
a thread, and pretty much anywhere a thread would get stuck is in I/O,
where boost's (voluntary) thread interruption cannot follow.

It also removes thread attributes because they have really limited
usefulness.  There *was* a reason to introduce them many years ago (when
musl libc ran into a stack limit problem with libunbound) but musl
increased the default stack size long since.
2020-07-02 12:52:13 -03:00
Jason Rhinelander
7584a6c3b8 sha256sum_str - fix recursion in string_views
Reorder and SFINAE the non-char string_view code to avoid infinite
recursion with a plain string_view.
2020-07-02 12:52:12 -03:00
Jason Rhinelander
49c693d0a9 Split up common/util.h
common/util.h has become something of a dumping ground of random
functions.  This splits them up a little by moving the filesystem bits
to common/file.h, the sha256sum functions to common/sha256sum.h, and the
(singleton) signal handler to common/signal_handler.h.
2020-07-02 12:52:12 -03:00
Jason Rhinelander
7a2811ba6a C++17 simplify memcpy_le
C++17 fold expressions and a mutable pointer-reference allow reducing
the code required here.
2020-07-02 12:52:12 -03:00
Jason Rhinelander
d5b9adf739 Misc. C++ modernization 2020-07-02 12:52:12 -03:00
Jason Rhinelander
b4cbd4af8d String handling improvements
Add number parsing and basic string splitting to common/string_util.h
and use it (replacing some regexes and boost string utilities).

Includes unit tests.
2020-07-02 12:52:12 -03:00
Jason Rhinelander
e7d056edf1 boost::variant -> std::variant
A huge amount of this is repetitive:

- `boost::get<T>(variant)` becomes `std::get<T>(variant)`
- `boost::get<T>(variant_ptr)` becomes `std::get_if<T>(variant_ptr)`
- `variant.type() == typeid(T)` becomes `std::holds_alternative<T>(variant)`

There are also some simplifications to visitors using simpler stl
visitors, or (simpler still) generic lambdas as visitors.

Also adds boost serialization serializers for std::variant and
std::optional.
2020-07-02 12:52:12 -03:00
Jason Rhinelander
799aa6aed5 Overhaul binary serialization code (part 1)
The serialization interface here had a lot going wrong with it.  This
overhauls it drastically and makes it a lot nicer to deal with.

(This commit is in two parts: this first one updating the base
serialization code, the subsequent one updating various places using
it.  There's a third part, depending on how you want to count,
converting boost::variant to std::variant which relies on the
serialization changes made here).

- everything is now in the `serialization` namespace instead of having
some things there and other things in the root namespace.

- serialization failures now throw exceptions with reasons for the
failure rather than needing to snake a bool back through the call stack
(without any message).

- the `template <bool W, template <bool> class Archive>` monstrosity is
gone.  Instead an Archive class has a Archive::is_serializer or
Archive::is_deserializer constexpr bool that can be checked (there was
something sort of similar before, but required messing around with
boost::mpl crap in both the generic and specific serialization code).

- the serialization code is significantly more flexible: instead of
having to slam everything into a class itself, you can also serialize
using with a free function in the same namespace as the class.

- serialization macros are still provided, but now considered
deprecated, replaced with (ADL callable) function names that don't hide
the action from the caller.  So:

    FIELD(a);
    VARINT_FIELD(b);
    FIELD_N("c", some_c);
    VARINT_FIELD_N("d", some_d);
    FIELDS(x); // (this is like the above, but doesn't write a tag)
    ENUM_FIELD(e, e < myenum::_count);
    FIELD(f);
    if (!W && f != 42) return false;

becomes (all of this is documented in serialization.h):

    field(ar, "a", a);
    field_varint(ar, "b", b);
    field(ar, "c", some_c);
    field_varint(ar, "d", some_d);
    value(x);
    // enums just get passed to field_varint.  It takes an optional
    // lambda to verify on deserialization:
    field_varint(ar, "e", f, [&] { return e < myenum::_count; });
    // But the verifier isn't limited to enums:
    field(ar, "f", f, [&] { return f == 42; });

and all of this works without needing to `serialization::` qualify the
beginning.  In the rare case where you have a conflicting function
defined (e.g. a local `field()`) you can qualify to disambiguate.

- The messy eof hacks where you call `serialize_noeof` is cleaned up.
You now call `serialization::serialize(ar, val)` to deserialize an
*entire* value (which requires that the whole strem is consumed), and
`serialization::value(ar, val)` to append a serialization.

- Container serialization is significantly simplified; the various
serialization/vector.h (and similar) are now extremely thin wrappers
around the generic main container serialization code.

- INSERT_INTO_JSON_OBJECT, GET_FROM_JSON_OBJECT, and
OBJECT_HAS_MEMBER_OR_THROW macros are gone, replaced with nearly
identical yet more flexible (for both the caller and the compiler)
relatively simple templated functions.

- Drastically simplified the ability to serialize to/from a string via
new `serialization::binary_string_archiver` and
`serialization::binary_string_unarchiver` serializers.  The former takes
no arguments; the latter takes a string_view.  This means you can
serialize to binary using:

    serialization::binary_string_archiver ar;
    serialization::serialize(ar, myvalue);
    std::string serialized = ar.str();

and can deserialize using:

    MyType myvalue;
    serialization::binary_string_unarchiver ar{serialized};
    serialization::serialize(ar, myvalue);

(though really this interface is for slightly more complicated cases
than these; see the next point)

- the existing dump_binary() and parse_binary() are tweaked a bit: both
now throw, and dump_binary() returns the result string instead of taking
it as an output parameter.  (parse_binary() is now void, rather than
returning a bool, because there are many places where in-place
deserialization is desirable).

- make one_shot_read_buffer internal to binary_string_unarchiver, and
use it there.  The interfaces here means we no longer need to rely on
the seeking behaviour, so the serialization issues on mac shouldn't
happen now.

- begin_array()/begin_object() now use an RAII interface to make
serializing arrays much easier.  Where previously we had a lot of code
that did something like this:

    ar.begin_array();
    for (auto it = whatever.begin(); it != whatever.end(); it++)
    {
      FIELDS(val);
      if (*(it+1) != whatever.end())
      {
        ar.delimit_array();
      }
    }
    ar.end_array();

Now an array serialization looks like this:

      auto arr = ar.begin_array();
      for (auto& val : whatever)
        value(arr.element(), val);

- serialized non-varint integer values weren't endian safe, now they
are.

- variant serialization converted to use std::variant instead of
boost::variant and significantly cleaned up using C++17 features.

- varint (no "a", i.e. variable length integers) was not easy to follow
and badly documented (the given examples in the description were flat
out wrong).  Rewrote it, with substantially better documentation and
unit tests, and taking advantage of C++14 `0b` and `'` in integer
literals to make it far easier to follow.
2020-07-02 12:52:12 -03:00
Jason Rhinelander
e02545ca4b boost->std: mutex, locks; C++17 lock vars
Changes all boost mutexes, locks, and condition_variables to their stl
equivalents.

Changes all lock_guard/unique_lock/shared_lock to not specify the mutex
type (C++17), e.g.

    std::lock_guard foo{mutex};

instead of

    std::lock_guard<oh::um::what::mutex> foo{mutex};

Also changes some related boost::thread calls to std::thread, and some
related boost chrono calls to stl chrono.

boost::thread isn't changed here to std::thread because some of the
instances rely on some boost thread extensions.
2020-07-02 12:52:12 -03:00
Jason Rhinelander
96354a0e0f boost::optional -> std::optional 2020-07-02 12:52:12 -03:00
Jason Rhinelander
b9448febdf Replace boost::string_ref with std::string_view
Also a few related small places in here where a `const std::string&`
made mode sense to be a std::string_view.
2020-07-02 12:52:12 -03:00
Jason Rhinelander
9c5c1dac50 Replace boost::regex with std::regex 2020-07-02 12:52:12 -03:00
Jason Rhinelander
6af3666fd3 Improve checkpoint loading code; make sha256sum less dangerous
- replace the gross cmake shell script tools being used to create the data file with
cmake code and a single configure_file
- change checkpoint data to string_view
- tools::sha256sum() had two different overloads that did very different
things, yet presents two overloads: one that takes a pointer+size, the
other that takes a string lvalue ref, and yet the string lvalue
reference is *entirely* different (it reads a file).  Append _str and
_file suffixes to make it less dangerous.
2020-07-02 12:52:12 -03:00
Jason Rhinelander
59df48b951 Simplified sfinae_helpers
C++14 and 17 additions let the type traits here be greatly simplified.
2020-07-02 12:52:12 -03:00
Jason Rhinelander
83dd656e74 C++17
Switch loki dev branch to C++17 compilation, and update the code with
various C++17 niceties.

- stop including the (deprecated) lokimq/string_view.h header and
instead switch everything to use std::string_view and `""sv` instead of
`""_sv`.

- std::string_view is much nicer than epee::span, so updated various
loki-specific code to use it instead.

- made epee "portable storage" serialization accept a std::string_view
instead of const lvalue std::string so that we can avoid copying.

- switched from mapbox::variant to std::variant

- use `auto [a, b] = whatever()` instead of `T1 a; T2 b; std::tie(a, b)
= whatever()` in a couple places (in the wallet code).

- switch to std::lock(...) instead of boost::lock(...) for simultaneous
lock acquisition.  boost::lock() won't compile in C++17 mode when given
locks of different types.

- removed various pre-C++17 workarounds, e.g. for fold expressions,
unused argument attributes, and byte-spannable object detection.

- class template deduction means lock types no longer have to specify
the mutex, so `std::unique_lock<std::mutex> lock{mutex}` can become
`std::unique_lock lock{mutex}`.  This will make switching any mutex
types (e.g. from boost to std mutexes) far easier as you just have to
update the type in the header and everything should work.  This also
makes the tools::unique_lock and tools::shared_lock methods redundant
(which were a sort of poor-mans-pre-C++17 way to eliminate the
redundancy) so they are now gone and replaced with direct unique_lock or
shared_lock constructions.

- Redid the LNS validation using a string_view; instead of using raw
char pointers the code now uses a string view and chops off parts of the
view as it validates.  So, for instance, it starts with "abcd.loki",
validates the ".loki" and chops the view to "abcd", then validates the
first character and chops to "bcd", validates the last and chops to
"bc", then can just check everything remaining for is-valid-middle-char.

- LNS validation gained a couple minor validation checks in the process:
  - slightly tightened the requirement on lokinet addresses to require
    that the last character of the mapped address is 'y' or 'o' (the
    last base32z char holds only one significant bit).
  - In parse_owner_to_generic_owner made sure that the owner value has
    the correct size (otherwise we could up end not filling or
    overfilling the pubkey buffer).

- Replaced base32z/base64/hex conversions with lokimq's versions which
have a nicer interface, are better optimized, and don't depend on epee.
2020-07-02 12:52:12 -03:00
Jason Rhinelander
da400f6d66 Rewrite translation file generation using cmake
This makes three big changes to how translation files are generated:

- use Qt5 cmake built-in commands to do the translations rather than
calling lrelease directly.  lrelease is often not in the path, while Qt5
cmake knows how to find and invoke it.

- Slam the resulting files into a C++ file using a cmake script rather
than needing to compile a .c file to generate C++ file.  This is
simpler, but more importantly avoids the mess needed when cross
compiling of having to import a cmake script from an external native
build.

- In the actual generated files, use an unordered_map rather than a
massive list of static variable pointers.
2020-06-15 12:49:33 -03:00
Jason Rhinelander
2c89428f7c Windows build fixes 2020-06-14 23:43:35 -03:00
Doyle
a8abb83b7d Merge commit '2d729fb' into MergeUpstream3 2020-05-28 16:56:01 +10:00
Doyle
b71ce522c1 Merge commit '6c7d928' into MergeUpstream3 2020-05-28 15:02:40 +10:00
Doyle
00545b4920 Merge commit '5e384f2' into MergeUpstream3 2020-05-27 15:45:13 +10:00
Doyle
334f94af62 Merge commit 'c39ea48' into MergeUpstream3 2020-05-27 14:43:35 +10:00