Commit Graph

53 Commits

Author SHA1 Message Date
Jason Rhinelander 5f1bd2f1e4 Drop integration test code.
This code is bitrotting, doesn't compile, and isn't being maintained
anymore.

The integration test suite was an interesting idea, in early Loki days,
but is no longer being maintained and is quite cumbersome to run (for
instance, it is not possible to run it via CI because it depends on
xterm to actually run).  The code to actually run it (in doy-lee's
loki-integration-testing repository) is also a large burden of "janky"
code that isn't worth maintaining.

Remove this from the code; if someone wants to pick it back up in the
future reverting this commit shouldn't be too difficult (though I'd
suggest that a much better approach to integration testing would be to
run different daemons/wallets via rpc commands, as the network-tests do,
rather than trying to feed stdin and parse stdout from running
individual oxends/wallets).
2021-08-19 16:42:15 -03:00
Sean Darcy 99ad4b5c31 added new reason field to status change 2021-03-26 15:25:12 -03:00
Sean Darcy 432dc319a9 executable names changed 2021-01-04 14:19:42 +11:00
Sean Darcy 0396698ee7 initial loki -> oxen pass 2021-01-04 11:09:45 +11:00
Jason Rhinelander b627b3b4bb Move epee includes under "epee/..."
This ends epee's include pollution.
2020-10-24 12:46:27 -03:00
Jason Rhinelander 78833f9d69 Remove deprecated epee code 2020-10-24 12:46:26 -03:00
Jason Rhinelander b7dd5e8911 Target macos 10.12
When targetting macos <10.14 macos won't allow use of anything from
C++17 that throws, such as:
- std::get on a variant
- std::visit
- std::optional::value()
- std::any_cast

This avoids all of these.

For std::get, we either replace with std::get_if (where appropriate), or
else use a `var::get` implementation of std::get added to lokimq (also
updated here).  (This `var` namespace is just an `std` alias everywhere
*except* old target macos).

For std::visit, likewise lokimq adds an var::visit implementation for
old macos that we use.

