Attempt to remove a bottleneck during the transactions view load, as
revealed by JProfiler, by optimising the code to determine if any given
transaction and trade are related. Since both these sets will tend to
grow linearly with time, causing quadratic slowdown of TransactionsView,
try to alleviate (without completely fixing) the problem.
To do this, add a cached set of disputed trade IDs to DisputeListService
so that TransactionAwareTradable.is(Dispute|RefundPayout)Tx can be made
O(1) in the common case that the given trade is not involved in any
dispute. Also avoid calling Sha256Hash::toString by passing tx IDs as
Sha256Hash objects directly to is(Deposit|Payout)Tx, and short circuit
an expensive call BtcWalletService.getTransaction in isDelayedPayoutTx,
in the common case, by pre-checking the transaction locktime.
This also fixes a bug in isRefundPayoutTx whereby it incorrectly returns
false if there are >1 disputes in the list returned by RefundManager but
the given trade is not involved in the last one.
Use a guava SetMultimap (a many-to-many mapping without duplicates) to
cache the set of live txs in the user's wallet with a given address as
an input or output. As with the cache of output counts from the previous
commit, compute all the tx sets in one go (by a tx stream followed by a
map inverse) and store in an ImmutableSetMultimap<Address, Transaction>,
invalidating the entire cache immediately upon each wallet change event.
This is to fix another (larger) quadratic time bug in DepositView, when
getting the confidence (i.e. confirmation count) of each wallet address.
Also simplify getTransactionConfidence & onTransactionConfidenceChanged
methods slightly, which generated (possibly unintentionally) repeating &
singleton lists of TransactionConfidence objects to pass to
WalletService.getMostRecentConfidence(..) respectively.
Use a guava Multiset to cache the total number of tx outputs (out of the
live txs in the user's wallet) with a given address. Since this requires
a scan of the entire tx set, compute all the counts in one go and store
in an ImmutableMultiset<Address>. Invalidate the entire cache any time a
tx set change occurs, by attaching a WalletChangeEventListener to the
wallet (using a direct executor for immediate effect).
This is to fix a quadratic time bug in DepositView, which uses the count
to determine if a given address in the BTC wallet is used/unused.
Make the WalletService.walletEventListener field private and add it via
a protected method defined in the base class, addListenersToWallet(), so
that the setup code in the two subclasses (Bsq|Btc)WalletService can be
deduplicated and more easily kept in sync with the listener removal code
in WalletService.shutDown().
Also remove some unnecessary deprecation warning suppressions.
- trims whitespace from numeric input fields before parsing
- adds percentage display of the tx fee
- validates that the tx fee percentage is not higher than 10%
The price feed service throws PriceRequestExceptions when switching
currencies, log those exceptions as warnings in the server and don't
pass them up to the CLI.
The server impl was there, but it is now needed by the trading
sim scripts (CLI) to get the price from the Bisq server instead
of the feed. (The server does not request prices more than
once a minute.)
This server log output was intended as an aid to api devs, but
is no longer needed after the change to posix-sytle method opts
with self explanatory labels (replacing the ambiguous positional
CLI method opts).
Two regtest trading simulation scripts are contained in this change:
- trade-simulation.sh goes through the steps of creating F2F payment
accounts for Bob & Alice, and each step of a trade from createoffer to
completion.
- limit-order-simulation.sh shows one way to trigger creation of an offer
when a limit price is reached.
Each script prints CLI commands just before they are run.
Both scripts depend on functions contained in supporting bash and python3
scripts.
Examples:
trade-simulation.sh
Simulate the entire trade protocol between Bob (taker) & Alice (maker),
where Alice buys 0.1 BTC from Bob, paying in Renminbi (CYN).
Note the script takes a country code (CN) not a currency code, so the
script can create the appropriate country based face to face payment accounts.
$ apitest/scripts/trade-simulation.sh -d buy -c cn -m 0.0 -a 0.1
limit-order.sh
Create a CAD/BUY 0.1 BTC order at mkt price margin of 0.0% if price falls to
or below 47900 CAD.
Note the script takes a country code (CA) not a currency code, so the script
can create the appropriate country based face to face payment accounts.
$ apitest/scripts/limit-order-simulation.sh -l 47900 -d buy -c CA -m 0.0 -a 0.1
Create a USD/SELL 0.1 BTC order at mkt price margin of 0.0% if price rises to
or above 37200 USD.
$ apitest/scripts/limit-order-simulation.sh -l 37200 -d sell -c US -m 0.0 -a 0.1