Add filter for arbitrators

This commit is contained in:
Manfred Karrer 2017-10-25 17:24:54 -05:00
parent b7c7f6f615
commit 2c84623154
No known key found for this signature in database
GPG key ID: 401250966A6B2C46
11 changed files with 284 additions and 188 deletions

View file

@ -6,16 +6,16 @@ public class DevEnv {
// If that is true all the privileged features which requires a private key to enable it are overridden by a dev ey pair.
// The UI got set the private dev key so the developer does not need to do anything and can test those features.
// Features: Arbitration registration (alt+R at account), Alert/Update (alt+m), private message to a
// Features: Arbitration registration (alt+R at account), Alert/Update (alt+m), private message to a
// peer (click user icon and alt+r), filter/block offers by various data like offer ID (cmd + f).
// The user can set a program argument to ignore all of those privileged network_messages. They are intended for
// emergency cases only (beside update message and arbitrator registration).
public static final boolean USE_DEV_PRIVILEGE_KEYS = true;
public static final boolean USE_DEV_PRIVILEGE_KEYS = false;
public static final String DEV_PRIVILEGE_PUB_KEY = "027a381b5333a56e1cc3d90d3a7d07f26509adf7029ed06fc997c656621f8da1ee";
public static final String DEV_PRIVILEGE_PRIV_KEY = "6ac43ea1df2a290c1c8391736aa42e4339c5cb4f110ff0257a13b63211977b7a";
// If set to true we ignore several UI behavior like confirmation popups as well dummy accounts are created and
// If set to true we ignore several UI behavior like confirmation popups as well dummy accounts are created and
// offers are filled with default values. Intended to make dev testing faster.
@SuppressWarnings("PointlessBooleanExpression")
public static final boolean DEV_MODE = STRESS_TEST_MODE || true;

View file

@ -561,6 +561,9 @@ message Filter {
map<string, string> extra_data = 6;
repeated string banned_currencies = 7;
repeated string banned_payment_methods = 8;
repeated string arbitrators = 9;
repeated string seed_nodes = 10;
repeated string price_relay_nodes = 11;
}
message TradeStatistics {

View file

@ -1096,6 +1096,10 @@ filterWindow.onions=Filtered onion addresses (comma sep.):
filterWindow.accounts=Filtered trading account data:\nFormat: comma sep. list of [payment method id | data field | value]
filterWindow.bannedCurrencies=Filtered currency codes (comma sep.):
filterWindow.bannedPaymentMethods=Filtered payment method IDs (comma sep.):
filterWindow.arbitrators=Filtered arbitrator (comma sep. onion):
filterWindow.seedNode=Filtered seed node (comma sep. onion):
filterWindow.priceRelayNode=Filtered price relay node (comma sep. onion):
filterWindow.add=Add filter
filterWindow.remove=Remove filter

View file

@ -25,6 +25,7 @@ import io.bisq.common.crypto.KeyRing;
import io.bisq.common.handlers.ErrorMessageHandler;
import io.bisq.common.handlers.ResultHandler;
import io.bisq.common.util.Utilities;
import io.bisq.core.filter.FilterManager;
import io.bisq.core.user.Preferences;
import io.bisq.core.user.User;
import io.bisq.network.p2p.BootstrapListener;
@ -64,24 +65,24 @@ public class ArbitratorManager {
@SuppressWarnings("ConstantConditions")
private static final List<String> publicKeys = DevEnv.USE_DEV_PRIVILEGE_KEYS ?
new ArrayList<>(Collections.singletonList(DevEnv.DEV_PRIVILEGE_PUB_KEY)) :
new ArrayList<>(Arrays.asList(
"0365c6af94681dbee69de1851f98d4684063bf5c2d64b1c73ed5d90434f375a054",
"031c502a60f9dbdb5ae5e438a79819e4e1f417211dd537ac12c9bc23246534c4bd",
"02c1e5a242387b6d5319ce27246cea6edaaf51c3550591b528d2578a4753c56c2c",
"025c319faf7067d9299590dd6c97fe7e56cd4dac61205ccee1cd1fc390142390a2",
"038f6e24c2bfe5d51d0a290f20a9a657c270b94ef2b9c12cd15ca3725fa798fc55",
"0255256ff7fb615278c4544a9bbd3f5298b903b8a011cd7889be19b6b1c45cbefe",
"024a3a37289f08c910fbd925ebc72b946f33feaeff451a4738ee82037b4cda2e95",
"02a88b75e9f0f8afba1467ab26799dcc38fd7a6468fb2795444b425eb43e2c10bd",
"02349a51512c1c04c67118386f4d27d768c5195a83247c150a4b722d161722ba81",
"03f718a2e0dc672c7cdec0113e72c3322efc70412bb95870750d25c32cd98de17d",
"028ff47ee2c56e66313928975c58fa4f1b19a0f81f3a96c4e9c9c3c6768075509e",
"02b517c0cbc3a49548f448ddf004ed695c5a1c52ec110be1bfd65fa0ca0761c94b",
"03df837a3a0f3d858e82f3356b71d1285327f101f7c10b404abed2abc1c94e7169",
"0203a90fb2ab698e524a5286f317a183a84327b8f8c3f7fa4a98fec9e1cefd6b72",
"023c99cc073b851c892d8c43329ca3beb5d2213ee87111af49884e3ce66cbd5ba5"
));
new ArrayList<>(Collections.singletonList(DevEnv.DEV_PRIVILEGE_PUB_KEY)) :
new ArrayList<>(Arrays.asList(
"0365c6af94681dbee69de1851f98d4684063bf5c2d64b1c73ed5d90434f375a054",
"031c502a60f9dbdb5ae5e438a79819e4e1f417211dd537ac12c9bc23246534c4bd",
"02c1e5a242387b6d5319ce27246cea6edaaf51c3550591b528d2578a4753c56c2c",
"025c319faf7067d9299590dd6c97fe7e56cd4dac61205ccee1cd1fc390142390a2",
"038f6e24c2bfe5d51d0a290f20a9a657c270b94ef2b9c12cd15ca3725fa798fc55",
"0255256ff7fb615278c4544a9bbd3f5298b903b8a011cd7889be19b6b1c45cbefe",
"024a3a37289f08c910fbd925ebc72b946f33feaeff451a4738ee82037b4cda2e95",
"02a88b75e9f0f8afba1467ab26799dcc38fd7a6468fb2795444b425eb43e2c10bd",
"02349a51512c1c04c67118386f4d27d768c5195a83247c150a4b722d161722ba81",
"03f718a2e0dc672c7cdec0113e72c3322efc70412bb95870750d25c32cd98de17d",
"028ff47ee2c56e66313928975c58fa4f1b19a0f81f3a96c4e9c9c3c6768075509e",
"02b517c0cbc3a49548f448ddf004ed695c5a1c52ec110be1bfd65fa0ca0761c94b",
"03df837a3a0f3d858e82f3356b71d1285327f101f7c10b404abed2abc1c94e7169",
"0203a90fb2ab698e524a5286f317a183a84327b8f8c3f7fa4a98fec9e1cefd6b72",
"023c99cc073b851c892d8c43329ca3beb5d2213ee87111af49884e3ce66cbd5ba5"
));
///////////////////////////////////////////////////////////////////////////////////////////
// Instance fields
@ -91,6 +92,7 @@ public class ArbitratorManager {
private final ArbitratorService arbitratorService;
private final User user;
private final Preferences preferences;
private final FilterManager filterManager;
private final ObservableMap<NodeAddress, Arbitrator> arbitratorsObservableMap = FXCollections.observableHashMap();
private List<Arbitrator> persistedAcceptedArbitrators;
private Timer republishArbitratorTimer, retryRepublishArbitratorTimer;
@ -101,11 +103,12 @@ public class ArbitratorManager {
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public ArbitratorManager(KeyRing keyRing, ArbitratorService arbitratorService, User user, Preferences preferences) {
public ArbitratorManager(KeyRing keyRing, ArbitratorService arbitratorService, User user, Preferences preferences, FilterManager filterManager) {
this.keyRing = keyRing;
this.arbitratorService = arbitratorService;
this.user = user;
this.preferences = preferences;
this.filterManager = filterManager;
}
public void shutDown() {
@ -156,6 +159,8 @@ public class ArbitratorManager {
});
}
filterManager.filterProperty().addListener((observable, oldValue, newValue) -> updateArbitratorMap());
updateArbitratorMap();
}
@ -171,39 +176,39 @@ public class ArbitratorManager {
Map<NodeAddress, Arbitrator> map = arbitratorService.getArbitrators();
arbitratorsObservableMap.clear();
Map<NodeAddress, Arbitrator> filtered = map.values().stream()
.filter(e -> {
final boolean isInPublicKeyInList = isPublicKeyInList(Utils.HEX.encode(e.getRegistrationPubKey()));
if (!isInPublicKeyInList)
log.warn("We got an arbitrator which is not in our list of publicKeys. RegistrationPubKey={}, nodeAddress={}",
Utilities.bytesAsHexString(e.getRegistrationPubKey()),
e.getNodeAddress().getFullAddress());
final boolean isSigValid = verifySignature(e.getPubKeyRing().getSignaturePubKey(),
e.getRegistrationPubKey(),
e.getRegistrationSignature());
if (!isSigValid)
log.warn("Sig check for arbitrator failed. Arbitrator=", e.toString());
.filter(e -> {
final boolean isInPublicKeyInList = isPublicKeyInList(Utils.HEX.encode(e.getRegistrationPubKey()));
if (!isInPublicKeyInList)
log.warn("We got an arbitrator which is not in our list of publicKeys. RegistrationPubKey={}, nodeAddress={}",
Utilities.bytesAsHexString(e.getRegistrationPubKey()),
e.getNodeAddress().getFullAddress());
final boolean isSigValid = verifySignature(e.getPubKeyRing().getSignaturePubKey(),
e.getRegistrationPubKey(),
e.getRegistrationSignature());
if (!isSigValid)
log.warn("Sig check for arbitrator failed. Arbitrator=", e.toString());
return isInPublicKeyInList && isSigValid;
})
.collect(Collectors.toMap(Arbitrator::getNodeAddress, Function.identity()));
return isInPublicKeyInList && isSigValid;
})
.collect(Collectors.toMap(Arbitrator::getNodeAddress, Function.identity()));
arbitratorsObservableMap.putAll(filtered);
arbitratorsObservableMap.values().stream()
.filter(persistedAcceptedArbitrators::contains)
.filter(persistedAcceptedArbitrators::contains)
.forEach(a -> {
user.addAcceptedArbitrator(a);
user.addAcceptedMediator(getMediator(a)
);
});
if (preferences.isAutoSelectArbitrators()) {
arbitratorsObservableMap.values().stream()
.filter(user::hasMatchingLanguage)
.forEach(a -> {
user.addAcceptedArbitrator(a);
user.addAcceptedMediator(getMediator(a)
);
});
if (preferences.isAutoSelectArbitrators()) {
arbitratorsObservableMap.values().stream()
.filter(user::hasMatchingLanguage)
.forEach(a -> {
user.addAcceptedArbitrator(a);
user.addAcceptedMediator(getMediator(a)
);
});
} else {
// if we don't have any arbitrator we set all matching
// we use a delay as we might get our matching arbitrator a bit delayed (first we get one we did not selected
@ -211,12 +216,12 @@ public class ArbitratorManager {
UserThread.runAfter(() -> {
if (user.getAcceptedArbitrators().isEmpty()) {
arbitratorsObservableMap.values().stream()
.filter(user::hasMatchingLanguage)
.forEach(a -> {
user.addAcceptedArbitrator(a);
user.addAcceptedMediator(getMediator(a)
);
});
.filter(user::hasMatchingLanguage)
.forEach(a -> {
user.addAcceptedArbitrator(a);
user.addAcceptedMediator(getMediator(a)
);
});
}
}, 100, TimeUnit.MILLISECONDS);
}
@ -226,28 +231,28 @@ public class ArbitratorManager {
@NotNull
public static Mediator getMediator(Arbitrator arbitrator) {
return new Mediator(arbitrator.getNodeAddress(),
arbitrator.getPubKeyRing(),
arbitrator.getLanguageCodes(),
arbitrator.getRegistrationDate(),
arbitrator.getRegistrationPubKey(),
arbitrator.getRegistrationSignature(),
arbitrator.getEmailAddress(),
null,
arbitrator.getExtraDataMap());
arbitrator.getPubKeyRing(),
arbitrator.getLanguageCodes(),
arbitrator.getRegistrationDate(),
arbitrator.getRegistrationPubKey(),
arbitrator.getRegistrationSignature(),
arbitrator.getEmailAddress(),
null,
arbitrator.getExtraDataMap());
}
public void addArbitrator(Arbitrator arbitrator, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
user.setRegisteredArbitrator(arbitrator);
arbitratorsObservableMap.put(arbitrator.getNodeAddress(), arbitrator);
arbitratorService.addArbitrator(arbitrator,
() -> {
log.debug("Arbitrator successfully saved in P2P network");
resultHandler.handleResult();
() -> {
log.debug("Arbitrator successfully saved in P2P network");
resultHandler.handleResult();
if (arbitratorsObservableMap.size() > 0)
UserThread.runAfter(this::updateArbitratorMap, 100, TimeUnit.MILLISECONDS);
},
errorMessageHandler::handleErrorMessage);
if (arbitratorsObservableMap.size() > 0)
UserThread.runAfter(this::updateArbitratorMap, 100, TimeUnit.MILLISECONDS);
},
errorMessageHandler::handleErrorMessage);
}
public void removeArbitrator(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
@ -256,11 +261,11 @@ public class ArbitratorManager {
user.setRegisteredArbitrator(null);
arbitratorsObservableMap.remove(registeredArbitrator.getNodeAddress());
arbitratorService.removeArbitrator(registeredArbitrator,
() -> {
log.debug("Arbitrator successfully removed from P2P network");
resultHandler.handleResult();
},
errorMessageHandler::handleErrorMessage);
() -> {
log.debug("Arbitrator successfully removed from P2P network");
resultHandler.handleResult();
},
errorMessageHandler::handleErrorMessage);
}
}
@ -298,14 +303,14 @@ public class ArbitratorManager {
Arbitrator registeredArbitrator = user.getRegisteredArbitrator();
if (registeredArbitrator != null) {
addArbitrator(registeredArbitrator,
this::updateArbitratorMap,
errorMessage -> {
if (retryRepublishArbitratorTimer == null)
retryRepublishArbitratorTimer = UserThread.runPeriodically(() -> {
stopRetryRepublishArbitratorTimer();
republishArbitrator();
}, RETRY_REPUBLISH_SEC);
}
this::updateArbitratorMap,
errorMessage -> {
if (retryRepublishArbitratorTimer == null)
retryRepublishArbitratorTimer = UserThread.runPeriodically(() -> {
stopRetryRepublishArbitratorTimer();
republishArbitrator();
}, RETRY_REPUBLISH_SEC);
}
);
}
}

View file

@ -22,6 +22,7 @@ import io.bisq.common.handlers.ErrorMessageHandler;
import io.bisq.common.handlers.ResultHandler;
import io.bisq.common.util.Utilities;
import io.bisq.core.app.BisqEnvironment;
import io.bisq.core.filter.FilterManager;
import io.bisq.network.p2p.NodeAddress;
import io.bisq.network.p2p.P2PService;
import io.bisq.network.p2p.storage.HashMapChangedListener;
@ -30,6 +31,7 @@ import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@ -41,6 +43,7 @@ public class ArbitratorService {
private static final Logger log = LoggerFactory.getLogger(ArbitratorService.class);
private final P2PService p2PService;
private final FilterManager filterManager;
interface ArbitratorMapResultHandler {
void handleResult(Map<String, Arbitrator> arbitratorsMap);
@ -52,8 +55,9 @@ public class ArbitratorService {
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public ArbitratorService(P2PService p2PService) {
public ArbitratorService(P2PService p2PService, FilterManager filterManager) {
this.p2PService = p2PService;
this.filterManager = filterManager;
}
public void addHashSetChangedListener(HashMapChangedListener hashMapChangedListener) {
@ -62,8 +66,8 @@ public class ArbitratorService {
public void addArbitrator(Arbitrator arbitrator, final ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
log.debug("addArbitrator arbitrator.hashCode() " + arbitrator.hashCode());
if (!BisqEnvironment.getBaseCurrencyNetwork().isMainnet() ||
!Utilities.encodeToHex(arbitrator.getRegistrationPubKey()).equals(DevEnv.DEV_PRIVILEGE_PUB_KEY)) {
if (!BisqEnvironment.getBaseCurrencyNetwork().isMainnet() ||
!Utilities.encodeToHex(arbitrator.getRegistrationPubKey()).equals(DevEnv.DEV_PRIVILEGE_PUB_KEY)) {
boolean result = p2PService.addData(arbitrator, true);
if (result) {
log.trace("Add arbitrator to network was successful. Arbitrator.hashCode() = " + arbitrator.hashCode());
@ -92,10 +96,15 @@ public class ArbitratorService {
}
public Map<NodeAddress, Arbitrator> getArbitrators() {
final List<String> bannedArbitrators = filterManager.getFilter() != null ? filterManager.getFilter().getArbitrators() : null;
if (bannedArbitrators != null)
log.warn("bannedArbitrators=" + bannedArbitrators);
Set<Arbitrator> arbitratorSet = p2PService.getDataMap().values().stream()
.filter(data -> data.getProtectedStoragePayload() instanceof Arbitrator)
.map(data -> (Arbitrator) data.getProtectedStoragePayload())
.collect(Collectors.toSet());
.filter(data -> data.getProtectedStoragePayload() instanceof Arbitrator)
.map(data -> (Arbitrator) data.getProtectedStoragePayload())
.filter(a -> bannedArbitrators == null ||
!bannedArbitrators.contains(a.getNodeAddress().getHostName()))
.collect(Collectors.toSet());
Map<NodeAddress, Arbitrator> map = new HashMap<>();
for (Arbitrator arbitrator : arbitratorSet) {

View file

@ -53,10 +53,19 @@ public final class Filter implements ProtectedStoragePayload {
@Nullable
private final List<String> bannedPaymentMethods;
// added in v0.6
@Nullable
private final List<String> arbitrators;
@Nullable
private final List<String> seedNodes;
@Nullable
private final List<String> priceRelayNodes;
private String signatureAsBase64;
private byte[] ownerPubKeyBytes;
// Should be only used in emergency case if we need to add data but do not want to break backward compatibility
// at the P2P network storage checks. The hash of the object will be used to verify if the data is valid. Any new
// Should be only used in emergency case if we need to add data but do not want to break backward compatibility
// at the P2P network storage checks. The hash of the object will be used to verify if the data is valid. Any new
// field in a class would break that hash and therefore break the storage mechanism.
@Nullable
private Map<String, String> extraDataMap;
@ -66,12 +75,18 @@ public final class Filter implements ProtectedStoragePayload {
List<String> bannedNodeAddress,
List<PaymentAccountFilter> bannedPaymentAccounts,
@Nullable List<String> bannedCurrencies,
@Nullable List<String> bannedPaymentMethods) {
@Nullable List<String> bannedPaymentMethods,
@Nullable List<String> arbitrators,
@Nullable List<String> seedNodes,
@Nullable List<String> priceRelayNodes) {
this.bannedOfferIds = bannedOfferIds;
this.bannedNodeAddress = bannedNodeAddress;
this.bannedPaymentAccounts = bannedPaymentAccounts;
this.bannedCurrencies = bannedCurrencies;
this.bannedPaymentMethods = bannedPaymentMethods;
this.arbitrators = arbitrators;
this.seedNodes = seedNodes;
this.priceRelayNodes = priceRelayNodes;
}
@ -85,14 +100,20 @@ public final class Filter implements ProtectedStoragePayload {
List<PaymentAccountFilter> bannedPaymentAccounts,
@Nullable List<String> bannedCurrencies,
@Nullable List<String> bannedPaymentMethods,
@Nullable List<String> arbitrators,
@Nullable List<String> seedNodes,
@Nullable List<String> priceRelayNodes,
String signatureAsBase64,
byte[] ownerPubKeyBytes,
@Nullable Map<String, String> extraDataMap) {
this(bannedOfferIds,
bannedNodeAddress,
bannedPaymentAccounts,
bannedCurrencies,
bannedPaymentMethods);
bannedNodeAddress,
bannedPaymentAccounts,
bannedCurrencies,
bannedPaymentMethods,
arbitrators,
seedNodes,
priceRelayNodes);
this.signatureAsBase64 = signatureAsBase64;
this.ownerPubKeyBytes = ownerPubKeyBytes;
this.extraDataMap = extraDataMap;
@ -105,17 +126,20 @@ public final class Filter implements ProtectedStoragePayload {
checkNotNull(signatureAsBase64, "signatureAsBase64 must nto be null");
checkNotNull(ownerPubKeyBytes, "ownerPubKeyBytes must nto be null");
List<PB.PaymentAccountFilter> paymentAccountFilterList = bannedPaymentAccounts.stream()
.map(PaymentAccountFilter::toProtoMessage)
.collect(Collectors.toList());
.map(PaymentAccountFilter::toProtoMessage)
.collect(Collectors.toList());
final PB.Filter.Builder builder = PB.Filter.newBuilder()
.addAllBannedOfferIds(bannedOfferIds)
.addAllBannedNodeAddress(bannedNodeAddress)
.addAllBannedPaymentAccounts(paymentAccountFilterList)
.setSignatureAsBase64(signatureAsBase64)
.setOwnerPubKeyBytes(ByteString.copyFrom(ownerPubKeyBytes));
.addAllBannedOfferIds(bannedOfferIds)
.addAllBannedNodeAddress(bannedNodeAddress)
.addAllBannedPaymentAccounts(paymentAccountFilterList)
.setSignatureAsBase64(signatureAsBase64)
.setOwnerPubKeyBytes(ByteString.copyFrom(ownerPubKeyBytes));
Optional.ofNullable(bannedCurrencies).ifPresent(builder::addAllBannedCurrencies);
Optional.ofNullable(bannedPaymentMethods).ifPresent(builder::addAllBannedPaymentMethods);
Optional.ofNullable(arbitrators).ifPresent(builder::addAllArbitrators);
Optional.ofNullable(seedNodes).ifPresent(builder::addAllSeedNodes);
Optional.ofNullable(priceRelayNodes).ifPresent(builder::addAllPriceRelayNodes);
Optional.ofNullable(extraDataMap).ifPresent(builder::putAllExtraData);
return PB.StoragePayload.newBuilder().setFilter(builder).build();
@ -123,15 +147,18 @@ public final class Filter implements ProtectedStoragePayload {
public static Filter fromProto(PB.Filter proto) {
return new Filter(proto.getBannedOfferIdsList().stream().collect(Collectors.toList()),
proto.getBannedNodeAddressList().stream().collect(Collectors.toList()),
proto.getBannedPaymentAccountsList().stream()
.map(PaymentAccountFilter::fromProto)
.collect(Collectors.toList()),
CollectionUtils.isEmpty(proto.getBannedCurrenciesList()) ? null : proto.getBannedCurrenciesList().stream().collect(Collectors.toList()),
CollectionUtils.isEmpty(proto.getBannedPaymentMethodsList()) ? null : proto.getBannedPaymentMethodsList().stream().collect(Collectors.toList()),
proto.getSignatureAsBase64(),
proto.getOwnerPubKeyBytes().toByteArray(),
CollectionUtils.isEmpty(proto.getExtraDataMap()) ? null : proto.getExtraDataMap());
proto.getBannedNodeAddressList().stream().collect(Collectors.toList()),
proto.getBannedPaymentAccountsList().stream()
.map(PaymentAccountFilter::fromProto)
.collect(Collectors.toList()),
CollectionUtils.isEmpty(proto.getBannedCurrenciesList()) ? null : proto.getBannedCurrenciesList().stream().collect(Collectors.toList()),
CollectionUtils.isEmpty(proto.getBannedPaymentMethodsList()) ? null : proto.getBannedPaymentMethodsList().stream().collect(Collectors.toList()),
CollectionUtils.isEmpty(proto.getArbitratorsList()) ? null : proto.getArbitratorsList().stream().collect(Collectors.toList()),
CollectionUtils.isEmpty(proto.getSeedNodesList()) ? null : proto.getSeedNodesList().stream().collect(Collectors.toList()),
CollectionUtils.isEmpty(proto.getPriceRelayNodesList()) ? null : proto.getPriceRelayNodesList().stream().collect(Collectors.toList()),
proto.getSignatureAsBase64(),
proto.getOwnerPubKeyBytes().toByteArray(),
CollectionUtils.isEmpty(proto.getExtraDataMap()) ? null : proto.getExtraDataMap());
}

View file

@ -30,7 +30,6 @@ import io.bisq.network.p2p.P2PService;
import io.bisq.network.p2p.storage.HashMapChangedListener;
import io.bisq.network.p2p.storage.payload.ProtectedStorageEntry;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.Utils;
@ -56,8 +55,8 @@ public class FilterManager {
@SuppressWarnings("ConstantConditions")
private static final String pubKeyAsHex = DevEnv.USE_DEV_PRIVILEGE_KEYS ?
DevEnv.DEV_PRIVILEGE_PUB_KEY :
"022ac7b7766b0aedff82962522c2c14fb8d1961dabef6e5cfd10edc679456a32f1";
DevEnv.DEV_PRIVILEGE_PUB_KEY :
"022ac7b7766b0aedff82962522c2c14fb8d1961dabef6e5cfd10edc679456a32f1";
private ECKey filterSigningKey;
@ -100,10 +99,11 @@ public class FilterManager {
// API
///////////////////////////////////////////////////////////////////////////////////////////
public ReadOnlyObjectProperty<Filter> filterProperty() {
public ObjectProperty<Filter> filterProperty() {
return filterProperty;
}
@Nullable
public Filter getFilter() {
return filterProperty.get();
}
@ -169,11 +169,11 @@ public class FilterManager {
// We dont use full data from Filter as we are only interested in the filter data not the sig and keys
private String getHexFromData(Filter filter) {
PB.Filter.Builder builder = PB.Filter.newBuilder()
.addAllBannedOfferIds(filter.getBannedOfferIds())
.addAllBannedNodeAddress(filter.getBannedNodeAddress())
.addAllBannedPaymentAccounts(filter.getBannedPaymentAccounts().stream()
.map(PaymentAccountFilter::toProtoMessage)
.collect(Collectors.toList()));
.addAllBannedOfferIds(filter.getBannedOfferIds())
.addAllBannedNodeAddress(filter.getBannedNodeAddress())
.addAllBannedPaymentAccounts(filter.getBannedPaymentAccounts().stream()
.map(PaymentAccountFilter::toProtoMessage)
.collect(Collectors.toList()));
Optional.ofNullable(filter.getBannedCurrencies()).ifPresent(builder::addAllBannedCurrencies);
Optional.ofNullable(filter.getBannedPaymentMethods()).ifPresent(builder::addAllBannedPaymentMethods);
@ -188,60 +188,60 @@ public class FilterManager {
public boolean isCurrencyBanned(String currencyCode) {
return getFilter() != null &&
getFilter().getBannedCurrencies() != null &&
getFilter().getBannedCurrencies().stream()
.filter(e -> e.equals(currencyCode))
.findAny()
.isPresent();
getFilter().getBannedCurrencies() != null &&
getFilter().getBannedCurrencies().stream()
.filter(e -> e.equals(currencyCode))
.findAny()
.isPresent();
}
public boolean isPaymentMethodBanned(PaymentMethod paymentMethod) {
return getFilter() != null &&
getFilter().getBannedPaymentMethods() != null &&
getFilter().getBannedPaymentMethods().stream()
.filter(e -> e.equals(paymentMethod.getId()))
.findAny()
.isPresent();
getFilter().getBannedPaymentMethods() != null &&
getFilter().getBannedPaymentMethods().stream()
.filter(e -> e.equals(paymentMethod.getId()))
.findAny()
.isPresent();
}
public boolean isOfferIdBanned(String offerId) {
return getFilter() != null &&
getFilter().getBannedOfferIds().stream()
.filter(e -> e.equals(offerId))
.findAny()
.isPresent();
getFilter().getBannedOfferIds().stream()
.filter(e -> e.equals(offerId))
.findAny()
.isPresent();
}
public boolean isNodeAddressBanned(String nodeAddress) {
return getFilter() != null &&
getFilter().getBannedNodeAddress().stream()
.filter(e -> e.equals(nodeAddress))
.findAny()
.isPresent();
getFilter().getBannedNodeAddress().stream()
.filter(e -> e.equals(nodeAddress))
.findAny()
.isPresent();
}
public boolean isPeersPaymentAccountDataAreBanned(PaymentAccountPayload paymentAccountPayload,
PaymentAccountFilter[] appliedPaymentAccountFilter) {
return getFilter() != null &&
getFilter().getBannedPaymentAccounts().stream()
.filter(paymentAccountFilter -> {
final boolean samePaymentMethodId = paymentAccountFilter.getPaymentMethodId().equals(
paymentAccountPayload.getPaymentMethodId());
if (samePaymentMethodId) {
try {
Method method = paymentAccountPayload.getClass().getMethod(paymentAccountFilter.getGetMethodName());
String result = (String) method.invoke(paymentAccountPayload);
appliedPaymentAccountFilter[0] = paymentAccountFilter;
return result.equals(paymentAccountFilter.getValue());
} catch (Throwable e) {
log.error(e.getMessage());
return false;
}
} else {
return false;
}
})
.findAny()
.isPresent();
getFilter().getBannedPaymentAccounts().stream()
.filter(paymentAccountFilter -> {
final boolean samePaymentMethodId = paymentAccountFilter.getPaymentMethodId().equals(
paymentAccountPayload.getPaymentMethodId());
if (samePaymentMethodId) {
try {
Method method = paymentAccountPayload.getClass().getMethod(paymentAccountFilter.getGetMethodName());
String result = (String) method.invoke(paymentAccountPayload);
appliedPaymentAccountFilter[0] = paymentAccountFilter;
return result.equals(paymentAccountFilter.getValue());
} catch (Throwable e) {
log.error(e.getMessage());
return false;
}
} else {
return false;
}
})
.findAny()
.isPresent();
}
}

View file

@ -86,10 +86,10 @@ public class UserPayload implements PersistableEnvelope {
.ifPresent(developersAlert -> builder.setDevelopersAlert(developersAlert.toProtoMessage().getAlert()));
Optional.ofNullable(acceptedArbitrators)
.ifPresent(e -> builder.addAllAcceptedArbitrators(ProtoUtil.collectionToProto(acceptedArbitrators,
storage -> ((PB.StoragePayload) storage).getArbitrator())));
message -> ((PB.StoragePayload) message).getArbitrator())));
Optional.ofNullable(acceptedMediators)
.ifPresent(e -> builder.addAllAcceptedMediators(ProtoUtil.collectionToProto(acceptedMediators,
storage -> ((PB.StoragePayload) storage).getMediator())));
message -> ((PB.StoragePayload) message).getMediator())));
return PB.PersistableEnvelope.newBuilder().setUserPayload(builder).build();
}

View file

@ -42,7 +42,8 @@ public class UserPayloadModelVOTest {
vo.setAccountId("accountId");
vo.setDisplayedAlert(new Alert("message", true, "version", new byte[]{12, -64, 12}, "string", null));
vo.setDevelopersFilter(new Filter(Lists.newArrayList(), Lists.newArrayList(), Lists.newArrayList(),
Lists.newArrayList(), Lists.newArrayList(), "string", new byte[]{10, 0, 0}, null));
Lists.newArrayList(), Lists.newArrayList(), Lists.newArrayList(), Lists.newArrayList(), Lists.newArrayList(),
"string", new byte[]{10, 0, 0}, null));
vo.setRegisteredArbitrator(ArbitratorTest.getArbitratorMock());
vo.setRegisteredMediator(MediatorTest.getMediatorMock());
vo.setAcceptedArbitrators(Lists.newArrayList(ArbitratorTest.getArbitratorMock()));

View file

@ -197,7 +197,7 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
switch (BisqEnvironment.getBaseCurrencyNetwork().getCurrencyCode()) {
case "BTC":
amount.set("0.125");
price.set("5400");
price.set("7400");
break;
case "LTC":
amount.set("50");

View file

@ -36,6 +36,7 @@ import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static io.bisq.gui.util.FormBuilder.addLabelInputTextField;
@ -115,9 +116,12 @@ public class FilterWindow extends Overlay<FilterWindow> {
InputTextField offerIdsInputTextField = addLabelInputTextField(gridPane, ++rowIndex, Res.get("filterWindow.offers")).second;
InputTextField nodesInputTextField = addLabelInputTextField(gridPane, ++rowIndex, Res.get("filterWindow.onions")).second;
InputTextField paymentAccountFilterInputTextField = addLabelInputTextField(gridPane, ++rowIndex, Res.get("filterWindow.accounts")).second;
GridPane.setHalignment(paymentAccountFilterInputTextField, HPos.RIGHT);
InputTextField bannedCurrenciesInputTextField = addLabelInputTextField(gridPane, ++rowIndex, Res.get("filterWindow.bannedCurrencies")).second;
InputTextField bannedPaymentMethodsInputTextField = addLabelInputTextField(gridPane, ++rowIndex, Res.get("filterWindow.bannedPaymentMethods")).second;
GridPane.setHalignment(paymentAccountFilterInputTextField, HPos.RIGHT);
InputTextField arbitratorsInputTextField = addLabelInputTextField(gridPane, ++rowIndex, Res.get("filterWindow.arbitrators")).second;
InputTextField seedNodesInputTextField = addLabelInputTextField(gridPane, ++rowIndex, Res.get("filterWindow.seedNode")).second;
InputTextField priceRelayNodesInputTextField = addLabelInputTextField(gridPane, ++rowIndex, Res.get("filterWindow.priceRelayNode")).second;
final Filter filter = filterManager.getDevelopersFilter();
if (filter != null) {
@ -128,11 +132,11 @@ public class FilterWindow extends Overlay<FilterWindow> {
filter.getBannedPaymentAccounts().stream().forEach(e -> {
if (e != null && e.getPaymentMethodId() != null) {
sb.append(e.getPaymentMethodId())
.append("|")
.append(e.getGetMethodName())
.append("|")
.append(e.getValue())
.append(", ");
.append("|")
.append(e.getGetMethodName())
.append("|")
.append(e.getValue())
.append(", ");
}
});
paymentAccountFilterInputTextField.setText(sb.toString());
@ -143,51 +147,94 @@ public class FilterWindow extends Overlay<FilterWindow> {
if (filter.getBannedPaymentMethods() != null)
bannedPaymentMethodsInputTextField.setText(filter.getBannedPaymentMethods().stream().collect(Collectors.joining(", ")));
if (filter.getArbitrators() != null)
arbitratorsInputTextField.setText(filter.getArbitrators().stream().collect(Collectors.joining(", ")));
if (filter.getSeedNodes() != null)
seedNodesInputTextField.setText(filter.getSeedNodes().stream().collect(Collectors.joining(", ")));
if (filter.getPriceRelayNodes() != null)
priceRelayNodesInputTextField.setText(filter.getPriceRelayNodes().stream().collect(Collectors.joining(", ")));
}
Button sendButton = new Button(Res.get("filterWindow.add"));
sendButton.setOnAction(e -> {
ArrayList<String> offerIds = new ArrayList<>();
ArrayList<String> nodes = new ArrayList<>();
ArrayList<PaymentAccountFilter> paymentAccountFilters = new ArrayList<>();
ArrayList<String> bannedCurrencies = new ArrayList<>();
ArrayList<String> bannedPaymentMethods = new ArrayList<>();
List<String> offerIds = new ArrayList<>();
List<String> nodes = new ArrayList<>();
List<PaymentAccountFilter> paymentAccountFilters = new ArrayList<>();
List<String> bannedCurrencies = new ArrayList<>();
List<String> bannedPaymentMethods = new ArrayList<>();
List<String> arbitrators = new ArrayList<>();
List<String> seedNodes = new ArrayList<>();
List<String> priceRelayNodes = new ArrayList<>();
if (!offerIdsInputTextField.getText().isEmpty()) {
offerIds = new ArrayList<>(Arrays.asList(StringUtils.deleteWhitespace(offerIdsInputTextField.getText())
.split(",")));
.split(",")));
}
if (!nodesInputTextField.getText().isEmpty()) {
nodes = new ArrayList<>(Arrays.asList(StringUtils.deleteWhitespace(nodesInputTextField.getText()).replace(":9999", "")
.replace(".onion", "")
.split(",")));
nodes = new ArrayList<>(Arrays.asList(StringUtils.deleteWhitespace(nodesInputTextField.getText())
.replace(":9999", "")
.replace(".onion", "")
.split(",")));
}
if (!paymentAccountFilterInputTextField.getText().isEmpty()) {
paymentAccountFilters = new ArrayList<>(Arrays.asList(paymentAccountFilterInputTextField.getText()
.replace(", ", ",")
.split(","))
.stream().map(item -> {
String[] list = item.split("\\|");
if (list.length == 3)
return new PaymentAccountFilter(list[0], list[1], list[2]);
else
return new PaymentAccountFilter("", "", "");
})
.collect(Collectors.toList()));
.replace(", ", ",")
.split(","))
.stream().map(item -> {
String[] list = item.split("\\|");
if (list.length == 3)
return new PaymentAccountFilter(list[0], list[1], list[2]);
else
return new PaymentAccountFilter("", "", "");
})
.collect(Collectors.toList()));
}
if (!bannedCurrenciesInputTextField.getText().isEmpty()) {
bannedCurrencies = new ArrayList<>(Arrays.asList(StringUtils.deleteWhitespace(bannedCurrenciesInputTextField.getText())
.split(",")));
.split(",")));
}
if (!bannedPaymentMethodsInputTextField.getText().isEmpty()) {
bannedPaymentMethods = new ArrayList<>(Arrays.asList(StringUtils.deleteWhitespace(bannedPaymentMethodsInputTextField.getText())
.split(",")));
.split(",")));
}
if (sendFilterMessageHandler.handle(new Filter(offerIds, nodes, paymentAccountFilters, bannedCurrencies, bannedPaymentMethods), keyInputTextField.getText()))
if (!arbitratorsInputTextField.getText().isEmpty()) {
arbitrators = new ArrayList<>(Arrays.asList(StringUtils.deleteWhitespace(arbitratorsInputTextField.getText())
.replace(":9999", "")
.replace(".onion", "")
.split(",")));
}
if (!seedNodesInputTextField.getText().isEmpty()) {
seedNodes = new ArrayList<>(Arrays.asList(StringUtils.deleteWhitespace(seedNodesInputTextField.getText())
.replace(":9999", "")
.replace(".onion", "")
.split(",")));
}
if (!priceRelayNodesInputTextField.getText().isEmpty()) {
priceRelayNodes = new ArrayList<>(Arrays.asList(StringUtils.deleteWhitespace(priceRelayNodesInputTextField.getText())
.replace(":9999", "")
.replace(".onion", "")
.split(",")));
}
if (sendFilterMessageHandler.handle(new Filter(offerIds,
nodes,
paymentAccountFilters,
bannedCurrencies,
bannedPaymentMethods,
arbitrators,
seedNodes,
priceRelayNodes),
keyInputTextField.getText()))
hide();
else
new Popup<>().warning(Res.get("shared.invalidKey")).width(300).onClose(this::blurAgain).show();