Skip to content

Commit

Permalink
Merge pull request #4533 from chimp1984/fix-trade-protocol-issues
Browse files Browse the repository at this point in the history
Fix trade protocol issues
  • Loading branch information
sqrrm authored Sep 19, 2020
2 parents 9735a85 + 48a3f74 commit de71811
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 52 deletions.
46 changes: 46 additions & 0 deletions core/src/main/java/bisq/core/app/AsciiLogo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/

package bisq.core.app;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class AsciiLogo {
public static void showAsciiLogo() {
log.info("\n\n" +
" ........ ...... \n" +
" .............. ...... \n" +
" ................. ...... \n" +
" ...... .......... .. ...... \n" +
" ...... ...... ...... ............... ..... ......... .......... \n" +
" ....... ........ .................. ..... ............. ............... \n" +
" ...... ........ .......... ....... ..... ...... ... ........ ....... \n" +
" ...... ..... ....... ..... ..... ..... ..... ...... \n" +
" ...... ... ... ...... ...... ..... ........... ...... ...... \n" +
" ...... ..... .... ...... ...... ..... ............ ..... ...... \n" +
" ...... ..... ...... ..... ........ ...... ...... \n" +
" ...... .... ... ...... ...... ..... .. ...... ...... ........ \n" +
" ........ .. ....... ................. ..... .............. ................... \n" +
" .......... ......... ............. ..... ............ ................. \n" +
" ...................... ..... .... .... ...... \n" +
" ................ ...... \n" +
" .... ...... \n" +
" ...... \n" +
"\n\n");
}
}
1 change: 1 addition & 0 deletions core/src/main/java/bisq/core/app/BisqExecutable.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ public void execute(String[] args) {
///////////////////////////////////////////////////////////////////////////////////////////

protected void doExecute() {
AsciiLogo.showAsciiLogo();
configUserThread();
CoreSetup.setup(config);
addCapabilities();
Expand Down
12 changes: 7 additions & 5 deletions core/src/main/java/bisq/core/btc/wallet/TxBroadcaster.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,22 +78,24 @@ default void onTimeout(TxBroadcastTimeoutException exception) {
// Wallet.complete() method is called which is the case for all BSQ txs. We will work on a fix for that but that
// will take more time. In the meantime we reduce the timeout to 5 seconds to avoid that the trade protocol runs
// into a timeout when using BSQ for trade fee.
// For trade fee txs we set only 1 sec timeout for now.
// FIXME
private static final int DEFAULT_BROADCAST_TIMEOUT = 5;
private static Map<String, Timer> broadcastTimerMap = new HashMap<>();
private static final Map<String, Timer> broadcastTimerMap = new HashMap<>();

public static void broadcastTx(Wallet wallet, PeerGroup peerGroup, Transaction localTx, Callback callback) {
broadcastTx(wallet, peerGroup, localTx, callback, DEFAULT_BROADCAST_TIMEOUT);
}

public static void broadcastTx(Wallet wallet, PeerGroup peerGroup, Transaction tx, Callback callback, int delayInSec) {
public static void broadcastTx(Wallet wallet, PeerGroup peerGroup, Transaction tx, Callback callback, int timeOut) {
Timer timeoutTimer;
final String txId = tx.getTxId().toString();
if (!broadcastTimerMap.containsKey(txId)) {
timeoutTimer = UserThread.runAfter(() -> {
log.warn("Broadcast of tx {} not completed after {} sec.", txId, delayInSec);
log.warn("Broadcast of tx {} not completed after {} sec.", txId, timeOut);
stopAndRemoveTimer(txId);
UserThread.execute(() -> callback.onTimeout(new TxBroadcastTimeoutException(tx, delayInSec, wallet)));
}, delayInSec);
UserThread.execute(() -> callback.onTimeout(new TxBroadcastTimeoutException(tx, timeOut, wallet)));
}, timeOut);

broadcastTimerMap.put(txId, timeoutTimer);
} else {
Expand Down
5 changes: 4 additions & 1 deletion core/src/main/java/bisq/core/btc/wallet/WalletService.java
Original file line number Diff line number Diff line change
Expand Up @@ -342,11 +342,14 @@ public static void signTransactionInput(Wallet wallet,
// Broadcast tx
///////////////////////////////////////////////////////////////////////////////////////////


public void broadcastTx(Transaction tx, TxBroadcaster.Callback callback) {
TxBroadcaster.broadcastTx(wallet, walletsSetup.getPeerGroup(), tx, callback);
}

public void broadcastTx(Transaction tx, TxBroadcaster.Callback callback, int timeOut) {
TxBroadcaster.broadcastTx(wallet, walletsSetup.getPeerGroup(), tx, callback, timeOut);
}


///////////////////////////////////////////////////////////////////////////////////////////
// TransactionConfidence
Expand Down
6 changes: 4 additions & 2 deletions core/src/main/java/bisq/core/btc/wallet/WalletsManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,11 @@ public void publishAndCommitBsqTx(Transaction tx, TxType txType, TxBroadcaster.C
// We need to create another instance, otherwise the tx would trigger an invalid state exception
// if it gets committed 2 times
// We clone before commit to avoid unwanted side effects
final Transaction clonedTx = btcWalletService.getClonedTransaction(tx);
Transaction clonedTx = btcWalletService.getClonedTransaction(tx);
btcWalletService.commitTx(clonedTx);
bsqWalletService.commitTx(tx, txType);
bsqWalletService.broadcastTx(tx, callback);

// We use a short timeout as there are issues with BSQ txs. See comment in TxBroadcaster
bsqWalletService.broadcastTx(tx, callback, 1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public void onFailure(TxBroadcastException exception) {
}
});
} else {
final BsqWalletService bsqWalletService = model.getBsqWalletService();
BsqWalletService bsqWalletService = model.getBsqWalletService();
Transaction preparedBurnFeeTx = model.getBsqWalletService().getPreparedTradeFeeTx(offer.getMakerFee());
Transaction txWithBsqFee = tradeWalletService.completeBsqTradingFeeTx(preparedBurnFeeTx,
fundingAddress,
Expand All @@ -126,32 +126,34 @@ public void onFailure(TxBroadcastException exception) {
// if it gets committed 2 times
tradeWalletService.commitTx(tradeWalletService.getClonedTransaction(signedTx));

// We use a short timeout as there are issues with BSQ txs. See comment in TxBroadcaster
bsqWalletService.broadcastTx(signedTx, new TxBroadcaster.Callback() {
@Override
public void onSuccess(@Nullable Transaction transaction) {
if (transaction != null) {
offer.setOfferFeePaymentTxId(transaction.getTxId().toString());
model.setTransaction(transaction);
log.debug("onSuccess, offerId={}, OFFER_FUNDING", id);
walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.OFFER_FUNDING);

log.debug("Successfully sent tx with id " + transaction.getTxId().toString());
model.getOffer().setState(Offer.State.OFFER_FEE_PAID);

complete();
}
}

@Override
public void onFailure(TxBroadcastException exception) {
log.error(exception.toString());
exception.printStackTrace();
offer.setErrorMessage("An error occurred.\n" +
"Error message:\n"
+ exception.getMessage());
failed(exception);
}
});
@Override
public void onSuccess(@Nullable Transaction transaction) {
if (transaction != null) {
offer.setOfferFeePaymentTxId(transaction.getTxId().toString());
model.setTransaction(transaction);
log.debug("onSuccess, offerId={}, OFFER_FUNDING", id);
walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.OFFER_FUNDING);

log.debug("Successfully sent tx with id " + transaction.getTxId().toString());
model.getOffer().setState(Offer.State.OFFER_FEE_PAID);

complete();
}
}

@Override
public void onFailure(TxBroadcastException exception) {
log.error(exception.toString());
exception.printStackTrace();
offer.setErrorMessage("An error occurred.\n" +
"Error message:\n"
+ exception.getMessage());
failed(exception);
}
},
1);
}
} catch (Throwable t) {
if (t instanceof DaoDisabledException) {
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/bisq/core/setup/CoreSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public static void setup(Config config) {
private static void setupLog(Config config) {
String logPath = Paths.get(config.appDataDir.getPath(), "bisq").toString();
Log.setup(logPath);
log.info("\n\n\nLog files under: " + logPath);
log.info("Log files under: {}", logPath);
Utilities.printSysInfo();
Log.setLevel(Level.toLevel(config.logLevel));
}
Expand Down
19 changes: 5 additions & 14 deletions core/src/main/java/bisq/core/trade/protocol/TradeProtocol.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import bisq.core.trade.Trade;
import bisq.core.trade.TradeManager;
import bisq.core.trade.messages.CounterCurrencyTransferStartedMessage;
import bisq.core.trade.messages.InputsForDepositTxRequest;
import bisq.core.trade.messages.MediatedPayoutTxPublishedMessage;
import bisq.core.trade.messages.MediatedPayoutTxSignatureMessage;
import bisq.core.trade.messages.PeerPublishedDelayedPayoutTxMessage;
Expand Down Expand Up @@ -357,15 +356,8 @@ private void sendAckMessage(@Nullable TradeMessage tradeMessage, boolean result,
return;

String tradeId = tradeMessage.getTradeId();
String sourceUid = "";
if (tradeMessage instanceof MailboxMessage) {
sourceUid = ((MailboxMessage) tradeMessage).getUid();
} else {
// For direct msg we don't have a mandatory uid so we need to cast to get it
if (tradeMessage instanceof InputsForDepositTxRequest) {
sourceUid = tradeMessage.getUid();
}
}
String sourceUid = tradeMessage.getUid();

AckMessage ackMessage = new AckMessage(processModel.getMyNodeAddress(),
AckMessageSourceType.TRADE_MESSAGE,
tradeMessage.getClass().getSimpleName(),
Expand All @@ -378,7 +370,6 @@ private void sendAckMessage(@Nullable TradeMessage tradeMessage, boolean result,
final NodeAddress peersNodeAddress = trade.getTradingPeerNodeAddress() != null ? trade.getTradingPeerNodeAddress() : processModel.getTempTradingPeerNodeAddress();
log.info("Send AckMessage for {} to peer {}. tradeId={}, sourceUid={}",
ackMessage.getSourceMsgClassName(), peersNodeAddress, tradeId, sourceUid);
String finalSourceUid = sourceUid;
processModel.getP2PService().sendEncryptedMailboxMessage(
peersNodeAddress,
processModel.getTradingPeer().getPubKeyRing(),
Expand All @@ -387,19 +378,19 @@ private void sendAckMessage(@Nullable TradeMessage tradeMessage, boolean result,
@Override
public void onArrived() {
log.info("AckMessage for {} arrived at peer {}. tradeId={}, sourceUid={}",
ackMessage.getSourceMsgClassName(), peersNodeAddress, tradeId, finalSourceUid);
ackMessage.getSourceMsgClassName(), peersNodeAddress, tradeId, sourceUid);
}

@Override
public void onStoredInMailbox() {
log.info("AckMessage for {} stored in mailbox for peer {}. tradeId={}, sourceUid={}",
ackMessage.getSourceMsgClassName(), peersNodeAddress, tradeId, finalSourceUid);
ackMessage.getSourceMsgClassName(), peersNodeAddress, tradeId, sourceUid);
}

@Override
public void onFault(String errorMessage) {
log.error("AckMessage for {} failed. Peer {}. tradeId={}, sourceUid={}, errorMessage={}",
ackMessage.getSourceMsgClassName(), peersNodeAddress, tradeId, finalSourceUid, errorMessage);
ackMessage.getSourceMsgClassName(), peersNodeAddress, tradeId, sourceUid, errorMessage);
}
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ protected void run() {
processModel.removeMailboxMessageAfterProcessing(trade);

// If we got already the confirmation we don't want to apply an earlier state
if (trade.getState() != Trade.State.BUYER_SAW_DEPOSIT_TX_IN_NETWORK)
if (trade.getState().ordinal() < Trade.State.BUYER_SAW_DEPOSIT_TX_IN_NETWORK.ordinal())
trade.setState(Trade.State.BUYER_RECEIVED_DEPOSIT_TX_PUBLISHED_MSG);

processModel.getBtcWalletService().swapTradeEntryToAvailableEntry(trade.getId(), AddressEntry.Context.RESERVED_FOR_TRADE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public void onFailure(TxBroadcastException exception) {
// if it gets committed 2 times
tradeWalletService.commitTx(tradeWalletService.getClonedTransaction(takeOfferFeeTx));

// We use a short timeout as there are issues with BSQ txs. See comment in TxBroadcaster
bsqWalletService.broadcastTx(takeOfferFeeTx,
new TxBroadcaster.Callback() {
@Override
Expand Down Expand Up @@ -104,7 +105,8 @@ public void onFailure(TxBroadcastException exception) {
log.warn("We got the onFailure callback called after the timeout has been triggered a complete().");
}
}
});
},
1);
}
} catch (Throwable t) {
failed(t);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ public void activate() {
if (DevEnv.isDevMode()) {
UserThread.runAfter(() -> {
amount.set("0.001");
price.set("0.008");
price.set("70000");
minAmount.set(amount.get());
onFocusOutPriceAsPercentageTextField(true, false);
applyMakerFee();
Expand Down

0 comments on commit de71811

Please sign in to comment.