Avoid a bottleneck computing the cycle index & calling 'Res.get(..)' for
every block since genesis in the DAO state monitor view, when building
the DaoStateBlockListItem objects, by making the 'height' field lazy. To
do this, pass the cycle index into the constructor using an IntSupplier
and make the height a memoised 'Supplier<String>' with a custom getter.
Also add a unit test to check that the auto-generated equals & hashCode
methods still work as expected, as it isn't totally clear what Lombok
would do when a field type differs from its getter return type.
Since this map is final and every PaymentAccountPayload constructor
initialises it to something nonnull, the @Nullable field annotation is
redundant, so remove it.
Further simplify the code by passing an empty map into the constructor
directly from each subclass constructor, rather than mapping empties to
nulls from each 'proto.getExcludeFromJsonDataMap()' result, then mapping
nulls back to empties in the base constructor. This is safe, since
getExcludeFromJsonDataMap() always returns a nonnull map.
Finally, tidy the code slightly by replacing 'Charset.forName("UTF-8")'
with StandardCharsets.UTF_8 in each PaymentAccountPayload subclass.
With the removal of CoinMarketCap as an exchange rate provider in the
prior commit, the @Order values of the remaining three provider
implementations are non-contiguous. CoinMarketCap was @Order(3) and with
it gone, the remaining order values became 1, 2, 4. This is not a
problem in practice, but could be confusing for future maintainers, so
this commit simply decrements the Poloniex implementation from 4 to 3 in
order to make the values contiguous once again.
This commit also fixes a typo in ExchangeRateProvider's Javadoc.
There are circumstances where input via --appDataDir
will lead to the hiddenservice-directory to be deleted.
Successfully reproduced using
--appDataDir=~/foo
Although the "~" does not get interpreted correctly on
my linux system, it does manage to throw off the
mechanics of sparing the hiddenservice-directory from
being deletd.
Add toProtoMessageSynchronized() default method to PersistableEnvelope,
which performs (blocking) protobuf serialisation in the user thread,
regardless of the calling thread. This should prevent data races like
the ConcurrentModificationException observed in #3752, under the
reasonable assumption that shared persistable objects are only mutated
in the user thread.
Also add a ThreadedPersistableEnvelope sub-interface overriding the
default method above, to let objects which are expensive to serialise
(like DaoStateStore) be selectively serialised in the 'save-file-task-X'
thread as before, but directly synchronised with each mutating op. As
most objects are cheap to serialise, this avoids a noticeable perf drop
without having to track down every mutating method for each store.
In all cases but one, classes implementing ThreadedPersistableEnvelope
are stores like TradeStatistic2Store, with a single ConcurrentHashMap
field. These require no further serialisation, since the map entries are
immutable, so the only mutating operations are map.put(..) calls which
are already synchronised with map reads. (Even if map.values().stream()
sees updates @ different keys happen out-of-order, it should be benign.)
The remaining case is DaoStateStore, which is only ever reset or
modified via a single persist(..) call with a cloned DaoState instance
and hash chain from DaoStateSnapshotService, so there is no aliasing
risk from the various DAO state mutations done in DaoStateService and
elsewhere.
This should fix#3752.
Minor change for consistency: narrow the signature of some remaining
such methods, which have return type 'PersistableEnvelope'.
(This excludes some other cases with return type 'NetworkEnvelope'.)
Bisq frequently (once per minute) queries our price nodes for up-to-date
fee information. It does so by HTTP GET request. However, it provided
a UID via the "User-Agent" HTTP header field. This UID has been a random
number which changed everytime Bisq gets started up.
This UID has never been used. Thus, remove it.
This was originally added with the intention that the local Bitcoin node
port could be customized, but in fact it never could be, because Guice
configuration always hard-wired the value to the default port for the
CurrentBaseNetwork's Parameters (eg. 8333 for BTC_MAINNET).
This change removes the constant, removes any Guice wiring and injection
and localizes the hard-coded assignment to the LocalBitcoinNode
constructor to simplify and make things explicit.
If it is desired to allow users to specify a custom port for their local
Bitcoin node, a proper option shoud be added to Config. In the meantime,
users may work around this by using `--btcNodes=localhost:4242` where
4242 is the custom port. Note however, that the pruning and bloom filter
checks will not occur in this case as the provided node address will not
being treated as a LocalBitcoinNode.