This updates the coinbase transactions to reward service nodes
periodically rather than every block. If you recieve a service node
reward this reward will be delayed x blocks, if you receive another
reward to the same wallet before those blocks have been completed it
will be added to your total and all will be paid out after those x
blocks has passed.
For example if our batching interval is 2 blocks:
Block 1 - Address A receives reward of 10 oxen - added to batch
Block 2 - Address A receives reward of 10 oxen - added to batch
Block 3 - Address A is paid out 20 oxen.
Batching accumulates a small reward for all nodes every block
The batching of service node rewards allows us to drip feed rewards
to service nodes. Rather than accruing each service node 16.5 oxen every
time they are pulse block leader we now reward every node the 16.5 /
num_service_nodes every block and pay each wallet the full amount that
has been accrued after a period of time (Likely 3.5 days).
To spread each payment evenly we now pay the rewards based on the
address of the recipient. This modulus of their address determines which
block the address should be paid and by setting the interval to our
service_node_batching interval we can guarantee they will be paid out
regularly and evenly distribute the payments for all wallets over this
We could get a rounding error in the contributor spots that would make
the registration fail when passed to oxend. This fixes it by restoring
the missing logic that was accidentally dropped in the
prepare_registration refactor.
Testnet has shown that it is virtually impossible to route around a
checkpoint for a block that had to be rendered unacceptable because it
accepts the future checkpoint which then prevents an alternate block
from being generated at all.
This mitigates it in two ways:
- Don't accept new checkpoint votes before we receive the block
- Delay checkpoint voting & vote distribution by one block (e.g. nodes
will vote on block 12345 only once 12346 is received).
The first allows a manual pop_blocks to remove checkpoints that won't
get re-added (e.g. if the checkpointed block has become unacceptable, as
occurs sometimes in testnet/devnet, but could theoretically occur on
mainnet if we have to do a block reversal).
The second minimizes the number of rejected votes that will occur since
nodes will almost always have the block now when the checkpoint arrives.
Reorders the way questions are asked to flow better. Previously the way
questions was asked was sort of awkward.
The old order, for instance staking a partially open node:
- entire stake?
- fee?
- reserve more?
- how many more?
- operator address?
- operator stake size?
- contributor address?
- how much for contributor?
- more contributors, if any
- not filled okay?
- confirm everything?
where there are related values (e.g. operator addr & stake) intermingled
with around other things (e.g. fee & number of contributors).
With this commit the order is rewritten to:
- operator address?
- entire stake?
- operator stake size?
- fee?
- reserve more?
- how many more?
- contributor 1 addr
- contributor 1 amnt
- more contributors, if any
- not filled okay?
- confirm everything?
Additional changes:
- substantially DRY out the code. There was a huge amount of repeated
code in this section.
- highlight OXEN amounts in cyan.
- I rewrote much of the language to make it clearer and more grammatical
- reformatted the summary table to look a bit better
- the fee in the final summary is highlighted yellow.
- if there are multiple open spots this is now more clearly indicated in
the output and the final summary screen.
Example:
```
$ oxend prepare_registration
2022-04-15 20:11:29.211 I Oxen 'Audacious Aurochs' (v9.2.0-0b38bd982-dev)
Current staking requirement: 15000 OXEN
Enter the OXEN address of the Service Node operator (C/Cancel):
LDoptfyQB3YHbS9cnt2wHdTTj2wtZGPuM48evCFwZpomVajQw4eJ6mDCpXeUNTxsqbTiYytnqEDQNin3XGwp3nReMooMaWG
Will the operator contribute the entire stake? (Y/Yes/N/No/B/Back/C/Cancel): n
The operator contribution must be between 3750 OXEN and 15000 OXEN to meet the staking requirements.
How much OXEN does the operator want to stake? (B/Back/C/Cancel): 5555
Enter operator fee as a percentage of earned rewards [0-100]% (B/Back/C/Cancel): 4.567
Do you want to reserve stakes for specific contributors? (Y/Yes/N/No/B/Back/C/Cancel): y
Number of additional contributors [1-3] (B/Back/C/Cancel): 2
Enter the OXEN address of contributor 1 (B/Back/C/Cancel):
L6JasonXTGW6juHrJgsXTxXH1Jh9u94H8NQ9m4rMwz5a9SZGr2e1cXw9MqnVH6Qx5bTgL5wf7qfvHeNPdwyC63AzMixU5ad
The next contribution must be between 3148.333333333 OXEN and 9445 OXEN to meet the staking requirements.
How much OXEN does contributor 1 want to stake? (B/Back/C/Cancel): 5555
Enter the OXEN address of contributor 2 (B/Back/C/Cancel):
L7jC35E9MnQZu2dS1n8wCqbvVBFpGHJt7iNHgAuEy5is57dzX2uQZDASv4KvwzruxXARxa4omafN6i19QBY7KAcSH1Xz7ZL
The next contribution must be between 1945 OXEN and 3890 OXEN to meet the staking requirements.
How much OXEN does contributor 2 want to stake? (B/Back/C/Cancel): 3000
Total reserved contributions: 14110 OXEN
The total reserved amount (14110 OXEN) is less than the required full stake (15000 OXEN).
The remaining stake (890 OXEN) will be open to contribution from 1 public contributor.
The Service Node will not activate until the full contribution has been filled.
Is this acceptable? (Y/Yes/N/No/B/Back/C/Cancel): y
Registration Summary:
Operator fee (as % of Service Node rewards): 4.567%
Contributor Address Contribution Contr. %
_____________ _____________ _________________ ________
Operator LDoptfyQB..WG 5555.000000000 37.03%
Contributor 1 L6JasonXT..ad 5555.000000000 37.03%
Contributor 2 L7jC35E9M..ZL 3000.000000000 20.00%
(open) (any) 890.000000000 5.93%
Is the staking information above correct? (Y/Yes/N/No/B/Back/C/Cancel):
```
For a open node with 3 open spots the summary table looks like this:
```
Contributor Address Contribution Contr. %
_____________ _____________ _________________ ________
Operator L6JasonXT..ad 6789.000000000 45.26%
(open) (any) >=2737.000000000 >=18.25%
(open) (any)
(open) (any)
```
- The decimal point argument isn't used anywhere.
- change `get_unit()` to return `OXEN` instead of `oxen`
- Add a "strip_zeros" option to print_money that lets you remove
trailing insignificant 0's from the returned amount.
- Add format_money that does print_money (with 0s stripped by default) +
get_unit(). E.g. it returns `"45.67 OXEN"`.
When I issue a `prepare_registration` command the cursor gets positioned
at the beginning of the line instead of the end of the line, so typing
things in results in overwriting the text that I was asked.
E.g.:
```
Current staking requirement: 15000.000000000 oxen
yill the operator contribute the entire stake? (Y/Yes/N/No/C/Cancel):
`-- the y I typed replaced the "W"
```
or:
```
Enter the oxen address for the solo staker (B/Back/C/Cancel):
```
and because the cursor is positioned at the beginning, my address
overwrites the prompt as I type/paste it:
```
L6JasonXTGoxen address for the solo staker (B/Back/C/Cancel):
```
This is caused because we were suspending the readline buffer *after*
printing things out, and something (perhaps local config, or perhaps an
update to libreadline) repositions to cursor at column 0.
This commit suspends the readline handler *before* we print the message,
which makes it sane again:
```
Enter the oxen address for the solo staker (B/Back/C/Cancel): L6JasonXTG
```
Remove misc_language.h: Half of it is unused, half of it is crap doesn't
need to be used, and the two useful things (median calculator and a
scope exit caller) were poorly written.
Rewrote median from scratch and moved it out of epee.
Simplified the scope exit handler and moved it to its own small header
in epee.
openssl is a miserable dependency to fight with, especially for
iOS/Android, and we use it for very little:
- it gets (mis)used to write base64 data to a file in wallet2 for things
like multisig data. However this mode is *not* enabled by default,
basically completely unknown, completely unused, only exists in the
cli wallet, and is just dumb. (Honestly the justification given in
the PR is that "Windows users might want it", presupposing that there
exists Windows users who are capable of generating a multisig wallet
in a CLI-only application and yet are incapable of dealing with binary
files).
- it's a dependency of unbound (in order to do dnssec, I believe).
Unbound itself is fairly useless for Oxen, so I've removed it too:
- it does OpenAlias lookups, which are a Monero thing that has never
been used outside Monero, doesn't work reliably (because it fails
if the result isn't DNSSEC validated) and is pointless when we
have ONS.
- it does DNS resolution on seed nodes, but we have never set seed
nodes by name and just use seed node IPs instead (which seems a
bit better anyway since the DNS lookup leaks some metadata).
- it *was* being used for sha256, but an earlier commit in this PR
already replaced that with libsodium (entirely coincidentally).
- for static deps, it enables HTTPS support for the wallet. However
only the CLI wallet actually supports this (the GUI and mobile wallets
don't), and since oxend hasn't support this for a while I have strong
doubts it is being used anywhere. (Plus wallet3 will do everything
encrypted using zmq/libsodium, so doesn't need this to be secure).
Note here that it is *only* removed by this commit for static builds:
if doing a system build that links to libcurl supporting HTTPS then
HTTPS support will still work.
Libexpat is also gone because it was only there for libunbound.
- bump libusb version
- build hidapi using cmake (autoconf is deprecated, and doesn't properly
set up the required linking on Windows)
- pass through toolchain
- zmq/win32 compilation fix
static inline functions in headers are pointless and wasteful in C++,
and are the C equivalent of a plain inline function in C++. Make them
merely inline instead.
- Aside from converting code, this commit also:
- Cleans out a bunch of epee garbage that this code touches.
- Removes some of the wipeable_string usage from wallet2 added by
upstream Monero, because that usage was worse than useless: every
instance removed uses a wipeable_string but then *copies the value
into a std::string*, which makes the entire thing useless.
It is, however, *worse* than useless because it is deceptive: a casual
observer would think that the values are being wiped, when in
actuality it only added an extra intermediate buffer that gets wiped
while the final destination doesn't. This deception is worse than
nothing, and so I've removed it.
- Removes epee md5 code. It is entirely unused, and was depending on
the removed hex code.
- Removes a bunch of useless functions from
epee/storages/parserse_base_utils.h: in particular the
exception-to-bool wrappers were only being used in the test suite
(which was dumb: the test suite is perfectly capable of a "does not
throw" assertion).
- De-templatizes the parsing code in parserse_base_utils.h that was only
ever called with a `const char*` "It" (except for one place in the
test suite was which easily fixed), and moved the implementation into
a .cpp file.
We have disabled uPnP by default for nearly a year now (#1423) with no
adverse affects; this commit finishes it off entirely, removing it from
the codebase.
Fixes#1419 -- see discussion in that issue for why UPnP really doesn't
add much utility to Oxen.
All the encoding parts move to oxen-encoding recently; this updates to
the latest version of oxen-mq, adds oxen-encoding, and converts
everything to use oxenc headers rather than the oxenmq compatibility
shims.
This is currently returning all contributions in all service nodes you
are staked to, which causes the mobile wallet to list everyone's stakes
in multi-contribution service nodes as your own.