Use a mutable static tuple field to cache the last result of
'Sha256Hash.toString', which is used to get the ID string of the input
tx, when calling 'TransactionAwareTrade.isRelatedToTransaction'. In this
way, consecutive calls to 'isRelatedToTransaction' on the same input tx
(over all the past trades, as done by 'TransactionsView.updateList') are
sped up significantly, since hex encoding the txId is a bottleneck.
Replace the "Optional.ofNullable(...)..." constructs with more direct
code using short-circuit operators, as this is shorter and a little
faster. Also use "trade.get[Deposit|Payout]TxId()" instead of the code
"trade.get[Deposit|Payout]TxId().getTxId()", as (upon inspection of the
code) there should never be a case where the deposit/payout transaction
field of a Trade object is set but the respective txID field is null (or
set to an inconsistent value).
Also remove a redundant 'RefundManager.getDisputesAsObservableList'
method call, which was also slowing things down slightly.
The minor speedups afforded by the above are important because the
method 'TransactionAwareTrade.isRelatedToTransaction' is called a
quadratic number of times and consequently a major bottleneck when
loading the Transactions view.
Multiple threads read and write to the accounting blocks list causing
data races. Luckily, the LinkedList threw a ConcurrentModificationException
to limit damage. Now, a ReadWriteLock protects the LinkedList against
data races. Multiple threads can read the list at the same time but only
one thread can write to it. Other writing threads wait until it's their
turn.
Fixes#6545
Add a third cache to WalletService, cleared upon wallet change events,
which maps txIds to txs. This allows the speedup of repeated calls to
'WalletService.getConfidenceForTxId', by avoiding the need to copy and
scan the entire set of wallet txs to find the one with matching id,
for each method invocation.
This is mainly to provide a further speedup to the closed-trades-view
load, by making it much faster to filter the list of BSQ swap trades by
tx confirmation status in 'ClosedTradesDataModel.applyList' and
'ClosedTradesManager.getNumPastTrades'.
Reduce a bottleneck in the closed-trades-view load & table scrolling,
caused by a call to 'ClosedTradesManager.getNumPastTrades' for each
list item displayed. This repeatedly scans the entire collection of
closed trades and BSQ swap trades, in order to count all those which
share a given peer node address. (Scanning the BSQ swap trades is
particularly slow due to their filtering by tx confirmation status.)
To this end, cache the counts of trades by peer node address with a
nullable Multiset field in ClosedTradesManager & BsqSwapTradeManager,
so that the trades are scanned at most once when the view loads. Add
listeners to clear the respective cache when the trade list changes or
the BSQ wallet txs change.
Each time when MailboxMessageService.onAdded(...) got called with
multiple mailbox entries a new thread got created. That thread was never
shutdown. This change explicitly creates a new Thread and sets its
result with a SettableFuture. After its computation the thread
terminates.
The DaoStateStorageService submits tasks to a daemon thread executor
service. The JVM continues to execute threads until all non-daemon
threads have terminated. So the JVM will kill the DaoStateStorageService
during write requests leading to data corruption.
This change uses a non-daemon thread executor service at waits during
shutdown until all data is written to disk.
Before SynchronizedProtoOutputStream created a new thread and made a
blocking call to ProtoOutputStream.writeEnvelope(...). Each connection
had an instance of SynchronizedProtoOutputStream, so we had a redundant
thread per connection. This change makes ProtoBufOutputStream
thread-safe and reduces the number of thread per connection as a
side effect.