We want to allow people to buy LNS entries on behalf of other users. If
this is the case we don't need signatures to verify that the purchaser
knows the secret key. What we actually want in this scenario is that,
there's a LNS entry, and people can voluntarily pay to renew/buy that.
Check that lns_end_height is non-zero, to see if it's valid to process
blocks in the LNS subsystem. Otherwise, the start_height of LNS can
potentially override the start height, but, LNS won't process any of
blocks causing the message that multiple blocks are being processed
into Loki subsystems every block.
The wallet does something funky with the key storage that the
values have changed, even after decrypting the wallet keys. The ed keys are
different from when we originally derived them, so for now, just re-derive
Call service_node_lists's block added hook function manually instead of
hooking the hook. There's a common operation between the 2 subsystems,
Loki Name Service and Service Node List, in which they generate state
based off incoming blocks from the blockchain.
Upon profiling, the slowest factor of this is retrieving the blocks from
the DB in batches of a 1000 rather than the processing of the blocks in
the subsystems. So flatten out the hierarchy so that we can retrieve the
batch and simultaneously process the blocks in both subsystems on the
same fetch request.
A complete removal of the hook system so we have more flexibility at the
callsite can be done in a later PR, to avoid too many unneccesary
changes in the LNS PR.
* Creates a default address for the sweep_all command in the cli wallet
Previously the sweep all command required the user pass in the wallet
address for it to function. This commit allows for no address to be
passed in which case the software will use the same address that the
address command produces.
* Rename variable to addr, only call wallet if needed and update usage statements
* modify locked blocks parameters after making address optional
* removed log file and single sweep description
* updated the help descriptions for the 3 affected commands
Previously the loki-wallet-rpc print function set the bright parameter in set_console_color(int color, bool bright) to true when its emphasis parameter was false. This changes the bright flag so it mirrors the emphasis flag.
This enables optional support for systemd notification which allows
lokid to be run via `Type=notify`, allowing it to better signal status
to systemd and enables systemd watchdog handling to restart if something
goes wrong.
Enabled here are:
- systemd watchdog ping every 10s
- systemd status update every 10s, so that `systemctl status loki-node`
gives you a status line such as:
Status: "Height: 450085, SN: active, proof: 15m12s, storage: 3m7s, lokinet: 27s"
- initialization notification so that systemd can wait for
and report on initialization status rather than just that the process
has launched.
- shutdown notification
All of these require changing the service type to `Type=notify` in the
`[Service]` section of the systemd service file; enabling the watchdog
also requires adding a `WatchdogSec=5min` line in the `[Service]`
section.
The systemd support is optional and requires the libsystemd-dev package
to be built (and is probably not feasible at all for a static build).
cryptonote_protocol_handler calls `pool.get_blink(hash)` while already
holding a blink shared lock, which should have been
`pool.get_blink(hash, true)` to avoid `get_blink` trying to take its own
lock.
That double lock is undefined behaviour and can cause a deadlock on the
mutex, although it appears rare that it actually does. If it does,
however, this eventually backs up into vote relaying during the idle
loop, which then stalls the idle loop so we stop sending out uptime
proofs (since that is also in the idle loop).
A simple fix here is to add the `true` argument, but on reconsideration
this extra argument to take or not take a lock is messy and error prone,
so this commit instead removes the second argument entirely and instead
documents which call must and must not hold a lock, getting rid of the
three methods (get_blink, has_blink, and add_existing_blink) that had
the `have_lock` argument. This ends up having only a small impact on
calling code - the vast majority of callers already hold a lock, and the
few that don't are easily adjusted.
This fixes two issues: first when running with --disable-rpc-long-poll
the long poll isn't present, so the list of pool txes will always be
empty, which means unconfirmed_txs will get cleared on refresh because
they don't appear to be in the node's pool. This makes us likely to
wind up with double spending failures on subsequent txes since we don't
know about the outgoing unconfirmed_tx anymore.
Secondly, it seems like there's a potential race condition here even
when long polling is enabled that can cause the same failure depending
on the timing of polling in the long poll thread (for example, if it
hits the 30s cooldown from a MAX_CONNECTIONS response), so just fixing
this for the no-long-polling case doesn't seem sufficient.
The previous (< v6.1.1) code didn't have this issue because the tx
construction and refreshing new pool data were synchronous. (There is a
potential race condition if refresh requests span the node finding a new
block between the block refresh and the pool tx refresh, but that's
already handled in the code by requiring two refreshes before setting it
as unspent).
This reverts the old synchronous fetch-pool-txes behaviour on refresh so
that there is no window of opportunity with long polling for us to
prematurely treat unconfirmed_txs as failed/unspent.
set_daemon got changed to set the long polling daemon, but then this
later got removed but the extra logic (now unnecessary) remained. This
(mostly) reverts it back to the simpler pre-rpc-long-poll code.
The lock here also looked later than it should be: elsewhere it is
guarding changes to m_daemon_address and m_daemon_login but in the
change above it was moved to not guard them anymore.
x25519 -> pubkey cache entries weren't being updated on new but
unchanged proofs, so would eventually expire and cause SNs to stop
authenticating new quorumnet connections as being from SNs.
Updating the checkpoint table in place, something must have been done
incorrectly or some bug, such that querying MDB_LAST on the checkpoint
table returns not the latest expected checkpoint.
Pulling out all the old checkpoints, generating a new table and
reinserting them resolves this.
Handle errors better when long polling is disabled instead of endlessly
spamming logs.
Avoid lock contention when set_daemon is called. Instead of immediately
affecting the long polling thread (which could be engaging the mutex
until RPC timeout, meaning the program stalls for that duration), update
the address on the next iteration of the long polling thread.
Wallets handle daemons that disable long polling better by sleeping.
// NOTE: Compiling with a minimum Mac OSX API of 10.13 and generating
// a binary_archive with a one_shot_read_buffer, causes the following snippet
// to fail
explicit binary_archive(stream_type &s) : base_type(s) {
stream_type::pos_type pos = stream_.tellg();
stream_.seekg(0, std::ios_base::end);
eof_pos_ = stream_.tellg();
stream_.seekg(pos);
}
// In particular
// stream_.seekg(0, std::ios_base::end);
// eof_pos_ = stream_.tellg();
// A seekg followed by a tellg returns 0, no state flags are set on the io
// stream. So use the old method that copies the blob into a stringstream
// instead for APPLE targets.
`tools::wallet2::rpc_long_poll_timeout` was a static member declaration
without a definition, which isn't allowed before C++17 (although can
work depending on compiler optimizations). Adding the definition in
wallet2.cpp isn't really an option (it would make core depend on the
wallet), so just move it to a constexpr static global (which is allowed
without a definition, even before C++17) in `rpc/` instead.
This is really useful for the blink test suite as it lets us trigger a
resync (which normally only runs every 60s). In particular where we
have a (test) situation like this:
A - B - C
where we want to take down B and bring it up again but want to be sure
that new things learned from A get seen right away by C: if B does a
resync with C *before* it does a resync with A then C wouldn't get the
sync updates for a full minute, while if we force B to sync then force C
to sync we can ensure quick propagation for the test suite.
`--regtest` didn't work in some edge cases, this fixes various things:
- the genesis block wasn't accepted because it needed to be v7, not
vMax
- reduce initial uptime proof delay to 5s in regtest mode
- add --regtest flag to the wallet so that it can talk to a daemon in
--regtest mode.
This also adds two new mining options, available via rpc:
- slow_mining - this avoids the RandomX initialization. It is much
slower, but for regtest with fixed difficulty of 1 that is perfectly
fine.
- `num_blocks` - instruct the miner to mine for the given number of
blocks, then stop. (This can overmine if mining with multiple
threads at a low difficulty, but that's fine).
While we're syncing it's not uncommon to receive some mempool blinks
that we can't validate yet: the inputs may refer to outputs that we
don't know about yet, and we may not be able to construct the blink
quorum yet. We don't want to cut off our peers if they sent something
just because we can't handle it yet, so don't drop_connection in such a
case.
If a peer sends something invalid (i.e. a block containing a tx that
conflicts with a blink) we don't want to immediately close it because
the peer may be able to recover by rolling back, but in order to do that
it needs to be able to receive our blinks which (probably) won't happen
if it gets instantly close. So require *two* attempts to close before
we actually close the p2p connection.
This can occur when syncing if we get a blink tx before the blocks that
let us determine the quorum. Just ignore it at this point; we'll pick
it up at the next once-per-minute sync run.
Blink txes were not being properly passed in/out of the RPC wallet.
This adds the necessary bits both to submit a blink and to get a blink
submission status back from the daemon.