use tomp2p master branch

This commit is contained in:
Manfred Karrer 2014-07-31 19:43:46 +02:00
parent 79a52a6e38
commit d943ee0918
14 changed files with 40 additions and 952 deletions

View File

@ -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:

52
pom.xml
View File

@ -6,23 +6,14 @@
<groupId>io.bitsquare</groupId>
<artifactId>bitsquare</artifactId>
<version>0.01-SNAPSHOT</version>
<version>0.1-SNAPSHOT</version>
<name>BitSquare</name>
<description>A P2P Fiat-Bitcoin Exchange</description>
<url>https://www.bitsquare.io</url>
<description>The P2P Fiat-Bitcoin Exchange</description>
<url>http://www.bitsquare.io</url>
<organization>
<name>bitsquare.io</name>
</organization>
<!--
<parent>
<groupId>com.google</groupId>
<artifactId>bitcoinj-parent</artifactId>
<version>0.12-SNAPSHOT</version>
<relativePath>libs/bitcoinj/pom.xml</relativePath>
</parent>
-->
<licenses>
<license>
@ -53,13 +44,11 @@
<snapshots/>
<url>https://oss.sonatype.org/content/groups/public</url>
</repository>
<!-- bitcoin-j repo -->
<repository>
<id>bitcoinj-release</id>
<releases/>
<url>http://distribution.bitcoinj.googlecode.com/git/releases</url>
</repository>
<!-- zxing repo -->
<repository>
<id>mvn-adamgent</id>
<url>http://mvn-adamgent.googlecode.com/svn/maven/release</url>
@ -73,7 +62,6 @@
</repositories>
<!-- TODO Maven build not working yet... -->
<build>
<finalName>bitsquare</finalName>
<resources>
@ -113,13 +101,11 @@
<dependency>
<groupId>org.twdata.maven</groupId>
<artifactId>mojo-executor</artifactId>
<version>2.1.0</version>
<version>2.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
@ -131,13 +117,11 @@
<version>0.11.3</version>
</dependency>
<!--
<dependency>
<groupId>net.tomp2p</groupId>
<artifactId>tomp2p-all</artifactId>
<version>5.0-Alpha24-SNAPSHOT</version>
</dependency>
-->
<dependency>
<groupId>junit</groupId>
@ -151,13 +135,7 @@
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<!--
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.7</version>
</dependency>
-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
@ -170,7 +148,6 @@
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
@ -219,14 +196,6 @@
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
</dependency>
<!--
<dependency>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard</artifactId>
<version>4.4</version>
<scope>runtime</scope>
</dependency>
-->
<dependency>
<groupId>org.jetbrains</groupId>
@ -235,17 +204,6 @@
</dependency>
</dependencies>
<reporting>
<plugins>
<!-- Generate cross-referenced HTML source code listing -->
<!-- <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
<version>2.1</version>
</plugin> -->
</plugins>
</reporting>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

View File

