From d943ee0918c5ea576ab955caca87234aabce1417 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 31 Jul 2014 19:43:46 +0200 Subject: [PATCH] use tomp2p master branch --- README.md | 16 +- pom.xml | 52 +---- src/main/java/io/bitsquare/msg/P2PNode.java | 17 +- .../java/lighthouse/protocol/LHUtils.java | 139 ------------- .../threading/AffinityExecutor.java | 171 --------------- .../threading/ConcatenatingList.java | 101 --------- .../java/lighthouse/threading/MappedList.java | 113 ---------- .../threading/MarshallingObservers.java | 43 ---- .../threading/ObservableMirrors.java | 195 ------------------ .../java/io/bitsquare/BitSquareTestSuite.java | 2 + .../gui/util/BitSquareConverterTest.java | 16 +- .../java/io/bitsquare/msg/P2PNodeTest.java | 10 +- .../threading/ConcatenatingListTest.java | 26 --- .../lighthouse/threading/MappedListTest.java | 91 -------- 14 files changed, 40 insertions(+), 952 deletions(-) delete mode 100644 src/main/java/lighthouse/protocol/LHUtils.java delete mode 100644 src/main/java/lighthouse/threading/AffinityExecutor.java delete mode 100644 src/main/java/lighthouse/threading/ConcatenatingList.java delete mode 100644 src/main/java/lighthouse/threading/MappedList.java delete mode 100644 src/main/java/lighthouse/threading/MarshallingObservers.java delete mode 100644 src/main/java/lighthouse/threading/ObservableMirrors.java delete mode 100644 src/test/java/lighthouse/threading/ConcatenatingListTest.java delete mode 100644 src/test/java/lighthouse/threading/MappedListTest.java diff --git a/README.md b/README.md index da131bca1f..e0286edf29 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,26 @@ # bitsquare.io -Bitsquare is a P2P Fiat-BTC Exchange, extensible to a generic P2P trading platform (include commodities and cryptocurrencies) +Bitsquare is a P2P Fiat-BTC Exchange. The project use Java 8 and Maven. -We use the bitcoinj library and TomP2P for DHT and messaging. +We use the bitcoinj library and TomP2P for DHT and direct messaging. +For local testing it is best to use the regtest mode from Bitcoin qt clients. If you want to use the RegTest mode you need to set regtest=1 in the bitcoin.config file inside the bitcoin data directory (https://en.bitcoin.it/wiki/Running_Bitcoin). Then you can generate coins on demand with the Bitcoin qt client with that command in the console: setgenerate true 101 (101 only for the first start because the coin maturity of 100 blocks). -See: https://bitcoinj.github.io/testing +More information about how to use regtest mode can be found here: https://bitcoinj.github.io/testing +Take care if you have real bitcoin in your Bitcoin qt wallet (backup and copy first your data directory). You can change the network mode in the guice module: BitSquareModule.java +Testnet should also work, but was not tested a while now as for developing regtest is much more convenient. +Please don't use main net with real money, as the software is under heavy development and you can easily lose your funds. -We use a fork of the actual TomP2P master branch: https://github.com/ManfredKarrer/TomP2P +We use a fork of the actual TomP2P master branch: https://github.com/bitsquare/TomP2P You need to check that out as well and deploy it to the local maven repository: mvn clean install -DskipTests ### Resources: * Web: http://bitsquare.io -* Whitepaper: https://docs.google.com/document/d/1d3EiWZdaM89-P6MVhS53unXv2-pDpSFsN3W4kCGXKgY/edit?pli=1 -* Overview: http://bitsquare.io/images/overview.png -* Discussion: https://bitcointalk.org/index.php?topic=647457 -* Video of POC prototype: https://www.youtube.com/watch?v=ByfnzJzi0bo ### Screenshots of basic the use cases: diff --git a/pom.xml b/pom.xml index 2f42195fd0..d81600d968 100644 --- a/pom.xml +++ b/pom.xml @@ -6,23 +6,14 @@ io.bitsquare bitsquare - 0.01-SNAPSHOT + 0.1-SNAPSHOT BitSquare - A P2P Fiat-Bitcoin Exchange - https://www.bitsquare.io + The P2P Fiat-Bitcoin Exchange + http://www.bitsquare.io bitsquare.io - @@ -53,13 +44,11 @@ https://oss.sonatype.org/content/groups/public - bitcoinj-release http://distribution.bitcoinj.googlecode.com/git/releases - mvn-adamgent http://mvn-adamgent.googlecode.com/svn/maven/release @@ -73,7 +62,6 @@ - bitsquare @@ -113,13 +101,11 @@ org.twdata.maven mojo-executor - 2.1.0 + 2.0 - - @@ -131,13 +117,11 @@ 0.11.3 - junit @@ -151,13 +135,7 @@ slf4j-api 1.7.7 - + ch.qos.logback logback-core @@ -170,7 +148,6 @@ compile - com.google.inject guice @@ -219,14 +196,6 @@ jcip-annotations 1.0 - org.jetbrains @@ -235,17 +204,6 @@ - - - - - - - UTF-8 diff --git a/src/main/java/io/bitsquare/msg/P2PNode.java b/src/main/java/io/bitsquare/msg/P2PNode.java index 8cd24e88b7..1b02ded84c 100644 --- a/src/main/java/io/bitsquare/msg/P2PNode.java +++ b/src/main/java/io/bitsquare/msg/P2PNode.java @@ -110,7 +110,7 @@ public class P2PNode useDiscStorage(useDiskStorage); setupTimerForIPCheck(); - FutureCallback localCallback = new FutureCallback() + /* FutureCallback localCallback = new FutureCallback() { @Override public void onSuccess(@Nullable PeerDHT result) @@ -126,13 +126,18 @@ public class P2PNode log.error(t.toString()); callback.onFailure(t); } - }; + }; */ - bootstrapToLocalhostThread = runBootstrapThread(localCallback, new SeedNodeAddress(defaultStaticSeedNodeAddresses)); - bootstrapToServerThread = runBootstrapThread(localCallback, new SeedNodeAddress(SeedNodeAddress.StaticSeedNodeAddresses.DIGITAL_OCEAN)); + ListenableFuture bootstrapComplete = bootstrap(new SeedNodeAddress(defaultStaticSeedNodeAddresses)); + Futures.addCallback(bootstrapComplete, callback); + + // bootstrapToLocalhostThread = runBootstrapThread(localCallback, new SeedNodeAddress(defaultStaticSeedNodeAddresses)); + // bootstrapToServerThread = runBootstrapThread(localCallback, new SeedNodeAddress(SeedNodeAddress.StaticSeedNodeAddresses.DIGITAL_OCEAN)); } - public void bootstrapThreadCompleted() + // TODO: start multiple threads for bootstrapping, so we can get it done faster. + + /* public void bootstrapThreadCompleted() { if (bootstrapToLocalhostThread != null) bootstrapToLocalhostThread.interrupt(); @@ -155,7 +160,7 @@ public class P2PNode }); bootstrapThread.start(); return bootstrapThread; - } + } */ public void shutDown() { diff --git a/src/main/java/lighthouse/protocol/LHUtils.java b/src/main/java/lighthouse/protocol/LHUtils.java deleted file mode 100644 index de4a837eab..0000000000 --- a/src/main/java/lighthouse/protocol/LHUtils.java +++ /dev/null @@ -1,139 +0,0 @@ -package lighthouse.protocol; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.stream.Stream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class LHUtils -{ - private static final Logger log = LoggerFactory.getLogger(LHUtils.class); - - public static List listDir(Path dir) throws IOException - { - List contents = new LinkedList<>(); - try (Stream list = Files.list(dir)) - { - list.forEach(contents::add); - } - return contents; - } - - //region Generic Java 8 enhancements - public interface UncheckedRun - { - public T run() throws Throwable; - } - - public interface UncheckedRunnable - { - public void run() throws Throwable; - } - - public static T unchecked(UncheckedRun run) - { - try - { - return run.run(); - } catch (Throwable throwable) - { - throw new RuntimeException(throwable); - } - } - - public static void uncheck(UncheckedRunnable run) - { - try - { - run.run(); - } catch (Throwable throwable) - { - throw new RuntimeException(throwable); - } - } - - public static void ignoreAndLog(UncheckedRunnable runnable) - { - try - { - runnable.run(); - } catch (Throwable t) - { - log.error("Ignoring error", t); - } - } - - public static T ignoredAndLogged(UncheckedRun runnable) - { - try - { - return runnable.run(); - } catch (Throwable t) - { - log.error("Ignoring error", t); - return null; - } - } - - @SuppressWarnings("unchecked") - public static T checkedGet(Future future) throws E - { - try - { - return future.get(); - } catch (InterruptedException e) - { - throw new RuntimeException(e); - } catch (ExecutionException e) - { - throw (E) e.getCause(); - } - } - - public static boolean didThrow(UncheckedRun run) - { - try - { - run.run(); - return false; - } catch (Throwable throwable) - { - return true; - } - } - - public static boolean didThrow(UncheckedRunnable run) - { - try - { - run.run(); - return false; - } catch (Throwable throwable) - { - return true; - } - } - - public static T stopwatched(String description, UncheckedRun run) - { - long now = System.currentTimeMillis(); - T result = unchecked(run::run); - log.info("{}: {}ms", description, System.currentTimeMillis() - now); - return result; - } - - public static void stopwatch(String description, UncheckedRunnable run) - { - long now = System.currentTimeMillis(); - uncheck(run::run); - log.info("{}: {}ms", description, System.currentTimeMillis() - now); - } - - //endregion -} \ No newline at end of file diff --git a/src/main/java/lighthouse/threading/AffinityExecutor.java b/src/main/java/lighthouse/threading/AffinityExecutor.java deleted file mode 100644 index c43cba8baa..0000000000 --- a/src/main/java/lighthouse/threading/AffinityExecutor.java +++ /dev/null @@ -1,171 +0,0 @@ -package lighthouse.threading; - -import com.google.common.util.concurrent.Uninterruptibles; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.atomic.AtomicReference; -import javafx.application.Platform; -import lighthouse.protocol.LHUtils; - -import static com.google.common.base.Preconditions.checkState; - -/** - * An extended executor interface that supports thread affinity assertions and short circuiting. - */ -public interface AffinityExecutor extends Executor -{ - /** - * Returns true if the current thread is equal to the thread this executor is backed by. - */ - public boolean isOnThread(); - - /** - * Throws an IllegalStateException if the current thread is equal to the thread this executor is backed by. - */ - public void checkOnThread(); - - /** - * If isOnThread() then runnable is invoked immediately, otherwise the closure is queued onto the backing thread. - */ - public void executeASAP(LHUtils.UncheckedRunnable runnable); - - public abstract static class BaseAffinityExecutor implements AffinityExecutor - { - protected final Thread.UncaughtExceptionHandler exceptionHandler; - - protected BaseAffinityExecutor() - { - exceptionHandler = Thread.currentThread().getUncaughtExceptionHandler(); - } - - @Override - public abstract boolean isOnThread(); - - @Override - public void checkOnThread() - { - checkState(isOnThread(), "On wrong thread: %s", Thread.currentThread()); - } - - @Override - public void executeASAP(LHUtils.UncheckedRunnable runnable) - { - final Runnable command = () -> { - try - { - runnable.run(); - } catch (Throwable throwable) - { - exceptionHandler.uncaughtException(Thread.currentThread(), throwable); - } - }; - if (isOnThread()) - command.run(); - else - { - execute(command); - } - } - - // Must comply with the Executor definition w.r.t. exceptions here. - @Override - public abstract void execute(Runnable command); - } - - public static AffinityExecutor UI_THREAD = new BaseAffinityExecutor() - { - @Override - public boolean isOnThread() - { - return Platform.isFxApplicationThread(); - } - - @Override - public void execute(Runnable command) - { - Platform.runLater(command); - } - }; - - public static AffinityExecutor SAME_THREAD = new BaseAffinityExecutor() - { - @Override - public boolean isOnThread() - { - return true; - } - - @Override - public void execute(Runnable command) - { - command.run(); - } - }; - - public static class ServiceAffinityExecutor extends BaseAffinityExecutor - { - protected AtomicReference whichThread = new AtomicReference<>(null); - private final Thread.UncaughtExceptionHandler handler = Thread.currentThread().getUncaughtExceptionHandler(); - public final ScheduledExecutorService service; - - public ServiceAffinityExecutor(String threadName) - { - service = Executors.newSingleThreadScheduledExecutor(runnable -> { - Thread thread = new Thread(runnable); - thread.setDaemon(true); - thread.setName(threadName); - thread.setUncaughtExceptionHandler(handler); - whichThread.set(thread); - return thread; - }); - } - - @Override - public boolean isOnThread() - { - return Thread.currentThread() == whichThread.get(); - } - - @Override - public void execute(Runnable command) - { - service.execute(command); - } - } - - /** - * An executor useful for unit tests: allows the current thread to block until a command arrives from another - * thread, which is then executed. Inbound closures/commands stack up until they are cleared by looping. - */ - public static class Gate extends BaseAffinityExecutor - { - private final Thread thisThread = Thread.currentThread(); - private final LinkedBlockingQueue commandQ = new LinkedBlockingQueue<>(); - - @Override - public boolean isOnThread() - { - return Thread.currentThread() == thisThread; - } - - @Override - public void execute(Runnable command) - { - Uninterruptibles.putUninterruptibly(commandQ, command); - } - - public void waitAndRun() - { - final Runnable runnable = Uninterruptibles.takeUninterruptibly(commandQ); - System.err.println("Gate running " + runnable); - runnable.run(); - } - - public int getTaskQueueSize() - { - return commandQ.size(); - } - } -} diff --git a/src/main/java/lighthouse/threading/ConcatenatingList.java b/src/main/java/lighthouse/threading/ConcatenatingList.java deleted file mode 100644 index 010906bc1b..0000000000 --- a/src/main/java/lighthouse/threading/ConcatenatingList.java +++ /dev/null @@ -1,101 +0,0 @@ -package lighthouse.threading; - -import java.util.ArrayList; -import java.util.List; -import javafx.collections.ListChangeListener; -import javafx.collections.ObservableList; -import javafx.collections.ObservableListBase; -import javafx.collections.WeakListChangeListener; - -/** - * This list is created by dynamically concatenating all the source lists together. - */ -public class ConcatenatingList extends ObservableListBase implements ObservableList -{ - private List> sources = new ArrayList<>(); - private ListChangeListener listener = this::sourceChanged; - - @SafeVarargs - public ConcatenatingList(ObservableList... source) - { - super(); - for (ObservableList s : source) - { - sources.add(s); - s.addListener(new WeakListChangeListener(listener)); - } - if (sources.isEmpty()) - throw new IllegalArgumentException(); - } - - private int calculateOffset(ObservableList source) - { - int cursor = 0; - for (ObservableList ts : sources) - { - if (ts == source) return cursor; - cursor += ts.size(); - } - return cursor; - } - - private void sourceChanged(ListChangeListener.Change c) - { - ObservableList source = c.getList(); - int offset = calculateOffset(source); - beginChange(); - while (c.next()) - { - if (c.wasPermutated()) - { - int[] perm = new int[c.getTo() - c.getFrom()]; - for (int i = c.getFrom(); i < c.getTo(); i++) - perm[i - c.getFrom()] = c.getPermutation(i) + offset; - nextPermutation(c.getFrom() + offset, c.getTo() + offset, perm); - } - else if (c.wasUpdated()) - { - for (int i = c.getFrom(); i < c.getTo(); i++) - { - nextUpdate(i + offset); - } - } - else - { - if (c.wasRemoved()) - { - // Removed should come first to properly handle replacements, then add. - nextRemove(c.getFrom() + offset, c.getRemoved()); - } - if (c.wasAdded()) - { - nextAdd(c.getFrom() + offset, c.getTo() + offset); - } - } - } - endChange(); - } - - @Override - public T get(int index) - { - for (ObservableList source : sources) - { - if (index < source.size()) - { - return source.get(index); - } - else - { - index -= source.size(); - } - } - throw new IndexOutOfBoundsException(); - } - - @Override - public int size() - { - return sources.stream().mapToInt(List::size).sum(); - } -} \ No newline at end of file diff --git a/src/main/java/lighthouse/threading/MappedList.java b/src/main/java/lighthouse/threading/MappedList.java deleted file mode 100644 index 91cfae0320..0000000000 --- a/src/main/java/lighthouse/threading/MappedList.java +++ /dev/null @@ -1,113 +0,0 @@ -package lighthouse.threading; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; -import javafx.collections.ListChangeListener; -import javafx.collections.ObservableList; -import javafx.collections.transformation.TransformationList; - -/** - * Maps elements of type F to E with change listeners working as expected. - */ -public class MappedList extends TransformationList -{ - private final Function mapper; - private final ArrayList mapped; - - /** - * Creates a new MappedList list wrapped around the source list. - * Each element will have the given function applied to it, such that the list is cast through the mapper. - */ - public MappedList(ObservableList source, Function mapper) - { - super(source); - this.mapper = mapper; - this.mapped = new ArrayList<>(source.size()); - mapAll(); - } - - private void mapAll() - { - mapped.clear(); - for (F val : getSource()) - mapped.add(mapper.apply(val)); - } - - @Override - protected void sourceChanged(ListChangeListener.Change c) - { - // Is all this stuff right for every case? Probably it doesn't matter for this app. - beginChange(); - while (c.next()) - { - if (c.wasPermutated()) - { - int[] perm = new int[c.getTo() - c.getFrom()]; - for (int i = c.getFrom(); i < c.getTo(); i++) - perm[i - c.getFrom()] = c.getPermutation(i); - nextPermutation(c.getFrom(), c.getTo(), perm); - } - else if (c.wasUpdated()) - { - for (int i = c.getFrom(); i < c.getTo(); i++) - { - remapIndex(i); - nextUpdate(i); - } - } - else - { - if (c.wasRemoved()) - { - // Removed should come first to properly handle replacements, then add. - List removed = mapped.subList(c.getFrom(), c.getFrom() + c.getRemovedSize()); - ArrayList duped = new ArrayList<>(removed); - removed.clear(); - nextRemove(c.getFrom(), duped); - } - if (c.wasAdded()) - { - for (int i = c.getFrom(); i < c.getTo(); i++) - { - mapped.addAll(c.getFrom(), c.getAddedSubList().stream().map(mapper).collect(Collectors.toList())); - remapIndex(i); - } - nextAdd(c.getFrom(), c.getTo()); - } - } - } - endChange(); - } - - private void remapIndex(int i) - { - if (i >= mapped.size()) - { - for (int j = mapped.size(); j <= i; j++) - { - mapped.add(mapper.apply(getSource().get(j))); - } - } - mapped.set(i, mapper.apply(getSource().get(i))); - } - - @Override - public int getSourceIndex(int index) - { - return index; - } - - @Override - public E get(int index) - { - return mapped.get(index); - } - - @Override - public int size() - { - return mapped.size(); - } -} \ No newline at end of file diff --git a/src/main/java/lighthouse/threading/MarshallingObservers.java b/src/main/java/lighthouse/threading/MarshallingObservers.java deleted file mode 100644 index e0d4a1380f..0000000000 --- a/src/main/java/lighthouse/threading/MarshallingObservers.java +++ /dev/null @@ -1,43 +0,0 @@ -package lighthouse.threading; - -import java.util.concurrent.Executor; -import javafx.beans.InvalidationListener; -import javafx.beans.Observable; -import javafx.collections.*; - -/** - * An attempt to make multi-threading and observable/reactive UI programming work together inside JavaFX without too - * many headaches. This class allows you to register change listeners on the target Observable which will be - * run with the given {@link java.util.concurrent.Executor}. In this way an observable collection which is updated by - * one thread can be observed from another thread without needing to use explicit locks or explicit marshalling. - */ -public class MarshallingObservers -{ - public static InvalidationListener addListener(Observable observable, InvalidationListener listener, Executor executor) - { - InvalidationListener l = x -> executor.execute(() -> listener.invalidated(x)); - observable.addListener(l); - return l; - } - - public static ListChangeListener addListener(ObservableList observable, ListChangeListener listener, Executor executor) - { - ListChangeListener l = (ListChangeListener.Change c) -> executor.execute(() -> listener.onChanged(c)); - observable.addListener(l); - return l; - } - - public static SetChangeListener addListener(ObservableSet observable, SetChangeListener listener, Executor executor) - { - SetChangeListener l = (SetChangeListener.Change c) -> executor.execute(() -> listener.onChanged(c)); - observable.addListener(l); - return l; - } - - public static MapChangeListener addListener(ObservableMap observable, MapChangeListener listener, Executor executor) - { - MapChangeListener l = (MapChangeListener.Change c) -> executor.execute(() -> listener.onChanged(c)); - observable.addListener(l); - return l; - } -} diff --git a/src/main/java/lighthouse/threading/ObservableMirrors.java b/src/main/java/lighthouse/threading/ObservableMirrors.java deleted file mode 100644 index e55a7260c4..0000000000 --- a/src/main/java/lighthouse/threading/ObservableMirrors.java +++ /dev/null @@ -1,195 +0,0 @@ -package lighthouse.threading; - -import java.lang.ref.WeakReference; -import java.util.List; -import java.util.Set; -import javafx.beans.WeakListener; -import javafx.collections.*; - -/** - * Utility functions that mirror changes from one list into another list. JavaFX already provides this functionality - * of course under the name "content binding"; a mirror is a content binding that relays changes into other threads - * first. Thus you can have an ObservableList which is updated in one thread, but still bound to directly in the UI - * thread, without needing to worry about cross-thread interference. - */ -public class ObservableMirrors -{ - /** - * Creates an unmodifiable list that asynchronously follows changes in mirrored, with changes applied using - * the given executor. This should only be called on the thread that owns the list to be mirrored, as the contents - * will be read. - */ - public static ObservableList mirrorList(ObservableList mirrored, AffinityExecutor runChangesIn) - { - ObservableList result = FXCollections.observableArrayList(); - result.setAll(mirrored); - mirrored.addListener(new ListMirror(result, runChangesIn)); - return FXCollections.unmodifiableObservableList(result); - } - - private static class ListMirror implements ListChangeListener, WeakListener - { - private final WeakReference> targetList; - private final AffinityExecutor runChangesIn; - - public ListMirror(ObservableList list, AffinityExecutor runChangesIn) - { - this.targetList = new WeakReference<>(list); - this.runChangesIn = runChangesIn; - } - - @Override - public void onChanged(Change change) - { - final List list = targetList.get(); - if (list == null) - { - change.getList().removeListener(this); - } - else - { - // If we're already in the right thread this will just run the change immediately, as per normal. - runChangesIn.executeASAP(() -> { - while (change.next()) - { - if (change.wasPermutated()) - { - list.subList(change.getFrom(), change.getTo()).clear(); - list.addAll(change.getFrom(), change.getList().subList(change.getFrom(), change.getTo())); - } - else - { - if (change.wasRemoved()) - { - list.subList(change.getFrom(), change.getFrom() + change.getRemovedSize()).clear(); - } - if (change.wasAdded()) - { - list.addAll(change.getFrom(), change.getAddedSubList()); - } - } - } - }); - } - } - - @Override - public boolean wasGarbageCollected() - { - return targetList.get() == null; - } - - // Do we really need these? - @Override - public int hashCode() - { - final List list = targetList.get(); - return (list == null) ? 0 : list.hashCode(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) - { - return true; - } - - final List list1 = targetList.get(); - if (list1 == null) - { - return false; - } - - if (obj instanceof ListMirror) - { - final ListMirror other = (ListMirror) obj; - final List list2 = other.targetList.get(); - return list1 == list2; - } - return false; - } - } - - - /** - * Creates an unmodifiable list that asynchronously follows changes in mirrored, with changes applied using - * the given executor. This should only be called on the thread that owns the list to be mirrored, as the contents - * will be read. - */ - public static ObservableSet mirrorSet(ObservableSet mirrored, AffinityExecutor runChangesIn) - { - @SuppressWarnings("unchecked") ObservableSet result = FXCollections.observableSet(); - result.addAll(mirrored); - mirrored.addListener(new SetMirror(result, runChangesIn)); - return FXCollections.unmodifiableObservableSet(result); - } - - private static class SetMirror implements SetChangeListener, WeakListener - { - private final WeakReference> targetSet; - private final AffinityExecutor runChangesIn; - - public SetMirror(ObservableSet set, AffinityExecutor runChangesIn) - { - this.targetSet = new WeakReference<>(set); - this.runChangesIn = runChangesIn; - } - - @Override - public void onChanged(final Change change) - { - final ObservableSet set = targetSet.get(); - if (set == null) - { - change.getSet().removeListener(this); - } - else - { - // If we're already in the right thread this will just run the change immediately, as per normal. - runChangesIn.executeASAP(() -> { - if (change.wasAdded()) - set.add(change.getElementAdded()); - if (change.wasRemoved()) - set.remove(change.getElementRemoved()); - }); - } - } - - @Override - public boolean wasGarbageCollected() - { - return targetSet.get() == null; - } - - @Override - public int hashCode() - { - final ObservableSet set = targetSet.get(); - return (set == null) ? 0 : set.hashCode(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) - { - return true; - } - - final Set set1 = targetSet.get(); - if (set1 == null) - { - return false; - } - - if (obj instanceof SetMirror) - { - final SetMirror other = (SetMirror) obj; - final Set list2 = other.targetSet.get(); - return set1 == list2; - } - return false; - } - } -} diff --git a/src/test/java/io/bitsquare/BitSquareTestSuite.java b/src/test/java/io/bitsquare/BitSquareTestSuite.java index 2962904316..4930225b08 100644 --- a/src/test/java/io/bitsquare/BitSquareTestSuite.java +++ b/src/test/java/io/bitsquare/BitSquareTestSuite.java @@ -3,6 +3,7 @@ package io.bitsquare; import io.bitsquare.btc.BtcValidatorTest; import io.bitsquare.gui.util.BitSquareConverterTest; import io.bitsquare.gui.util.BitSquareValidatorTest; +import io.bitsquare.msg.P2PNodeTest; import org.junit.runner.RunWith; import org.junit.runners.Suite; @@ -11,6 +12,7 @@ import org.junit.runners.Suite; BtcValidatorTest.class, BitSquareConverterTest.class, BitSquareValidatorTest.class, + P2PNodeTest.class }) public class BitSquareTestSuite diff --git a/src/test/java/io/bitsquare/gui/util/BitSquareConverterTest.java b/src/test/java/io/bitsquare/gui/util/BitSquareConverterTest.java index 9cffaef731..6ca9aad628 100644 --- a/src/test/java/io/bitsquare/gui/util/BitSquareConverterTest.java +++ b/src/test/java/io/bitsquare/gui/util/BitSquareConverterTest.java @@ -17,13 +17,13 @@ public class BitSquareConverterTest assertEquals(1, BitSquareConverter.stringToDouble("1.0"), 0); assertEquals(1, BitSquareConverter.stringToDouble("1,0"), 0); - assertEquals(Double.NEGATIVE_INFINITY, BitSquareConverter.stringToDouble("1,000.2"), 0); - assertEquals(Double.NEGATIVE_INFINITY, BitSquareConverter.stringToDouble("1,000.2"), 0); - assertEquals(Double.NEGATIVE_INFINITY, BitSquareConverter.stringToDouble(null), 0); - assertEquals(Double.NEGATIVE_INFINITY, BitSquareConverter.stringToDouble(""), 0); - assertEquals(Double.NEGATIVE_INFINITY, BitSquareConverter.stringToDouble(""), 0); - assertEquals(Double.NEGATIVE_INFINITY, BitSquareConverter.stringToDouble("."), 0); - assertEquals(Double.NEGATIVE_INFINITY, BitSquareConverter.stringToDouble(","), 0); - assertEquals(Double.NEGATIVE_INFINITY, BitSquareConverter.stringToDouble("a"), 0); + assertEquals(0, BitSquareConverter.stringToDouble("1,000.2"), 0); + assertEquals(0, BitSquareConverter.stringToDouble("1,000.2"), 0); + assertEquals(0, BitSquareConverter.stringToDouble(null), 0); + assertEquals(0, BitSquareConverter.stringToDouble(""), 0); + assertEquals(0, BitSquareConverter.stringToDouble(""), 0); + assertEquals(0, BitSquareConverter.stringToDouble("."), 0); + assertEquals(0, BitSquareConverter.stringToDouble(","), 0); + assertEquals(0, BitSquareConverter.stringToDouble("a"), 0); } } diff --git a/src/test/java/io/bitsquare/msg/P2PNodeTest.java b/src/test/java/io/bitsquare/msg/P2PNodeTest.java index 3dc408deb7..f01df87659 100644 --- a/src/test/java/io/bitsquare/msg/P2PNodeTest.java +++ b/src/test/java/io/bitsquare/msg/P2PNodeTest.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.util.Random; +import net.tomp2p.connection.Ports; import net.tomp2p.dht.FutureGet; import net.tomp2p.dht.FuturePut; import net.tomp2p.dht.FutureRemove; @@ -29,7 +30,7 @@ public class P2PNodeTest @Test public void testSendData() throws Exception { - PeerDHT[] peers = UtilsDHT2.createNodes(3, rnd, 41001); + PeerDHT[] peers = UtilsDHT2.createNodes(3, rnd, new Ports().tcpPort()); PeerDHT master = peers[0]; PeerDHT client = peers[1]; PeerDHT otherPeer = peers[2]; @@ -66,12 +67,14 @@ public class P2PNodeTest assertTrue(futureDirect.isSuccess()); // we return true from objectDataReply assertTrue((Boolean) futureDirect.object()); + + master.shutdown(); } @Test public void testProtectedPutGet() throws Exception { - PeerDHT[] peers = UtilsDHT2.createNodes(3, rnd, 41001); + PeerDHT[] peers = UtilsDHT2.createNodes(3, rnd, new Ports().tcpPort()); PeerDHT master = peers[0]; PeerDHT client = peers[1]; PeerDHT otherPeer = peers[2]; @@ -157,7 +160,7 @@ public class P2PNodeTest @Test public void testAddToListGetList() throws Exception { - PeerDHT[] peers = UtilsDHT2.createNodes(3, rnd, 41001); + PeerDHT[] peers = UtilsDHT2.createNodes(3, rnd, new Ports().tcpPort()); PeerDHT master = peers[0]; PeerDHT client = peers[1]; PeerDHT otherPeer = peers[2]; @@ -367,7 +370,6 @@ public class P2PNodeTest assertTrue(foundData3); assertEquals(2, futureGet.dataMap().values().size()); - master.shutdown(); } diff --git a/src/test/java/lighthouse/threading/ConcatenatingListTest.java b/src/test/java/lighthouse/threading/ConcatenatingListTest.java deleted file mode 100644 index 17b6c76865..0000000000 --- a/src/test/java/lighthouse/threading/ConcatenatingListTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package lighthouse.threading; - -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - - -public class ConcatenatingListTest -{ - @Test - public void basic() throws Exception - { - ObservableList a = FXCollections.observableArrayList(); - ObservableList b = FXCollections.observableArrayList(); - ConcatenatingList concat = new ConcatenatingList<>(a, b); - assertEquals(0, concat.size()); - a.add("1"); - assertEquals(1, concat.size()); - assertEquals("1", concat.get(0)); - b.add("2"); - assertEquals(2, concat.size()); - assertEquals("2", concat.get(1)); - } -} \ No newline at end of file diff --git a/src/test/java/lighthouse/threading/MappedListTest.java b/src/test/java/lighthouse/threading/MappedListTest.java deleted file mode 100644 index 08faacdb83..0000000000 --- a/src/test/java/lighthouse/threading/MappedListTest.java +++ /dev/null @@ -1,91 +0,0 @@ -package lighthouse.threading; - -import java.util.LinkedList; -import java.util.Queue; -import javafx.collections.FXCollections; -import javafx.collections.ListChangeListener; -import javafx.collections.ObservableList; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -public class MappedListTest -{ - private ObservableList inputs; - private ObservableList outputs; - private Queue> changes; - - @Before - public void setup() - { - inputs = FXCollections.observableArrayList(); - outputs = new MappedList<>(inputs, str -> "Hello " + str); - changes = new LinkedList<>(); - outputs.addListener(changes::add); - } - - @Test - public void add() throws Exception - { - assertEquals(0, outputs.size()); - inputs.add("Mike"); - ListChangeListener.Change change = getChange(); - assertTrue(change.wasAdded()); - assertEquals("Hello Mike", change.getAddedSubList().get(0)); - assertEquals(1, outputs.size()); - assertEquals("Hello Mike", outputs.get(0)); - inputs.remove(0); - assertEquals(0, outputs.size()); - } - - private ListChangeListener.Change getChange() - { - ListChangeListener.Change change = changes.poll(); - change.next(); - return change; - } - - @Test - public void remove() - { - inputs.add("Mike"); - inputs.add("Dave"); - inputs.add("Katniss"); - getChange(); - getChange(); - getChange(); - assertEquals("Hello Mike", outputs.get(0)); - assertEquals("Hello Dave", outputs.get(1)); - assertEquals("Hello Katniss", outputs.get(2)); - inputs.remove(0); - ListChangeListener.Change change = getChange(); - assertTrue(change.wasRemoved()); - assertEquals(2, outputs.size()); - assertEquals(1, change.getRemovedSize()); - assertEquals("Hello Mike", change.getRemoved().get(0)); - assertEquals("Hello Dave", outputs.get(0)); - - inputs.remove(1); - assertEquals(1, outputs.size()); - assertEquals("Hello Dave", outputs.get(0)); - } - - @Test - public void replace() throws Exception - { - inputs.add("Mike"); - inputs.add("Dave"); - getChange(); - getChange(); - inputs.set(0, "Bob"); - assertEquals("Hello Bob", outputs.get(0)); - ListChangeListener.Change change = getChange(); - assertTrue(change.wasReplaced()); - assertEquals("Hello Mike", change.getRemoved().get(0)); - assertEquals("Hello Bob", change.getAddedSubList().get(0)); - } - - // Could also test permutation here if I could figure out how to actually apply one! -} \ No newline at end of file