From 7c63e5ab00d1315ee6c2353440365d5dd0b390ec Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 11 Mar 2016 16:44:25 +0100 Subject: [PATCH] Fix issues with delayed mailbox messages, handle ui state when peer is offline --- .../src/main/java/io/bitsquare/app/Log.java | 2 +- .../main/java/io/bitsquare/trade/Trade.java | 3 +- .../createoffer/CreateOfferViewModel.java | 2 +- .../offer/takeoffer/TakeOfferViewModel.java | 2 +- .../pendingtrades/PendingTradesViewModel.java | 1 + .../steps/buyer/BuyerStep4View.java | 35 +++++++++++++------ .../offerbook/OfferBookViewModelTest.java | 19 +++++++--- .../io/bitsquare/p2p/network/Connection.java | 13 ++----- .../bitsquare/p2p/peers/BroadcastHandler.java | 8 ++--- .../p2p/peers/getdata/RequestDataHandler.java | 17 ++------- .../bitsquare/p2p/storage/P2PDataStorage.java | 2 +- 11 files changed, 55 insertions(+), 49 deletions(-) diff --git a/common/src/main/java/io/bitsquare/app/Log.java b/common/src/main/java/io/bitsquare/app/Log.java index 54370c784e5..f7dc0ef6242 100644 --- a/common/src/main/java/io/bitsquare/app/Log.java +++ b/common/src/main/java/io/bitsquare/app/Log.java @@ -63,7 +63,7 @@ public static void setup(String fileName, boolean useDetailedLogging) { logbackLogger = loggerContext.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); //TODO for now use always trace - logbackLogger.setLevel(useDetailedLogging ? Level.TRACE : Level.INFO); + logbackLogger.setLevel(useDetailedLogging ? Level.TRACE : Level.TRACE); // logbackLogger.setLevel(useDetailedLogging ? Level.TRACE : Level.DEBUG); logbackLogger.addAppender(appender); } diff --git a/core/src/main/java/io/bitsquare/trade/Trade.java b/core/src/main/java/io/bitsquare/trade/Trade.java index 10b01dd1935..2432f5a0ca0 100644 --- a/core/src/main/java/io/bitsquare/trade/Trade.java +++ b/core/src/main/java/io/bitsquare/trade/Trade.java @@ -221,7 +221,7 @@ public void init(P2PService p2PService, OpenOfferManager openOfferManager, User user, KeyRing keyRing) { - + Log.traceCall(); processModel.onAllServicesInitialized(offer, tradeManager, openOfferManager, @@ -234,6 +234,7 @@ public void init(P2PService p2PService, createProtocol(); + log.trace("decryptedMsgWithPubKey = " + decryptedMsgWithPubKey); if (decryptedMsgWithPubKey != null) { tradeProtocol.applyMailboxMessage(decryptedMsgWithPubKey, this); } diff --git a/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferViewModel.java b/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferViewModel.java index 3a9dac7277d..31de186d0cb 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferViewModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferViewModel.java @@ -171,7 +171,7 @@ private void updateSpinnerInfo() { isSpinnerVisible.set(false); spinnerInfoText.set(""); } else if (showPayFundsScreenDisplayed) { - spinnerInfoText.set("Waiting for funds..."); + spinnerInfoText.set("Waiting for receiving funds..."); isSpinnerVisible.set(true); } } diff --git a/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferViewModel.java b/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferViewModel.java index 397936d4150..4b3c9743069 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferViewModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/offer/takeoffer/TakeOfferViewModel.java @@ -453,7 +453,7 @@ private void updateSpinnerInfo() { isSpinnerVisible.set(false); spinnerInfoText.set(""); } else if (showPayFundsScreenDisplayed) { - spinnerInfoText.set("Waiting for funds..."); + spinnerInfoText.set("Waiting for receiving funds..."); isSpinnerVisible.set(true); } } diff --git a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/PendingTradesViewModel.java b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/PendingTradesViewModel.java index f445bda8f3f..3b45bc3d642 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/PendingTradesViewModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/PendingTradesViewModel.java @@ -301,6 +301,7 @@ private void onTradeStateChanged(Trade.State tradeState) { case BUYER_RECEIVED_FIAT_PAYMENT_RECEIPT_MSG: case BUYER_COMMITTED_PAYOUT_TX: case BUYER_STARTED_SEND_PAYOUT_TX: + // TODO would need extra state for wait until msg arrived and PAYOUT_BROAD_CASTED gets called. buyerState.set(PendingTradesViewModel.BuyerState.WAIT_FOR_BROADCAST_AFTER_UNLOCK); break; case SELLER_RECEIVED_AND_COMMITTED_PAYOUT_TX: diff --git a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/buyer/BuyerStep4View.java b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/buyer/BuyerStep4View.java index 48c701ec394..381f32c53fb 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/buyer/BuyerStep4View.java +++ b/gui/src/main/java/io/bitsquare/gui/main/portfolio/pendingtrades/steps/buyer/BuyerStep4View.java @@ -93,9 +93,13 @@ public void deactivate() { @Override protected void addContent() { addTradeInfoBlock(); - blockTextField = addLabelTextField(gridPane, gridRow, "Block(s) to wait until lock time elapsed:", "").second; - timeTextField = addLabelTextField(gridPane, ++gridRow, "Approx. date when payout gets unlocked:").second; - GridPane.setRowSpan(tradeInfoTitledGroupBg, 5); + if (model.getLockTime() > 0) { + blockTextField = addLabelTextField(gridPane, gridRow, "Block(s) to wait until lock time elapsed:", "").second; + timeTextField = addLabelTextField(gridPane, ++gridRow, "Approx. date when payout gets unlocked:").second; + GridPane.setRowSpan(tradeInfoTitledGroupBg, 5); + } else { + GridPane.setRowSpan(tradeInfoTitledGroupBg, 3); //TODO should never reach + } addInfoBlock(); } @@ -107,15 +111,21 @@ protected void addContent() { @Override protected String getInfoBlockTitle() { - return "Wait until payout lock time is over"; + if (model.getLockTime() > 0) + return "Wait until payout lock time is over"; + else + return "Sending payout transaction to peer"; } @Override protected String getInfoText() { - return "The payout transaction is signed and finalized by both parties.\n" + - "For reducing bank chargeback risks the payout transaction is blocked by a lock time.\n" + - "After that lock time is over the payout transaction gets published and you receive " + - "your bitcoin."; + if (model.getLockTime() > 0) + return "The payout transaction is signed and finalized by both parties.\n" + + "For reducing bank chargeback risks the payout transaction is blocked by a lock time.\n" + + "After that lock time is over the payout transaction gets published and you receive " + + "your bitcoin."; + else + return "We are sending the payout transaction to the other peer."; } @@ -137,9 +147,12 @@ protected String getWarningText() { /////////////////////////////////////////////////////////////////////////////////////////// private void updateDateFromBlockHeight(long bestBlocKHeight) { - long missingBlocks = model.getLockTime() - bestBlocKHeight; - blockTextField.setText(String.valueOf(missingBlocks)); - timeTextField.setText(model.getOpenDisputeTimeAsFormattedDate()); + if (model.getLockTime() > 0) { + long missingBlocks = model.getLockTime() - bestBlocKHeight; + + blockTextField.setText(String.valueOf(missingBlocks)); + timeTextField.setText(model.getOpenDisputeTimeAsFormattedDate()); + } } diff --git a/gui/src/test/java/io/bitsquare/gui/main/offer/offerbook/OfferBookViewModelTest.java b/gui/src/test/java/io/bitsquare/gui/main/offer/offerbook/OfferBookViewModelTest.java index ac811b957b1..c609f861f27 100644 --- a/gui/src/test/java/io/bitsquare/gui/main/offer/offerbook/OfferBookViewModelTest.java +++ b/gui/src/test/java/io/bitsquare/gui/main/offer/offerbook/OfferBookViewModelTest.java @@ -24,6 +24,10 @@ public void testIsAnyPaymentAccountValidForOffer() { Offer offer; Collection paymentAccounts; + paymentAccounts = new ArrayList<>(Arrays.asList(getSepaAccount("EUR", "DE", "1212324", new ArrayList<>(Arrays.asList("AT", "DE"))))); + assertTrue(OfferBookViewModel.isAnyPaymentAccountValidForOffer( + getSEPAPaymentMethod("EUR", "AT", new ArrayList(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts)); + // empty paymentAccounts paymentAccounts = new ArrayList<>(); @@ -56,15 +60,20 @@ public void testIsAnyPaymentAccountValidForOffer() { assertTrue(OfferBookViewModel.isAnyPaymentAccountValidForOffer( getSameBankPaymentMethod("EUR", "AT", "PSK"), paymentAccounts)); - // offer: SpecificBanks paymentAccount: SpecificBanks - same country, same currency - paymentAccounts = new ArrayList<>(Arrays.asList(getSpecificBanksAccount("EUR", "AT", "PSK", - new ArrayList<>(Arrays.asList("PSK", "Raika"))))); + // offer: sepa paymentAccount: sepa - diff. country, same currency + paymentAccounts = new ArrayList<>(Arrays.asList(getSepaAccount("EUR", "DE", "1212324", new ArrayList<>(Arrays.asList("AT", "DE"))))); assertTrue(OfferBookViewModel.isAnyPaymentAccountValidForOffer( - getSpecificBanksPaymentMethod("EUR", "AT", "PSK", - new ArrayList<>(Arrays.asList("PSK", "Raika"))), paymentAccounts)); + getSEPAPaymentMethod("EUR", "AT", new ArrayList(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts)); + ////// + // offer: sepa paymentAccount: sepa - same country, same currency + paymentAccounts = new ArrayList<>(Arrays.asList(getSepaAccount("EUR", "AT", "1212324", new ArrayList<>(Arrays.asList("AT", "DE"))))); + assertTrue(OfferBookViewModel.isAnyPaymentAccountValidForOffer( + getSEPAPaymentMethod("EUR", "AT", new ArrayList(Arrays.asList("AT", "DE")), "PSK"), paymentAccounts)); + + // offer: sepa paymentAccount: nationalBank - same country, same currency // wrong method paymentAccounts = new ArrayList<>(Arrays.asList(getNationalBankAccount("EUR", "AT", "PSK"))); diff --git a/network/src/main/java/io/bitsquare/p2p/network/Connection.java b/network/src/main/java/io/bitsquare/p2p/network/Connection.java index 148f64f7a49..319ef0486f2 100644 --- a/network/src/main/java/io/bitsquare/p2p/network/Connection.java +++ b/network/src/main/java/io/bitsquare/p2p/network/Connection.java @@ -407,7 +407,7 @@ public void shutDown(CloseConnectionReason closeConnectionReason, @Nullable Runn } } else { //TODO find out why we get called that - log.warn("stopped was already true at shutDown call"); + log.debug("stopped was already at shutDown call"); UserThread.execute(() -> doShutDown(closeConnectionReason, shutDownCompleteHandler)); } } @@ -536,20 +536,13 @@ public void handleConnectionException(Throwable e) { closeConnectionReason = CloseConnectionReason.RESET; } else if (e instanceof SocketTimeoutException || e instanceof TimeoutException) { closeConnectionReason = CloseConnectionReason.SOCKET_TIMEOUT; - log.warn("SocketTimeoutException at socket " + socket.toString() + "\n\tconnection={}" + this); + log.debug("SocketTimeoutException at socket " + socket.toString() + "\n\tconnection={}" + this); } else if (e instanceof EOFException || e instanceof StreamCorruptedException) { closeConnectionReason = CloseConnectionReason.TERMINATED; } else { closeConnectionReason = CloseConnectionReason.UNKNOWN_EXCEPTION; - - String message; - if (e.getMessage() != null) - message = e.getMessage(); - else - message = e.toString(); - log.warn("Unknown reason for exception at socket {}\n\tconnection={}\n\tException=", - socket.toString(), this, message); + socket.toString(), this, e.toString()); e.printStackTrace(); } diff --git a/network/src/main/java/io/bitsquare/p2p/peers/BroadcastHandler.java b/network/src/main/java/io/bitsquare/p2p/peers/BroadcastHandler.java index bdf8592791e..b883aa8a684 100644 --- a/network/src/main/java/io/bitsquare/p2p/peers/BroadcastHandler.java +++ b/network/src/main/java/io/bitsquare/p2p/peers/BroadcastHandler.java @@ -112,14 +112,14 @@ public void broadcast(BroadcastMessage message, @Nullable NodeAddress sender, Re numOfPeers = connectedPeersList.size(); int factor = 1; if (!isDataOwner) { - // for not data owner (relay nodes) we send to max. 4 nodes and use a longer delay - numOfPeers = Math.min(4, connectedPeersList.size()); + // for not data owner (relay nodes) we send to max. 5 nodes and use a longer delay + numOfPeers = Math.min(5, connectedPeersList.size()); factor = 2; } log.info("Broadcast message to {} peers out of {} total connected peers.", numOfPeers, connectedPeersSet.size()); for (int i = 0; i < numOfPeers; i++) { - final long minDelay = i * 50 * factor + 1; - final long maxDelay = minDelay * 2 + 50 * factor; + final long minDelay = i * 30 * factor + 1; + final long maxDelay = minDelay * 2 + 30 * factor; final Connection connection = connectedPeersList.get(i); UserThread.runAfterRandomDelay(() -> sendToPeer(connection, message), minDelay, maxDelay, TimeUnit.MILLISECONDS); } diff --git a/network/src/main/java/io/bitsquare/p2p/peers/getdata/RequestDataHandler.java b/network/src/main/java/io/bitsquare/p2p/peers/getdata/RequestDataHandler.java index 3b021f81a87..7410d2e4b30 100644 --- a/network/src/main/java/io/bitsquare/p2p/peers/getdata/RequestDataHandler.java +++ b/network/src/main/java/io/bitsquare/p2p/peers/getdata/RequestDataHandler.java @@ -18,16 +18,12 @@ import io.bitsquare.p2p.peers.getdata.messages.GetUpdatedDataRequest; import io.bitsquare.p2p.peers.getdata.messages.PreliminaryGetDataRequest; import io.bitsquare.p2p.storage.P2PDataStorage; -import io.bitsquare.p2p.storage.storageentry.ProtectedStorageEntry; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.List; import java.util.Random; -import java.util.concurrent.TimeUnit; import static com.google.common.base.Preconditions.checkArgument; @@ -160,17 +156,10 @@ public void onMessage(Message message, Connection connection) { "RequestDataHandler.onMessage: connection.getPeersNodeAddressOptional() must be present " + "at that moment"); - final List dataList = new ArrayList<>(((GetDataResponse) message).dataSet); final NodeAddress sender = connection.getPeersNodeAddressOptional().get(); - for (int i = 0; i < dataList.size(); i++) { - // roughly 3-6 sec for 100 entries - final long minDelay = i * 30 + 1; - final long maxDelay = minDelay * 2 + 30; - final ProtectedStorageEntry protectedData = dataList.get(i); - // TODO questionable if it is needed to relay the data to our peers - UserThread.runAfterRandomDelay(() -> dataStorage.add(protectedData, sender, null, false), - minDelay, maxDelay, TimeUnit.MILLISECONDS); - } + ((GetDataResponse) message).dataSet.stream().forEach(protectedStorageEntry -> { + dataStorage.add(protectedStorageEntry, sender, null, false); + }); cleanup(); listener.onComplete(); diff --git a/network/src/main/java/io/bitsquare/p2p/storage/P2PDataStorage.java b/network/src/main/java/io/bitsquare/p2p/storage/P2PDataStorage.java index c908d37d56d..dea147e113a 100644 --- a/network/src/main/java/io/bitsquare/p2p/storage/P2PDataStorage.java +++ b/network/src/main/java/io/bitsquare/p2p/storage/P2PDataStorage.java @@ -254,7 +254,7 @@ public boolean refreshTTL(RefreshTTLMessage refreshTTLMessage, @Nullable NodeAdd return result; } } else { - log.warn("We don't have data for that refresh message in our map."); + log.debug("We don't have data for that refresh message in our map. That is expected if we missed the data publishing."); return false; } }