@ -110,7 +110,7 @@ public class P2PNode
useDiscStorage(useDiskStorage);
setupTimerForIPCheck();
FutureCallback<PeerDHT> localCallback = new FutureCallback<PeerDHT>()
/* FutureCallback<PeerDHT> localCallback = new FutureCallback<PeerDHT>()
{
@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<PeerDHT> 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()
{

View File

@ -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<Path> listDir(Path dir) throws IOException
{
List<Path> contents = new LinkedList<>();
try (Stream<Path> list = Files.list(dir))
{
list.forEach(contents::add);
}
return contents;
}
//region Generic Java 8 enhancements
public interface UncheckedRun<T>
{
public T run() throws Throwable;
}
public interface UncheckedRunnable
{
public void run() throws Throwable;
}
public static <T> T unchecked(UncheckedRun<T> 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> T ignoredAndLogged(UncheckedRun<T> runnable)
{
try
{
return runnable.run();
} catch (Throwable t)
{
log.error("Ignoring error", t);
return null;
}
}
@SuppressWarnings("unchecked")
public static <T, E extends Throwable> T checkedGet(Future<T> 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> T stopwatched(String description, UncheckedRun<T> 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
}

View File

@ -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<Thread> 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<Runnable> 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();
}
}
}

View File

@ -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<T> extends ObservableListBase<T> implements ObservableList<T>
{
private List<ObservableList<T>> sources = new ArrayList<>();
private ListChangeListener<T> listener = this::sourceChanged;
@SafeVarargs
public ConcatenatingList(ObservableList<T>... source)
{
super();
for (ObservableList<T> s : source)
{
sources.add(s);
s.addListener(new WeakListChangeListener<T>(listener));
}
if (sources.isEmpty())
throw new IllegalArgumentException();
}
private int calculateOffset(ObservableList<? extends T> source)
{
int cursor = 0;
for (ObservableList<T> ts : sources)
{
if (ts == source) return cursor;
cursor += ts.size();
}
return cursor;
}
private void sourceChanged(ListChangeListener.Change<? extends T> c)
{
ObservableList<? extends T> 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<T> 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();
}
}

View File

@ -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<E, F> extends TransformationList<E, F>
{
private final Function<F, E> mapper;
private final ArrayList<E> 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<? extends F> source, Function<F, E> 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<? extends F> 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<E> removed = mapped.subList(c.getFrom(), c.getFrom() + c.getRemovedSize());
ArrayList<E> 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();
}
}

View File

@ -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 <T> ListChangeListener<T> addListener(ObservableList<T> observable, ListChangeListener<T> listener, Executor executor)
{
ListChangeListener<T> l = (ListChangeListener.Change<? extends T> c) -> executor.execute(() -> listener.onChanged(c));
observable.addListener(l);
return l;
}
public static <T> SetChangeListener<T> addListener(ObservableSet<T> observable, SetChangeListener<T> listener, Executor executor)
{
SetChangeListener<T> l = (SetChangeListener.Change<? extends T> c) -> executor.execute(() -> listener.onChanged(c));
observable.addListener(l);
return l;
}
public static <K, V> MapChangeListener<K, V> addListener(ObservableMap<K, V> observable, MapChangeListener<K, V> listener, Executor executor)
{
MapChangeListener<K, V> l = (MapChangeListener.Change<? extends K, ? extends V> c) -> executor.execute(() -> listener.onChanged(c));
observable.addListener(l);
return l;
}
}

View File

@ -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 <T> ObservableList<T> mirrorList(ObservableList<T> mirrored, AffinityExecutor runChangesIn)
{
ObservableList<T> result = FXCollections.observableArrayList();
result.setAll(mirrored);
mirrored.addListener(new ListMirror<T>(result, runChangesIn));
return FXCollections.unmodifiableObservableList(result);
}
private static class ListMirror<E> implements ListChangeListener<E>, WeakListener
{
private final WeakReference<ObservableList<E>> targetList;
private final AffinityExecutor runChangesIn;
public ListMirror(ObservableList<E> list, AffinityExecutor runChangesIn)
{
this.targetList = new WeakReference<>(list);
this.runChangesIn = runChangesIn;
}
@Override
public void onChanged(Change<? extends E> change)
{
final List<E> 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<E> list = targetList.get();
return (list == null) ? 0 : list.hashCode();
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
final List<E> 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 <T> ObservableSet<T> mirrorSet(ObservableSet<T> mirrored, AffinityExecutor runChangesIn)
{
@SuppressWarnings("unchecked") ObservableSet<T> result = FXCollections.observableSet();
result.addAll(mirrored);
mirrored.addListener(new SetMirror<T>(result, runChangesIn));
return FXCollections.unmodifiableObservableSet(result);
}
private static class SetMirror<E> implements SetChangeListener<E>, WeakListener
{
private final WeakReference<ObservableSet<E>> targetSet;
private final AffinityExecutor runChangesIn;
public SetMirror(ObservableSet<E> set, AffinityExecutor runChangesIn)
{
this.targetSet = new WeakReference<>(set);
this.runChangesIn = runChangesIn;
}
@Override
public void onChanged(final Change<? extends E> change)
{
final ObservableSet<E> 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<E> set = targetSet.get();
return (set == null) ? 0 : set.hashCode();
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
final Set<E> 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;
}
}
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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();
}

View File

@ -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<String> a = FXCollections.observableArrayList();
ObservableList<String> b = FXCollections.observableArrayList();
ConcatenatingList<String> 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));
}
}

View File

@ -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<String> inputs;
private ObservableList<String> outputs;
private Queue<ListChangeListener.Change<? extends String>> 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<? extends String> 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<? extends String> getChange()
{
ListChangeListener.Change<? extends String> 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<? extends String> 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<? extends String> 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!
}