mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-04-19 23:36:00 -04:00
Fix issues with delayed mailbox messages, handle ui state when peer is offline
This commit is contained in:
parent
4fc3b00fa4
commit
7c63e5ab00
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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")));
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user