verify arbitrator signature when dispute closed

This commit is contained in:
woodser 2023-01-15 11:23:46 -05:00
parent 435fc164b2
commit 9260cf53ee
15 changed files with 76 additions and 88 deletions

View file

@ -174,9 +174,11 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
@Override
public List<ChatMessage> getAllChatMessages() {
return getDisputeList().stream()
.flatMap(dispute -> dispute.getChatMessages().stream())
.collect(Collectors.toList());
synchronized (getDisputeList()) {
return getDisputeList().stream()
.flatMap(dispute -> dispute.getChatMessages().stream())
.collect(Collectors.toList());
}
}
@Override
@ -294,12 +296,14 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
}
public Optional<Dispute> findOwnDispute(String tradeId) {
T disputeList = getDisputeList();
if (disputeList == null) {
log.warn("disputes is null");
return Optional.empty();
synchronized (getDisputeList()) {
T disputeList = getDisputeList();
if (disputeList == null) {
log.warn("disputes is null");
return Optional.empty();
}
return disputeList.stream().filter(e -> e.getTradeId().equals(tradeId)).findAny();
}
return disputeList.stream().filter(e -> e.getTradeId().equals(tradeId)).findAny();
}
///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -25,6 +25,8 @@ import bisq.common.util.Utilities;
import org.bitcoinj.core.Coin;
import com.google.protobuf.ByteString;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
@ -159,6 +161,8 @@ public final class DisputeResult implements NetworkPayload {
.setSellerPayoutAmount(sellerPayoutAmount)
.setCloseDate(closeDate);
Optional.ofNullable(arbitratorSignature).ifPresent(arbitratorSignature -> builder.setArbitratorSignature(ByteString.copyFrom(arbitratorSignature)));
Optional.ofNullable(arbitratorPubKey).ifPresent(arbitratorPubKey -> builder.setArbitratorPubKey(ByteString.copyFrom(arbitratorPubKey)));
Optional.ofNullable(winner).ifPresent(result -> builder.setWinner(protobuf.DisputeResult.Winner.valueOf(winner.name())));
Optional.ofNullable(chatMessage).ifPresent(chatMessage ->
builder.setChatMessage(chatMessage.toProtoNetworkEnvelope().getChatMessage()));

View file

@ -19,8 +19,7 @@ package bisq.core.support.dispute;
import bisq.core.locale.Res;
import bisq.core.support.dispute.agent.DisputeAgent;
import bisq.core.support.dispute.mediation.mediator.MediatorManager;
import bisq.core.support.dispute.refund.refundagent.RefundAgentManager;
import bisq.core.support.dispute.arbitration.arbitrator.ArbitratorManager;
import bisq.network.p2p.NodeAddress;
@ -64,18 +63,14 @@ public class DisputeSummaryVerification {
SEPARATOR2);
}
public static String verifySignature(String input,
MediatorManager mediatorManager,
RefundAgentManager refundAgentManager) {
public static void verifySignature(String input,
ArbitratorManager arbitratorMediator) {
try {
String[] parts = input.split(SEPARATOR1);
String textToSign = parts[0];
String fullAddress = textToSign.split("\n")[1].split(": ")[1];
NodeAddress nodeAddress = new NodeAddress(fullAddress);
DisputeAgent disputeAgent = mediatorManager.getDisputeAgentByNodeAddress(nodeAddress).orElse(null);
if (disputeAgent == null) {
disputeAgent = refundAgentManager.getDisputeAgentByNodeAddress(nodeAddress).orElse(null);
}
DisputeAgent disputeAgent = arbitratorMediator.getDisputeAgentByNodeAddress(nodeAddress).orElse(null);
checkNotNull(disputeAgent);
PublicKey pubKey = disputeAgent.getPubKeyRing().getSignaturePubKey();
@ -85,15 +80,15 @@ public class DisputeSummaryVerification {
try {
boolean result = Sig.verify(pubKey, hash, sig);
if (result) {
return Res.get("support.sigCheck.popup.success");
return;
} else {
return Res.get("support.sigCheck.popup.failed");
throw new IllegalArgumentException(Res.get("support.sigCheck.popup.failed"));
}
} catch (CryptoException e) {
return Res.get("support.sigCheck.popup.failed");
throw new IllegalArgumentException(Res.get("support.sigCheck.popup.failed"));
}
} catch (Throwable e) {
return Res.get("support.sigCheck.popup.invalidFormat");
throw new IllegalArgumentException(Res.get("support.sigCheck.popup.invalidFormat"));
}
}
}

View file

@ -28,7 +28,9 @@ import bisq.core.support.SupportType;
import bisq.core.support.dispute.Dispute;
import bisq.core.support.dispute.DisputeManager;
import bisq.core.support.dispute.DisputeResult;
import bisq.core.support.dispute.DisputeSummaryVerification;
import bisq.core.support.dispute.DisputeResult.Winner;
import bisq.core.support.dispute.arbitration.arbitrator.ArbitratorManager;
import bisq.core.support.dispute.messages.DisputeClosedMessage;
import bisq.core.support.dispute.messages.DisputeOpenedMessage;
import bisq.core.support.messages.ChatMessage;
@ -73,6 +75,8 @@ import monero.wallet.model.MoneroTxWallet;
@Singleton
public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeList> {
private final ArbitratorManager arbitratorManager;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@ -83,6 +87,7 @@ public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeL
XmrWalletService walletService,
CoreMoneroConnectionsService connectionService,
CoreNotificationService notificationService,
ArbitratorManager arbitratorManager,
TradeManager tradeManager,
ClosedTradableManager closedTradableManager,
OpenOfferManager openOfferManager,
@ -92,7 +97,8 @@ public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeL
PriceFeedService priceFeedService) {
super(p2PService, tradeWalletService, walletService, connectionService, notificationService, tradeManager, closedTradableManager,
openOfferManager, keyRing, arbitrationDisputeListService, config, priceFeedService);
HavenoUtils.arbitrationManager = this; // store static reference
this.arbitratorManager = arbitratorManager;
HavenoUtils.arbitrationManager = this; // TODO: storing static reference, better way?
}
@ -181,6 +187,10 @@ public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeL
log.info("Processing {} for {} {}", disputeClosedMessage.getClass().getSimpleName(), trade.getClass().getSimpleName(), disputeResult.getTradeId());
// verify arbitrator signature
String summaryText = chatMessage.getMessage();
DisputeSummaryVerification.verifySignature(summaryText, arbitratorManager);
// get dispute
Optional<Dispute> disputeOptional = findDispute(disputeResult);
String uid = disputeClosedMessage.getUid();

View file

@ -289,7 +289,7 @@ public class HavenoUtils {
message.setBuyerSignature(signature);
// verify signature
String errMessage = "The buyer signature is invalid for the " + message.getClass().getSimpleName() + " for trade " + trade.getId();
String errMessage = "The buyer signature is invalid for the " + message.getClass().getSimpleName() + " for " + trade.getClass().getSimpleName() + " " + trade.getId();
try {
if (!Sig.verify(trade.getBuyer().getPubKeyRing().getSignaturePubKey(), unsignedMessageAsJson.getBytes(Charsets.UTF_8), signature)) throw new RuntimeException(errMessage);
} catch (Exception e) {
@ -320,7 +320,7 @@ public class HavenoUtils {
message.setSellerSignature(signature);
// verify signature
String errMessage = "The seller signature is invalid for the " + message.getClass().getSimpleName() + " for trade " + trade.getId();
String errMessage = "The seller signature is invalid for the " + message.getClass().getSimpleName() + " for " + trade.getClass().getSimpleName() + " " + trade.getId();
try {
if (!Sig.verify(trade.getSeller().getPubKeyRing().getSignaturePubKey(), unsignedMessageAsJson.getBytes(Charsets.UTF_8), signature)) throw new RuntimeException(errMessage);
} catch (Exception e) {