Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new fields to filter #7149

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions common/src/main/java/bisq/common/config/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,10 @@ public class Config {
public static final String MAX_MEMORY = "maxMemory";
public static final String LOG_LEVEL = "logLevel";
public static final String BANNED_BTC_NODES = "bannedBtcNodes";
private static final String FILTER_PROVIDED_BTC_NODES = "filterProvidedBtcNodes";
public static final String BANNED_PRICE_RELAY_NODES = "bannedPriceRelayNodes";
public static final String BANNED_SEED_NODES = "bannedSeedNodes";
private static final String FILTER_PROVIDED_SEED_NODES = "filterProvidedSeedNodes";
public static final String BASE_CURRENCY_NETWORK = "baseCurrencyNetwork";
public static final String REFERRAL_ID = "referralId";
public static final String USE_DEV_MODE = "useDevMode";
Expand Down Expand Up @@ -170,8 +172,10 @@ public class Config {
public final int maxMemory;
public final String logLevel;
public final List<String> bannedBtcNodes;
public final List<String> filterProvidedBtcNodes;
public final List<String> bannedPriceRelayNodes;
public final List<String> bannedSeedNodes;
public final List<String> filterProvidedSeedNodes;
public final BaseCurrencyNetwork baseCurrencyNetwork;
public final NetworkParameters networkParameters;
public final boolean ignoreLocalBtcNode;
Expand Down Expand Up @@ -336,6 +340,12 @@ public Config(String defaultAppName, File defaultUserDataDir, String... args) {
.ofType(String.class)
.withValuesSeparatedBy(',')
.describedAs("host:port[,...]");
ArgumentAcceptingOptionSpec<String> filterProvidedBtcNodesOpt =
parser.accepts(FILTER_PROVIDED_BTC_NODES, "List of filter provided Bitcoin nodes")
.withRequiredArg()
.ofType(String.class)
.withValuesSeparatedBy(',')
.describedAs("host:port[,...]");

ArgumentAcceptingOptionSpec<String> bannedPriceRelayNodesOpt =
parser.accepts(BANNED_PRICE_RELAY_NODES, "List Bisq price nodes to ban")
Expand All @@ -350,6 +360,12 @@ public Config(String defaultAppName, File defaultUserDataDir, String... args) {
.ofType(String.class)
.withValuesSeparatedBy(',')
.describedAs("host:port[,...]");
ArgumentAcceptingOptionSpec<String> filterProvidedSeedNodesOpt =
parser.accepts(FILTER_PROVIDED_SEED_NODES, "List of filer provided seed nodes")
.withRequiredArg()
.ofType(String.class)
.withValuesSeparatedBy(',')
.describedAs("host:port[,...]");

//noinspection rawtypes
ArgumentAcceptingOptionSpec<Enum> baseCurrencyNetworkOpt =
Expand Down Expand Up @@ -539,9 +555,11 @@ public Config(String defaultAppName, File defaultUserDataDir, String... args) {
.defaultsTo(50); // Pause in ms to sleep if we get too many messages to send

ArgumentAcceptingOptionSpec<String> btcNodesOpt =
parser.accepts(BTC_NODES, "Custom nodes used for BitcoinJ as comma separated IP addresses.")
parser.accepts(BTC_NODES, "Override provided Bitcoin nodes as comma separated list e.g. " +
"'rxdkppp3vicnbgqt.onion:8002,mfla72c4igh5ta2t.onion:8002'")
.withRequiredArg()
.describedAs("ip[,...]")
.withValuesSeparatedBy(',')
.describedAs("host:port[,...]")
.defaultsTo("");

ArgumentAcceptingOptionSpec<Boolean> useTorForBtcOpt =
Expand Down Expand Up @@ -780,8 +798,10 @@ public Config(String defaultAppName, File defaultUserDataDir, String... args) {
this.maxMemory = options.valueOf(maxMemoryOpt);
this.logLevel = options.valueOf(logLevelOpt);
this.bannedBtcNodes = options.valuesOf(bannedBtcNodesOpt);
this.filterProvidedBtcNodes = options.valuesOf(filterProvidedBtcNodesOpt);
this.bannedPriceRelayNodes = options.valuesOf(bannedPriceRelayNodesOpt);
this.bannedSeedNodes = options.valuesOf(bannedSeedNodesOpt);
this.filterProvidedSeedNodes = options.valuesOf(filterProvidedSeedNodesOpt);
this.baseCurrencyNetwork = (BaseCurrencyNetwork) options.valueOf(baseCurrencyNetworkOpt);
this.networkParameters = baseCurrencyNetwork.getParameters();
this.ignoreLocalBtcNode = options.valueOf(ignoreLocalBtcNodeOpt);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,44 @@

package bisq.core.btc.nodes;

import bisq.core.btc.nodes.BtcNodes.BtcNode;
import bisq.core.user.Preferences;

import bisq.network.p2p.NodeAddress;

import bisq.common.config.Config;
import bisq.common.util.Utilities;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.jetbrains.annotations.Nullable;


public class BtcNodesSetupPreferences {
private static final Logger log = LoggerFactory.getLogger(BtcNodesSetupPreferences.class);

private final Preferences preferences;
private final int numConnectionsForBtc;
private final Config config;

public BtcNodesSetupPreferences(Preferences preferences,
int numConnectionsForBtc) {
int numConnectionsForBtc,
Config config) {
this.preferences = preferences;
this.numConnectionsForBtc = numConnectionsForBtc;
this.config = config;
}

public List<BtcNodes.BtcNode> selectPreferredNodes(BtcNodes nodes) {
List<BtcNodes.BtcNode> result;
public List<BtcNode> selectPreferredNodes(BtcNodes btcNodes) {
List<BtcNode> result;

BtcNodes.BitcoinNodesOption nodesOption = BtcNodes.BitcoinNodesOption.values()[preferences.getBitcoinNodesOptionOrdinal()];
switch (nodesOption) {
Expand All @@ -51,18 +63,35 @@ public List<BtcNodes.BtcNode> selectPreferredNodes(BtcNodes nodes) {
Set<String> distinctNodes = Utilities.commaSeparatedListToSet(bitcoinNodes, false);
result = BtcNodes.toBtcNodesList(distinctNodes);
if (result.isEmpty()) {
log.warn("Custom nodes is set but no valid nodes are provided. " +
"We fall back to provided nodes option.");
log.warn("Custom btcNodes is set but no valid btcNodes are provided. " +
"We fall back to provided btcNodes option.");
preferences.setBitcoinNodesOptionOrdinal(BtcNodes.BitcoinNodesOption.PROVIDED.ordinal());
result = nodes.getProvidedBtcNodes();
result = btcNodes.getProvidedBtcNodes();
}
break;
case PUBLIC:
result = Collections.emptyList();
break;
case PROVIDED:
default:
result = nodes.getProvidedBtcNodes();
Set<BtcNode> providedBtcNodes = new HashSet<>(btcNodes.getProvidedBtcNodes());
Set<BtcNode> filterProvidedBtcNodes = config.filterProvidedBtcNodes.stream()
.filter(n -> !n.isEmpty())
.map(this::getNodeAddress)
.filter(Objects::nonNull)
.map(nodeAddress -> new BtcNode(null, nodeAddress.getHostName(), null, nodeAddress.getPort(), "Provided by filter"))
.collect(Collectors.toSet());
providedBtcNodes.addAll(filterProvidedBtcNodes);

Set<String> bannedBtcNodeHostNames = config.bannedBtcNodes.stream()
.filter(n -> !n.isEmpty())
.map(this::getNodeAddress)
.filter(Objects::nonNull)
.map(NodeAddress::getHostName)
.collect(Collectors.toSet());
result = providedBtcNodes.stream()
.filter(e -> !bannedBtcNodeHostNames.contains(e.getHostName()))
.collect(Collectors.toList());
break;
}

Expand All @@ -73,7 +102,7 @@ public boolean isUseCustomNodes() {
return BtcNodes.BitcoinNodesOption.CUSTOM.ordinal() == preferences.getBitcoinNodesOptionOrdinal();
}

public int calculateMinBroadcastConnections(List<BtcNodes.BtcNode> nodes) {
public int calculateMinBroadcastConnections(List<BtcNode> nodes) {
BtcNodes.BitcoinNodesOption nodesOption = BtcNodes.BitcoinNodesOption.values()[preferences.getBitcoinNodesOptionOrdinal()];
int result;
switch (nodesOption) {
Expand All @@ -97,4 +126,13 @@ public int calculateMinBroadcastConnections(List<BtcNodes.BtcNode> nodes) {
return result;
}

@Nullable
private NodeAddress getNodeAddress(String address) {
try {
return new NodeAddress(address);
} catch (Throwable t) {
log.error("exception when filtering banned seednodes", t);
}
return null;
}
}
3 changes: 1 addition & 2 deletions core/src/main/java/bisq/core/btc/setup/WalletsSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -396,8 +396,7 @@ private void configPeerNodesForRegTestServer() {
}

private void configPeerNodes(@Nullable Socks5Proxy proxy) {
BtcNodesSetupPreferences btcNodesSetupPreferences = new BtcNodesSetupPreferences(preferences,
numConnectionsForBtc);
BtcNodesSetupPreferences btcNodesSetupPreferences = new BtcNodesSetupPreferences(preferences, numConnectionsForBtc, config);

List<BtcNode> nodes = btcNodesSetupPreferences.selectPreferredNodes(btcNodes);
int minBroadcastConnections = btcNodesSetupPreferences.calculateMinBroadcastConnections(nodes);
Expand Down
36 changes: 29 additions & 7 deletions core/src/main/java/bisq/core/filter/Filter.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ public final class Filter implements ProtectedStoragePayload, ExpirablePayload {
// Added at v1.9.13
private final List<PaymentAccountFilter> delayedPayoutPaymentAccounts;

// Added at v 1.9.16
private final List<String> addedBtcNodes;
private final List<String> addedSeedNodes;

// After we have created the signature from the filter data we clone it and apply the signature
static Filter cloneWithSig(Filter filter, String signatureAsBase64) {
return new Filter(filter.getBannedOfferIds(),
Expand Down Expand Up @@ -160,7 +164,9 @@ static Filter cloneWithSig(Filter filter, String signatureAsBase64) {
filter.getTakerFeeBtc(),
filter.getMakerFeeBsq(),
filter.getTakerFeeBsq(),
filter.getDelayedPayoutPaymentAccounts());
filter.getDelayedPayoutPaymentAccounts(),
filter.getAddedBtcNodes(),
filter.getAddedSeedNodes());
}

// Used for signature verification as we created the sig without the signatureAsBase64 field we set it to null again
Expand Down Expand Up @@ -200,7 +206,9 @@ static Filter cloneWithoutSig(Filter filter) {
filter.getTakerFeeBtc(),
filter.getMakerFeeBsq(),
filter.getTakerFeeBsq(),
filter.getDelayedPayoutPaymentAccounts());
filter.getDelayedPayoutPaymentAccounts(),
filter.getAddedBtcNodes(),
filter.getAddedSeedNodes());
}

public Filter(List<String> bannedOfferIds,
Expand Down Expand Up @@ -235,7 +243,9 @@ public Filter(List<String> bannedOfferIds,
long takerFeeBtc,
long makerFeeBsq,
long takerFeeBsq,
List<PaymentAccountFilter> delayedPayoutPaymentAccounts) {
List<PaymentAccountFilter> delayedPayoutPaymentAccounts,
List<String> addedBtcNodes,
List<String> addedSeedNodes) {
this(bannedOfferIds,
nodeAddressesBannedFromTrading,
bannedPaymentAccounts,
Expand Down Expand Up @@ -271,7 +281,9 @@ public Filter(List<String> bannedOfferIds,
takerFeeBtc,
makerFeeBsq,
takerFeeBsq,
delayedPayoutPaymentAccounts);
delayedPayoutPaymentAccounts,
addedBtcNodes,
addedSeedNodes);
}


Expand Down Expand Up @@ -315,7 +327,9 @@ public Filter(List<String> bannedOfferIds,
long takerFeeBtc,
long makerFeeBsq,
long takerFeeBsq,
List<PaymentAccountFilter> delayedPayoutPaymentAccounts) {
List<PaymentAccountFilter> delayedPayoutPaymentAccounts,
List<String> addedBtcNodes,
List<String> addedSeedNodes) {
this.bannedOfferIds = bannedOfferIds;
this.nodeAddressesBannedFromTrading = nodeAddressesBannedFromTrading;
this.bannedPaymentAccounts = bannedPaymentAccounts;
Expand Down Expand Up @@ -352,6 +366,8 @@ public Filter(List<String> bannedOfferIds,
this.makerFeeBsq = makerFeeBsq;
this.takerFeeBsq = takerFeeBsq;
this.delayedPayoutPaymentAccounts = delayedPayoutPaymentAccounts;
this.addedBtcNodes = addedBtcNodes;
this.addedSeedNodes = addedSeedNodes;

// ownerPubKeyBytes can be null when called from tests
if (ownerPubKeyBytes != null) {
Expand Down Expand Up @@ -403,7 +419,9 @@ public protobuf.StoragePayload toProtoMessage() {
.setTakerFeeBtc(takerFeeBtc)
.setMakerFeeBsq(makerFeeBsq)
.setTakerFeeBsq(takerFeeBsq)
.addAllDelayedPayoutPaymentAccounts(delayedPayoutPaymentAccountList);
.addAllDelayedPayoutPaymentAccounts(delayedPayoutPaymentAccountList)
.addAllAddedBtcNodes(addedBtcNodes)
.addAllAddedSeedNodes(addedSeedNodes);

Optional.ofNullable(signatureAsBase64).ifPresent(builder::setSignatureAsBase64);
Optional.ofNullable(extraDataMap).ifPresent(builder::putAllExtraData);
Expand Down Expand Up @@ -454,7 +472,9 @@ public static Filter fromProto(protobuf.Filter proto) {
proto.getTakerFeeBtc(),
proto.getMakerFeeBsq(),
proto.getTakerFeeBsq(),
delayedPayoutPaymentAccounts
delayedPayoutPaymentAccounts,
ProtoUtil.protocolStringListToList(proto.getAddedBtcNodesList()),
ProtoUtil.protocolStringListToList(proto.getAddedSeedNodesList())
);
}

Expand Down Expand Up @@ -512,6 +532,8 @@ public String toString() {
",\n takerFeeBtc=" + takerFeeBtc +
",\n makerFeeBsq=" + makerFeeBsq +
",\n takerFeeBsq=" + takerFeeBsq +
",\n addedBtcNodes=" + addedBtcNodes +
",\n addedSeedNodes=" + addedSeedNodes +
"\n}";
}
}
6 changes: 6 additions & 0 deletions core/src/main/java/bisq/core/filter/FilterManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ public class FilterManager {
private static final String BANNED_PRICE_RELAY_NODES = "bannedPriceRelayNodes";
private static final String BANNED_SEED_NODES = "bannedSeedNodes";
private static final String BANNED_BTC_NODES = "bannedBtcNodes";
private static final String FILTER_PROVIDED_SEED_NODES = "filterProvidedSeedNodes";
private static final String FILTER_PROVIDED_BTC_NODES = "filterProvidedBtcNodes";

///////////////////////////////////////////////////////////////////////////////////////////
// Listener
Expand Down Expand Up @@ -570,6 +572,8 @@ private void onFilterAddedFromNetwork(Filter newFilter) {
// We persist it to the property file which is read before any other initialisation.
saveBannedNodes(BANNED_SEED_NODES, newFilter.getSeedNodes());
saveBannedNodes(BANNED_BTC_NODES, newFilter.getBtcNodes());
saveBannedNodes(FILTER_PROVIDED_BTC_NODES, newFilter.getAddedBtcNodes());
saveBannedNodes(FILTER_PROVIDED_SEED_NODES, newFilter.getAddedSeedNodes());

// Banned price relay nodes we can apply at runtime
List<String> priceRelayNodes = newFilter.getPriceRelayNodes();
Expand Down Expand Up @@ -614,7 +618,9 @@ private void onFilterRemovedFromNetwork(Filter filter) {
// Clears options files from banned nodes
private void clearBannedNodes() {
saveBannedNodes(BANNED_BTC_NODES, null);
saveBannedNodes(FILTER_PROVIDED_BTC_NODES, null);
saveBannedNodes(BANNED_SEED_NODES, null);
saveBannedNodes(FILTER_PROVIDED_SEED_NODES, null);
saveBannedNodes(BANNED_PRICE_RELAY_NODES, null);

if (providersRepository.getBannedNodes() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
Expand All @@ -51,7 +52,7 @@ public class DefaultSeedNodeRepository implements SeedNodeRepository {
//TODO add support for localhost addresses
private static final Pattern pattern = Pattern.compile("^([a-z0-9]+\\.onion:\\d+)");
private static final String ENDING = ".seednodes";
private final Collection<NodeAddress> cache = new HashSet<>();
private final Set<NodeAddress> cache = new HashSet<>();
private final Config config;

@Inject
Expand All @@ -73,13 +74,19 @@ private void reload() {
List<NodeAddress> result = getSeedNodeAddressesFromPropertyFile(config.baseCurrencyNetwork.name().toLowerCase(Locale.ENGLISH));
cache.addAll(result);

// let values configured by filter fail more gracefully
cache.removeAll(
config.bannedSeedNodes.stream()
.filter(n -> !n.isEmpty())
.map(this::getNodeAddress)
.filter(Objects::nonNull)
.collect(Collectors.toSet()));
Set<NodeAddress> filterProvidedSeedNodes = config.filterProvidedSeedNodes.stream()
.filter(n -> !n.isEmpty())
.map(this::getNodeAddress)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
cache.addAll(filterProvidedSeedNodes);

Set<NodeAddress> bannedSeedNodes = config.bannedSeedNodes.stream()
.filter(n -> !n.isEmpty())
.map(this::getNodeAddress)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
cache.removeAll(bannedSeedNodes);

log.info("Seed nodes: {}", cache);
} catch (Throwable t) {
Expand Down
4 changes: 3 additions & 1 deletion core/src/main/resources/i18n/displayStrings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3057,8 +3057,10 @@ filterWindow.arbitrators=Filtered arbitrators (comma sep. onion addresses)
filterWindow.mediators=Filtered mediators (comma sep. onion addresses)
filterWindow.refundAgents=Filtered refund agents (comma sep. onion addresses)
filterWindow.seedNode=Filtered seed nodes (comma sep. onion addresses)
filterWindow.addedSeedNodes=Added Seed nodes (comma sep. addresses + port)
filterWindow.priceRelayNode=Filtered price relay nodes (comma sep. onion addresses)
filterWindow.btcNode=Filtered Bitcoin nodes (comma sep. addresses + port)
filterWindow.btcNode=Banned Bitcoin nodes (comma sep. addresses + port)
filterWindow.addedBtcNodes=Added Bitcoin nodes (comma sep. addresses + port)
filterWindow.preventPublicBtcNetwork=Prevent usage of public Bitcoin network
filterWindow.disableDao=Disable DAO
filterWindow.disableAutoConf=Disable auto-confirm
Expand Down
Loading
Loading