Merge remote-tracking branch 'origin/Allow_reopen_dispute' into doa_with_translations

This commit is contained in:
Manfred Karrer 2017-03-06 15:08:46 -05:00
commit 7f5441b953
5 changed files with 92 additions and 11 deletions

View File

@ -0,0 +1,24 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare 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.
*
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.arbitration;
public class DisputeAlreadyOpenException extends Exception {
public DisputeAlreadyOpenException() {
super();
}
}

View File

@ -31,7 +31,7 @@ import io.bitsquare.common.Timer;
import io.bitsquare.common.UserThread;
import io.bitsquare.common.crypto.KeyRing;
import io.bitsquare.common.crypto.PubKeyRing;
import io.bitsquare.common.handlers.ErrorMessageHandler;
import io.bitsquare.common.handlers.FaultHandler;
import io.bitsquare.common.handlers.ResultHandler;
import io.bitsquare.crypto.DecryptedMsgWithPubKey;
import io.bitsquare.p2p.BootstrapListener;
@ -184,6 +184,7 @@ public class DisputeManager {
private void applyMessages() {
decryptedDirectMessageWithPubKeys.forEach(decryptedMessageWithPubKey -> {
Message message = decryptedMessageWithPubKey.message;
log.debug("decryptedDirectMessageWithPubKeys.message " + message);
if (message instanceof DisputeMessage)
dispatchMessage((DisputeMessage) message);
});
@ -215,10 +216,10 @@ public class DisputeManager {
log.warn("Unsupported message at dispatchMessage.\nmessage=" + message);
}
public void sendOpenNewDisputeMessage(Dispute dispute, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
public void sendOpenNewDisputeMessage(Dispute dispute, boolean reOpen, ResultHandler resultHandler, FaultHandler faultHandler) {
if (!disputes.contains(dispute)) {
final Optional<Dispute> storedDisputeOptional = findDispute(dispute.getTradeId(), dispute.getTraderId());
if (!storedDisputeOptional.isPresent()) {
if (!storedDisputeOptional.isPresent() || reOpen) {
DisputeCommunicationMessage disputeCommunicationMessage = new DisputeCommunicationMessage(dispute.getTradeId(),
keyRing.getPubKeyRing().hashCode(),
true,
@ -228,8 +229,10 @@ public class DisputeManager {
p2PService.getAddress());
disputeCommunicationMessage.setIsSystemMessage(true);
dispute.addDisputeMessage(disputeCommunicationMessage);
if (!reOpen) {
disputes.add(dispute);
disputesObservableList.add(dispute);
}
p2PService.sendEncryptedMailboxMessage(dispute.getContract().arbitratorNodeAddress,
dispute.getArbitratorPubKeyRing(),
@ -250,7 +253,7 @@ public class DisputeManager {
@Override
public void onFault(String errorMessage) {
log.error("sendEncryptedMessage failed");
errorMessageHandler.handleErrorMessage("Sending dispute message failed: " + errorMessage);
faultHandler.handleFault("Sending dispute message failed: " + errorMessage, new MessageDeliveryFailedException());
}
}
);
@ -258,12 +261,12 @@ public class DisputeManager {
final String msg = "We got a dispute already open for that trade and trading peer.\n" +
"TradeId = " + dispute.getTradeId();
log.warn(msg);
errorMessageHandler.handleErrorMessage(msg);
faultHandler.handleFault(msg, new DisputeAlreadyOpenException());
}
} else {
final String msg = "We got a dispute msg what we have already stored. TradeId = " + dispute.getTradeId();
log.warn(msg);
errorMessageHandler.handleErrorMessage(msg);
faultHandler.handleFault(msg, new DisputeAlreadyOpenException());
}
}

View File

@ -0,0 +1,24 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare 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.
*
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.arbitration;
public class MessageDeliveryFailedException extends Exception {
public MessageDeliveryFailedException() {
super();
}
}

View File

@ -21,6 +21,7 @@ import com.google.inject.Inject;
import io.bitsquare.app.Log;
import io.bitsquare.arbitration.Arbitrator;
import io.bitsquare.arbitration.Dispute;
import io.bitsquare.arbitration.DisputeAlreadyOpenException;
import io.bitsquare.arbitration.DisputeManager;
import io.bitsquare.btc.provider.fee.FeeService;
import io.bitsquare.btc.wallet.BtcWalletService;
@ -397,9 +398,7 @@ public class PendingTradesDataModel extends ActivatableDataModel {
trade.setDisputeState(Trade.DisputeState.DISPUTE_REQUESTED);
if (p2PService.isBootstrapped()) {
disputeManager.sendOpenNewDisputeMessage(dispute,
() -> navigation.navigateTo(MainView.class, DisputesView.class),
errorMessage -> new Popup().warning(errorMessage).show());
sendOpenNewDisputeMessage(dispute, false);
} else {
new Popup().information("You need to wait until you are fully connected to the network.\n" +
"That might take up to about 2 minutes at startup.").show();
@ -408,5 +407,25 @@ public class PendingTradesDataModel extends ActivatableDataModel {
log.warn("trade is null at doOpenDispute");
}
}
private void sendOpenNewDisputeMessage(Dispute dispute, boolean reOpen) {
disputeManager.sendOpenNewDisputeMessage(dispute,
reOpen,
() -> navigation.navigateTo(MainView.class, DisputesView.class),
(errorMessage, throwable) -> {
if ((throwable instanceof DisputeAlreadyOpenException)) {
errorMessage += "\n\n" +
"If you are not sure that the message to the arbitrator arrived (e.g. if you did not got " +
"a response after 1 day) feel free to open a dispute again.";
new Popup().warning(errorMessage)
.actionButtonText("Open dispute again")
.onAction(() -> sendOpenNewDisputeMessage(dispute, true))
.closeButtonText("Cancel")
.show();
} else {
new Popup().warning(errorMessage).show();
}
});
}
}

View File

@ -700,6 +700,17 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
}
public void removeEntryFromMailbox(DecryptedMsgWithPubKey decryptedMsgWithPubKey) {
// We need to delay a bit to avoid that we remove our msg then get it from other peers again and reapply it again.
// If we delay the removal we have better chances that repeated messages we got from other peers are already filtered
// at the P2PService layer.
// Though we have to check in the client classes to not apply the same message again as there is no guarantee
// when we would get a message again from the network.
UserThread.runAfter(() -> {
delayedRemoveEntryFromMailbox(decryptedMsgWithPubKey);
}, 2);
}
private void delayedRemoveEntryFromMailbox(DecryptedMsgWithPubKey decryptedMsgWithPubKey) {
Log.traceCall();
checkArgument(optionalKeyRing.isPresent(), "keyRing not set. Seems that is called on a seed node which must not happen.");
if (isBootstrapped()) {