Commit graph

62 commits

Author SHA1 Message Date
Calin Culianu
eba8431a0b
API nit: Use Util::AsyncOnObject everywhere instead of QTimer::singleShot
This is just to make the API easier to follow. Also cleaned up
AsyncOnObject to not default to caarse timer unless the interval is
>2000 msec.

Also we use QMetaObject::invokeMethod() directly by default if the
AsyncOnObjectCall() has when_ms <= 0 (default).

This should have no real observable change on app behavior other than
being a code cleanup & nit.
2026-08-03 23:45:42 -05:00
Calin Culianu
acd2685433 PeerMgr: Throttle new connections in process()
This fixes issue #324. We throttle the creation of new connections to max 10 per second, and
we also impose some additional logic on windows to pause the creation of new connections if
the windows object count exceeds 5000, or the active client connections in PeerMgr exceed 50.

For non-windows we just limit active client connections in PeerMgr to 200 before we pause.

This should avoid future unforeseen issues on all platforms, but definitely also fixes the
actual issue we have seen with Windows (issue #324).
2026-04-22 12:00:54 -05:00
Calin Culianu
cd513f65a0
Bump copyright year to 2026
Used a sed script to do it.
2026-02-09 10:55:22 -06:00
Calin Culianu
057bacd552
Got rid of UNLIKELY/LIKELY macros in favor of C++20 [[likely]]/[[unlikelu]]
Also in this commit: Some small nits and 1 comment typo fixed
2025-11-05 22:44:56 +02:00
Calin Culianu
c76b9a5897
Fix a compile error on gcc: explicit specialization in non-namespace scope 2025-10-26 09:43:41 +02:00
Calin Culianu
6ba09bfc41
Redid broadcast_package to do some work in an asynch thread
We validate args in an asynch thread since that is potentially costly
(we must hash the first txn, etc).

When that's done, we forward request to bitcoind.

This required us allowing generic_do_async to accept an optional
"completion" function. In order to make things cleaner and faster we
templatized ServerBase::generic_do_async, and redid its internals
slightly. Hopefully this is cleaner and also hopefully redundant copies
of e.g. std::function are avoided with this template implementation.

Also in this commit: Various nits and fixups in Util.h, added
ThrowInternalErrorIf() macro, and other misc. cleanup.
2025-10-26 09:35:01 +02:00
Calin Culianu
e0c31f0e11
Added a mechanism to detect unclean shutdown conditions
This mechanism depends on the use of a 'latch' file in the datadir
which is created on startup and deleted on clean shutdown. If the file
is found to already exist when it is about to created, a flag is set and
storage uses this flag to know to take some corrective action.

Storage undoes latest block if the unclean shutdown flag is set, as a safety
measure, even though rocksdb guarantees should make this superfluous. Just
in case, it would be safer to undo the latest block in such a situation, if
such a thing is possible, for belt-and-suspenders.

Also in this commit:

- Added a new log type; Alert(), which has bright magenta text and is
  slightly above a Warning but below an Error
- Various small nits and fixups
2025-09-17 09:06:53 -05:00
Calin Culianu
1e864e4603 Moved some Util-related tests to new file, Util_tests.cpp + add endian ops + refactor
- Added ability to declare benches with macros in test/Test.h
- Moved all the tests in Util.cpp to a new file, test/Util_tests.cpp
- Converted extant bench and tests to newer macro-based format
- Moved the private endian ops that lived in RecordFile.cpp into Util.h
- Added tests for the endian ops to Util_tests.cpp
2025-08-31 23:19:05 -05:00
Calin Culianu
2031a7879a Increased default db_mem to 1GiB from 512MiB (if unspecified)
It's time. Several years have passed since the original default of
512MiB was determined, and hardware now is even better and it should not
be uncommon to have a 2GiB or above machine. It has been observed that
more db_mem means better performance overall, so we want to be greedy
here. 1 GiB should be a good default for most installs.

Note that we try to not be too greedy and not take up more db_mem than
25% of what the machine reports as having as total physical RAM. We also
don't default to anything less than 512MiB (the older Fulcrum default).
2025-08-31 23:19:05 -05:00
Calin Culianu
94a97ad03d
Update copyright year to 2025 2025-03-20 21:21:56 -05:00
Calin Culianu
2eccf4aa31
Added UPnP support
Default off. Enable with CLI arg --upnp or conf variable upnp=1

Still need to:

- Get the static builds to statically include libminiupnpc
- Update the example config(s) to talk about this option
2025-03-20 09:14:06 -05:00
Calin Culianu
6bfae6193b
Introduce "thread internal name" mechanism for logger, and use it
The existing way we were logging thread names was to query the
QThread::currentThread() object name. But this is not thread safe
because the QThread::currenntThread() object may not be "living in" the
current thread! As such, this could lead to crashes in some cases (in
particular with the CoTask).

Instead, we introduce the concept of a "thread internal name" with
getters/setters in the Util::ThreadName namespace.

All ThreadObjectMixins and other thread objects in the app explicitly
must set their thread name when they are running, and the logger picks
up the name.

The thread names live in TLS and are thread-safe.
2024-06-09 00:08:23 +03:00
Calin Culianu
c1d511b7d6
Converted more templates and SFINAE to C++20 requires/concepts
Hopefully this is more readable going forward.
2024-06-07 01:13:43 +03:00
Calin Culianu
2d14478278
win32: Query the number of physical and virtual cores properly
We were using std:🧵hardware_concurrency() on Windows which
doesn't return the number of physical cores properly. Instead, we
directly call into win32 API to get this information now.
2024-06-05 22:54:28 +03:00
Calin Culianu
8d1b397ca8
Update Copyright year for all source files 2024-05-21 01:35:13 +03:00
Calin Culianu
6dc265af7a
Util.cpp, make RenderHostPortPair check for ret.isEmpty()
Rather than .isNull(), which may be false even for an empty string.
A string may be empty but not null. :/
2024-05-03 06:28:04 +03:00
Calin Culianu
3d16caaeec
IPv6: Render "ip6:port" as "[ip6]:port". Also accept this notation from conf file.
This closes #242.

Summary of changes:

- Fulcrum will optionally also be able to parse IPv6 addr:port strings
  from the conf file: "[2001:44b8:315f:bc00:1f7b:dcc3:8823:722d]:60000".
  Note that bracket-less strings e.g. "2001:44b8:315f:bc00:1f7b:dcc3:8823:722d:60000"
  will also continue to work (to preserve backward compat.).
- `FulcrumAdmin clients` (aka `FulcrumAdmin sessions`) will now render
  client host:port pairs in the table with brackets for IPv6.
- /stats HTTP endpoint will also render client IPs in this way for IPv6.
2024-04-17 17:55:23 +03:00
Calin Culianu
4aa8f841b2
Add RPA Support (#234)
* Start adding RPA files.
* Update Servers.h -- add batchid for rpc methods
* Update Servers.cpp -- add batchId to RPA methods
* Update Servers.cpp - add batchId params to generic async
* Add key 'rpa' to features map to quell client-side warnings
* Code quality fixups and make it compile on latest clang

It wasn't compiling at all on latest clang. Also in this commit some
code quality fixups and nits, and avoid some double-copies.

Also added additional unit testing of prefixSearch & remove functionality.

* fix bug

* add some sloppy testing code for debug of client

Also in this commit: Add files missed by previous merge

* Optimize ReusableBlock::serializeInput to be faster

This should help reduce CPU usage on initial synch and in general.

We added a facility to hash bitcoin objects "in-place", rather than what
we were doing before which was serializing them then hashing the
serialized bytes.

* Refactor

- Move the serialization stuff into the .cpp file to avoid header noise
  and speed up compilation.
- Add the trie map thingie into the headers for Fulcrum.pro
- Misc. other small nits

* Added utility class PackedNumView

We will need this later for our new rpa data storage technique.

* Added the `Rpa` module

This will replace the facilities in `ReusableBlock.cpp` & `.h`.

Also ported over the unit tests from `ReusableBlock` to this `Rpa`
module.

* Tweak to support PackedNumView of 32-bits

* Made Rpa::PrefixTable support a read-only "view" into serialized data

We will need this in order to quickly be able to read from the DB
without too much allocation or other processing to service requests.

Also in this commit:

- Updated unit tests
- Modified GenericVectorReader: added GetPos() and seek() methods

* Rpa::PrefixTable ser/deser error path tweak

Improved exeption messages and added paranoia check(s)

* Some tweaks and additional in-code comments

Small refactoring tweaks to the Rpa namespace classes and some small
amounts of comments added to document the intention behind the code better.

* Small perf. tweak for BTC::Hash2ByteArrayRev

And also added some unit tests for various functions we touched/added
recently.

Also a small nit/refactor in Rpa.h

* Removed Jt's Trie-based implementation, swapped in my own

Also added some tests and other refactorings.

Still TODO:

- Mempool handling
- Options handling to enable/disable this index
- Finish TODOs in comments
- Lots of other stuff like maybe an asynch indexing of RPA in the
  background for servers that are already "up"

* Made Rpa logging less verbose by default

* Allocate DB memory property for RPA (don't exceed db_mem)

Also in this commit, some nits.

TODO: If RPA index is disabled, give the memory back to scripthash_unspent and
utxoset (which is where we took it from).

* Fixed hex parsing bug for blockchain.reusable.* RPCs

Turns out our Prefix(uint16, uint8_t) c'tor was buggy due to misplaced
parens, so RPC was broken. Fixed.

Also added unit tests to test this case as well as others.

Also added some perf logging for dev (to be removed later) to the guts
function that does the work for blockchain.reusable.get_history.

* Nit

* Tweaks to unit tests

* Added better profile printing for debug, plus 1 nit

* Fixed arg parsing for blockchain.reusable.get_history

* Added come conf file args for RPA, renamed RPC methods, raised min prefix to 8 bits

Conf file args to control various RPA aspects (min prefix, max history,
etc) were added.

Also, renamed blockchain.reusable.* -> blockchain.rpa.*. The old
blockchain.reusable names are still supported but are deprecated.

We raised the min prefix to 8 bits because 4 is too small and leads to
heavy-ish server load on some queries.

We also set the number of blocks one can scan with
blockchain.rpa.get_history to a limit of 60 by default (configurable),
to make for small and light queries to the server.

* Removed unused #include

* Added MempoolPrefixTable

Will be used by the mempool. Still needs tests.

* Simplified MempoolPrefixTable (it doesn't need 2 associative containers)

* Hooked RPA into Mempool; works.

Also added "tests" in the mempool bench to use it.

* Added some more MempoolPrefixTable unit tests

* Added more logic to Storage and Controller to handle RPA

- added an "auto" mode that is auto-on for BCH, off for every other coin
- user can override this auto mode (which is the default) with a cli or
  conf file arg
- misc nits and fixups

Still more to do in this regard.

* Added rpa_start_height conf option

Suppress indexing until this height. Defaults to -1 which means
"Automatic" and is height 825,000 for mainnet, 0 for all other nets.

* Tweaks to RPA max history code

- Re-use the history-too-large lambda mechanism we use in getHistory()
- Have rpa_max_history inherit max_history if max_history was specified
  and rpa_max_history was not (since this is what users might expect).

* Refactor and fixups to getRpaHistory()

Made the RPC to blockchain.rpa.get_history take params in the same
from,to way as blockchain.scripthash.get_history.
blockchain.reusable.get_history still works like the old way.

Neither of them return mempool (unlike *.scripthash.get_history).

Also switched the getRpaHistory() function to use a rocksdb iterator to
scan records in sequence, since this should in theory be faster than
individual O(log N) db gets.

Also other minor fixes.

* Tweak to getRpaHistory()

Just forward the iterator 1 item at a time since it should be faster.
Also refine the logic to not append mempool unconditionally if we didn't
hit tipHeight in the confirmed scan (branch not currently used).

* Optimized PackedNumView deserialization

Use built-in byteswap functions rather than looping and doing it
ourselves. Should be faster.

* Optimized PackedNumView::Make

Leverage byteswap calls that are possibly-no-ops is host and destination
byte order match, and even if they don't, should be faster anyway than
our hand-crafted loops that achieve same.

* Added some Rpa stats tracking in Storage.cpp

And also loading the DB now does faster checks.

Still todo: use firstHeight and lastHeight from DB to decide if/how to
(re)synch the index on app startup.

* Fleshed out the initial check of the RPA db more, still more to do.

We need to now have a way to synch the index separately in Controller..
and handle all corner cases that may arise.

* Fixes and nits, mainly in loadCheckRpaDB

* Small nits and header cleanup

* Added method getRpaDBHeightRange to Storage

May be useful later for the Controller.

* wip

* Refactored code that puts RPA data into DB into a function

It's now in Storage::addRpaDataForHeight_nolock, since it does some
defensive sanity checking.

* Added 2 fields to RpaOnlyModeData

* Got RPA index sync independent of block sync working

It needs work in recovering from DL failure and other corner cases but
it basically works.

* Solved the last of the consistency corner cases on RPA index synch

I'm pretty sure we are solid now and the RPA index eventally synchs
separate of the general block download on config change. Meaning users
get a decent experience with the index if they play with enabled/disabled
toggling.

* Bumped version to 1.10.0

This is due to the addition of the RPA index facility.
Also bumped protocol version to 1.5.3 due to addition of new RPA
RPCs.

* Fixed percent display for RPA Index synch

It really should be a percentage of the current download progress and
not a full blockchain percentage as the normal blocks synch is.

Fixed.

* Corrected a debug string message

* Took the bitcoin byte swap functions out of the `bitcoin` namespace

This is because on some platforms they are actually #defines to some
global thing, so eg `bitcoin::htole16` was failing to compile on such
platforms.

* Fixed some compile issue on Ubuntu 22

GCC-11 + Qt5 didn't like some of the stuff we did in recent commits.
Fixed.

* Fixed a failing test: `rpcmsgid` for Linux

* Follow-up

* Disabled the rpa subscribe/unsubscribe RPC methods (for now)

They are unimplemented anyway and no clients use them (for now).

* 2 nits

* Fixed a potential bug

* Renamed a /debug endpoint key

* Some rename rpa_history_blocks_limit -> rpa_history_blocks

And also some other minor tweaks. Mostly a renaming/nit commit.

* A small refactoring of some boilerplate

* Added docs for RPA options to example conf file in docs/ dir.

* Made the rpa.get_history call use [from, to) (exclusive) range

This is more akin to how existing calls operate.

Also updated the electrum-cash-protocol submodule pointer to latest.

* Updated electrum-cash-protocol submodule pointer

* Update to electurm-cash-protocol module copyright

* Got rid of some dead code and updated some comments

* Corrected a comment

---------

Co-authored-by: = <=jonaldfyookball@outlook.com>
Co-authored-by: fyookball <jonaldfyookball@outlook.com>
Co-authored-by: blockparty <hello@blockparty.sh>
2024-03-04 02:16:27 +02:00
Calin Culianu
40a27ed7ac
Made Windows also print color if stdout is a tty
Figured out how to do it. Windows 10 now has some calls to enable VT
terminal interpretation of escape codes, so we can try them at
ConsoleLogger class construction.

Also in this commit: For UNIX systems, don't call isatty() over and over
again, call it once and save the result in a class variable for
ConsoleLogger class. (Slight perf. benefit here).

Additionally, don't use std::cerr/std::cout but use cstdio fwrite
to write to stdout/stderr because it's significantly faster.
2023-11-06 23:05:41 +02:00
Calin Culianu
7689402ec3
Add the query subcommand to the FulcrumAdmin script. (#166)
This closes #165. It allows the user to use a new `query` verb with `FulcrumAdmin`, 
similar to how it works on elextrumx_rpc.
2023-04-07 20:12:16 -04:00
Calin Culianu
baf9acd303
Bumped copyright year to 2023 2023-03-21 10:19:55 -05:00
Calin Culianu
52a3cc1b42
Ensure signal handler really is 100% async signal-safe
- We were entering a "try" block in our signal handler (and potentially throwing).
  According to cppreference this is NOT async-signal-safe.
- We were accessing a static storage variable not wrapped in an atomic (the
  _globalInstance variable). Again, according to cppreference this is not
  strictly permitted.

As such, we made App::_globalInstance be an atomic pointer, and we made sure that
our low-level Sem::acquire and Sem::release can never throw (they instead
return an error string if there should happen to be an error).
2022-09-19 23:51:27 -05:00
Calin Culianu
cfce15f2a3
Added more thorough merkle test, fixed a bug for Log::Color::BrightGreen
We added a more thorough unit test for the Merkle functions, which
verifies the branch as well against a real block's txns.

Also, BrightGreen had the wrong vt100 code, fixed.

Also made benches and tests display color-coded titles for each test to
more visually separate them.
2022-09-18 11:46:31 -05:00
Calin Culianu
d24a02c1bf
Updated Copyright to 2022 2022-02-03 03:34:32 -06:00
Calin Culianu
e0ddc123a2
Add new experimental option: --fast-sync + upgrade robin_hood to 3.11.15 (#98)
This new option (default disabled) only takes effect on initial sync. The option can be
specified either via CLI as --fast-sync <MB> or in the conf file as fast-sync = <MB>. 
Where <MB> is a value in megabytes (minimum: 200, maximum: machine available 
physical RAM). When enabled, and on initial sync only, a UTXO Cache will be 
created to store both TXO/TXOInfo pairs and scripthash_unspent DB adds/deletes.

Seem merge request description #98 for more details on this new feature.

Also in this commit: Updated robin_hood to 3.11.15 because previous version had
some bugs.
2022-01-24 20:51:30 -06:00
Calin Culianu
40a8a8698d
Imbue std::ifstream and std::istringstream with "classic" in Util.cpp
This is just a nit to avoid unexpected locale issues.
2022-01-19 12:22:44 -06:00
Calin Culianu
1e739ecae6
Fixups for compiling against Qt6
Codebase can now compile and run against Qt6 (as well as Qt5). Still
requires more testing, but so far it seems to work without a hitch.
2021-09-05 03:49:11 +03:00
Jonny Heggheim
ad036744f1
Removed dead code (#88)
* Removed function Util::getPlatformMinimumThreadStackSize() + PLATFORM_STACK_MIN
* Forgot to remove the declaration of getPlatformMinimumThreadStackSize
2021-08-08 12:16:01 +03:00
Calin Culianu
7242e3edea
Add DSProof feature: New RPC methods plus code cleanup / refactoring (#74)
- Adds 4 new RPC methods:
  - `blockchain.transaction.dsproof.list` (0 args): returns a list of txids 
    that have dsproofs or for which in-mempool ancestors have dsproofs.
  - `blockchain.transaction.dsproof.subscribe` (`txHash` arg): subscribe 
    for dsproof notification on an in-mempool `txHash`. If `txHash` has a 
    dsproof now, or it gets one in the future, or if the dsproof status 
    changes, then a JSON-RPC notification will be sent (similar in spirit to 
    `blockchain.scripthash.subscribe`). The notification is either `null` for 
    no dsproof, if there is a dsproof then a dsproof JSON object similar in 
    structure to what the BCHN bitcoind RPC call `getdsproof` would return.
  - `blockchain.transaction.dsproof.subscribe` (`txHash` arg): Inverse of 
    above. Unsubscribe this client from dsproof notifications for `txHash`.
  - `blockchain.transaction.dsproof.list` (`txHash` or `dspid` arg): Get the 
    dsproof associated with a `txHash` (or lookup a dsproof by its `dspid`). 
    Returns a JSON object  similar in structure to what the BCHN bitcoind RPC 
    call `getdsproof` would return.

- Adds the following key to the `server.features` map:  **`dsproof`**. This 
  is a boolean which is set to `true` if the fulcrum server is connected to 
  a bitcoind that has the dsproof RPC. currently only BCHN 22.3.0 (unreleased) 
  has this RPC. It is set to `false` otherwise.  Note that `server.features` 
  maps may contain arbitrary optional keys, so this should cause no issues 
  with peers (ElectrumX and Fulcrum both follow the Electrum protocol spec here 
  and allow for optional additional keys).

- Additionally this PR contains a lot of refactoring to make the above possible, 
  as well as some code cleanup.

- The DSProof facility is optional and is auto-probed on (re)connect to bitcoind.  
  If bitcoind lacks dsproofs, the impact of the new code added in this PR is 
  asymptotically close to 0.  Even in rare pathological cases where bitcoind is 
  tracking many dsproofs, this new dsproof facility was designed with performance 
  in mind such that it can scale.
2021-02-23 16:39:43 +02:00
Calin Culianu
bc08115a18
Added ZMQ support for bitcoind "hashblock" notifications
This should significantly speed up the detection and processing of a new
block. Fulcrum now probes bitcoind for its ZMQ endpoints using the `getzmqnotifications`
RPC, and if it finds the "hashblock" notification, it then creates a
subscribe socket to the address/port that bitcoind advertises.

Requires Fulcrum be built with libzmq support enabled, as well as
running: BCHN, Core, ABC, or the upcoming BU 1.9.1 (not yet released).
2021-02-08 23:32:27 +02:00
Calin Culianu
e00c03171c
Added zmq support to the app, plus building zmq static in docker
- New class: ZmqSubNotifier which only does something if libzmq was
  enabled at compile-time
- Fulcrum.pro now tries to auto-detect libzmq using pkg-config (on
  unix). One can override this auto-detection with `LIBS=-L/path/to/zmqlibdir -lzmq`
- App now compiles-in the commit hash used to build it (Unix only).
  Auto-detected on unix only. On Windows the commit hash must be
  specified as a DEFINE.
- Added -v/--version CLI arg to print extended information about which
  libs the app was built against, including Fulcrum's own commit hash.
- Updated static docker builds to link-in a statically built libzmq
- App now prints what libs it contains / is using at startup to the log.
2021-02-07 01:07:28 +02:00
Calin Culianu
a0e3e05bcd
Updated Json lib from upstream; updated copyright year 2021-01-09 22:08:59 +02:00
Calin Culianu
5c6cb58b84
Misc fixes + update robin_hood (to fix memory leaks, one hopes)
- robin_hood updated to latest master 4869243035a2732fdb96407db234bdc7a3a985cc
- Use the new robin_hood::compact() call to shrink_to_fit our robin hood
  hash tables. This hopefully saves memory.  Note the new robin_hood.h
  did in fact fix a memory leak bug.  Hope this does it!
- Fixed an issue reported by Jonny Heggheim where build fails on rawhide
  due to missing <mutex> include in RecordFile.h. Went ahead and put the
  <mutex> include everywhere we use std::unique_lock
- Strictly enforce kNoCompression for all rocksdb table file levels
  (rocksdb sneakily tries to compress L1, L2, etc tables, it seems).
2020-12-09 15:07:48 +02:00
Calin Culianu
18c94ef5dc
Misc. nits and fixups
- WebSocket.cpp was doing UB unaligned int32 access, fixed
- Prefer QByteArray::constData() wherever possible (to prevent
  inadvertent detach). This didn't really matter, since in every place
  we were const-correct anyway -- this was more of a style nit.
- Added Merkle test and Merkle bench
- Expanded the txo test a bit to also test CompactTXO hashing as well as
  operator< on both TXO and CompactTXO
2020-12-08 12:57:09 +02:00
Calin Culianu
ba08ae926a
Made the mempool bench test much more accurate
But also slowed it down significnatly. It now takes a deep copy of the
TxRefs and after the "drop any tx" test runs, a second mempool is built
only via adds.  The two mempools ae depp-compared for equality (which
runs very slow, but at least it tests thoroughly).

Also in this commit:

- Added the Mempool::deepCompareEqual() function (very slow) for tests.

- Added the "Tic" class to stop having to write timing/profiling
  boilerplate code.  It manages taking a timestamp.

- Made the getTime*() functions noexcept

- Made the AsyncSignalSafe::writeStdErr function noexcept
2020-12-05 00:33:03 +02:00
Calin Culianu
5b68b48594
Feature: Support synching to Bitcoin BTC and serving Electrum (BTC) clients (#63)
This PR adds support for synching to Bitcoin Core and serving up data for
the BTC chain(s).  

- BTC vs BCH is auto-detected.  The app enters BCH mode or BTC mode 
depending on the bitcoind's useragent.
- The mode of the app is saved to DB on first synch and must match the 
remote bitcoind's mode on each connection to bitcoind.
- In order for us to enter BTC mode, the bitcoind useragent must match 
the regex: `^/Satoshi.*`, otherwise it is categorized as BCH, and we default to 
BCH mode.
   - This means that only Bitcoin Core (/Satoshi..) nodes are supported for
   BTC mode.
- SegWit tx's and blocks are now parsed correctly in BTC mode only.
- The `blockchain.address.*` RPC's only work in BCH mode.
- If the db says "BTC" and the bitcoind is detected as non-BTC (or vice-versa), 
the app complains and refuses to continue, exiting with an error message.
- Added seed peers files (`servers.json` and `servers_testnet.json`) for peering 
to BTC nodes. These were taken from latest Electrum master.  Peering works as 
expected on BTC, as it does on BCH.

Also in this PR, various fixups:

- Bumped version to 1.3.0.
- Made the app request the maximum number of open file descriptors on startup 
(Unix only).  It now also prints how many max open files it has detected to the Log.
- Miscellaneous code fixups.

---

Squashed Commits:

* wip

* wip - made synchmempool more efficient in both the btc and bch cases. yay!

* added btc servers.json

* tweaks - use hash ref in synchmempool, plus use easier to read code in transaction.h

* Added --btc option and ironed out logic for BTC vs BCH detection and paranoia. Plus more refactoring.

* Added support for peering to BTC servers

- Moved BCH servers.json into bch/ subdirectory
- Also added a key/value pair to the getinfo results for the active
  coin.

* Removed the "your client is vulnerable" messaging

It has been 2 years since the exploit -- and now that we are supporting
Electrum and potentiallu other clients with all sorts of version
numbers, the message may return false positives.

It has been disable and commented-out.

* Redid BTC vs BCH auto-detect logic, got rid of --btc CLI arg

The --btc CLI arg is superfluous.  We can just detect the coin based on
user agent.  Unknown user agents for bitcoind default to BCH.

This implies that we cannot use BTC with anything other than Satoshi as
the bitcoind, which is fine for now.

TODO: Possibly support more BTC bitcoinds in the future, if it proves
that Fulcrum becomes popular on BTC.

* Updated a comment

* Updated some comments

* Tweaks, updated comments, updated an error message

* Don't use QStringView

In this context better to just take a reference to QString

* Nits: Updated some comments, made a variable a reference

* Added code to raise open file limit on startup, also tweaked db mem allocation

* Fickst a typoe

* Forgot a paren.

* Forgot a colon

* Enable the phishing warning for verisons < 3.3.4 again, also for BTC

* Disabled blockchain.address.* methods for BTC

* Use .arg(str1, str2) in a few places
2020-11-07 08:32:10 +02:00
Calin Culianu
25ebeca4b8
Added facility for pushing/popping log suppressions for qt msgs
Qt sometimes puts messages in the log we would rather suppress during
certain operations.  Added a facility for this. (Some static functions
in the App class).
2020-11-03 22:54:29 +02:00
Calin Culianu
234c25f3c0
Fixup for PTHREAD_STACK_MIN not being accurate in static builds
This is because we build on 1 system but potentially run on others with
different libs.  PTHREAD_STACK_MIN may not be accurate in that case. So
we probe the minimum stack size by actually attempting to start a thread
with that stack size set, and if it succeeds, we can assume the minimum
given by PTHREAD_STACK_MIN is accurate.

If it does not succeed, we just can proceed with the default stack size,
as the "minimum" stack size, which should always work.
2020-11-03 21:06:09 +02:00
Calin Culianu
e8bfb5f2d0
Tweaks to the thread used to detect signal handler-initiated exits
We use a QThread now as opposed to std::thread for the "exit thread".
 Rationale: QThread's API is richer and we can set the thread stack size.

Since this thread does almost nothing, we want to set it to have a very
minimal thread stack size so as to avoid wasting virtual address space
for a thread that probably will never use more then ~200 bytes of stack.

As such we added generic platform-neutral code in Util.cpp to detect the
minimum stack size on the system the code is running on, and to set the
ExitThr's stack size to this size.

ExitThr is now a nested private class, implemented inside
App::startup_Signalhandlers(). I love this language feature. :)
2020-11-03 17:36:54 +02:00
Calin Culianu
040ceda2f8
Tweaks to the AsyncSignalSafe namespace
- Renamed Cond -> Sem.  Semantically it's really a semaphore.
- Made the Windows case use a smaller buffer for the pipe, 32 vs 256
  bytes. We really only write 1 character to this pipe ever in the
  normal case, but I am not sure if Windows would return an error if we
  specify extremely small values here, so 32 should be safe.
2020-11-03 12:15:20 +02:00
Calin Culianu
7138b506f3
Made signal handling for SIGINT, SIGTERM, etc safer
Previously, when catching these quit signals, we were directly calling
into the QCoreApplication quit() method and doing other unsafe things
(such as allocating strings).  This is not technically safe because
signals may be delivered at any time -- including while the app was in a
state where such calls would be reentrant or otherwise problematic (e.g.
app was in the middle of allocating memory or inside the core qt kernel,
etc).

So I modified the way the code that catches these quit signals works to
guarantee safety.  The technique employed ultimately rests on using a
simple pipe() (self-pipe technique) that is read from in a thread. The
signal handler just wakes up the waiting thread when a signal arrives,
and the thread then does (safe) calls into Qt to initiate app shutdown.
2020-11-03 11:43:22 +02:00
Calin Culianu
827c1e4256
Added simdjson CLI arg and conf file variable
If enabled, and if the app supports it at runtime (and it it has
simdjson compiled-in), then simdjson will be used for all JSON-RPC
parsing.  It is an extremely fast backend (at *least* 2x faster and
sometimes even faster than that on large data sets).

Since it is a new backend and it hasn't been war-tested yet, we will
default it to off.

This commit also contains various small bits of code cleanup as well.
2020-10-25 22:35:32 +02:00
Calin Culianu
dc954213c9
Imported latest Json lib sources, added simdjson
Also reorganized the source tree a little bit -- the Json lib now lives
in its own subdirectory.

Moved the benches/tests out of Json.cpp and into its own file, test.cpp
in the Json/ folder.

Updated the benchmark to be able to read our custom .qz file for
benches. And other assorted small changes and fixes, mostly related to
the Json lib.

Hopefully going forward this ensures there are minimal diffs between the
Json lib and Fulcrum's own embedded Json lib, so it should be easier to
keep the two codebases in sync.
2020-10-25 20:06:19 +02:00
Calin Culianu
089fb4771e
Added process memory usage information to the getinfo rpc
Also added to the /stats endpoint.  Prints physical and virtual memory
used by the process.
2020-08-30 20:33:06 +03:00
Calin Culianu
ba1eb39eef
Compile fix for Qt < 5.14.0
The "keyset" test we added doesn't compile on Qt less than 5.14.0
because QString lacks a std::hash specialization.  So for Qt 5.13 and
earlier we added this specialization.
2020-08-13 02:52:20 +03:00
Calin Culianu
90fe4b7866
Compile fix for Linux
Apparently std::hash<QString> does not exist.  Oops. :)
2020-08-13 02:36:39 +03:00
Calin Culianu
69b48a8b1a
Added "all" keyword for --test and --bench
If compiling with -DENABLE_TESTS:

- --test all    - to run all the tests
- --bench all   - to run all the benchmarks

Also in this commit: Refactoed/redid the generic Util::keySet() and
Util::valueSet() to be able to produce any common container type from
any common map type.
2020-08-13 02:13:56 +03:00
Calin Culianu
201329f55a
Reworded a comment to be clearer, plus 1 minor nit
The nit is that we had an extraneous %s in an error message string on
Linux; the error message itself never ever occurs in practice.
2020-07-19 23:33:51 +03:00
Calin Culianu
e5b0ccfb94
Refactor away some often-user boilerplate for bytes into ByteView (#34)
When implementing the `RollingBloomFilter` (and the TrivialHashHasher)
there was ugly boilerplate: multiple overloads doing repetitive 
`reinterpret_casts`, in order to support various POD types as well as 
`QByteArray`, `std::vector`, etc.  All of this has been refactored into a 
utility class, `ByteView`, which has  templated auto-conversions from 
often used containers, e.g.: `base_blob`,  `QString`, `QByteArray`, 
`std::vector`, etc.

This class is is a zero-cost abstraction that compiles away into nothing.  
It is lightweight and inherits from `std::basic_string_view` but its underlying 
type is `const std::byte *` (rather than `const char *`).

It is intended to encapsulate a pointer, size pair into binary data
blobs, and its intended use is as an argument on the stack to hasher
functions, bloom filters, and other such functions that take byte pointers
into arbitrary data.

In addition, our `base_blob` type that we copied over from bitcoin sources
has been refactored to be more STL-like in its api.
2020-07-18 05:23:42 +03:00
Calin Culianu
dd5beeb018
Simplified the hashData* functions in Util.h
- Made them take std::byte * (rather than uint8_t) to make it clear it
is designed to operate on arbitrary byte data.
- Removed unused inline functions that nothing was calling.
2020-07-05 18:45:12 +03:00