This adds the ability for check_fee() to also check the burn amount.
This requires passing extra info through `add_tx()` (and the various
things that call it), so I took the:
bool keeped_by_block, bool relayed, bool do_not_relay
argument triplet, moved it into a struct in tx_pool.h, then added the other fee
options there (along with some static factory functions for generating the
typical sets of option).
The majority of this commit is chasing that change through the codebase and
test suite.
This is used by blink but should also help LNS and other future burn
transactions to verify a burn amount simply when adding the transation to the
mempool. It supports a fixed burn amount, a burn amount as a multiple of the
minimum tx fee, and also allows you to increase the minimum tx fee (so that,
for example, we could require blink txes to pay miners 250% of the usual
minimum (unimportant) priority tx fee.
- Removed a useless core::add_new_tx() overload that wasn't used anywhere.
Blink-specific changes:
(I'd normally separate these into a separate commit, but they got interwoven
fairly heavily with the above change).
- changed the way blink burning is specified so that we have three knobs for
fee adjustment (fixed burn fee; base fee multiple; and required miner tx fee).
The fixed amount is currently 0, base fee is 400%, and require miner tx fee is
simply 100% (i.e. no different than a normal transaction). This is the same as
before this commit, but is changing how they are being specified in
cryptonote_config.h.
- blink tx fee, burn amount, and miner tx fee (if > 100%) now get checked
before signing a blink tx. (These fee checks don't apply to anyone else --
when propagating over the network only the miner tx fee is checked).
- Added a couple of checks for blink quorums: 1) make sure they have reached
the blink hf; 2) make sure the submitted tx version conforms to the current hf
min/max tx version.
- print blink fee information in simplewallet's `fee` output
- add "typical" fee calculations in the `fee` output:
[wallet T6SCwL (has locked stakes)]: fee
Current fee is 0.000000850 loki per byte + 0.020000000 loki per output
No backlog at priority 1
No backlog at priority 2
No backlog at priority 3
No backlog at priority 4
Current blink fee is 0.000004250 loki per byte + 0.100000000 loki per output
Estimated typical small transaction fees: 0.042125000 (unimportant), 0.210625000 (normal), 1.053125000 (elevated), 5.265625000 (priority), 0.210625000 (blink)
where "small" here is the same tx size (2500 bytes + 2 outputs) used to
estimate backlogs.
The MAINNET default here doesn't make sense: not specifying the network
type in the call (and relying on the MAINNET default) seems likely to be
a bug.
This catches any exception thrown in the inner quorumnet blink code and
sets it in the promise if it occurs, which propagates it out to
core_rpc_server to catch and deal with.
- confirmed was erroneously being set to true for mempool transactions
causing it to sort at the beginning instead of the end of the list.
(Since it gets zero initialized just delete it)
- show_transfers `min_height` was for some inexpicable reason being
treated as a strict inequality so that `show_transfers 123 456` would
not show you transactions from height 123. (The max_height was *not*
strict, so you *do* get transactions from height 456).
- Adds blink signature synchronization and storage through the regular
p2p network
- Adds wallet support (though this is still currently buggy and needs
additional fixes - it sees the tx when it arrives in the mempool but
isn't properly updating when the blink tx gets mined.)
There are a bunch trivial forwarding wrappers in cryptonote_core that
simply call the same method in the pool, and blink would require adding
several more. Instead of all of these existing (and new) wrappers, just
directly expose the tx_pool reference so that anything with a `core`
reference can access and call to the mempool directly.
These structures will always end up packed anyway (everything in them is
8-byte aligned and a multiple of 8 bytes), but the pack pragma also
changes their alignment which isn't good (and causes warnings). This
just static_asserts that they are padding-free instead, which is the
intention.
This code was too convoluted not to fix.
- There are 5 linear searches done over 2 vectors (without any changes
done to the vectors in between).
- One of the linear searches calls out to epee to convert the same value
to a hex string for every element.
- Both a set and a map are used here with identical key contents. The
old code looks like it only conditionally adds to the map if it finds
a match in the loop, but the for loop is doing exactly the same test
as the `find_if` that guards the entire `else if` containing it, so it
will *always* match.
- Removed some error code that can never actually run (because of the
above set/map equivalence).
The default copy and move constructors would be broken and dangerous;
delete the copy ctor and provide a usable move ctor. Also explicitly
delete copy and move assignment (they are implicitly deleted already but
making this explicit signals intent).
We can also save a bit of indirection by storing the BlockchainDB
reference directly rather than the Blockchain (which isn't needed except
to get the db).
Also remove the `m_active` variable: the two bools here are doing
nothing that a single m_batch bool can't do.
The only difference between long and short is one string (the json
info).
Also remove std::endl because using it like this indicates that the
author doesn't understand what std::endl is for.
Also removed a completely ridiculous inline lambda.
Pool printing is separately implemented in rpc_command_executor; this
method in tx_pool is both obsolete (missing some fields) and not called
anywhere.
There is nothing gained at all by trying to pad the data to an even
multiple of 1024 but it adds quite a lot of complexity (which would get
worse with blink). Just adding some 0-1023 random bytes prevents
traffic analysis just as well and considerably simplifies the code.
This adds a thread-local, pre-seeded rng at `tools::rng` (to avoid the
multiple places we are creating + seeding such an RNG currently).
This also moves the portable uniform value and generic shuffle code
there as well as neither function is specific to service nodes and this
seems a logical place for them.
We don't impose any alignment on hashable types, but this means the
hashing function is doing invalid misaligned access when converting to a
size_t. This aligns all of the primitive data types (crypto::hash,
public keys, etc.) to the same alignment as size_t.
That cascades into a few places in epee which only allow byte spanning
types that have byte alignment when what it really requires is just that
the type has no padding. In C++17 this is exactly the purpose of
std::has_unique_object_representations, but that isn't available (or
even implementable) in C++14 so add specializations for the type that
need it to tell epee that we know those types are properly packed and
that it can safely use them as bytes.
Related to this, monero/epee also misuses `is_standard_layout` when the
purpose is actually `is_trivially_copyable`, so fixed that too. (You
need the latter but don't need the former for a type to be safely
memcpy'able; the only purpose of `is_standard_layout` is when you need
to be sure your structs are compatible with C structs which is
irrelevant here).
Removes one unnecessary layer of templated indirection in kv
serialization, and removes use of boost::mpl::vector code generation.
Also removes a double-specification of the same type in the epee
array_entry specification.
This allows the caller to also take the response by rvalue reference so
that they can move outsubvalues. The rvalue is totally fine here (once
the callback is invoked it is never used again) and still binds
perfectly well to const-lvalue accepting callbacks.
Neither of these have a place in modern C++11; boost::value_initialized
is entirely superseded by `Type var{};` which does value initialization
(or default construction if a default constructor is defined). More
problematically, each `boost::value_initialized<T>` requires
instantiation of another wrapping templated type which is a pointless
price to pay the compiler in C++11 or newer.
Also removed is the AUTO_VAL_INIT macro (which is just a simple macro
around constructing a boost::value_initialized<T>).
BOOST_FOREACH is a similarly massive pile of code to implement
C++11-style for-each loops. (And bizarrely it *doesn't* appear to fall
back to C++ for-each loops even when under a C++11 compiler!)
This removes both entirely from the codebase.
This adds a tx extra field that specifies an amount of the tx fee that
must be burned; the miner can claim only (txnFee - burnFee) when
including the block.
This will be used for the extra, burned part of blink fees and LNS fees
and any other transaction that requires fee burning in the future.
This is the bulk of the work for blink. There is two pieces yet to come
which will follow shortly, which are: the p2p communication of blink
transactions (which needs to be fully synchronized, not just shared,
unlike regular mempool txes); and an implementation of fee burning.
Blink approval, multi-quorum signing, cli wallet and node support for
submission denial are all implemented here.
This overhauls and fixes various parts of the SNNetwork interface to fix
some issues (particularly around non-SN communication with SNs, which
wasn't working).
There are also a few sundry FIXME's and TODO's of other minor details
that will follow shortly under cleanup/testing/etc.
This was preliminary to support including v1 txes in sweeps, but we
didn't actually build the support and elected instead to effectively
just burn those txes.
uint64_t values above max int64_t (which are used in blink quorum
checksums) were failing because we were deserializing too early.
Also fixes a couple related out-of-date comments.
The owning pointer is stashed in a unique_ptr so that it gets properly
destroyed; everything else gets a plain pointer to it.
(Ideally it would be std::optional instead, but that's not until C++17)
This tweaks uptime proofs to go out on the first timer tick in the
58.5-62.5 interval (rather than 60-65) which should result in proofs
usually being very close to the 60 minute mark. (Currently a fair
percentage end up at the 65m mark because the timer fires just before
the 60m mark).
It also tweaks the first uptime proof to go out after 2 minutes instead
of 5 minutes, and uses separate constants
(UPTIME_PROOF_INITIAL_DELAY_SECONDS, UPTIME_PROOF_TIMER_SECONDS) for
times that were previously overloading the
UPTIME_PROOF_BUFFER_IN_SECONDS constant.
For debugging this also adds a cmake option LOKI_DEBUG_SHORT_PROOFS
that, when enabled, makes the whole proof cycle (sending and acceptance)
20x faster, which is very useful for local testnet debugging.
Currently we store it as various different things: 3 separate ints, 2
u16s, 3 separate u16s, and a vector of u16s. This unifies all version
values to a `std::array<uint16_t,3>`.
- LOKI_VERSION_{MAJOR,MINOR,PATCH} are now just LOKI_VERSION
- The previous LOKI_VERSION (C-string of the version) is now renamed
LOKI_VERSION_STR
A related change included here is that the restricted RPC now returns
the major version in the get_info rpc call instead of an empty string
(e.g. "5" instead of ""). There is almost certainly enough difference
in the RPC results to distinguish major versions already so this doesn't
seem like it actually leaks anything significant.