mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-07-26 16:35:18 -04:00
check trades, disputes, and offers and add prompt on shut down
Co-authored-by: jmacxx <47253594+jmacxx@users.noreply.github.com>
This commit is contained in:
parent
3b89212c6f
commit
cb7d9364e5
14 changed files with 155 additions and 217 deletions
|
@ -114,7 +114,7 @@ public abstract class SupportManager {
|
|||
|
||||
public abstract boolean channelOpen(ChatMessage message);
|
||||
|
||||
public abstract List<ChatMessage> getAllChatMessages();
|
||||
public abstract List<ChatMessage> getAllChatMessages(String tradeId);
|
||||
|
||||
public abstract void addAndPersistChatMessage(ChatMessage message);
|
||||
|
||||
|
@ -204,7 +204,7 @@ public abstract class SupportManager {
|
|||
ackMessage.getSourceMsgClassName(), ackMessage.getSourceId(), ackMessage.getErrorMessage());
|
||||
}
|
||||
|
||||
getAllChatMessages().stream()
|
||||
getAllChatMessages(ackMessage.getSourceId()).stream()
|
||||
.filter(msg -> msg.getUid().equals(ackMessage.getSourceUid()))
|
||||
.forEach(msg -> {
|
||||
if (ackMessage.isSuccess())
|
||||
|
|
|
@ -92,12 +92,8 @@ public final class Dispute implements NetworkPayload, PersistablePayload {
|
|||
@Nullable
|
||||
private final byte[] contractHash;
|
||||
@Nullable
|
||||
private final byte[] depositTxSerialized;
|
||||
@Nullable
|
||||
private final byte[] payoutTxSerialized;
|
||||
@Nullable
|
||||
private final String depositTxId;
|
||||
@Nullable
|
||||
private final String payoutTxId;
|
||||
private String contractAsJson;
|
||||
@Nullable
|
||||
|
@ -171,9 +167,7 @@ public final class Dispute implements NetworkPayload, PersistablePayload {
|
|||
long tradePeriodEnd,
|
||||
Contract contract,
|
||||
@Nullable byte[] contractHash,
|
||||
@Nullable byte[] depositTxSerialized,
|
||||
@Nullable byte[] payoutTxSerialized,
|
||||
@Nullable String depositTxId,
|
||||
@Nullable String payoutTxId,
|
||||
String contractAsJson,
|
||||
@Nullable byte[] makerContractSignature,
|
||||
|
@ -194,9 +188,7 @@ public final class Dispute implements NetworkPayload, PersistablePayload {
|
|||
this.tradePeriodEnd = tradePeriodEnd;
|
||||
this.contract = contract;
|
||||
this.contractHash = contractHash;
|
||||
this.depositTxSerialized = depositTxSerialized;
|
||||
this.payoutTxSerialized = payoutTxSerialized;
|
||||
this.depositTxId = depositTxId;
|
||||
this.payoutTxId = payoutTxId;
|
||||
this.contractAsJson = contractAsJson;
|
||||
this.makerContractSignature = makerContractSignature;
|
||||
|
@ -243,9 +235,7 @@ public final class Dispute implements NetworkPayload, PersistablePayload {
|
|||
.setId(id);
|
||||
|
||||
Optional.ofNullable(contractHash).ifPresent(e -> builder.setContractHash(ByteString.copyFrom(e)));
|
||||
Optional.ofNullable(depositTxSerialized).ifPresent(e -> builder.setDepositTxSerialized(ByteString.copyFrom(e)));
|
||||
Optional.ofNullable(payoutTxSerialized).ifPresent(e -> builder.setPayoutTxSerialized(ByteString.copyFrom(e)));
|
||||
Optional.ofNullable(depositTxId).ifPresent(builder::setDepositTxId);
|
||||
Optional.ofNullable(payoutTxId).ifPresent(builder::setPayoutTxId);
|
||||
Optional.ofNullable(disputePayoutTxId).ifPresent(builder::setDisputePayoutTxId);
|
||||
Optional.ofNullable(makerContractSignature).ifPresent(e -> builder.setMakerContractSignature(ByteString.copyFrom(e)));
|
||||
|
@ -273,9 +263,7 @@ public final class Dispute implements NetworkPayload, PersistablePayload {
|
|||
proto.getTradePeriodEnd(),
|
||||
Contract.fromProto(proto.getContract(), coreProtoResolver),
|
||||
ProtoUtil.byteArrayOrNullFromProto(proto.getContractHash()),
|
||||
ProtoUtil.byteArrayOrNullFromProto(proto.getDepositTxSerialized()),
|
||||
ProtoUtil.byteArrayOrNullFromProto(proto.getPayoutTxSerialized()),
|
||||
ProtoUtil.stringOrNullFromProto(proto.getDepositTxId()),
|
||||
ProtoUtil.stringOrNullFromProto(proto.getPayoutTxId()),
|
||||
proto.getContractAsJson(),
|
||||
ProtoUtil.byteArrayOrNullFromProto(proto.getMakerContractSignature()),
|
||||
|
@ -516,9 +504,7 @@ public final class Dispute implements NetworkPayload, PersistablePayload {
|
|||
",\n tradePeriodEnd=" + tradePeriodEnd +
|
||||
",\n contract=" + contract +
|
||||
",\n contractHash=" + Utilities.bytesAsHexString(contractHash) +
|
||||
",\n depositTxSerialized=" + Utilities.bytesAsHexString(depositTxSerialized) +
|
||||
",\n payoutTxSerialized=" + Utilities.bytesAsHexString(payoutTxSerialized) +
|
||||
",\n depositTxId='" + depositTxId + '\'' +
|
||||
",\n payoutTxId='" + payoutTxId + '\'' +
|
||||
",\n contractAsJson='" + contractAsJson + '\'' +
|
||||
",\n makerContractSignature='" + Utilities.bytesAsHexString(makerContractSignature) + '\'' +
|
||||
|
|
|
@ -91,6 +91,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
protected final DisputeListService<T> disputeListService;
|
||||
private final Config config;
|
||||
private final PriceFeedService priceFeedService;
|
||||
protected String pendingOutgoingMessage;
|
||||
|
||||
@Getter
|
||||
protected final ObservableList<DisputeValidation.ValidationException> validationExceptions =
|
||||
|
@ -122,6 +123,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
this.disputeListService = disputeListService;
|
||||
this.config = config;
|
||||
this.priceFeedService = priceFeedService;
|
||||
clearPendingMessage();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -140,7 +142,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
@Override
|
||||
public NodeAddress getPeerNodeAddress(ChatMessage message) {
|
||||
Optional<Dispute> disputeOptional = findDispute(message);
|
||||
if (!disputeOptional.isPresent()) {
|
||||
if (disputeOptional.isEmpty()) {
|
||||
log.warn("Could not find dispute for tradeId = {} traderId = {}",
|
||||
message.getTradeId(), message.getTraderId());
|
||||
return null;
|
||||
|
@ -151,7 +153,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
@Override
|
||||
public PubKeyRing getPeerPubKeyRing(ChatMessage message) {
|
||||
Optional<Dispute> disputeOptional = findDispute(message);
|
||||
if (!disputeOptional.isPresent()) {
|
||||
if (disputeOptional.isEmpty()) {
|
||||
log.warn("Could not find dispute for tradeId = {} traderId = {}",
|
||||
message.getTradeId(), message.getTraderId());
|
||||
return null;
|
||||
|
@ -161,12 +163,11 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ChatMessage> getAllChatMessages() {
|
||||
synchronized (getDisputeList()) {
|
||||
return getDisputeList().stream()
|
||||
.flatMap(dispute -> dispute.getChatMessages().stream())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
public List<ChatMessage> getAllChatMessages(String tradeId) {
|
||||
return getDisputeList().stream()
|
||||
.filter(dispute -> dispute.getTradeId().equals(tradeId))
|
||||
.flatMap(dispute -> dispute.getChatMessages().stream())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -369,6 +370,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
disputeOpenedMessage.getClass().getSimpleName(), agentNodeAddress,
|
||||
disputeOpenedMessage.getTradeId(), disputeOpenedMessage.getUid(),
|
||||
chatMessage.getUid());
|
||||
recordPendingMessage(disputeOpenedMessage.getClass().getSimpleName());
|
||||
mailboxMessageService.sendEncryptedMailboxMessage(agentNodeAddress,
|
||||
dispute.getAgentPubKeyRing(),
|
||||
disputeOpenedMessage,
|
||||
|
@ -380,6 +382,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
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
|
||||
|
@ -396,6 +399,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
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
|
||||
|
@ -413,6 +417,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
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);
|
||||
|
@ -586,9 +591,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
disputeFromOpener.getTradePeriodEnd().getTime(),
|
||||
contractFromOpener,
|
||||
disputeFromOpener.getContractHash(),
|
||||
disputeFromOpener.getDepositTxSerialized(),
|
||||
disputeFromOpener.getPayoutTxSerialized(),
|
||||
disputeFromOpener.getDepositTxId(),
|
||||
disputeFromOpener.getPayoutTxId(),
|
||||
disputeFromOpener.getContractAsJson(),
|
||||
disputeFromOpener.getMakerContractSignature(),
|
||||
|
@ -653,6 +656,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
peerOpenedDisputeMessage.getClass().getSimpleName(), peersNodeAddress,
|
||||
peerOpenedDisputeMessage.getTradeId(), peerOpenedDisputeMessage.getUid(),
|
||||
chatMessage.getUid());
|
||||
recordPendingMessage(peerOpenedDisputeMessage.getClass().getSimpleName());
|
||||
mailboxMessageService.sendEncryptedMailboxMessage(peersNodeAddress,
|
||||
peersPubKeyRing,
|
||||
peerOpenedDisputeMessage,
|
||||
|
@ -665,6 +669,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
peerOpenedDisputeMessage.getTradeId(), peerOpenedDisputeMessage.getUid(),
|
||||
chatMessage.getUid());
|
||||
|
||||
clearPendingMessage();
|
||||
// We use the chatMessage wrapped inside the peerOpenedDisputeMessage for
|
||||
// the state, as that is displayed to the user and we only persist that msg
|
||||
chatMessage.setArrived(true);
|
||||
|
@ -679,6 +684,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
peerOpenedDisputeMessage.getTradeId(), peerOpenedDisputeMessage.getUid(),
|
||||
chatMessage.getUid());
|
||||
|
||||
clearPendingMessage();
|
||||
// We use the chatMessage wrapped inside the peerOpenedDisputeMessage for
|
||||
// the state, as that is displayed to the user and we only persist that msg
|
||||
chatMessage.setStoredInMailbox(true);
|
||||
|
@ -693,6 +699,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
peerOpenedDisputeMessage.getTradeId(), peerOpenedDisputeMessage.getUid(),
|
||||
chatMessage.getUid(), errorMessage);
|
||||
|
||||
clearPendingMessage();
|
||||
// We use the chatMessage wrapped inside the peerOpenedDisputeMessage for
|
||||
// the state, as that is displayed to the user and we only persist that msg
|
||||
chatMessage.setSendMessageError(errorMessage);
|
||||
|
@ -749,6 +756,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
disputeClosedMessage.getClass().getSimpleName(), receiver.getNodeAddress(),
|
||||
disputeClosedMessage.getClass().getSimpleName(), disputeClosedMessage.getTradeId(),
|
||||
disputeClosedMessage.getUid(), disputeResult.getChatMessage().getUid());
|
||||
recordPendingMessage(disputeClosedMessage.getClass().getSimpleName());
|
||||
mailboxMessageService.sendEncryptedMailboxMessage(receiver.getNodeAddress(),
|
||||
dispute.getTraderPubKeyRing(),
|
||||
disputeClosedMessage,
|
||||
|
@ -761,6 +769,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
disputeClosedMessage.getTradeId(), disputeClosedMessage.getUid(),
|
||||
disputeResult.getChatMessage().getUid());
|
||||
|
||||
clearPendingMessage();
|
||||
// We use the chatMessage wrapped inside the DisputeClosedMessage for
|
||||
// the state, as that is displayed to the user and we only persist that msg
|
||||
disputeResult.getChatMessage().setArrived(true);
|
||||
|
@ -778,6 +787,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
disputeClosedMessage.getTradeId(), disputeClosedMessage.getUid(),
|
||||
disputeResult.getChatMessage().getUid());
|
||||
|
||||
clearPendingMessage();
|
||||
// We use the chatMessage wrapped inside the DisputeClosedMessage for
|
||||
// the state, as that is displayed to the user and we only persist that msg
|
||||
disputeResult.getChatMessage().setStoredInMailbox(true);
|
||||
|
@ -795,6 +805,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
disputeClosedMessage.getTradeId(), disputeClosedMessage.getUid(),
|
||||
disputeResult.getChatMessage().getUid(), errorMessage);
|
||||
|
||||
clearPendingMessage();
|
||||
// We use the chatMessage wrapped inside the DisputeClosedMessage for
|
||||
// the state, as that is displayed to the user and we only persist that msg
|
||||
disputeResult.getChatMessage().setSendMessageError(errorMessage);
|
||||
|
@ -1091,4 +1102,20 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasPendingMessageAtShutdown() {
|
||||
if (pendingOutgoingMessage.length() > 0) {
|
||||
log.warn("{} has an outgoing message pending: {}", this.getClass().getSimpleName(), pendingOutgoingMessage);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void recordPendingMessage(String className) {
|
||||
pendingOutgoingMessage = className;
|
||||
}
|
||||
|
||||
private void clearPendingMessage() {
|
||||
pendingOutgoingMessage = "";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,6 @@ package haveno.core.support.dispute;
|
|||
|
||||
import haveno.common.config.Config;
|
||||
import haveno.common.crypto.Hash;
|
||||
import haveno.common.util.Tuple3;
|
||||
import haveno.core.support.SupportType;
|
||||
import haveno.core.trade.Contract;
|
||||
import haveno.core.trade.HavenoUtils;
|
||||
import haveno.core.trade.Trade;
|
||||
|
@ -35,13 +33,7 @@ import org.bitcoinj.core.Transaction;
|
|||
import org.bitcoinj.core.TransactionOutput;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
@ -131,122 +123,6 @@ public class DisputeValidation {
|
|||
"; dispute.getDonationAddressOfDelayedPayoutTx()=" + dispute.getDonationAddressOfDelayedPayoutTx());
|
||||
}
|
||||
|
||||
public static void testIfAnyDisputeTriedReplay(List<Dispute> disputeList,
|
||||
Consumer<DisputeReplayException> exceptionHandler) {
|
||||
var tuple = getTestReplayHashMaps(disputeList);
|
||||
Map<String, Set<String>> disputesPerTradeId = tuple.first;
|
||||
Map<String, Set<String>> disputesPerDelayedPayoutTxId = tuple.second;
|
||||
Map<String, Set<String>> disputesPerDepositTxId = tuple.third;
|
||||
|
||||
disputeList.forEach(disputeToTest -> {
|
||||
try {
|
||||
testIfDisputeTriesReplay(disputeToTest,
|
||||
disputesPerTradeId,
|
||||
disputesPerDelayedPayoutTxId,
|
||||
disputesPerDepositTxId);
|
||||
|
||||
} catch (DisputeReplayException e) {
|
||||
exceptionHandler.accept(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void testIfDisputeTriesReplay(Dispute dispute,
|
||||
List<Dispute> disputeList) throws DisputeReplayException {
|
||||
var tuple = getTestReplayHashMaps(disputeList);
|
||||
Map<String, Set<String>> disputesPerTradeId = tuple.first;
|
||||
Map<String, Set<String>> disputesPerDelayedPayoutTxId = tuple.second;
|
||||
Map<String, Set<String>> disputesPerDepositTxId = tuple.third;
|
||||
|
||||
testIfDisputeTriesReplay(dispute,
|
||||
disputesPerTradeId,
|
||||
disputesPerDelayedPayoutTxId,
|
||||
disputesPerDepositTxId);
|
||||
}
|
||||
|
||||
private static Tuple3<Map<String, Set<String>>, Map<String, Set<String>>, Map<String, Set<String>>> getTestReplayHashMaps(
|
||||
List<Dispute> disputeList) {
|
||||
Map<String, Set<String>> disputesPerTradeId = new HashMap<>();
|
||||
Map<String, Set<String>> disputesPerDelayedPayoutTxId = new HashMap<>();
|
||||
Map<String, Set<String>> disputesPerDepositTxId = new HashMap<>();
|
||||
disputeList.forEach(dispute -> {
|
||||
String uid = dispute.getUid();
|
||||
|
||||
String tradeId = dispute.getTradeId();
|
||||
disputesPerTradeId.putIfAbsent(tradeId, new HashSet<>());
|
||||
Set<String> set = disputesPerTradeId.get(tradeId);
|
||||
set.add(uid);
|
||||
|
||||
String delayedPayoutTxId = dispute.getDelayedPayoutTxId();
|
||||
if (delayedPayoutTxId != null) {
|
||||
disputesPerDelayedPayoutTxId.putIfAbsent(delayedPayoutTxId, new HashSet<>());
|
||||
set = disputesPerDelayedPayoutTxId.get(delayedPayoutTxId);
|
||||
set.add(uid);
|
||||
}
|
||||
|
||||
String depositTxId = dispute.getDepositTxId();
|
||||
if (depositTxId != null) {
|
||||
disputesPerDepositTxId.putIfAbsent(depositTxId, new HashSet<>());
|
||||
set = disputesPerDepositTxId.get(depositTxId);
|
||||
set.add(uid);
|
||||
}
|
||||
});
|
||||
|
||||
return new Tuple3<>(disputesPerTradeId, disputesPerDelayedPayoutTxId, disputesPerDepositTxId);
|
||||
}
|
||||
|
||||
private static void testIfDisputeTriesReplay(Dispute disputeToTest,
|
||||
Map<String, Set<String>> disputesPerTradeId,
|
||||
Map<String, Set<String>> disputesPerDelayedPayoutTxId,
|
||||
Map<String, Set<String>> disputesPerDepositTxId)
|
||||
throws DisputeReplayException {
|
||||
try {
|
||||
String disputeToTestTradeId = disputeToTest.getTradeId();
|
||||
String disputeToTestDelayedPayoutTxId = disputeToTest.getDelayedPayoutTxId();
|
||||
String disputeToTestDepositTxId = disputeToTest.getDepositTxId();
|
||||
String disputeToTestUid = disputeToTest.getUid();
|
||||
|
||||
// For pre v1.4.0 we do not get the delayed payout tx sent in mediation cases but in refund agent case we do.
|
||||
// So until all users have updated to 1.4.0 we only check in refund agent case. With 1.4.0 we send the
|
||||
// delayed payout tx also in mediation cases and that if check can be removed.
|
||||
if (disputeToTest.getSupportType() == SupportType.REFUND) {
|
||||
checkNotNull(disputeToTestDelayedPayoutTxId,
|
||||
"Delayed payout transaction ID is null. " +
|
||||
"Trade ID: " + disputeToTestTradeId);
|
||||
}
|
||||
checkNotNull(disputeToTestDepositTxId,
|
||||
"depositTxId must not be null. Trade ID: " + disputeToTestTradeId);
|
||||
checkNotNull(disputeToTestUid,
|
||||
"agentsUid must not be null. Trade ID: " + disputeToTestTradeId);
|
||||
|
||||
Set<String> disputesPerTradeIdItems = disputesPerTradeId.get(disputeToTestTradeId);
|
||||
checkArgument(disputesPerTradeIdItems != null && disputesPerTradeIdItems.size() <= 2,
|
||||
"We found more then 2 disputes with the same trade ID. " +
|
||||
"Trade ID: " + disputeToTestTradeId);
|
||||
if (!disputesPerDelayedPayoutTxId.isEmpty()) {
|
||||
Set<String> disputesPerDelayedPayoutTxIdItems = disputesPerDelayedPayoutTxId.get(disputeToTestDelayedPayoutTxId);
|
||||
checkArgument(disputesPerDelayedPayoutTxIdItems != null && disputesPerDelayedPayoutTxIdItems.size() <= 2,
|
||||
"We found more then 2 disputes with the same delayedPayoutTxId. " +
|
||||
"Trade ID: " + disputeToTestTradeId);
|
||||
}
|
||||
if (!disputesPerDepositTxId.isEmpty()) {
|
||||
Set<String> disputesPerDepositTxIdItems = disputesPerDepositTxId.get(disputeToTestDepositTxId);
|
||||
checkArgument(disputesPerDepositTxIdItems != null && disputesPerDepositTxIdItems.size() <= 2,
|
||||
"We found more then 2 disputes with the same depositTxId. " +
|
||||
"Trade ID: " + disputeToTestTradeId);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new DisputeReplayException(disputeToTest, e.getMessage());
|
||||
} catch (NullPointerException e) {
|
||||
log.error("NullPointerException at testIfDisputeTriesReplay: " +
|
||||
"disputeToTest={}, disputesPerTradeId={}, disputesPerDelayedPayoutTxId={}, " +
|
||||
"disputesPerDepositTxId={}",
|
||||
disputeToTest, disputesPerTradeId, disputesPerDelayedPayoutTxId, disputesPerDepositTxId);
|
||||
throw new DisputeReplayException(disputeToTest, e.toString() + " at dispute " + disputeToTest.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Exceptions
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -31,13 +31,14 @@ import haveno.core.trade.TradeManager;
|
|||
import haveno.network.p2p.AckMessageSourceType;
|
||||
import haveno.network.p2p.NodeAddress;
|
||||
import haveno.network.p2p.P2PService;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.Optional;
|
||||
|
||||
@Slf4j
|
||||
@Singleton
|
||||
|
@ -97,10 +98,9 @@ public class TraderChatManager extends SupportManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<ChatMessage> getAllChatMessages() {
|
||||
return tradeManager.getObservableList().stream()
|
||||
.flatMap(trade -> trade.getChatMessages().stream())
|
||||
.collect(Collectors.toList());
|
||||
public List<ChatMessage> getAllChatMessages(String tradeId) {
|
||||
return Optional.of(tradeManager.getTrade(tradeId)).map(Trade::getChatMessages)
|
||||
.orElse(FXCollections.emptyObservableList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue