Merged with master

This commit is contained in:
Manfred Karrer 2015-02-16 12:16:40 +01:00
commit 75b2e4462f
11 changed files with 342 additions and 69 deletions

View File

@ -75,6 +75,7 @@
<package name="" withSubpackages="true" static="true" />
</value>
</option>
<option name="RIGHT_MARGIN" value="160" />
<option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" />
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />

View File

@ -6,13 +6,13 @@
What is Bitsquare?
------------------
Bitsquare is a cross-platform desktop application that allows users to trade fiat money (dollars, euros, etc) for bitcoin without relying on centralized exchanges such as Coinbase, Bitstamp or (the former) Mt. Gox.
Bitsquare is a cross-platform desktop application that allows users to trade national currency (dollars, euros, etc) for bitcoin without relying on centralized exchanges such as Coinbase, Bitstamp or (the former) Mt. Gox.
By running Bitsquare on their local machines, users form a peer-to-peer network. Offers to buy and sell bitcoin are broadcast to that network, and through the process of offering and accepting these trades via the Bitsquare UI, a market is established.
There are no central points of control or failure in the Bitsquare network. There are no trusted third parties. When two parties agree to trade fiat money for bitcoin, the bitcoin to be bought or sold is held in escrow using multisignature transaction capabilities native to the bitcoin protocol.
There are no central points of control or failure in the Bitsquare network. There are no trusted third parties. When two parties agree to trade national currency for bitcoin, the bitcoin to be bought or sold is held in escrow using multisignature transaction capabilities native to the bitcoin protocol.
Because the fiat money portion of any trade must be transferred via traditional means such as a wire transfer, Bitsquare incorporates first-class support for human arbitration to resolve any errors or disputes.
Because the national currency portion of any trade must be transferred via traditional means such as a wire transfer, Bitsquare incorporates first-class support for human arbitration to resolve any errors or disputes.
You can read about all of this and more in the [whitepaper](https://bitsquare.io/bitsquare.pdf), [arbitration](https://bitsquare.io/arbitration_system.pdf) and [risk analysis](https://bitsquare.io/risk_analysis.pdf) documents. Several [videos](https://bitsquare.io/blog/category/video) are available as well.

View File

@ -36,12 +36,12 @@ processResources {
repositories {
jcenter()
maven { url 'http://partnerdemo.artifactoryonline.com/partnerdemo/libs-snapshots-local' }
maven { url 'http://tomp2p.net/dev/mvn/' }
}
dependencies {
compile 'org.bitcoinj:bitcoinj-core:0.12.2'
compile 'net.tomp2p:tomp2p-all:5.0-Alpha.8f1cafb-SNAPSHOT'
compile 'net.tomp2p:tomp2p-all:5.0-Beta3'
compile 'io.reactivex:rxjava:1.0.0'
compile 'org.springframework:spring-core:4.1.1.RELEASE'
compile 'net.sf.jopt-simple:jopt-simple:4.8'

View File

@ -30,5 +30,6 @@ public class CryptoModule extends BitsquareModule {
@Override
protected void configure() {
bind(SignatureService.class).asEagerSingleton();
bind(HashService.class).asEagerSingleton();
}
}

View File

@ -0,0 +1,29 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare 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.
*
* Bitsquare 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 Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.crypto;
import org.bitcoinj.core.Sha256Hash;
import org.bitcoinj.core.Utils;
public class HashService {
public Sha256Hash hash(String message) {
byte[] data = Utils.formatMessageForSigning(message);
return Sha256Hash.createDouble(data);
}
}

View File

@ -30,6 +30,10 @@ public class SignatureService {
public String signMessage(ECKey key, String message) {
byte[] data = Utils.formatMessageForSigning(message);
Sha256Hash hash = Sha256Hash.createDouble(data);
return signMessage(key, hash);
}
public String signMessage(ECKey key, Sha256Hash hash) {
ECKey.ECDSASignature sig = key.sign(hash, null);
// Now we have to work backwards to figure out the recId needed to recover the signature.
int recId = -1;
@ -54,4 +58,8 @@ public class SignatureService {
String signedMessage = signMessage(key, message);
return Utils.sha256hash160(message.concat(signedMessage).getBytes(Charsets.UTF_8));
}
public boolean verify(ECKey key, Sha256Hash hash, ECKey.ECDSASignature signature) {
return key.verify(hash, signature);
}
}

View File

@ -20,6 +20,7 @@ package io.bitsquare.gui.main.funds.transactions;
import io.bitsquare.btc.WalletService;
import io.bitsquare.gui.components.Popups;
import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.util.Utilities;
import org.bitcoinj.core.Transaction;
@ -85,8 +86,14 @@ public class TransactionsView extends ActivatableViewAndModel {
// TODO Open popup with details view
log.debug("openTxDetails " + item);
Popups.openWarningPopup("Under construction",
"This will open a details popup but that is not implemented yet.");
try {
// TODO get the url form the app preferences
Utilities.openWebPage("https://www.biteasy.com/testnet/addresses/" + item.getAddressString());
} catch (Exception e) {
log.error(e.getMessage());
Popups.openWarningPopup("Warning", "Opening browser failed. Please check your internet " +
"connection.");
}
}
private void setAddressColumnCellFactory() {

View File

@ -46,6 +46,7 @@ import net.tomp2p.futures.BaseFutureListener;
import net.tomp2p.futures.FutureBootstrap;
import net.tomp2p.futures.FutureDiscover;
import net.tomp2p.nat.FutureNAT;
import net.tomp2p.nat.FutureRelayNAT;
import net.tomp2p.nat.PeerBuilderNAT;
import net.tomp2p.nat.PeerNAT;
import net.tomp2p.p2p.Peer;
@ -54,6 +55,7 @@ import net.tomp2p.peers.Number160;
import net.tomp2p.peers.PeerAddress;
import net.tomp2p.peers.PeerMapChangeListener;
import net.tomp2p.peers.PeerStatistic;
import net.tomp2p.relay.tcp.TCPRelayClientConfig;
import org.jetbrains.annotations.NotNull;
@ -194,17 +196,18 @@ class BootstrappedPeerBuilder {
// If that is successfully setup we need to try again a discover so we find out our external address and have
// tested successfully our reachability (the additional discover is done internally from startSetupPortforwarding)
// 4. If the port forwarding failed we can try as last resort to open a permanent TCP connection to the
// bootstrap node and use that peer as relay (currently not supported as its too unstable)
// bootstrap node and use that peer as relay
private void discoverExternalAddress() {
FutureDiscover futureDiscover = peer.discover().peerAddress(getBootstrapAddress()).start();
setState(BootstrapState.DISCOVERY_STARTED, "Starting discovery...");
PeerNAT peerNAT = new PeerBuilderNAT(peer).start();
FutureNAT futureNAT = peerNAT.startSetupPortforwarding(futureDiscover);
futureNAT.addListener(new BaseFutureListener<BaseFuture>() {
FutureRelayNAT futureRelayNAT = peerNAT.startRelay(new TCPRelayClientConfig(), futureDiscover, futureNAT);
futureRelayNAT.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception {
// If futureDiscover was successful we are directly connected (or manual port forwarding is set)
if (futureDiscover.isSuccess()) {
if (useManualPortForwarding) {
setState(BootstrapState.DISCOVERY_MANUAL_PORT_FORWARDING_SUCCEEDED,
@ -225,57 +228,27 @@ class BootstrappedPeerBuilder {
bootstrap();
}
else {
handleError(BootstrapState.DISCOVERY_AUTO_PORT_FORWARDING_FAILED,
"Automatic port forwarding failed.\n\n" +
"Check whether UPnP (Universal Plug and Play) is enabled on your router.\n\n" +
"If UPnP is enabled and you still cannot connect, you will need to set up " +
"manual port forwarding.\n\n" +
"See https://github.com/bitsquare/bitsquare/wiki for instructions.");
// For the moment we don't support relay mode as it has too much problems
/* setState(BootstrapState.AUTO_PORT_FORWARDING_NOT_SUCCEEDED, "Port forwarding has failed. " +
"We try to use a relay as next step.");
bootstrapWithRelay();*/
if (future.isSuccess()) {
// relay mode succeeded
setState(BootstrapState.RELAY_SUCCEEDED, "Bootstrap using relay was successful.");
bootstrap();
}
else {
// All attempts failed. Give up...
handleError(BootstrapState.RELAY_FAILED, "Bootstrap using relay has failed " +
futureRelayNAT.failedReason());
}
}
}
}
@Override
public void exceptionCaught(Throwable t) throws Exception {
handleError(BootstrapState.DISCOVERY_FAILED, "Exception at discover visibility: " + t
.getMessage());
handleError(BootstrapState.RELAY_FAILED, "Exception at bootstrap: " + t.getMessage());
}
});
}
// For the moment we don't support relay mode as it has too much problems
// 3. Attempt: We try to use another peer as relay
/* private void bootstrapWithRelay() {
setState(BootstrapState.RELAY_INIT, "We try to use another peer as relay.");
FutureDiscover futureDiscover = peer.discover().peerAddress(getBootstrapAddress()).start();
PeerNAT peerNAT = new PeerBuilderNAT(peer).start();
FutureNAT futureNAT = peerNAT.startSetupPortforwarding(futureDiscover);
FutureRelayNAT futureRelayNAT = peerNAT.startRelay(RelayConfig.OpenTCP(), futureDiscover, futureNAT);
futureRelayNAT.addListener(new BaseFutureListener<BaseFuture>() {
@Override
public void operationComplete(BaseFuture future) throws Exception {
if (future.isSuccess()) {
setState(BootstrapState.RELAY_SUCCESS, "Bootstrap using relay was successful.");
bootstrap(BootstrapState.RELAY_SUCCESS);
}
else {
handleError(BootstrapState.RELAY_FAILED, "Bootstrap using relay has failed " +
futureRelayNAT.failedReason());
}
}
@Override
public void exceptionCaught(Throwable t) throws Exception {
handleError(BootstrapState.RELAY_FAILED, "Exception at bootstrapWithRelay: " + t.getMessage());
}
});
}*/
private void bootstrap() {
FutureBootstrap futureBootstrap = peer.bootstrap().peerAddress(getBootstrapAddress()).start();
futureBootstrap.addListener(new BaseFutureListener<BaseFuture>() {

View File

@ -7,6 +7,7 @@
</appender>
<!--
-->
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>bitsquare_out.log</file>
<append>false</append>
@ -14,7 +15,7 @@
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg %xEx%n</pattern>
</encoder>
</appender>
-->
<root level="WARN">
<appender-ref ref="CONSOLE_APPENDER"/>

View File

@ -53,7 +53,9 @@ import net.tomp2p.p2p.Peer;
import net.tomp2p.p2p.PeerBuilder;
import net.tomp2p.peers.Number160;
import net.tomp2p.peers.PeerAddress;
import net.tomp2p.relay.RelayConfig;
import net.tomp2p.peers.PeerMap;
import net.tomp2p.peers.PeerMapConfiguration;
import net.tomp2p.relay.tcp.TCPRelayClientConfig;
import net.tomp2p.storage.Data;
import org.junit.After;
@ -82,7 +84,7 @@ public class TomP2PTests {
private static final Logger log = LoggerFactory.getLogger(TomP2PTests.class);
// If you want to test in one specific connection mode define it directly, otherwise use UNKNOWN
private static final ConnectionType FORCED_CONNECTION_TYPE = ConnectionType.DIRECT;
private static final ConnectionType FORCED_CONNECTION_TYPE = ConnectionType.RELAY;
// Typically you run the bootstrap node in localhost to test direct connection.
// If you have a setup where you are not behind a router you can also use a WAN bootstrap node.
@ -293,9 +295,23 @@ public class TomP2PTests {
@Test
@Repeat(STRESS_TEST_COUNT)
public void testParallelStartupWithPutGet() throws IOException, ClassNotFoundException, InterruptedException {
PeerMapConfiguration pmc1 = new PeerMapConfiguration(Number160.createHash("peer1")).peerNoVerification();
PeerMap pm1 = new PeerMap(pmc1);
PeerDHT peer1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash("peer1")).ports(3006).peerMap(pm1).start()).start();
PeerMapConfiguration pmc2 = new PeerMapConfiguration(Number160.createHash("peer2")).peerNoVerification();
PeerMap pm2 = new PeerMap(pmc2);
PeerDHT peer2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash("peer2")).ports(3007).peerMap(pm2).start()).start();
/* PeerAddress masterPeerAddress = new PeerAddress(Number160.createHash(BOOTSTRAP_NODE_ID),
BOOTSTRAP_NODE_IP, BOOTSTRAP_NODE_PORT,
BOOTSTRAP_NODE_PORT);
PeerDHT peer1 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash("peer1")).ports(3006).start()).start();
PeerDHT peer2 = new PeerBuilderDHT(new PeerBuilder(Number160.createHash("peer2")).ports(3007).start()).start();
*/
PeerAddress masterPeerAddress = new PeerAddress(Number160.createHash(BootstrapNodes.LOCALHOST.getName()),
BootstrapNodes.LOCALHOST.getIp(), BootstrapNodes.LOCALHOST.getPort(),
BootstrapNodes.LOCALHOST.getPort());
@ -315,6 +331,7 @@ public class TomP2PTests {
@Override
public void exceptionCaught(Throwable t) throws Exception {
log.error(t.toString());
}
});
@ -326,6 +343,7 @@ public class TomP2PTests {
@Override
public void exceptionCaught(Throwable t) throws Exception {
log.error(t.toString());
}
});
@ -520,7 +538,9 @@ public class TomP2PTests {
FutureDirect futureDirect = peer1DHT.peer().sendDirect(futurePeerConnection).object("hallo").start();
futureDirect.awaitUninterruptibly();
assertTrue(futureDirect.isSuccess());
assertEquals("pong", futureDirect.object());
// server node does not reply
// assertEquals("pong", futureDirect.object());
}
private Peer bootstrapDirectConnection(int clientPort) {
@ -647,7 +667,7 @@ public class TomP2PTests {
PeerNAT peerNAT = new PeerBuilderNAT(peer).start();
FutureDiscover futureDiscover = peer.discover().peerAddress(BOOTSTRAP_NODE_ADDRESS).start();
FutureNAT futureNAT = peerNAT.startSetupPortforwarding(futureDiscover);
FutureRelayNAT futureRelayNAT = peerNAT.startRelay(RelayConfig.OpenTCP(), futureDiscover, futureNAT);
FutureRelayNAT futureRelayNAT = peerNAT.startRelay(new TCPRelayClientConfig(), futureDiscover, futureNAT);
futureRelayNAT.awaitUninterruptibly();
if (futureRelayNAT.isSuccess()) {
log.info("Bootstrap using relay was successful. Address = " + peer.peerAddress());

View File

@ -1,12 +1,12 @@
/*
* Copyright 2012 Thomas Bocek
*
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@ -16,20 +16,96 @@
package net.tomp2p.dht;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.NavigableSet;
import java.util.Random;
import java.util.TreeSet;
import net.tomp2p.connection.Bindings;
import net.tomp2p.futures.FutureBootstrap;
import net.tomp2p.futures.FutureDiscover;
import net.tomp2p.message.Message;
import net.tomp2p.message.Message.Type;
import net.tomp2p.p2p.AutomaticFuture;
import net.tomp2p.p2p.Peer;
import net.tomp2p.p2p.PeerBuilder;
import net.tomp2p.peers.Number160;
import net.tomp2p.peers.PeerAddress;
import net.tomp2p.peers.PeerMap;
import net.tomp2p.peers.PeerMapConfiguration;
import net.tomp2p.peers.PeerSocketAddress;
public class UtilsDHT2 {
/**
* Used to make the testcases predictable. Used as an input for {@link Random}.
*/
public static final long THE_ANSWER = 42L;
/**
* Having two peers in a network, the seed needs to be different, otherwise we create a peer with the same id twice.
*/
public static final long THE_ANSWER2 = 43L;
public static Message createDummyMessage() throws UnknownHostException {
return createDummyMessage(false, false);
}
public static Message createDummyMessage(boolean firewallUDP, boolean firewallTCP)
throws UnknownHostException {
return createDummyMessage(new Number160("0x4321"), "127.0.0.1", 8001, 8002, new Number160("0x1234"),
"127.0.0.1", 8003, 8004, (byte) 0, Type.REQUEST_1, firewallUDP, firewallTCP);
}
public static PeerAddress createAddress(Number160 id) throws UnknownHostException {
return createAddress(id, "127.0.0.1", 8005, 8006, false, false);
}
public static PeerAddress createAddress() throws UnknownHostException {
return createAddress(new Number160("0x5678"), "127.0.0.1", 8005, 8006, false, false);
}
public static PeerAddress createAddress(int id) throws UnknownHostException {
return createAddress(new Number160(id), "127.0.0.1", 8005, 8006, false, false);
}
public static PeerAddress createAddress(String id) throws UnknownHostException {
return createAddress(new Number160(id), "127.0.0.1", 8005, 8006, false, false);
}
public static PeerAddress createAddress(Number160 idSender, String inetSender, int tcpPortSender,
int udpPortSender, boolean firewallUDP, boolean firewallTCP) throws UnknownHostException {
InetAddress inetSend = InetAddress.getByName(inetSender);
PeerSocketAddress peerSocketAddress = new PeerSocketAddress(inetSend, tcpPortSender, udpPortSender);
PeerAddress n1 = new PeerAddress(idSender, peerSocketAddress, firewallTCP, firewallUDP, false, false, false,
PeerAddress.EMPTY_PEER_SOCKET_ADDRESSES);
return n1;
}
public static Message createDummyMessage(Number160 idSender, String inetSender, int tcpPortSendor,
int udpPortSender, Number160 idRecipien, String inetRecipient, int tcpPortRecipient,
int udpPortRecipient, byte command, Type type, boolean firewallUDP, boolean firewallTCP)
throws UnknownHostException {
Message message = new Message();
PeerAddress n1 = createAddress(idSender, inetSender, tcpPortSendor, udpPortSender, firewallUDP,
firewallTCP);
message.sender(n1);
//
PeerAddress n2 = createAddress(idRecipien, inetRecipient, tcpPortRecipient, udpPortRecipient,
firewallUDP, firewallTCP);
message.recipient(n2);
message.type(type);
message.command(command);
return message;
}
public static PeerDHT[] createNodes(int nrOfPeers, Random rnd, int port) throws Exception {
return createNodes(nrOfPeers, rnd, port, null);
@ -44,18 +120,22 @@ public class UtilsDHT2 {
* Creates peers for testing. The first peer (peer[0]) will be used as the master. This means that shutting down
* peer[0] will shut down all other peers
*
* @param nrOfPeers The number of peers to create including the master
* @param rnd The random object to create random peer IDs
* @param port The port where the master peer will listen to
* @param nrOfPeers
* The number of peers to create including the master
* @param rnd
* The random object to create random peer IDs
* @param port
* The port where the master peer will listen to
* @return All the peers, with the master peer at position 0 -> peer[0]
* @throws Exception If the creation of nodes fail.
* @throws Exception
* If the creation of nodes fail.
*/
public static PeerDHT[] createNodes(int nrOfPeers, Random rnd, int port, AutomaticFuture automaticFuture,
boolean maintenance) throws Exception {
if (nrOfPeers < 1) {
throw new IllegalArgumentException("Cannot create less than 1 peer");
}
Bindings bindings = new Bindings().addInterface("lo");
Bindings bindings = new Bindings();
PeerDHT[] peers = new PeerDHT[nrOfPeers];
final Peer master;
if (automaticFuture != null) {
@ -81,8 +161,7 @@ public class UtilsDHT2 {
PeerMap peerMap = new PeerMap(new PeerMapConfiguration(peerId));
Peer peer = new PeerBuilder(peerId)
.masterPeer(master)
.enableMaintenance(maintenance).enableMaintenance(maintenance).peerMap(peerMap).bindings
(bindings).start().addAutomaticFuture(automaticFuture);
.enableMaintenance(maintenance).enableMaintenance(maintenance).peerMap(peerMap).bindings(bindings).start().addAutomaticFuture(automaticFuture);
peers[i] = new PeerBuilderDHT(peer).start();
}
else {
@ -98,16 +177,53 @@ public class UtilsDHT2 {
return peers;
}
public static Peer[] createRealNodes(int nrOfPeers, Random rnd, int startPort,
AutomaticFuture automaticFuture) throws Exception {
if (nrOfPeers < 1) {
throw new IllegalArgumentException("Cannot create less than 1 peer");
}
Peer[] peers = new Peer[nrOfPeers];
for (int i = 0; i < nrOfPeers; i++) {
peers[i] = new PeerBuilder(new Number160(rnd))
.ports(startPort + i).start().addAutomaticFuture(automaticFuture);
}
System.err.println("real peers created.");
return peers;
}
public static Peer[] createNonMaintenanceNodes(int nrOfPeers, Random rnd, int port) throws IOException {
if (nrOfPeers < 1) {
throw new IllegalArgumentException("Cannot create less than 1 peer");
}
Peer[] peers = new Peer[nrOfPeers];
peers[0] = new PeerBuilder(new Number160(rnd)).enableMaintenance(false).ports(port).start();
for (int i = 1; i < nrOfPeers; i++) {
peers[i] = new PeerBuilder(new Number160(rnd)).enableMaintenance(false).masterPeer(peers[0])
.start();
}
System.err.println("non-maintenance peers created.");
return peers;
}
/**
* Perfect routing, where each neighbor has contacted each other. This means that for small number of peers, every
* peer knows every other peer.
*
* @param peers The peers taking part in the p2p network.
* @param peers
* The peers taking part in the p2p network.
*/
public static void perfectRouting(PeerDHT... peers) {
for (int i = 0; i < peers.length; i++) {
for (int j = 0; j < peers.length; j++)
peers[i].peer().peerBean().peerMap().peerFound(peers[j].peer().peerAddress(), null, null);
peers[i].peer().peerBean().peerMap().peerFound(peers[j].peer().peerAddress(), null, null, null);
}
System.err.println("perfect routing done.");
}
public static void perfectRoutingIndirect(PeerDHT... peers) {
for (int i = 0; i < peers.length; i++) {
for (int j = 0; j < peers.length; j++)
peers[i].peerBean().peerMap().peerFound(peers[j].peerAddress(), peers[j].peerAddress(), null, null);
}
System.err.println("perfect routing done.");
}
@ -131,4 +247,121 @@ public class UtilsDHT2 {
throw new IllegalStateException("Failed to create directory within " + TEMP_DIR_ATTEMPTS
+ " attempts (tried " + baseName + "0 to " + baseName + (TEMP_DIR_ATTEMPTS - 1) + ')');
}
public static Peer[] createAndAttachNodes(int nr, int port, Random rnd) throws Exception {
Peer[] peers = new Peer[nr];
for (int i = 0; i < nr; i++) {
if (i == 0) {
peers[0] = new PeerBuilder(new Number160(rnd)).ports(port).start();
}
else {
peers[i] = new PeerBuilder(new Number160(rnd)).masterPeer(peers[0]).start();
}
}
return peers;
}
public static void bootstrap(Peer[] peers) {
List<FutureBootstrap> futures1 = new ArrayList<FutureBootstrap>();
List<FutureDiscover> futures2 = new ArrayList<FutureDiscover>();
for (int i = 1; i < peers.length; i++) {
FutureDiscover tmp = peers[i].discover().peerAddress(peers[0].peerAddress()).start();
futures2.add(tmp);
}
for (FutureDiscover future : futures2) {
future.awaitUninterruptibly();
}
for (int i = 1; i < peers.length; i++) {
FutureBootstrap tmp = peers[i].bootstrap().peerAddress(peers[0].peerAddress()).start();
futures1.add(tmp);
}
for (int i = 1; i < peers.length; i++) {
FutureBootstrap tmp = peers[0].bootstrap().peerAddress(peers[i].peerAddress()).start();
futures1.add(tmp);
}
for (FutureBootstrap future : futures1)
future.awaitUninterruptibly();
}
public static void routing(Number160 key, Peer[] peers, int start) {
System.out.println("routing: searching for key " + key);
NavigableSet<PeerAddress> pa1 = new TreeSet<PeerAddress>(PeerMap.createXORAddressComparator(key));
NavigableSet<PeerAddress> queried = new TreeSet<PeerAddress>(PeerMap.createXORAddressComparator(key));
Number160 result = Number160.ZERO;
Number160 resultPeer = new Number160("0xd75d1a3d57841fbc9e2a3d175d6a35dc2e15b9f");
int round = 0;
while (!resultPeer.equals(result)) {
System.out.println("round " + round);
round++;
pa1.addAll(peers[start].peerBean().peerMap().all());
queried.add(peers[start].peerAddress());
System.out.println("closest so far: " + queried.first());
PeerAddress next = pa1.pollFirst();
while (queried.contains(next)) {
next = pa1.pollFirst();
}
result = next.peerId();
start = findNr(next.peerId().toString(), peers);
}
}
public static void findInMap(PeerAddress key, Peer[] peers) {
for (int i = 0; i < peers.length; i++) {
if (peers[i].peerBean().peerMap().contains(key)) {
System.out.println("Peer " + i + " with the id " + peers[i].peerID() + " knows the peer "
+ key);
}
}
}
public static int findNr(String string, Peer[] peers) {
for (int i = 0; i < peers.length; i++) {
if (peers[i].peerID().equals(new Number160(string))) {
System.out.println("we found the number " + i + " for peer with id " + string);
return i;
}
}
return -1;
}
public static Peer find(String string, Peer[] peers) {
for (int i = 0; i < peers.length; i++) {
if (peers[i].peerID().equals(new Number160(string))) {
System.out.println("!!we found the number " + i + " for peer with id " + string);
return peers[i];
}
}
return null;
}
public static void exec(String cmd) throws Exception {
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}
public static PeerAddress createAddressIP(String inet) throws UnknownHostException {
return createAddress(Number160.createHash(inet), inet, 8005, 8006, false, false);
}
public static PeerAddress[] createDummyAddress(int size, int portTCP, int portUDP) throws UnknownHostException {
PeerAddress[] pa = new PeerAddress[size];
for (int i = 0; i < size; i++) {
pa[i] = createAddress(i + 1, portTCP, portUDP);
}
return pa;
}
public static PeerAddress createAddress(int iid, int portTCP, int portUDP) throws UnknownHostException {
Number160 id = new Number160(iid);
InetAddress address = InetAddress.getByName("127.0.0.1");
return new PeerAddress(id, address, portTCP, portUDP);
}
}