Some of the keys here are executable and have very screwed up line
endings (not just Windows line endings, but "\r\r\n" at the end of every
line.
Fix line endings, and make all keys non-executable.
Some of the keys here are executable and have very screwed up line
endings (not just Windows line endings, but "\r\r\n" at the end of every
line.
Fix line endings, and make all keys non-executable.
(Merged from various earlier blink test commits)
These tests spin up a network of nodes, mining, registering service
nodes, then send blink txes in various ways across them testing that
blinks work as expected and that various potential scenarios blink is
designed to protect against are actually prevented.
The tests use python to spool up nodes and wallets, and require python3
with pytest and requests installed. Tests can be run manually with:
cd tests/network_tests
pytest-3
or with moderately and much more verbose output of operations with:
pytest-3 -v # Shows individual test cases
pytest-3 -vv # Same, but also spews tons of output on failures
pytest-3 -svv # Show the verbose output live (even on success)
It gets added to the default testing suite (assume the python requisites
are installed), though in very non-verbose form.
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.
This replaces the horrible, horrible, badly misused templated
once_a_time_seconds and once_a_time_milliseconds with a `periodic_task`
that works the same way but takes parameters as constructor arguments
instead of template parameters.
It also makes various small improvements:
- uses std::chrono::steady_clock instead of ifdef'ing platform dependent
timer code.
- takes a std::chrono duration rather than a template integer and
scaling parameter.
- timers can be reset to trigger on the next invocation, and this is
thread-safe.
- timer intervals can be changed at run-time.
This all then gets used to reset the proof timer immediately upon
receiving a ping (initially or after expiring) from storage server and
lokinet so that we send proofs out faster.
Blockchain::prepare_handle_incoming_blocks locks m_tx_pool, but uses a
local RAII lock on the blockchain object itself, then also starts a
batch. Blockchain::cleanup_handle_incoming_blocks then also takes out a
local RAII blockchain lock, then cleans up the batch.
But the lmdb layer is retarded in that it throws an exception if any
thread tries to write to the database while a batch is active in another
thread, and so the blockchain lock is *also* used as a guard writes.
Holding an open batch but *not* holding the blockchain lock then hits
this exception if a write arrives in another thread at just the right
time.
This is, of course, terrible design at multiple layers, but this close
to release I am reluctant to make more drastic fixes.
Other small changes here:
- All the locks in `blockchain.cpp` now use tools::unique_lock or
tools::unique_locks rather than the nasty epee macro. This also
reduces the likelihood of accidental deadlock because this means the
dual txpool-blockchain locks are not taken out simultaneously via
std::lock rather than sequentially.
- Removed a completely useless "if (1)". Git blame shows that there was
previously a condition here, but apparently the upstream monero author
who changed it was afraid of removing the `if` keyword.
- Reduced the sleep in the loop that waits for a batch to 100ms from
1000ms because sleeping for a full second for a fairly light test is
insane.
- boost isn't happy calling boost::lock() on the tx pool or blockchain
object because the lock/unlock/try_lock methods are const, and so the
workaround of using boost::lock because std::lock and
std::shared_time_mutex are broken on the macOS SDK 10.11 that we use
for mac builds now requires extra workarounds. Joy.