From b13848154a0ba7feb0c8db00242ed73447361471 Mon Sep 17 00:00:00 2001 From: Chris Beams Date: Wed, 17 Dec 2014 22:36:38 +0100 Subject: [PATCH 01/14] Use "national currency" vs "fiat" where appropriate --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4823e5e85c..347d96897d 100644 --- a/README.md +++ b/README.md @@ -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. From f5282fc3d6ca1e51a71837fcbbbb58f741bb7958 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sun, 21 Dec 2014 01:17:44 +0100 Subject: [PATCH 02/14] Open blockexplorer for address --- .../gui/main/funds/transactions/TransactionsView.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/bitsquare/gui/main/funds/transactions/TransactionsView.java b/src/main/java/io/bitsquare/gui/main/funds/transactions/TransactionsView.java index 9dfb002275..647568a681 100644 --- a/src/main/java/io/bitsquare/gui/main/funds/transactions/TransactionsView.java +++ b/src/main/java/io/bitsquare/gui/main/funds/transactions/TransactionsView.java @@ -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() { From fd6b78f06968b3e0f113b3239f9ad61f8ab20567 Mon Sep 17 00:00:00 2001 From: Sean Gilligan Date: Mon, 22 Dec 2014 00:11:16 -0800 Subject: [PATCH 03/14] Use https URL for artifactoryonline.com --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 192b6e8dca..4af61312f0 100644 --- a/build.gradle +++ b/build.gradle @@ -36,7 +36,7 @@ processResources { repositories { jcenter() - maven { url 'http://partnerdemo.artifactoryonline.com/partnerdemo/libs-snapshots-local' } + maven { url 'https://partnerdemo.artifactoryonline.com/partnerdemo/libs-snapshots-local' } } dependencies { From 089007a498a9e3b71b955c3a706a6afd32628e56 Mon Sep 17 00:00:00 2001 From: Joe Schmid Date: Fri, 6 Feb 2015 22:54:16 -0500 Subject: [PATCH 04/14] Updated project to use 5.0-Beta2 of tomp2p Note that this has not been thoroughly tested and, in particular, my router does not support UPnP so I've only been able to test with --node.useManualPortForwarding=true The project does compile and run successfully though. With manual port forwarding I'm able to connect to the p2p network and view open offers successfully. --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 4af61312f0..fca1d48c79 100644 --- a/build.gradle +++ b/build.gradle @@ -36,12 +36,12 @@ processResources { repositories { jcenter() - maven { url 'https://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-Beta2' 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' From c506bc420b6cf434e76771c696be4f7da3ec37ce Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 14 Feb 2015 22:09:19 +0100 Subject: [PATCH 05/14] Update to TomP2P master --- src/test/java/net/tomp2p/dht/UtilsDHT2.java | 257 +++++++++++++++++++- 1 file changed, 245 insertions(+), 12 deletions(-) diff --git a/src/test/java/net/tomp2p/dht/UtilsDHT2.java b/src/test/java/net/tomp2p/dht/UtilsDHT2.java index 52f0a256ec..edd0453d27 100644 --- a/src/test/java/net/tomp2p/dht/UtilsDHT2.java +++ b/src/test/java/net/tomp2p/dht/UtilsDHT2.java @@ -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 futures1 = new ArrayList(); + List futures2 = new ArrayList(); + 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 pa1 = new TreeSet(PeerMap.createXORAddressComparator(key)); + NavigableSet queried = new TreeSet(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); + } + } From d0295d7997b68bb216710e47feb96021238f402d Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 14 Feb 2015 22:10:13 +0100 Subject: [PATCH 06/14] Add log to file --- src/main/resources/logback.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index fe780b595e..b49ce9d4ff 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -7,6 +7,7 @@ bitsquare_out.log false @@ -14,7 +15,7 @@ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg %xEx%n - --> + From b72c5aaebf31936607f3420d70b4b47ab5e19c5e Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 14 Feb 2015 22:11:02 +0100 Subject: [PATCH 07/14] Change formatting rule RIGHT_MARGIN --- .idea/codeStyleSettings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml index ff0fbb1d5a..c5c60b8c1d 100644 --- a/.idea/codeStyleSettings.xml +++ b/.idea/codeStyleSettings.xml @@ -75,6 +75,7 @@ +