std::optional::value() uses weren't useful anyway as everywhere it calls
them we've already checked that the option has a value, in which case we
can use `*opt` (which doesn't check for contents and throw).

std::any just has to be avoided as far as I can tell, but the one place
we used it is only ever a block, so I just replaced it with a `const
block*`.
2020-10-18 11:18:08 -03:00
Doyle 4d589f7cec blockchain: Log more useful data 2020-09-27 16:38:19 +10:00
Doyle f6ee81fa05 temp: Log L0 block verification to global 2020-09-18 13:47:16 -03:00
Doyle 81afcdd1a6 temp: Raise log levels for debuggin 2020-09-18 13:43:51 -03:00
Doyle 6cf53600e1 Pulse: Add work around for core_tests and fix cast 2020-09-18 13:43:51 -03:00
Doyle 9213df406c Pulse: fix off by 2 quorum gen bug, recategories log msgs 2020-08-18 11:59:54 +10:00
Doyle 601e9f77e1 Pulse: Rename participation to validator_bitset 2020-08-18 11:59:53 +10:00
Doyle a6e1f82f7a Pulse: Make active snodes info public, disambiguate next_block_template
- Make active snods info public for Pulse to query the list to allow
  Pulse quorums to be generated outside of the Service Node List.
2020-08-18 11:59:53 +10:00
Doyle 254e6aa80d Code review
- Remove PoW/Difficulty information for Pulse Block printout
- Use unary + to co-erce char's in ostreams
- Avoid epee::string_tools::pod_to_hex for lokimq equivalent
- Express validator bitmask in terms of PULSE_QUORUM_NUM_VALIDATORS
- Fix bug in generating Pulse Quorum, avoiding the use of the 0th
  service node in pulse_candidates
- Switch to std::any for void * context
2020-08-18 11:59:53 +10:00
Doyle 63ba795c7e Pulse: DRY quorum signature verification
- By merging the quorum verification with pre-existing checkpointing
code, checkpoints votes are currently being sorted by the vote index
order. This was also enforced on the pulse signatures.
2020-08-18 11:59:53 +10:00
Jason Rhinelander 443c5e8cea Purge epee::critical_crap and CRITICAL_CRAP
This purges epee::critical_region/epee::critical_section and the awful
CRITICAL_REGION_LOCAL and CRITICAL_REGION_LOCAL1 and
CRITICAL_REGION_BEGIN1 and all that crap from epee code.

This wrapper class around a mutex is just painful, macro-infested
indirection that accomplishes nothing (and, worse, forces all using code
to use a std::recursive_mutex even when a different mutex type is more
appropriate).

This commit purges it, replacing the "critical_section" mutex wrappers
with either std::mutex, std::recursive_mutex, or std::shared_mutex as
appropriate.  I kept anything that looked uncertain as a
recursive_mutex, simple cases that obviously don't recurse as
std::mutex, and simple cases with reader/writing mechanics as a
shared_mutex.

Ideally all the recursive_mutexes should be eliminated because a
recursive_mutex is almost always a design flaw where someone has let the
locking code get impossibly tangled, but that requires a lot more time
to properly trace down all the ways the mutexes are used.

Other notable changes:

- There was one NIH promise/future-like class here that was used in
example one place in p2p/net_node; I replaced it with a
std::promise/future.

- moved the mutex for LMDB resizing into LMDB itself; having it in the
abstract base class is bad design, and also made it impossible to make a
moveable base class (which gets used for the fake db classes in the test
code).
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
Doyle c93dbf7ce6 SN: Remove old vote blob serialisation fixes
Votes are ephemeral and the backwards compat fixes are only needed at
the time of the hard fork.
2020-06-11 10:16:55 +10:00
Jason Rhinelander 0e3f173c7f RPC overhaul
High-level details:

This redesigns the RPC layer to make it much easier to work with,
decouples it from an embedded HTTP server, and gets the vast majority of
the RPC serialization and dispatch code out of a very commonly included
header.

There is unfortunately rather a lot of interconnected code here that
cannot be easily separated out into separate commits.  The full details
of what happens here are as follows:

Major details:
- All of the RPC code is now in a `cryptonote::rpc` namespace; this
  renames quite a bit to be less verbose: e.g. CORE_RPC_STATUS_OK
  becomes `rpc::STATUS_OK`, and `cryptonote::COMMAND_RPC_SOME_LONG_NAME`
  becomes `rpc::SOME_LONG_NAME` (or just SOME_LONG_NAME for code already
  working in the `rpc` namespace).
- `core_rpc_server` is now completely decoupled from providing any
  request protocol: it is now *just* the core RPC call handler.
- The HTTP RPC interface now lives in a new rpc/http_server.h; this code
  handles listening for HTTP requests and dispatching them to
  core_rpc_server, then sending the results back to the caller.
- There is similarly a rpc/lmq_server.h for LMQ RPC code; more details
  on this (and other LMQ specifics) below.
- RPC implementing code now returns the response object and throws when
  things go wrong which simplifies much of the rpc error handling.  They
  can throw anything; generic exceptions get logged and a generic
  "internal error" message gets returned to the caller, but there is
  also an `rpc_error` class to return an error code and message used by
  some json-rpc commands.
- RPC implementing functions now overload `core_rpc_server::invoke`
  following the pattern:

    RPC_BLAH_BLAH::response core_rpc_server::invoke(RPC_BLAH_BLAH::request&& req, rpc_context context);

  This overloading makes the code vastly simpler: all instantiations are
  now done with a small amount of generic instantiation code in a single
  .cpp rather than needing to go to hell and back with a nest of epee
  macros in a core header.
- each RPC endpoint is now defined by the RPC types themselves,
  including its accessible names and permissions, in
  core_rpc_server_commands_defs.h:
  - every RPC structure now has a static `names()` function that returns
    the names by which the end point is accessible.  (The first one is
    the primary, the others are for deprecated aliases).
  - RPC command wrappers define their permissions and type by inheriting
    from special tag classes:
    - rpc::RPC_COMMAND is a basic, admin-only, JSON command, available
      via JSON RPC.  *All* JSON commands are now available via JSON RPC,
      instead of the previous mix of some being at /foo and others at
      /json_rpc.  (Ones that were previously at /foo are still there for
      backwards compatibility; see `rpc::LEGACY` below).
    - rpc::PUBLIC specifies that the command should be available via a
      restricted RPC connection.
    - rpc::BINARY specifies that the command is not JSON, but rather is
      accessible as /name and takes and returns values in the magic epee
      binary "portable storage" (lol) data format.
    - rpc::LEGACY specifies that the command should be available via the
      non-json-rpc interface at `/name` for backwards compatibility (in
      addition to the JSON-RPC interface).
- some epee serialization got unwrapped and de-templatized so that it
  can be moved into a .cpp file with just declarations in the .h.  (This
  makes a *huge* difference for core_rpc_server_commands_defs.h and for
  every compilation unit that includes it which previously had to
  compile all the serialization code and then throw all by one copy away
  at link time).  This required some new macros so as to not break a ton
  of places that will use the old way putting everything in the headers;
  The RPC code uses this as does a few other places; there are comments
  in contrib/epee/include/serialization/keyvalue_serialization.h as to
  how to use it.
- Detemplatized a bunch of epee/storages code.  Most of it should have
  have been using templates at all (because it can only ever be called
  with one type!), and now it isn't.  This broke some things that didn't
  properly compile because of missing headers or (in one case) a messed
  up circular dependency.
- Significantly simplified a bunch of over-templatized serialization
  code.
- All RPC serialization definitions is now out of
  core_rpc_server_commands_defs.h and into a single .cpp file
  (core_rpc_server_commands_defs.cpp).
- core RPC no longer uses the disgusting
  BEGIN_URI_MAP2/MAP_URI_BLAH_BLAH macros.  This was a terrible design
  that forced slamming tons of code into a common header that didn't
  need to be there.
- epee::struct_init is gone.  It was a horrible hack that instiated
  multiple templates just so the coder could be so lazy and write
  `some_type var;` instead of properly value initializing with
  `some_type var{};`.
- Removed a bunch of useless crap from epee.  In particular, forcing
  extra template instantiations all over the place in order to nest
  return objects inside JSON RPC values is no longer needed, as are a
  bunch of stuff related to the above de-macroization of the code.
- get_all_service_nodes, get_service_nodes, and get_n_service_nodes are
  now combined into a single `get_service_nodes` (with deprecated
  aliases for the others), which eliminates a fair amount of
  duplication.  The biggest obstacle here was getting the requested
  fields reference passed through: this is now done by a new ability to
  stash a context in the serialization object that can be retrieved by a
  sub-serialized type.

LMQ-specifics:

- The LokiMQ instance moves into `cryptonote::core` rather than being
  inside cryptonote_protocol.  Currently the instance is used both for
  qnet and rpc calls (and so needs to be in a common place), but I also
  intend future PRs to use the batching code for job processing
  (replacing the current threaded job queue).
- rpc/lmq_server.h handles the actual LMQ-request-to-core-RPC glue.
  Unlike http_server it isn't technically running the whole LMQ stack
  from here, but the parallel name with http_server seemed appropriate.
- All RPC endpoints are supported by LMQ under the same names as defined
  generically, but prefixed with `rpc.` for public commands and `admin.`
  for restricted ones.
- service node keys are now always available, even when not running in
  `--service-node` mode: this is because we want the x25519 key for
  being able to offer CURVE encryption for lmq RPC end-points, and
  because it doesn't hurt to have them available all the time.  In the
  RPC layer this is now called "get_service_keys" (with
  "get_service_node_key" as an alias) since they aren't strictly only
  for service nodes.  This also means code needs to check
  m_service_node, and not m_service_node_keys, to tell if it is running
  as a service node.  (This is also easier to notice because
  m_service_node_keys got renamed to `m_service_keys`).
- Added block and mempool monitoring LMQ RPC endpoints: `sub.block` and
  `sub.mempool` subscribes the connection for new block and new mempool
  TX notifications.  The latter can notify on just blink txes, or all
  new mempool txes (but only new ones -- txes dumped from a block don't
  trigger it).  The client gets pushed a [`notify.block`, `height`,
  `hash`] or [`notify.tx`, `txhash`, `blob`] message when something
  arrives.

Minor details:
- rpc::version_t is now a {major,minor} pair.  Forcing everyone to pack
  and unpack a uint32_t was gross.
- Changed some macros to constexprs (e.g. CORE_RPC_ERROR_CODE_...).
  (This immediately revealed a couple of bugs in the RPC code that was
  assigning CORE_RPC_ERROR_CODE_... to a string, and it worked because
  the macro allows implicit conversion to a char).
- De-templatizing useless templates in epee (i.e. a bunch of templated
  types that were never invoked with different types) revealed a painful
  circular dependency between epee and non-epee code for tor_address and
  i2p_address.  This crap is now handled in a suitably named
  `net/epee_network_address_hack.cpp` hack because it really isn't
  trivial to extricate this mess.
- Removed `epee/include/serialization/serialize_base.h`.  Amazingly the
  code somehow still all works perfectly with this previously vital
  header removed.
- Removed bitrotted, unused epee "crypted_storage" and
  "gzipped_inmemstorage" code.
- Replaced a bunch of epee::misc_utils::auto_scope_leave_caller with
  LOKI_DEFERs.  The epee version involves quite a bit more instantiation
  and is ugly as sin.  Also made the `loki::defer` class invokable for
  some edge cases that need calling before destruction in particular
  conditions.
- Moved the systemd code around; it makes much more sense to do the
  systemd started notification as in daemon.cpp as late as possible
  rather than in core (when we can still have startup failures, e.g. if
  the RPC layer can't start).
- Made the systemd short status string available in the get_info RPC
  (and no longer require building with systemd).
- during startup, print (only) the x25519 when not in SN mode, and
  continue to print all three when in SN mode.
- DRYed out some RPC implementation code (such as set_limit)
- Made wallet_rpc stop using a raw m_wallet pointer
2020-05-11 18:44:45 -03:00
Doyle 632f6a6e83 Rebase fix, blink_lns -> blink, v15 and reserve types for protocol 2020-02-13 11:07:46 +11:00
Jason Rhinelander ac784faeb3 Don't print worker_index when not an obligations vote (#987)
DEBUG is printing:

    Signature accepted for checkpointing voter n/<pubkey> voting  for worker NNNNN at height H

where NNNNN is some random 16-bit number.
2019-12-19 09:40:49 +10:00
Jason Rhinelander 19c562f800 Vote serialization compatibility fix (#984)
quorum_vote_t's were serialized as blob data, which is highly
non-portable (probably isn't the same on non-amd64 arches) and broke
between 5.x and 6.x because `signature` is aligned now (which changed
its offset and thus broke 5.x <-> 6.x vote transmission).

This adds a hack to write votes into a block of memory compatible with
AMD64 5.x nodes up until HF14, then switches to a new command that fully
serializes starting at the hard fork (after which we can remove the
backwards compatibility stuff added here).
2019-12-17 10:47:12 +10:00
Jason Rhinelander bbb72b5c17 Keep checkpoint votes over p2p
Checkpoint votes were only going over quorumnet, which was quite broken
as they need to go out universally: random nodes piece together the
individual checkpoints to create checkpoints on their own, and so need
to see all of the votes.  With the current code only service nodes that
participated in the specific quorum ever saw the checkpoint votes.

This commit returns checkpoint vote distribution to distribution over
p2p.

We could, in theory, do checkpoint vote collection over quorumnet and
then relay the set of votes as a pack to reduce p2p traffic a bit, but
this wouldn't be a huge optimization since we'd still have to distribute
all the votes over p2p at some point anyway, so leaving that as a future
optimization for now.

(Obligations votes, in contrast, don't need to be distributed at all --
if a vote results in a state change, the quorum members themselves can
produce and distribute the state change tx).
2019-12-10 16:29:17 -04:00
Jason Rhinelander b3d6150fa9 Store uptime proof data separately from states
This extracts uptime proof data entirely from service node states,
instead storing (some) proof data as its own first-class object in the
code and backed by the database.  We now persistently store:

- timestamp
- version
- ip & ports
- ed25519 pubkey

and update it every time a proof is received.  Upon restart, we load all
the proofs from the database, which means we no longer lose last proof
received times on restart, and always have the most recently received ip
and port information (rather than only having whatever it was in the
most recently stored state, which could be ~12 blocks ago).  It also
means we don't need to spam the network with proofs for up to half an
hour after a restart because we now know when we last sent (and
received) our own proof before restarting.

This separation required some restructuring: most notably changing
`state_t` to be constructed with a `service_node_list` pointer, which it
needs both directly and for BlockchainDB access.  Related to this is
also eliminating the separate BlockchainDB pointer stored in
service_node_list in favour of just accessing it via m_blockchain (which
now has a new `has_db()` method to detect when it has been initialized).
2019-12-09 22:26:38 -04:00
Jason Rhinelander 20c07f8e8d Promote SN state change errors to MERROR
These are quite serious: if they occur there's a good chance that the
local SN state data is wrong.  (At default logging they aren't printed
at all, and really should be).

This also fixes and adds more detail in the the "height is not stored"
error.
2019-12-02 18:19:39 -04:00
Jason Rhinelander 4522a7ae58 Add & use `tools::enum_count` to get _count as underlying type
Unify the field we use to store the count as `_count` (using the leading
underscore to indicate a private value rather than an intended enum
value) and add/use a new `enum_count` template variable to extract the
_count enum value and cast it to the enum's underlying_type.
2019-11-27 14:07:52 -04:00
Jason Rhinelander 1b5234e6a6 Rename `testing_quorum` class to just `quorum`
testing_quorum is a bit of a misnomer: it only does testing when used
for an obligations quorum, but it is also used for checkpointing and
soon Blink.
2019-11-27 14:07:52 -04:00
Doyle e949e15c6e
Remove hard-forking code on the boundary of 12 and 13 (#919) 2019-10-30 14:50:34 +11:00
Jason Rhinelander c85b0189c8 Simplify memcpy with offset using recently added memcpy_le helper 2019-10-07 22:09:17 -03:00
Jason Rhinelander 2c52c1c020 Add unified key container
This puts the SN pubkey/privkey into a single struct (which have
ed25519/x25519 keys added to it in the future), which simplifies various
places to just pass the struct rather than storing and passing the
pubkey and privkey separately.
2019-10-07 22:09:17 -03:00
Doyle f94328bf37
Switch to using validators for checkpoints (#850)
* Add temporary HF12/13 code to switch to validators for checkpointing

* Don't use target height for verifying vote age

You wouldn't have the quorum calculated to verify the vote in the first place.

* Update core tests to use validators for checkpoints
2019-09-20 15:54:00 +10:00
Doyle b76df2bdfa
Clean up core tests (#830)
* Fix core test for test_deregister_on_split for hf13 and reorganize tests

* Rename service_nodes tests to loki_tests

* Actually commit new files
2019-09-11 16:04:58 +10:00
Doyle 50228e2a0e Merge branch 'dev' into AlternativeQuorums 2019-09-10 12:31:03 +10:00
Doyle 39987729ab
Update soft-forking checks to be effective HF13 (#825)
Code review

m_oldest_allowable_alternative_block -> m_immutable_height
2019-09-10 10:04:44 +10:00
Doyle 0b92e9ba89 Code review 2019-09-09 11:14:19 +10:00
Doyle d2b619ea9a Revamp core_tests linear_chain_generator to support state_t
Remove using crypto, using cryptonote, using epee in chaingen

Add loki prefix to data structures, cleanup warts

Remove the need for get_static_keys(), remove useless functions and
attempt to remove some pointless function overloading that puts too many
levels of indirection and makes it harder to follow code execution.

Rehaul tests further, persist test generator when replaying through core

The class used to generate the testing events to replay through core is
now preserved. This subtle change simplifies a big chunk of core testing
in that we can remove the need for using callbacks to track events in
the events vector.

Add preliminary checkpoint/alt service node tests

Allow inlining of fail cases for test conditions

Add more checkpoint core tests

add_block in generator is parameterised with checkpoints

Add test to check chain with equal checkpoints

Add test for chain reorging when recieving enough votes for checkpoint
2019-09-06 14:41:55 +10:00
Doyle 4724a7436f Incorporate checkpoint validation into syncing step
Fix checkpoint verification check and add messages
2019-09-06 14:41:55 +10:00
Doyle 15ff209db0 Add alt block added hook
Move service node list methods to state_t methods

Add querying state from alt blocks and put key image parsing into function

Incorporate hash into state_t to find alt states

Add a way to query alternate testing quorums

Rebase cleanup
2019-09-06 14:41:55 +10:00
Doyle 8fdf2a7819 Fix service node winner incorrect error
If we are re-deriving states we still also need the historical quorums
such that we can process incoming blocks with state changes. Without it,
state changes will be ignored and skipped causing inconsistent state in
the service node list.

This mandates a rescan and stores the most recent in state_ts, and only
just quorums for states preceeding 10k intervals. We can no longer store
the 1st most recent state in the DB as that will be missing quorums as
well for similar reason when rederiving on start-up.
2019-08-16 15:30:36 +10:00
Doyle a6cbad1701 Enforce ordering of votes in HF13 2019-08-15 11:42:46 +10:00
Doyle d14aba3329
Merge pull request #778 from Doy-lee/HF12CleanupCode
Hf12 cleanup code
2019-08-07 11:22:54 +10:00
Doyle 0f7133044c
Filter vote age before querying quorum (#777)
* Reject new votes received before daemon realises it is syncing

* Fix unit tests and print_vote_* warning
2019-08-07 10:52:32 +10:00
Doyle df454e7cbb Remove legacy P2P vote conversion methods 2019-08-07 10:30:58 +10:00
Doyle bdf8829f6b Switch to a circular buffer for recording checkpointing votes 2019-07-11 14:21:59 +10:00
Jason Rhinelander 0c05ce4502 Fix rejection of ip changes state change txes (#706) 2019-07-03 10:22:57 +10:00
Jason Rhinelander 2199a3b6f4 Fix broken height rejection rule 2019-07-01 12:08:29 -03:00
Jason Rhinelander 3bc4f1ac13 Extend height tolerance to state_change tx "verifivation" 2019-06-30 23:18:33 -03:00
Jason Rhinelander 192ea32326 Don't relay expired votes; add vote tolerance before disconnection
Update the way votes are relayed to fix superfluous p2p disconnections:
- check that votes are actually not older than VOTE_LIFETIME before
  relaying.
- Fix off-by-one error in incoming vote handling (it was rejecting on >=
  maximum age instead of > maximum age).
- Add a 5-block buffer to the incoming vote tolerance handling: don't
  accept a vote that is too new or too old, but also don't trigger a
  disconnection if it is within 5 blocks of where it would be
  acceptable so that relays from slightly out of sync peers don't
  trigger p2p disconnections.
2019-06-30 14:25:20 -03:00
Doyle fdc340b0ee
Service node checkpointing: rebased on relaxed deregistration (#662)
* core: do not commit half constructed batch db txn

* Add defer macro

* Revert dumb extra copy/move change

* Fix pop_blocks not calling hooks, fix BaseTestDB missing prototypes

* Merge ServiceNodeCheckpointing5 branch, syncing and integration fixes

* Update tests to compile with relaxed-registration changes

* Get back to feature parity pre-relaxed registration changes

* Remove debug changes noticed in code review and some small bugs
2019-06-26 14:00:05 +10:00