Seed nodes do not connect to correct network. The PR needs to be better
tested and fixed.
This commit is contained in:
Manfred Karrer 2019-02-27 14:00:05 -05:00
parent 740c112b48
commit a9ee15d9f6
No known key found for this signature in database
GPG Key ID: 401250966A6B2C46
21 changed files with 589 additions and 171 deletions

View File

@ -30,6 +30,7 @@ import bisq.core.btc.BitcoinModule;
import bisq.core.dao.DaoModule;
import bisq.core.filter.FilterModule;
import bisq.core.network.p2p.seed.DefaultSeedNodeRepository;
import bisq.core.network.p2p.seed.SeedNodeAddressLookup;
import bisq.core.notifications.MobileMessageEncryption;
import bisq.core.notifications.MobileModel;
import bisq.core.notifications.MobileNotificationService;
@ -98,6 +99,7 @@ public class CoreModule extends AppModule {
bind(CorruptedDatabaseFilesHandler.class).in(Singleton.class);
bind(AvoidStandbyModeService.class).in(Singleton.class);
bind(SeedNodeAddressLookup.class).in(Singleton.class);
bind(SeedNodeRepository.class).to(DefaultSeedNodeRepository.class).in(Singleton.class);
File storageDir = new File(environment.getRequiredProperty(Storage.STORAGE_DIR));

View File

@ -57,7 +57,6 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
@ -346,7 +345,7 @@ public class BisqEnvironment extends StandardEnvironment {
bannedPriceRelayNodes = !bannedPriceRelayNodesAsString.isEmpty() ? Arrays.asList(StringUtils.deleteWhitespace(bannedPriceRelayNodesAsString).split(",")) : null;
final String bannedSeedNodesAsString = getProperty(FilterManager.BANNED_SEED_NODES, "");
bannedSeedNodes = !bannedSeedNodesAsString.isEmpty() ? Arrays.asList(StringUtils.deleteWhitespace(bannedSeedNodesAsString).split(",")) : new ArrayList<>();
bannedSeedNodes = !bannedSeedNodesAsString.isEmpty() ? Arrays.asList(StringUtils.deleteWhitespace(bannedSeedNodesAsString).split(",")) : null;
final String bannedBtcNodesAsString = getProperty(FilterManager.BANNED_BTC_NODES, "");
bannedBtcNodes = !bannedBtcNodesAsString.isEmpty() ? Arrays.asList(StringUtils.deleteWhitespace(bannedBtcNodesAsString).split(",")) : null;

View File

@ -26,6 +26,7 @@ import bisq.core.btc.BitcoinModule;
import bisq.core.dao.DaoModule;
import bisq.core.filter.FilterModule;
import bisq.core.network.p2p.seed.DefaultSeedNodeRepository;
import bisq.core.network.p2p.seed.SeedNodeAddressLookup;
import bisq.core.offer.OfferModule;
import bisq.core.proto.network.CoreNetworkProtoResolver;
import bisq.core.proto.persistable.CorePersistenceProtoResolver;
@ -76,6 +77,7 @@ public class ModuleForAppWithP2p extends AppModule {
bind(BridgeAddressProvider.class).to(Preferences.class).in(Singleton.class);
bind(TorSetup.class).in(Singleton.class);
bind(SeedNodeAddressLookup.class).in(Singleton.class);
bind(SeedNodeRepository.class).to(DefaultSeedNodeRepository.class).in(Singleton.class);
File storageDir = new File(environment.getRequiredProperty(Storage.STORAGE_DIR));

View File

@ -0,0 +1,97 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.core.network.p2p.seed;
import bisq.network.p2p.NodeAddress;
import com.google.common.collect.ImmutableSet;
import java.util.Set;
class DefaultSeedNodeAddresses {
// Addresses are used if the last digit of their port match the network id:
// - mainnet use port ends in 0
// - testnet use port ends in 1
// - regtest use port ends in 2
public static final Set<NodeAddress> DEFAULT_LOCALHOST_SEED_NODE_ADDRESSES = ImmutableSet.of(
// BTC
// mainnet
new NodeAddress("localhost:2000"),
new NodeAddress("localhost:3000"),
new NodeAddress("localhost:4000"),
// testnet
new NodeAddress("localhost:2001"),
new NodeAddress("localhost:3001"),
new NodeAddress("localhost:4001"),
// regtest
new NodeAddress("localhost:2002"),
new NodeAddress("localhost:3002")
/* new NodeAddress("localhost:4002"),*/
);
// Addresses are used if their port match the network id:
// - mainnet uses port 8000
// - testnet uses port 8001
// - regtest uses port 8002
public static final Set<NodeAddress> DEFAULT_TOR_SEED_NODE_ADDRESSES = ImmutableSet.of(
// BTC mainnet
new NodeAddress("5quyxpxheyvzmb2d.onion:8000"), // @miker
new NodeAddress("s67qglwhkgkyvr74.onion:8000"), // @emzy
new NodeAddress("ef5qnzx6znifo3df.onion:8000"), // @manfredkarrer
new NodeAddress("jhgcy2won7xnslrb.onion:8000"), // @manfredkarrer
new NodeAddress("3f3cu2yw7u457ztq.onion:8000"), // @manfredkarrer
new NodeAddress("723ljisnynbtdohi.onion:8000"), // @manfredkarrer
new NodeAddress("rm7b56wbrcczpjvl.onion:8000"), // @manfredkarrer
new NodeAddress("fl3mmribyxgrv63c.onion:8000"), // @manfredkarrer
// local dev
// new NodeAddress("joehwtpe7ijnz4df.onion:8000"),
// new NodeAddress("uqxi3zrpobhtoes6.onion:8000"),
// BTC testnet
// new NodeAddress("vjkh4ykq7x5skdlt.onion:8001"), // local dev test
//new NodeAddress("fjr5w4eckjghqtnu.onion:8001"), // testnet seed 1
/* new NodeAddress("74w2sttlo4qk6go3.onion:8001"), // testnet seed 2
new NodeAddress("jmc5ajqvtnzqaggm.onion:8001"), // testnet seed 3
new NodeAddress("3d56s6acbi3vk52v.onion:8001"), // testnet seed 4*/
// BTC regtest
// For development you need to change that to your local onion addresses
// 1. Run a seed node with prog args: --bitcoinNetwork=regtest --nodePort=8002 --myAddress=rxdkppp3vicnbgqt:8002 --appName=bisq_seed_node_rxdkppp3vicnbgqt.onion_8002
// 2. Find your local onion address in bisq_seed_node_rxdkppp3vicnbgqt.onion_8002/regtest/tor/hiddenservice/hostname
// 3. Shut down the seed node
// 4. Rename the directory with your local onion address
// 5. Edit here your found onion address (new NodeAddress("YOUR_ONION.onion:8002")
new NodeAddress("rxdkppp3vicnbgqt.onion:8002"),
new NodeAddress("4ie52dse64kaarxw.onion:8002"),
// DAO TESTNET (server side regtest dedicated for DAO testing)
new NodeAddress("fjr5w4eckjghqtnu.onion:8003"), // testnet seed 1
new NodeAddress("74w2sttlo4qk6go3.onion:8003"), // testnet seed 2
new NodeAddress("jmc5ajqvtnzqaggm.onion:8003"), // testnet seed 3
new NodeAddress("3d56s6acbi3vk52v.onion:8003") // testnet seed 4
// explorer
// new NodeAddress("gtif46mfxirv533z.onion:8003")
);
private DefaultSeedNodeAddresses() {
}
}

View File

@ -17,87 +17,59 @@
package bisq.core.network.p2p.seed;
import bisq.core.app.BisqEnvironment;
import bisq.network.NetworkOptionKeys;
import bisq.network.p2p.NodeAddress;
import bisq.network.p2p.seed.SeedNodeRepository;
import javax.inject.Inject;
import javax.inject.Named;
import java.net.URL;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import java.util.Set;
import java.util.stream.Stream;
public class DefaultSeedNodeRepository implements SeedNodeRepository {
private static final Pattern pattern = Pattern.compile("^([a-z0-9]+\\.onion:\\d+)");
private static final String ENDING = ".seednodes";
private static final Collection<NodeAddress> cache = new HashSet<>();
private final BisqEnvironment bisqEnvironment;
private final String seedNodes;
private final Set<NodeAddress> seedNodeAddresses;
private final Set<NodeAddress> torSeedNodeAddresses;
private final Set<NodeAddress> localhostSeedNodeAddresses;
@Inject
public DefaultSeedNodeRepository(BisqEnvironment environment,
@Nullable @Named(NetworkOptionKeys.SEED_NODES_KEY) String seedNodes) {
bisqEnvironment = environment;
this.seedNodes = seedNodes;
public DefaultSeedNodeRepository(SeedNodeAddressLookup lookup) {
this.seedNodeAddresses = lookup.resolveNodeAddresses();
this.torSeedNodeAddresses = DefaultSeedNodeAddresses.DEFAULT_TOR_SEED_NODE_ADDRESSES;
this.localhostSeedNodeAddresses = DefaultSeedNodeAddresses.DEFAULT_LOCALHOST_SEED_NODE_ADDRESSES;
}
private void reload() {
@Override
public Set<NodeAddress> getSeedNodeAddresses() {
return seedNodeAddresses;
}
// see if there are any seed nodes configured manually
if(seedNodes != null && !seedNodes.isEmpty()) {
cache.clear();
Arrays.stream(seedNodes.split(",")).forEach(s -> cache.add(new NodeAddress(s)));
return;
}
// else, we fetch the seed nodes from our resources
try {
// read appropriate file
final URL file = DefaultSeedNodeRepository.class.getClassLoader().getResource(BisqEnvironment.getBaseCurrencyNetwork().name().toLowerCase() + ENDING);
final BufferedReader seedNodeFile = new BufferedReader(new FileReader(file.getFile()));
// only clear if we have a fresh data source (otherwise, an exception would prevent us from getting here)
cache.clear();
// refill the cache
seedNodeFile.lines().forEach(s -> {
final Matcher matcher = pattern.matcher(s);
if(matcher.find())
cache.add(new NodeAddress(matcher.group(1)));
});
// filter
cache.removeAll(bisqEnvironment.getBannedSeedNodes().stream().map(s -> new NodeAddress(s)).collect(Collectors.toSet()));
} catch (FileNotFoundException e) {
e.printStackTrace();
@Override
public String getOperator(NodeAddress nodeAddress) {
switch (nodeAddress.getFullAddress()) {
case "5quyxpxheyvzmb2d.onion:8000":
return "@miker";
case "ef5qnzx6znifo3df.onion:8000":
return "@manfredkarrer";
case "s67qglwhkgkyvr74.onion:8000":
return "@emzy";
case "jhgcy2won7xnslrb.onion:8000":
return "@manfredkarrer";
case "3f3cu2yw7u457ztq.onion:8000":
return "@manfredkarrer";
case "723ljisnynbtdohi.onion:8000":
return "@manfredkarrer";
case "rm7b56wbrcczpjvl.onion:8000":
return "@manfredkarrer";
case "fl3mmribyxgrv63c.onion:8000":
return "@manfredkarrer";
default:
return "Undefined";
}
}
public Collection<NodeAddress> getSeedNodeAddresses() {
if(cache.isEmpty())
reload();
return cache;
}
@Override
public boolean isSeedNode(NodeAddress nodeAddress) {
if(cache.isEmpty())
reload();
return cache.contains(nodeAddress);
return Stream.concat(localhostSeedNodeAddresses.stream(), torSeedNodeAddresses.stream())
.anyMatch(e -> e.equals(nodeAddress));
}
}

View File

@ -0,0 +1,45 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.core.network.p2p.seed;
import com.google.common.collect.ImmutableSet;
import java.util.AbstractSet;
import java.util.Iterator;
import java.util.Set;
import org.jetbrains.annotations.NotNull;
class ImmutableSetDecorator<T> extends AbstractSet<T> {
private final Set<T> delegate;
public ImmutableSetDecorator(Set<T> delegate) {
this.delegate = ImmutableSet.copyOf(delegate);
}
@NotNull
@Override
public Iterator<T> iterator() {
return delegate.iterator();
}
@Override
public int size() {
return delegate.size();
}
}

View File

@ -0,0 +1,106 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.core.network.p2p.seed;
import bisq.core.app.BisqEnvironment;
import bisq.network.NetworkOptionKeys;
import bisq.network.p2p.NodeAddress;
import com.google.inject.name.Named;
import javax.inject.Inject;
import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
public class SeedNodeAddressLookup {
private static final Logger log = LoggerFactory.getLogger(SeedNodeAddressLookup.class);
private final BisqEnvironment environment;
private final boolean isLocalHostUsed;
private final int networkId;
@Nullable
private final String myAddress;
@Nullable
private final String seedNodes;
@Inject
public SeedNodeAddressLookup(BisqEnvironment environment,
@Named(NetworkOptionKeys.USE_LOCALHOST_FOR_P2P) boolean useLocalhostForP2P,
@Named(NetworkOptionKeys.NETWORK_ID) int networkId,
@Nullable @Named(NetworkOptionKeys.MY_ADDRESS) String myAddress,
@Nullable @Named(NetworkOptionKeys.SEED_NODES_KEY) String seedNodes) {
this.environment = environment;
this.isLocalHostUsed = useLocalhostForP2P;
this.networkId = networkId;
this.myAddress = myAddress;
this.seedNodes = seedNodes;
}
public Set<NodeAddress> resolveNodeAddresses() {
SeedNodeAddresses allSeedNodeAddresses = getAllAddresses();
Set<String> bannedHosts = getBannedHosts();
allSeedNodeAddresses = allSeedNodeAddresses.excludeByHost(bannedHosts);
if (myAddress != null) {
allSeedNodeAddresses = allSeedNodeAddresses.excludeByFullAddress(myAddress);
}
log.debug("We received banned seed nodes={}, seedNodeAddresses={}", bannedHosts, allSeedNodeAddresses);
return allSeedNodeAddresses;
}
private Set<String> getBannedHosts() {
return Optional.ofNullable(environment.getBannedSeedNodes())
.map(HashSet::new)
.map(hosts -> (Set<String>) hosts)
.orElse(Collections.emptySet());
}
private SeedNodeAddresses getAllAddresses() {
SeedNodeAddresses seedNodeAddresses = Optional.ofNullable(seedNodes)
.map(nodes -> SeedNodeAddresses.fromString(seedNodes))
.orElse(new SeedNodeAddresses(Collections.emptySet()));
if (seedNodeAddresses.isEmpty()) {
Set<NodeAddress> delegate = isLocalHostUsed
? DefaultSeedNodeAddresses.DEFAULT_LOCALHOST_SEED_NODE_ADDRESSES
: DefaultSeedNodeAddresses.DEFAULT_TOR_SEED_NODE_ADDRESSES;
seedNodeAddresses = delegate.stream()
.filter(address -> isAddressFromNetwork(address, networkId))
.collect(SeedNodeAddresses.collector());
}
return seedNodeAddresses;
}
private static boolean isAddressFromNetwork(NodeAddress address, int networkId) {
String suffix = "0" + networkId;
int port = address.getPort();
String portAsString = String.valueOf(port);
return portAsString.endsWith(suffix);
}
}

View File

@ -0,0 +1,67 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.core.network.p2p.seed;
import bisq.network.p2p.NodeAddress;
import org.apache.commons.lang3.StringUtils;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collector;
import java.util.stream.Collectors;
class SeedNodeAddresses extends ImmutableSetDecorator<NodeAddress> {
public SeedNodeAddresses(Set<NodeAddress> delegate) {
super(delegate);
}
public SeedNodeAddresses excludeByHost(Set<String> hosts) {
Set<NodeAddress> copy = new HashSet<>(this);
copy.removeIf(address -> {
String hostName = address.getHostName();
return hosts.contains(hostName);
});
return new SeedNodeAddresses(copy);
}
public SeedNodeAddresses excludeByFullAddress(String fullAddress) {
Set<NodeAddress> copy = new HashSet<>(this);
copy.removeIf(address -> fullAddress.equals(address.getFullAddress()));
return new SeedNodeAddresses(copy);
}
public static Collector<NodeAddress, ?, SeedNodeAddresses> collector() {
return Collectors.collectingAndThen(Collectors.toSet(), SeedNodeAddresses::new);
}
public static SeedNodeAddresses fromString(String seedNodes) {
if (seedNodes.isEmpty()) {
return new SeedNodeAddresses(Collections.emptySet());
}
String trimmed = StringUtils.deleteWhitespace(seedNodes);
String[] nodes = trimmed.split(",");
return Arrays.stream(nodes)
.map(NodeAddress::new)
.collect(collector());
}
}

View File

@ -1,5 +0,0 @@
# nodeaddress.onion:port [(@owner)]
fjr5w4eckjghqtnu.onion:8003
3d56s6acbi3vk52v.onion:8003
74w2sttlo4qk6go3.onion:8003
jmc5ajqvtnzqaggm.onion:8003

View File

@ -1,9 +0,0 @@
# nodeaddress.onion:port [(@owner)]
5quyxpxheyvzmb2d.onion:8000 (@miker)
s67qglwhkgkyvr74.onion:8000 (@emzy)
ef5qnzx6znifo3df.onion:8000 (@freimair)
jhgcy2won7xnslrb.onion:8000 (@freimair)
3f3cu2yw7u457ztq.onion:8000 (@manfredkarrer)
723ljisnynbtdohi.onion:8000 (@manfredkarrer)
rm7b56wbrcczpjvl.onion:8000 (@manfredkarrer)
fl3mmribyxgrv63c.onion:8000 (@manfredkarrer)

View File

@ -1,10 +0,0 @@
# For development you need to change that to your local onion addresses
# 1. Run a seed node with prog args: --bitcoinNetwork=regtest --nodePort=8002 --myAddress=rxdkppp3vicnbgqt:8002 --appName=bisq_seed_node_rxdkppp3vicnbgqt.onion_8002
# 2. Find your local onion address in bisq_seed_node_rxdkppp3vicnbgqt.onion_8002/regtest/tor/hiddenservice/hostname
# 3. Shut down the seed node
# 4. Rename the directory with your local onion address
# 5. Edit here your found onion address (new NodeAddress("YOUR_ONION.onion:8002")
# nodeaddress.onion:port [(@owner)]
rxdkppp3vicnbgqt.onion:8002
4ie52dse64kaarxw.onion:8002

View File

@ -1,2 +0,0 @@
# nodeaddress.onion:port [(@owner)]
# Bisq on BTC TESTNET has been discontinued

View File

@ -1,48 +0,0 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.core.network.p2p.seed;
import bisq.core.app.BisqEnvironment;
import bisq.network.p2p.NodeAddress;
import org.springframework.core.env.PropertySource;
import org.junit.Assert;
import org.junit.Test;
public class DefaultSeedNodeRepositoryTest {
@Test
public void getSeedNodes() {
DefaultSeedNodeRepository DUT = new DefaultSeedNodeRepository(new BisqEnvironment(new PropertySource.StubPropertySource("name")), null);
Assert.assertFalse(DUT.getSeedNodeAddresses().isEmpty());
}
@Test
public void manualSeedNodes() {
String seed1 = "asdf:8001";
String seed2 = "fdsa:6001";
String seedNodes = seed1 + "," + seed2;
DefaultSeedNodeRepository DUT = new DefaultSeedNodeRepository(new BisqEnvironment(new PropertySource.StubPropertySource("name")), seedNodes);
Assert.assertFalse(DUT.getSeedNodeAddresses().isEmpty());
Assert.assertEquals(2, DUT.getSeedNodeAddresses().size());
Assert.assertTrue(DUT.getSeedNodeAddresses().contains(new NodeAddress(seed1)));
Assert.assertTrue(DUT.getSeedNodeAddresses().contains(new NodeAddress(seed2)));
}
}

View File

@ -0,0 +1,65 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.core.network.p2p.seed;
import com.google.common.collect.Sets;
import java.util.Set;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
public class ImmutableSetDecoratorTest {
@Test(expected = UnsupportedOperationException.class)
public void testAdd() {
Set<Integer> original = Sets.newHashSet(1, 2, 3);
Set<Integer> decorator = new ImmutableSetDecorator<>(original);
decorator.add(4);
}
@Test(expected = UnsupportedOperationException.class)
public void testRemove() {
Set<Integer> original = Sets.newHashSet(1, 2, 3);
Set<Integer> decorator = new ImmutableSetDecorator<>(original);
decorator.remove(3);
}
@Test(expected = UnsupportedOperationException.class)
public void testClear() {
Set<Integer> original = Sets.newHashSet(1, 2, 3);
Set<Integer> decorator = new ImmutableSetDecorator<>(original);
decorator.clear();
}
@Test(expected = UnsupportedOperationException.class)
public void testRemoveWithIterator() {
Set<Integer> original = Sets.newHashSet(1, 2, 3);
Set<Integer> decorator = new ImmutableSetDecorator<>(original);
decorator.iterator().remove();
}
@Test
public void testBackingCollection() {
Set<Integer> original = Sets.newHashSet(1, 2, 3);
Set<Integer> decorator = new ImmutableSetDecorator<>(original);
original.remove(2);
assertTrue(decorator.contains(2));
}
}

View File

@ -0,0 +1,55 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.core.network.p2p.seed;
import bisq.core.app.BisqEnvironment;
import bisq.network.p2p.NodeAddress;
import java.util.Collections;
import java.util.Set;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.mockito.Mockito.mock;
public class SeedNodeAddressLookupTest {
@Test
public void testResolveNodeAddressesWhenLocalAddressSpecified() {
SeedNodeAddressLookup lookup = new SeedNodeAddressLookup(
mock(BisqEnvironment.class), false, 0, "192.168.0.1:1234",
"192.168.0.1:1234, 192.168.0.2:9897");
Set<NodeAddress> actual = lookup.resolveNodeAddresses();
Set<NodeAddress> expected = Collections.singleton(new NodeAddress("192.168.0.2:9897"));
assertEquals(expected, actual);
}
@Test
public void testResolveNodeAddressesWhenSeedNodesAreNull() {
SeedNodeAddressLookup lookup = new SeedNodeAddressLookup(
mock(BisqEnvironment.class), false, 0, "192.168.0.1:1234", null);
Set<NodeAddress> actual = lookup.resolveNodeAddresses();
assertFalse(actual.isEmpty());
}
}

View File

@ -0,0 +1,102 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.core.network.p2p.seed;
import bisq.network.p2p.NodeAddress;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.Security;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class SeedNodeAddressesTest {
@Test
public void testCollector() {
List<NodeAddress> addresses = Lists.newArrayList(
new NodeAddress("192.168.0.1:1111"),
new NodeAddress("192.168.0.1:1111"),
new NodeAddress("192.168.0.2:2222"));
Set<NodeAddress> expected = new HashSet<>(addresses);
SeedNodeAddresses actual = addresses.stream()
.collect(SeedNodeAddresses.collector());
assertEquals(expected, actual);
}
@Test
public void testExcludeByFullAddress() {
Set<NodeAddress> delegate = Sets.newHashSet(
new NodeAddress("192.168.0.1:1111"),
new NodeAddress("192.168.0.2:2222"));
SeedNodeAddresses addresses = new SeedNodeAddresses(delegate);
SeedNodeAddresses actual = addresses.excludeByFullAddress("192.168.0.1:1111");
assertEquals(1, actual.size());
}
@Test
public void testExcludeByHost() {
Set<NodeAddress> delegate = Sets.newHashSet(
new NodeAddress("aaa:1111"),
new NodeAddress("aaa:2222"),
new NodeAddress("bbb:1111"),
new NodeAddress("bbb:2222"),
new NodeAddress("ccc:1111"),
new NodeAddress("ccc:2222"));
SeedNodeAddresses addresses = new SeedNodeAddresses(delegate);
Set<String> hosts = Sets.newHashSet("aaa", "bbb");
SeedNodeAddresses actual = addresses.excludeByHost(hosts);
Set<NodeAddress> expected = Sets.newHashSet(
new NodeAddress("ccc:1111"),
new NodeAddress("ccc:2222"));
assertEquals(expected, actual);
}
@Test
public void testFromString() {
Set<NodeAddress> expected = Sets.newHashSet(
new NodeAddress("192.168.0.1:1111"),
new NodeAddress("192.168.0.2:2222"));
SeedNodeAddresses actual = SeedNodeAddresses.fromString("192.168.0.1:1111, 192.168.0.2:2222");
assertEquals(expected, actual);
}
@Test
public void testFromEmptyString() {
SeedNodeAddresses nodeAddresses = SeedNodeAddresses.fromString("");
assertTrue(nodeAddresses.isEmpty());
}
}

View File

@ -1,9 +0,0 @@
# nodeaddress.onion:port [(@owner)]
5quyxpxheyvzmb2d.onion:8000 (@miker)
s67qglwhkgkyvr74.onion:8000 (@emzy)
ef5qnzx6znifo3df.onion:8000 (@manfredkarrer)
jhgcy2won7xnslrb.onion:8000 (@manfredkarrer)
3f3cu2yw7u457ztq.onion:8000 (@manfredkarrer)
723ljisnynbtdohi.onion:8000 (@manfredkarrer)
rm7b56wbrcczpjvl.onion:8000 (@manfredkarrer)
fl3mmribyxgrv63c.onion:8000 (@manfredkarrer)

View File

@ -1,10 +0,0 @@
# For development you need to change that to your local onion addresses
# 1. Run a seed node with prog args: --bitcoinNetwork=regtest --nodePort=8002 --myAddress=rxdkppp3vicnbgqt:8002 --appName=bisq_seed_node_rxdkppp3vicnbgqt.onion_8002
# 2. Find your local onion address in bisq_seed_node_rxdkppp3vicnbgqt.onion_8002/regtest/tor/hiddenservice/hostname
# 3. Shut down the seed node
# 4. Rename the directory with your local onion address
# 5. Edit here your found onion address (new NodeAddress("YOUR_ONION.onion:8002")
# nodeaddress.onion:port [(@owner)]
rxdkppp3vicnbgqt.onion:8002
4ie52dse64kaarxw.onion:8002

View File

@ -1,7 +0,0 @@
# nodeaddress.onion:port [(@owner)]
snenz4mea65wigen.onion:8001
fjr5w4eckjghqtnu.onion:8001
3d56s6acbi3vk52v.onion:8001
74w2sttlo4qk6go3.onion:8001
gtif46mfxirv533z.onion:8001
jmc5ajqvtnzqaggm.onion:8001

View File

@ -32,12 +32,14 @@ import org.springframework.core.env.PropertySource;
import bisq.common.Clock;
import bisq.common.app.Capabilities;
import bisq.common.app.Version;
import bisq.common.proto.network.NetworkEnvelope;
import bisq.common.proto.network.NetworkProtoResolver;
import bisq.core.app.BisqEnvironment;
import bisq.core.btc.BaseCurrencyNetwork;
import bisq.core.btc.BtcOptionKeys;
import bisq.core.network.p2p.seed.DefaultSeedNodeRepository;
import bisq.core.network.p2p.seed.SeedNodeAddressLookup;
import bisq.core.proto.network.CoreNetworkProtoResolver;
import bisq.core.proto.persistable.CorePersistenceProtoResolver;
import bisq.monitor.AvailableTor;
@ -160,6 +162,7 @@ public class P2PNetworkLoad extends Metric implements MessageListener, SetupList
// boot up P2P node
File storageDir = torHiddenServiceDir;
String seedNodes = "";
try {
BisqEnvironment environment = new BisqEnvironment(new PropertySource<String>("name") {
@ -174,7 +177,8 @@ public class P2PNetworkLoad extends Metric implements MessageListener, SetupList
NetworkProtoResolver networkProtoResolver = new CoreNetworkProtoResolver();
CorePersistenceProtoResolver persistenceProtoResolver = new CorePersistenceProtoResolver(null,
networkProtoResolver, storageDir);
DefaultSeedNodeRepository seedNodeRepository = new DefaultSeedNodeRepository(environment, null);
DefaultSeedNodeRepository seedNodeRepository = new DefaultSeedNodeRepository(
new SeedNodeAddressLookup(environment, false, Version.getBaseCurrencyNetwork(), null, seedNodes));
PeerManager peerManager = new PeerManager(networkNode, seedNodeRepository, new Clock(),
persistenceProtoResolver, maxConnections, storageDir);

View File

@ -19,11 +19,13 @@ package bisq.network.p2p.seed;
import bisq.network.p2p.NodeAddress;
import java.util.Collection;
import java.util.Set;
public interface SeedNodeRepository {
boolean isSeedNode(NodeAddress nodeAddress);
Collection<NodeAddress> getSeedNodeAddresses();
Set<NodeAddress> getSeedNodeAddresses();
String getOperator(NodeAddress nodeAddress);
}