Fix issues with delayed mailbox messages, handle ui state when peer is offline

This commit is contained in:
Manfred Karrer 2016-03-11 16:44:25 +01:00
parent 4fc3b00fa4
commit 7c63e5ab00
11 changed files with 55 additions and 49 deletions

View File

@ -63,7 +63,7 @@ public class Log {
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);
}

View File

@ -221,7 +221,7 @@ public abstract class Trade implements Tradable, Model {
OpenOfferManager openOfferManager,
User user,
KeyRing keyRing) {
Log.traceCall();
processModel.onAllServicesInitialized(offer,
tradeManager,
openOfferManager,
@ -234,6 +234,7 @@ public abstract class Trade implements Tradable, Model {
createProtocol();
log.trace("decryptedMsgWithPubKey = " + decryptedMsgWithPubKey);
if (decryptedMsgWithPubKey != null) {
tradeProtocol.applyMailboxMessage(decryptedMsgWithPubKey, this);
}

View File

@ -171,7 +171,7 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
isSpinnerVisible.set(false);
spinnerInfoText.set("");
} else if (showPayFundsScreenDisplayed) {
spinnerInfoText.set("Waiting for funds...");
spinnerInfoText.set("Waiting for receiving funds...");
isSpinnerVisible.set(true);
}
}

View File

@ -453,7 +453,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
isSpinnerVisible.set(false);
spinnerInfoText.set("");
} else if (showPayFundsScreenDisplayed) {
spinnerInfoText.set("Waiting for funds...");
spinnerInfoText.set("Waiting for receiving funds...");
isSpinnerVisible.set(true);
}
}

View File

@ -301,6 +301,7 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
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:

View File

@ -93,9 +93,13 @@ public class BuyerStep4View extends TradeStepView {
@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 @@ public class BuyerStep4View extends TradeStepView {
@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 @@ public class BuyerStep4View extends TradeStepView {
///////////////////////////////////////////////////////////////////////////////////////////
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());
}
}

View File

@ -24,6 +24,10 @@ public class OfferBookViewModelTest {
Offer offer;
Collection<PaymentAccount> 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 class OfferBookViewModelTest {
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")));

View File

@ -407,7 +407,7 @@ public class Connection implements MessageListener {
}
} 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 class Connection implements MessageListener {
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();
}

View File

@ -112,14 +112,14 @@ public class BroadcastHandler implements PeerManager.Listener {
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);
}

View File

@ -18,16 +18,12 @@ import io.bitsquare.p2p.peers.getdata.messages.GetDataResponse;
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 class RequestDataHandler implements MessageListener {
"RequestDataHandler.onMessage: connection.getPeersNodeAddressOptional() must be present " +
"at that moment");
final List<ProtectedStorageEntry> 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();

View File

@ -254,7 +254,7 @@ public class P2PDataStorage implements MessageListener, ConnectionListener {
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;
}
}