diff --git a/core/src/main/java/bisq/core/filter/Filter.java b/core/src/main/java/bisq/core/filter/Filter.java index 5decd1ba25..2461dd0179 100644 --- a/core/src/main/java/bisq/core/filter/Filter.java +++ b/core/src/main/java/bisq/core/filter/Filter.java @@ -132,6 +132,10 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload, private final List addedBtcNodes; @ExcludeForHash private final List addedSeedNodes; + // As we might add more ExcludeForHash we want to ensure to have a unique identifier. + // The hash of the data is not unique anymore if the only change have been at + // the ExcludeForHash annotated fields. + private final String uid; // After we have created the signature from the filter data we clone it and apply the signature static Filter cloneWithSig(Filter filter, String signatureAsBase64) { @@ -172,7 +176,8 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload, filter.getTakerFeeBsq(), filter.getDelayedPayoutPaymentAccounts(), filter.getAddedBtcNodes(), - filter.getAddedSeedNodes()); + filter.getAddedSeedNodes(), + filter.getUid()); } // Used for signature verification as we created the sig without the signatureAsBase64 field we set it to null again @@ -214,7 +219,8 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload, filter.getTakerFeeBsq(), filter.getDelayedPayoutPaymentAccounts(), filter.getAddedBtcNodes(), - filter.getAddedSeedNodes()); + filter.getAddedSeedNodes(), + filter.getUid()); } public Filter(List bannedOfferIds, @@ -251,7 +257,8 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload, long takerFeeBsq, List delayedPayoutPaymentAccounts, List addedBtcNodes, - List addedSeedNodes) { + List addedSeedNodes, + String uid) { this(bannedOfferIds, nodeAddressesBannedFromTrading, bannedPaymentAccounts, @@ -289,7 +296,8 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload, takerFeeBsq, delayedPayoutPaymentAccounts, addedBtcNodes, - addedSeedNodes); + addedSeedNodes, + uid); } @@ -335,7 +343,8 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload, long takerFeeBsq, List delayedPayoutPaymentAccounts, List addedBtcNodes, - List addedSeedNodes) { + List addedSeedNodes, + String uid) { this.bannedOfferIds = bannedOfferIds; this.nodeAddressesBannedFromTrading = nodeAddressesBannedFromTrading; this.bannedPaymentAccounts = bannedPaymentAccounts; @@ -374,6 +383,7 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload, this.delayedPayoutPaymentAccounts = delayedPayoutPaymentAccounts; this.addedBtcNodes = addedBtcNodes; this.addedSeedNodes = addedSeedNodes; + this.uid = uid; // ownerPubKeyBytes can be null when called from tests if (ownerPubKeyBytes != null) { @@ -445,7 +455,8 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload, .setTakerFeeBsq(takerFeeBsq) .addAllDelayedPayoutPaymentAccounts(delayedPayoutPaymentAccountList) .addAllAddedBtcNodes(addedBtcNodes) - .addAllAddedSeedNodes(addedSeedNodes); + .addAllAddedSeedNodes(addedSeedNodes) + .setUid(uid); Optional.ofNullable(signatureAsBase64).ifPresent(builder::setSignatureAsBase64); Optional.ofNullable(extraDataMap).ifPresent(builder::putAllExtraData); @@ -498,7 +509,8 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload, proto.getTakerFeeBsq(), delayedPayoutPaymentAccounts, ProtoUtil.protocolStringListToList(proto.getAddedBtcNodesList()), - ProtoUtil.protocolStringListToList(proto.getAddedSeedNodesList()) + ProtoUtil.protocolStringListToList(proto.getAddedSeedNodesList()), + proto.getUid() ); } @@ -558,6 +570,7 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload, ",\n takerFeeBsq=" + takerFeeBsq + ",\n addedBtcNodes=" + addedBtcNodes + ",\n addedSeedNodes=" + addedSeedNodes + + ",\n uid=" + uid + "\n}"; } } diff --git a/core/src/test/java/bisq/core/filter/TestFilter.java b/core/src/test/java/bisq/core/filter/TestFilter.java index 047850f485..ff2c041f0c 100644 --- a/core/src/test/java/bisq/core/filter/TestFilter.java +++ b/core/src/test/java/bisq/core/filter/TestFilter.java @@ -32,6 +32,7 @@ import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; +import java.util.UUID; import static org.bitcoinj.core.Utils.HEX; @@ -104,7 +105,8 @@ public class TestFilter { 1, Collections.emptyList(), List.of("test1.onion:1221"), - List.of("test2.onion:1221") + List.of("test2.onion:1221"), + UUID.randomUUID().toString() ); } diff --git a/core/src/test/java/bisq/core/user/UserPayloadModelVOTest.java b/core/src/test/java/bisq/core/user/UserPayloadModelVOTest.java index 930bedadb7..52152c3118 100644 --- a/core/src/test/java/bisq/core/user/UserPayloadModelVOTest.java +++ b/core/src/test/java/bisq/core/user/UserPayloadModelVOTest.java @@ -26,6 +26,7 @@ import bisq.core.proto.CoreProtoResolver; import com.google.common.collect.Lists; import java.util.HashSet; +import java.util.UUID; import org.junit.jupiter.api.Disabled; @@ -79,7 +80,8 @@ public class UserPayloadModelVOTest { 0, Lists.newArrayList(), Lists.newArrayList(), - Lists.newArrayList())); + Lists.newArrayList(), + UUID.randomUUID().toString())); vo.setRegisteredArbitrator(ArbitratorTest.getArbitratorMock()); vo.setRegisteredMediator(MediatorTest.getMediatorMock()); diff --git a/desktop/src/main/java/bisq/desktop/main/overlays/windows/FilterWindow.java b/desktop/src/main/java/bisq/desktop/main/overlays/windows/FilterWindow.java index c997271d66..b736f73fee 100644 --- a/desktop/src/main/java/bisq/desktop/main/overlays/windows/FilterWindow.java +++ b/desktop/src/main/java/bisq/desktop/main/overlays/windows/FilterWindow.java @@ -60,6 +60,7 @@ import javafx.geometry.Insets; import java.util.Collection; import java.util.HashSet; import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; import static bisq.desktop.util.FormBuilder.addInputTextField; @@ -129,6 +130,8 @@ public class FilterWindow extends Overlay { InputTextField keyTF = addInputTextField(gridPane, ++rowIndex, Res.get("shared.unlock"), 10); + InputTextField uidTF = addInputTextField(gridPane, ++rowIndex, + "UID", 10); if (useDevPrivilegeKeys) { keyTF.setText(DevEnv.getDEV_PRIVILEGE_PRIV_KEY()); } @@ -212,6 +215,7 @@ public class FilterWindow extends Overlay { Filter filter = filterManager.getDevFilter(); if (filter != null) { + uidTF.setText(filter.getUid()); setupFieldFromList(offerIdsTF, filter.getBannedOfferIds()); setupFieldFromList(bannedFromTradingTF, filter.getNodeAddressesBannedFromTrading()); setupFieldFromList(bannedFromNetworkTF, filter.getNodeAddressesBannedFromNetwork()); @@ -247,6 +251,8 @@ public class FilterWindow extends Overlay { makerFeeBsqTF.setText(bsqFormatter.formatBSQSatoshis(filter.getMakerFeeBsq())); takerFeeBsqTF.setText(bsqFormatter.formatBSQSatoshis(filter.getTakerFeeBsq())); setupFieldFromPaymentAccountFiltersList(delayedPayoutTF, filter.getDelayedPayoutPaymentAccounts()); + } else { + uidTF.setText(UUID.randomUUID().toString()); } Button removeFilterMessageButton = new AutoTooltipButton(Res.get("filterWindow.remove")); @@ -292,7 +298,8 @@ public class FilterWindow extends Overlay { ParsingUtils.parseToCoin(takerFeeBsqTF.getText(), bsqFormatter).value, readAsPaymentAccountFiltersList(delayedPayoutTF), readAsList(addedBtcNodesTF), - readAsList(addedSeedNodesTF) + readAsList(addedSeedNodesTF), + uidTF.getText() ); // We remove first the old filter diff --git a/proto/src/main/proto/pb.proto b/proto/src/main/proto/pb.proto index f5be6a1f66..034343f199 100644 --- a/proto/src/main/proto/pb.proto +++ b/proto/src/main/proto/pb.proto @@ -769,6 +769,7 @@ message Filter { repeated PaymentAccountFilter delayedPayoutPaymentAccounts = 36; repeated string addedBtcNodes = 37; repeated string addedSeedNodes = 38; + string uid = 39; } /* Deprecated */