mirror of
https://github.com/boldsuck/haveno.git
synced 2024-12-22 20:19:21 +00:00
commit
c8a91de1b2
10 changed files with 126 additions and 127 deletions
|
@ -610,7 +610,7 @@ configure(project(':desktop')) {
|
|||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
apply from: 'package/package.gradle'
|
||||
|
||||
version = '1.0.13-SNAPSHOT'
|
||||
version = '1.0.14-SNAPSHOT'
|
||||
|
||||
jar.manifest.attributes(
|
||||
"Implementation-Title": project.name,
|
||||
|
|
|
@ -28,7 +28,7 @@ import static com.google.common.base.Preconditions.checkArgument;
|
|||
public class Version {
|
||||
// The application versions
|
||||
// We use semantic versioning with major, minor and patch
|
||||
public static final String VERSION = "1.0.13";
|
||||
public static final String VERSION = "1.0.14";
|
||||
|
||||
/**
|
||||
* Holds a list of the tagged resource files for optimizing the getData requests.
|
||||
|
|
|
@ -32,6 +32,7 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
|
@ -76,11 +77,11 @@ public class FileUtil {
|
|||
|
||||
public static List<File> getBackupFiles(File dir, String fileName) {
|
||||
File backupDir = new File(Paths.get(dir.getAbsolutePath(), BACKUP_DIR).toString());
|
||||
if (!backupDir.exists()) return null;
|
||||
if (!backupDir.exists()) return new ArrayList<File>();
|
||||
String dirName = "backups_" + fileName;
|
||||
if (dirName.contains(".")) dirName = dirName.replace(".", "_");
|
||||
File backupFileDir = new File(Paths.get(backupDir.getAbsolutePath(), dirName).toString());
|
||||
if (!backupFileDir.exists()) return null;
|
||||
if (!backupFileDir.exists()) return new ArrayList<File>();
|
||||
File[] files = backupFileDir.listFiles();
|
||||
return Arrays.asList(files);
|
||||
}
|
||||
|
|
|
@ -467,7 +467,7 @@ public final class Dispute implements NetworkPayload, PersistablePayload {
|
|||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return this.disputeState == State.OPEN || this.disputeState == State.REOPENED;
|
||||
return isNew() || this.disputeState == State.OPEN || this.disputeState == State.REOPENED;
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
|
|
|
@ -359,6 +359,13 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
return;
|
||||
}
|
||||
|
||||
// skip if payout is confirmed
|
||||
if (trade.isPayoutConfirmed()) {
|
||||
String errorMsg = "Cannot open dispute because payout is already confirmed for " + trade.getClass().getSimpleName() + " " + trade.getId();
|
||||
faultHandler.handleFault(errorMsg, new IllegalStateException(errorMsg));
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (disputeList.getObservableList()) {
|
||||
if (disputeList.contains(dispute)) {
|
||||
String msg = "We got a dispute msg that we have already stored. TradeId = " + dispute.getTradeId() + ", DisputeId = " + dispute.getId();
|
||||
|
@ -368,116 +375,109 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
}
|
||||
|
||||
Optional<Dispute> storedDisputeOptional = findDispute(dispute);
|
||||
boolean reOpen = storedDisputeOptional.isPresent() && storedDisputeOptional.get().isClosed();
|
||||
if (!storedDisputeOptional.isPresent() || reOpen) {
|
||||
boolean reOpen = storedDisputeOptional.isPresent();
|
||||
|
||||
// add or re-open dispute
|
||||
if (reOpen) {
|
||||
dispute = storedDisputeOptional.get();
|
||||
} else {
|
||||
disputeList.add(dispute);
|
||||
}
|
||||
|
||||
String disputeInfo = getDisputeInfo(dispute);
|
||||
String sysMsg = dispute.isSupportTicket() ?
|
||||
Res.get("support.youOpenedTicket", disputeInfo, Version.VERSION) :
|
||||
Res.get("support.youOpenedDispute", disputeInfo, Version.VERSION);
|
||||
|
||||
ChatMessage chatMessage = new ChatMessage(
|
||||
getSupportType(),
|
||||
dispute.getTradeId(),
|
||||
keyRing.getPubKeyRing().hashCode(),
|
||||
false,
|
||||
Res.get("support.systemMsg", sysMsg),
|
||||
p2PService.getAddress());
|
||||
chatMessage.setSystemMessage(true);
|
||||
dispute.addAndPersistChatMessage(chatMessage);
|
||||
|
||||
// export latest multisig hex
|
||||
try {
|
||||
trade.exportMultisigHex();
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to export multisig hex", e);
|
||||
}
|
||||
|
||||
// create dispute opened message
|
||||
NodeAddress agentNodeAddress = getAgentNodeAddress(dispute);
|
||||
DisputeOpenedMessage disputeOpenedMessage = new DisputeOpenedMessage(dispute,
|
||||
p2PService.getAddress(),
|
||||
UUID.randomUUID().toString(),
|
||||
getSupportType(),
|
||||
trade.getSelf().getUpdatedMultisigHex(),
|
||||
trade.getArbitrator().getPaymentSentMessage());
|
||||
log.info("Send {} to peer {}. tradeId={}, openNewDisputeMessage.uid={}, " +
|
||||
"chatMessage.uid={}",
|
||||
disputeOpenedMessage.getClass().getSimpleName(), agentNodeAddress,
|
||||
disputeOpenedMessage.getTradeId(), disputeOpenedMessage.getUid(),
|
||||
chatMessage.getUid());
|
||||
recordPendingMessage(disputeOpenedMessage.getClass().getSimpleName());
|
||||
|
||||
// send dispute opened message
|
||||
trade.setDisputeState(Trade.DisputeState.DISPUTE_REQUESTED);
|
||||
mailboxMessageService.sendEncryptedMailboxMessage(agentNodeAddress,
|
||||
dispute.getAgentPubKeyRing(),
|
||||
disputeOpenedMessage,
|
||||
new SendMailboxMessageListener() {
|
||||
@Override
|
||||
public void onArrived() {
|
||||
log.info("{} arrived at peer {}. tradeId={}, openNewDisputeMessage.uid={}, " +
|
||||
"chatMessage.uid={}",
|
||||
disputeOpenedMessage.getClass().getSimpleName(), agentNodeAddress,
|
||||
disputeOpenedMessage.getTradeId(), disputeOpenedMessage.getUid(),
|
||||
chatMessage.getUid());
|
||||
clearPendingMessage();
|
||||
|
||||
// We use the chatMessage wrapped inside the openNewDisputeMessage for
|
||||
// the state, as that is displayed to the user and we only persist that msg
|
||||
chatMessage.setArrived(true);
|
||||
trade.advanceDisputeState(Trade.DisputeState.DISPUTE_REQUESTED);
|
||||
requestPersistence();
|
||||
resultHandler.handleResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStoredInMailbox() {
|
||||
log.info("{} stored in mailbox for peer {}. tradeId={}, openNewDisputeMessage.uid={}, " +
|
||||
"chatMessage.uid={}",
|
||||
disputeOpenedMessage.getClass().getSimpleName(), agentNodeAddress,
|
||||
disputeOpenedMessage.getTradeId(), disputeOpenedMessage.getUid(),
|
||||
chatMessage.getUid());
|
||||
clearPendingMessage();
|
||||
|
||||
// We use the chatMessage wrapped inside the openNewDisputeMessage for
|
||||
// the state, as that is displayed to the user and we only persist that msg
|
||||
chatMessage.setStoredInMailbox(true);
|
||||
requestPersistence();
|
||||
resultHandler.handleResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFault(String errorMessage) {
|
||||
log.error("{} failed: Peer {}. tradeId={}, openNewDisputeMessage.uid={}, " +
|
||||
"chatMessage.uid={}, errorMessage={}",
|
||||
disputeOpenedMessage.getClass().getSimpleName(), agentNodeAddress,
|
||||
disputeOpenedMessage.getTradeId(), disputeOpenedMessage.getUid(),
|
||||
chatMessage.getUid(), errorMessage);
|
||||
|
||||
clearPendingMessage();
|
||||
// We use the chatMessage wrapped inside the openNewDisputeMessage for
|
||||
// the state, as that is displayed to the user and we only persist that msg
|
||||
chatMessage.setSendMessageError(errorMessage);
|
||||
trade.setDisputeState(Trade.DisputeState.NO_DISPUTE);
|
||||
requestPersistence();
|
||||
faultHandler.handleFault("Sending dispute message failed: " +
|
||||
errorMessage, new DisputeMessageDeliveryFailedException());
|
||||
}
|
||||
});
|
||||
// add or re-open dispute
|
||||
if (reOpen) {
|
||||
dispute = storedDisputeOptional.get();
|
||||
} else {
|
||||
String msg = "We got a dispute already open for that trade and trading peer.\n" +
|
||||
"TradeId = " + dispute.getTradeId();
|
||||
log.warn(msg);
|
||||
faultHandler.handleFault(msg, new DisputeAlreadyOpenException());
|
||||
disputeList.add(dispute);
|
||||
}
|
||||
|
||||
String disputeInfo = getDisputeInfo(dispute);
|
||||
String sysMsg = dispute.isSupportTicket() ?
|
||||
Res.get("support.youOpenedTicket", disputeInfo, Version.VERSION) :
|
||||
Res.get("support.youOpenedDispute", disputeInfo, Version.VERSION);
|
||||
|
||||
ChatMessage chatMessage = new ChatMessage(
|
||||
getSupportType(),
|
||||
dispute.getTradeId(),
|
||||
keyRing.getPubKeyRing().hashCode(),
|
||||
false,
|
||||
Res.get("support.systemMsg", sysMsg),
|
||||
p2PService.getAddress());
|
||||
chatMessage.setSystemMessage(true);
|
||||
dispute.addAndPersistChatMessage(chatMessage);
|
||||
|
||||
// export latest multisig hex
|
||||
try {
|
||||
trade.exportMultisigHex();
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to export multisig hex", e);
|
||||
}
|
||||
|
||||
// create dispute opened message
|
||||
NodeAddress agentNodeAddress = getAgentNodeAddress(dispute);
|
||||
DisputeOpenedMessage disputeOpenedMessage = new DisputeOpenedMessage(dispute,
|
||||
p2PService.getAddress(),
|
||||
UUID.randomUUID().toString(),
|
||||
getSupportType(),
|
||||
trade.getSelf().getUpdatedMultisigHex(),
|
||||
trade.getArbitrator().getPaymentSentMessage());
|
||||
log.info("Send {} to peer {}. tradeId={}, openNewDisputeMessage.uid={}, " +
|
||||
"chatMessage.uid={}",
|
||||
disputeOpenedMessage.getClass().getSimpleName(), agentNodeAddress,
|
||||
disputeOpenedMessage.getTradeId(), disputeOpenedMessage.getUid(),
|
||||
chatMessage.getUid());
|
||||
recordPendingMessage(disputeOpenedMessage.getClass().getSimpleName());
|
||||
|
||||
// send dispute opened message
|
||||
trade.setDisputeState(Trade.DisputeState.DISPUTE_REQUESTED);
|
||||
mailboxMessageService.sendEncryptedMailboxMessage(agentNodeAddress,
|
||||
dispute.getAgentPubKeyRing(),
|
||||
disputeOpenedMessage,
|
||||
new SendMailboxMessageListener() {
|
||||
@Override
|
||||
public void onArrived() {
|
||||
log.info("{} arrived at peer {}. tradeId={}, openNewDisputeMessage.uid={}, " +
|
||||
"chatMessage.uid={}",
|
||||
disputeOpenedMessage.getClass().getSimpleName(), agentNodeAddress,
|
||||
disputeOpenedMessage.getTradeId(), disputeOpenedMessage.getUid(),
|
||||
chatMessage.getUid());
|
||||
clearPendingMessage();
|
||||
|
||||
// We use the chatMessage wrapped inside the openNewDisputeMessage for
|
||||
// the state, as that is displayed to the user and we only persist that msg
|
||||
chatMessage.setArrived(true);
|
||||
trade.advanceDisputeState(Trade.DisputeState.DISPUTE_REQUESTED);
|
||||
requestPersistence();
|
||||
resultHandler.handleResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStoredInMailbox() {
|
||||
log.info("{} stored in mailbox for peer {}. tradeId={}, openNewDisputeMessage.uid={}, " +
|
||||
"chatMessage.uid={}",
|
||||
disputeOpenedMessage.getClass().getSimpleName(), agentNodeAddress,
|
||||
disputeOpenedMessage.getTradeId(), disputeOpenedMessage.getUid(),
|
||||
chatMessage.getUid());
|
||||
clearPendingMessage();
|
||||
|
||||
// We use the chatMessage wrapped inside the openNewDisputeMessage for
|
||||
// the state, as that is displayed to the user and we only persist that msg
|
||||
chatMessage.setStoredInMailbox(true);
|
||||
requestPersistence();
|
||||
resultHandler.handleResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFault(String errorMessage) {
|
||||
log.error("{} failed: Peer {}. tradeId={}, openNewDisputeMessage.uid={}, " +
|
||||
"chatMessage.uid={}, errorMessage={}",
|
||||
disputeOpenedMessage.getClass().getSimpleName(), agentNodeAddress,
|
||||
disputeOpenedMessage.getTradeId(), disputeOpenedMessage.getUid(),
|
||||
chatMessage.getUid(), errorMessage);
|
||||
|
||||
clearPendingMessage();
|
||||
// We use the chatMessage wrapped inside the openNewDisputeMessage for
|
||||
// the state, as that is displayed to the user and we only persist that msg
|
||||
chatMessage.setSendMessageError(errorMessage);
|
||||
trade.setDisputeState(Trade.DisputeState.NO_DISPUTE);
|
||||
requestPersistence();
|
||||
faultHandler.handleFault("Sending dispute message failed: " +
|
||||
errorMessage, new DisputeMessageDeliveryFailedException());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
requestPersistence();
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
<!-- See: https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -->
|
||||
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0.13</string>
|
||||
<string>1.0.14</string>
|
||||
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.13</string>
|
||||
<string>1.0.14</string>
|
||||
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>Haveno</string>
|
||||
|
|
|
@ -308,7 +308,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
|||
if (CurrencyUtil.isTraditionalCurrency(tradeCurrency.getCode())) {
|
||||
placeOfferButtonLabel = Res.get("createOffer.placeOfferButton", Res.get("shared.buy"));
|
||||
} else {
|
||||
placeOfferButtonLabel = Res.get("createOffer.placeOfferButtonCrypto", Res.get("shared.buy"), tradeCurrency.getCode());
|
||||
placeOfferButtonLabel = Res.get("createOffer.placeOfferButtonCrypto", Res.get("shared.sell"), tradeCurrency.getCode());
|
||||
}
|
||||
nextButton.setId("buy-button");
|
||||
fundFromSavingsWalletButton.setId("buy-button");
|
||||
|
@ -317,7 +317,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
|||
if (CurrencyUtil.isTraditionalCurrency(tradeCurrency.getCode())) {
|
||||
placeOfferButtonLabel = Res.get("createOffer.placeOfferButton", Res.get("shared.sell"));
|
||||
} else {
|
||||
placeOfferButtonLabel = Res.get("createOffer.placeOfferButtonCrypto", Res.get("shared.sell"), tradeCurrency.getCode());
|
||||
placeOfferButtonLabel = Res.get("createOffer.placeOfferButtonCrypto", Res.get("shared.buy"), tradeCurrency.getCode());
|
||||
}
|
||||
nextButton.setId("sell-button");
|
||||
fundFromSavingsWalletButton.setId("sell-button");
|
||||
|
@ -707,10 +707,10 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
|
|||
triggerPriceInputTextField.clear();
|
||||
if (!CurrencyUtil.isTraditionalCurrency(newValue)) {
|
||||
if (model.isShownAsBuyOffer()) {
|
||||
placeOfferButton.updateText(Res.get("createOffer.placeOfferButtonCrypto", Res.get("shared.buy"),
|
||||
placeOfferButton.updateText(Res.get("createOffer.placeOfferButtonCrypto", Res.get("shared.sell"),
|
||||
model.getTradeCurrency().getCode()));
|
||||
} else {
|
||||
placeOfferButton.updateText(Res.get("createOffer.placeOfferButtonCrypto", Res.get("shared.sell"),
|
||||
placeOfferButton.updateText(Res.get("createOffer.placeOfferButtonCrypto", Res.get("shared.buy"),
|
||||
model.getTradeCurrency().getCode()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -402,9 +402,7 @@ abstract class OfferBookViewModel extends ActivatableViewModel {
|
|||
}
|
||||
|
||||
public Optional<Double> getMarketBasedPrice(Offer offer) {
|
||||
OfferDirection displayDirection = offer.isTraditionalOffer() ? direction :
|
||||
direction.equals(OfferDirection.BUY) ? OfferDirection.SELL : OfferDirection.BUY;
|
||||
return priceUtil.getMarketBasedPrice(offer, displayDirection);
|
||||
return priceUtil.getMarketBasedPrice(offer, direction);
|
||||
}
|
||||
|
||||
String formatMarketPriceMarginPct(Offer offer) {
|
||||
|
|
|
@ -306,12 +306,12 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
takeOfferButton.setId("buy-button-big");
|
||||
nextButton.setId("buy-button");
|
||||
fundFromSavingsWalletButton.setId("buy-button");
|
||||
takeOfferButton.updateText(getTakeOfferLabel(offer, Res.get("shared.buy")));
|
||||
takeOfferButton.updateText(getTakeOfferLabel(offer, false));
|
||||
} else {
|
||||
takeOfferButton.setId("sell-button-big");
|
||||
nextButton.setId("sell-button");
|
||||
fundFromSavingsWalletButton.setId("sell-button");
|
||||
takeOfferButton.updateText(getTakeOfferLabel(offer, Res.get("shared.sell")));
|
||||
takeOfferButton.updateText(getTakeOfferLabel(offer, true));
|
||||
}
|
||||
priceAsPercentageDescription.setText(model.getPercentagePriceDescription());
|
||||
|
||||
|
@ -1232,11 +1232,11 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
|||
}
|
||||
|
||||
@NotNull
|
||||
private String getTakeOfferLabel(Offer offer, String direction) {
|
||||
private String getTakeOfferLabel(Offer offer, boolean isBuyOffer) {
|
||||
return offer.isTraditionalOffer() ?
|
||||
Res.get("takeOffer.takeOfferButton", direction) :
|
||||
Res.get("takeOffer.takeOfferButton", isBuyOffer ? Res.get("shared.sell") : Res.get("shared.buy")) :
|
||||
Res.get("takeOffer.takeOfferButtonCrypto",
|
||||
direction,
|
||||
isBuyOffer ? Res.get("shared.buy") : Res.get("shared.sell"),
|
||||
offer.getCurrencyCode());
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
@Slf4j
|
||||
public class SeedNodeMain extends ExecutableForAppWithP2p {
|
||||
private static final long CHECK_CONNECTION_LOSS_SEC = 30;
|
||||
private static final String VERSION = "1.0.13";
|
||||
private static final String VERSION = "1.0.14";
|
||||
private SeedNode seedNode;
|
||||
private Timer checkConnectionLossTime;
|
||||
|
||||
|
|
Loading…
Reference in a new issue