UTF-8
diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF
index de29527d5cd..4a577d5aa64 100644
--- a/src/main/java/META-INF/MANIFEST.MF
+++ b/src/main/java/META-INF/MANIFEST.MF
@@ -1,3 +1,3 @@
Manifest-Version: 1.0
-Main-Class: io.bitsquare.Relay
+Main-Class: io.bitsquare.BootstrapNode_
diff --git a/src/main/java/io/bitsquare/BitSquare.java b/src/main/java/io/bitsquare/BitSquare.java
index 559a855de84..b2bc1b4cb1b 100644
--- a/src/main/java/io/bitsquare/BitSquare.java
+++ b/src/main/java/io/bitsquare/BitSquare.java
@@ -1,5 +1,6 @@
package io.bitsquare;
+import akka.actor.ActorSystem;
import com.google.common.base.Throwables;
import com.google.inject.Guice;
import com.google.inject.Injector;
@@ -11,7 +12,7 @@
import io.bitsquare.locale.Localisation;
import io.bitsquare.msg.MessageFacade;
import io.bitsquare.settings.Settings;
-import io.bitsquare.storage.Storage;
+import io.bitsquare.storage.Persistence;
import io.bitsquare.user.User;
import io.bitsquare.util.AWTSystemTray;
import io.bitsquare.util.FileUtil;
@@ -33,17 +34,17 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
public class BitSquare extends Application
{
private static final Logger log = LoggerFactory.getLogger(BitSquare.class);
- public static boolean fillFormsWithDummyData = false;
+ public static boolean fillFormsWithDummyData = true;
private static String APP_NAME = "bitsquare";
private static Stage primaryStage;
private WalletFacade walletFacade;
private MessageFacade messageFacade;
+ private final ActorSystem system = ActorSystem.create(APP_NAME);
public static void main(String[] args)
{
@@ -74,6 +75,9 @@ public void start(Stage primaryStage) throws IOException
log.trace("Startup: start");
BitSquare.primaryStage = primaryStage;
+ //log.trace("Startup: setupAkka");
+ //setupAkka();
+
Thread.currentThread().setUncaughtExceptionHandler((thread, throwable) -> Popups.handleUncaughtExceptions(Throwables.getRootCause(throwable)));
StorageDirectory.setStorageDirectory(new File(StorageDirectory.getApplicationDirectory().getCanonicalPath() + "/data"));
@@ -90,10 +94,14 @@ public void start(Stage primaryStage) throws IOException
// apply stored data
final User user = injector.getInstance(User.class);
final Settings settings = injector.getInstance(Settings.class);
- final Storage storage = injector.getInstance(Storage.class);
- storage.init();
- user.updateFromStorage((User) storage.read(user.getClass().getName()));
- settings.updateFromStorage((Settings) storage.read(settings.getClass().getName()));
+ final Persistence persistence = injector.getInstance(Persistence.class);
+ persistence.init();
+
+ User persistedUser = (User) persistence.read(user);
+ user.applyPersistedUser(persistedUser);
+ persistence.write(user);
+
+ settings.applyPersistedSettings((Settings) persistence.read(settings.getClass().getName()));
primaryStage.setTitle("BitSquare (" + getUID() + ")");
@@ -111,10 +119,10 @@ public void start(Stage primaryStage) throws IOException
setupCloseHandlers(primaryStage, scene);
primaryStage.setScene(scene);
- primaryStage.setMinWidth(800);
- primaryStage.setMinHeight(400);
- primaryStage.setWidth(800);
- primaryStage.setHeight(600);
+ primaryStage.setMinWidth(750);
+ primaryStage.setMinHeight(500);
+ primaryStage.setWidth(1000);
+ primaryStage.setHeight(750);
primaryStage.show();
@@ -131,6 +139,12 @@ private void setupCloseHandlers(Stage primaryStage, Scene scene)
});
}
+ private void setupAkka()
+ {
+ log.trace("SetupAkka: create actors");
+
+ }
+
private MenuBar getMenuBar()
{
MenuBar menuBar = new MenuBar();
@@ -156,7 +170,6 @@ private MenuBar getMenuBar()
return menuBar;
}
-
@Override
public void stop() throws Exception
{
diff --git a/src/main/java/io/bitsquare/Relay.java b/src/main/java/io/bitsquare/Relay.java
deleted file mode 100644
index 5e0e0521dfe..00000000000
--- a/src/main/java/io/bitsquare/Relay.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package io.bitsquare;
-
-import java.io.IOException;
-import javafx.application.Application;
-import javafx.stage.Stage;
-import net.tomp2p.p2p.Peer;
-import net.tomp2p.p2p.PeerMaker;
-import net.tomp2p.peers.Number160;
-import net.tomp2p.peers.PeerAddress;
-import net.tomp2p.peers.PeerMapChangeListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-public class Relay extends Application
-{
- private static final Logger log = LoggerFactory.getLogger(Relay.class);
- private static final Number160 ID = Number160.createHash(1);
-
- private static Peer masterPeer = null;
- private static int port;
-
- public static void main(String[] args)
- {
- if (args != null && args.length == 1)
- {
- port = new Integer(args[0]);
- }
- else
- {
- port = 5001;
- }
-
- launch(args);
- }
-
- @Override
- public void start(Stage primaryStage) throws IOException
- {
- log.trace("Startup: start");
- if (masterPeer == null)
- {
- masterPeer = new PeerMaker(ID).setPorts(port).makeAndListen();
- // masterPeer = new PeerMaker(ID).setPorts(port).setBagSize(100).makeAndListen(); // setBagSize cause sync problems...
- masterPeer.getBroadcastRPC().getConnectionBean().getConnectionReservation().reserve(3).awaitUninterruptibly();
- masterPeer.getConnectionHandler().getPeerBean().getPeerMap().addPeerMapChangeListener(new PeerMapChangeListener()
- {
- @Override
- public void peerInserted(PeerAddress peerAddress)
- {
- log.info("peerInserted " + peerAddress);
- }
-
- @Override
- public void peerRemoved(PeerAddress peerAddress)
- {
- log.info("peerRemoved " + peerAddress);
- }
-
- @Override
- public void peerUpdated(PeerAddress peerAddress)
- {
- log.info("peerUpdated " + peerAddress);
- }
- });
- }
- }
-
-}
diff --git a/src/main/java/io/bitsquare/SeedNode.java b/src/main/java/io/bitsquare/SeedNode.java
new file mode 100644
index 00000000000..eb035c5001c
--- /dev/null
+++ b/src/main/java/io/bitsquare/SeedNode.java
@@ -0,0 +1,174 @@
+package io.bitsquare;
+
+import io.bitsquare.msg.SeedNodeAddress;
+import java.util.List;
+import net.tomp2p.dht.PeerBuilderDHT;
+import net.tomp2p.futures.BaseFuture;
+import net.tomp2p.futures.BaseFutureListener;
+import net.tomp2p.nat.PeerBuilderNAT;
+import net.tomp2p.nat.PeerNAT;
+import net.tomp2p.p2p.Peer;
+import net.tomp2p.p2p.PeerBuilder;
+import net.tomp2p.peers.Number160;
+import net.tomp2p.peers.PeerAddress;
+import net.tomp2p.peers.PeerMapChangeListener;
+import net.tomp2p.peers.PeerStatatistic;
+import net.tomp2p.relay.FutureRelay;
+import net.tomp2p.relay.RelayRPC;
+import net.tomp2p.tracker.PeerBuilderTracker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Well known node which is reachable for all peers for bootstrapping.
+ * There will be several SeedNodes running on several servers.
+ *
+ * TODO: Alternative bootstrap methods will follow later (save locally list of known nodes reported form other peers,...)
+ */
+public class SeedNode
+{
+ private static final Logger log = LoggerFactory.getLogger(SeedNode.class);
+
+ private static final List staticSedNodeAddresses = SeedNodeAddress.StaticSeedNodeAddresses.getAllSeedNodeAddresses();
+
+ /**
+ * @param args If no args passed we use localhost, otherwise the param is used as index for selecting an address from seedNodeAddresses
+ * @throws Exception
+ */
+ public static void main(String[] args)
+ {
+ int index = 0;
+ SeedNode seedNode = new SeedNode();
+ if (args.length > 0)
+ {
+ // use host index passes as param
+ int param = Integer.valueOf(args[0]);
+ if (param < staticSedNodeAddresses.size())
+ index = param;
+ }
+ try
+ {
+ seedNode.startupUsingAddress(new SeedNodeAddress(staticSedNodeAddresses.get(index)));
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ log.error(e.toString());
+ }
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Constructor
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+
+ public SeedNode()
+ {
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Public Methods
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ public void startupUsingAddress(SeedNodeAddress seedNodeAddress)
+ {
+ try
+ {
+ Peer peer = new PeerBuilder(Number160.createHash(seedNodeAddress.getId())).ports(seedNodeAddress.getPort()).start();
+
+ // Need to add all features the clients will use (otherwise msg type is UNKNOWN_ID)
+ new PeerBuilderDHT(peer).start();
+ PeerNAT nodeBehindNat = new PeerBuilderNAT(peer).start();
+ new RelayRPC(peer);
+ new PeerBuilderTracker(peer);
+ nodeBehindNat.startSetupRelay(new FutureRelay());
+
+ log.debug("Peer started. " + peer.peerAddress());
+
+ peer.peerBean().peerMap().addPeerMapChangeListener(new PeerMapChangeListener()
+ {
+ @Override
+ public void peerInserted(PeerAddress peerAddress, boolean verified)
+ {
+ log.debug("Peer inserted: peerAddress=" + peerAddress + ", verified=" + verified);
+ }
+
+ @Override
+ public void peerRemoved(PeerAddress peerAddress, PeerStatatistic peerStatistics)
+ {
+ log.debug("Peer removed: peerAddress=" + peerAddress + ", peerStatistics=" + peerStatistics);
+ }
+
+ @Override
+ public void peerUpdated(PeerAddress peerAddress, PeerStatatistic peerStatistics)
+ {
+ log.debug("Peer updated: peerAddress=" + peerAddress + ", peerStatistics=" + peerStatistics);
+ }
+ });
+
+ // We keep server in endless loop
+ for (; ; )
+ {
+ // Optional pinging
+ boolean pingPeers = false;
+ if (pingPeers)
+ {
+ for (PeerAddress peerAddress : peer.peerBean().peerMap().all())
+ {
+ BaseFuture future = peer.ping().peerAddress(peerAddress).tcpPing().start();
+ future.addListener(new BaseFutureListener()
+ {
+ @Override
+ public void operationComplete(BaseFuture future) throws Exception
+ {
+ if (future.isSuccess())
+ {
+ log.debug("peer online (TCP):" + peerAddress);
+ }
+ else
+ {
+ log.debug("offline " + peerAddress);
+ }
+ }
+
+ @Override
+ public void exceptionCaught(Throwable t) throws Exception
+ {
+ log.error("exceptionCaught " + t);
+ }
+ });
+
+ future = peer.ping().peerAddress(peerAddress).start();
+ future.addListener(new BaseFutureListener()
+ {
+ @Override
+ public void operationComplete(BaseFuture future) throws Exception
+ {
+ if (future.isSuccess())
+ {
+ log.debug("peer online (UDP):" + peerAddress);
+ }
+ else
+ {
+ log.debug("offline " + peerAddress);
+ }
+ }
+
+ @Override
+ public void exceptionCaught(Throwable t) throws Exception
+ {
+ log.error("exceptionCaught " + t);
+ }
+ });
+ }
+ Thread.sleep(1500);
+ }
+ }
+ } catch (Exception e)
+ {
+ log.error("Exception: " + e);
+ }
+ }
+
+}
diff --git a/src/main/java/io/bitsquare/bank/BankAccount.java b/src/main/java/io/bitsquare/bank/BankAccount.java
index 428ee3184e7..1eb9a929a6a 100644
--- a/src/main/java/io/bitsquare/bank/BankAccount.java
+++ b/src/main/java/io/bitsquare/bank/BankAccount.java
@@ -4,26 +4,21 @@
import java.io.Serializable;
import java.util.Currency;
import java.util.Objects;
+import javax.annotation.concurrent.Immutable;
+@Immutable
public class BankAccount implements Serializable
{
private static final long serialVersionUID = 1792577576443221268L;
-
private final BankAccountType bankAccountType;
-
- private final String accountPrimaryID;
-
- private final String accountSecondaryID;
-
+ private final String accountPrimaryID; // like IBAN
+ private final String accountSecondaryID; // like BIC
private final String accountHolderName;
-
- private final Country country;
-
+ private final Country country; // where bank is registered
+ // The main currency if account support multiple currencies.
+ // The user can create multiple bank accounts with same bank account but other currency if his bank account support that.
private final Currency currency;
-
- private final String uid;
-
private final String accountTitle;
public BankAccount(BankAccountType bankAccountType, Currency currency, Country country, String accountTitle, String accountHolderName, String accountPrimaryID, String accountSecondaryID)
@@ -35,28 +30,20 @@ public BankAccount(BankAccountType bankAccountType, Currency currency, Country c
this.accountHolderName = accountHolderName;
this.accountPrimaryID = accountPrimaryID;
this.accountSecondaryID = accountSecondaryID;
-
- uid = accountTitle;
}
public int hashCode()
{
- return Objects.hashCode(uid);
+ return Objects.hashCode(accountTitle);
}
public boolean equals(Object obj)
{
- if (!(obj instanceof BankAccount))
- {
- return false;
- }
- if (obj == this)
- {
- return true;
- }
+ if (!(obj instanceof BankAccount)) return false;
+ if (obj == this) return true;
final BankAccount other = (BankAccount) obj;
- return uid.equals(other.getUid());
+ return accountTitle.equals(other.getUid());
}
@@ -65,49 +52,42 @@ public String getAccountPrimaryID()
return accountPrimaryID;
}
-
public String getAccountSecondaryID()
{
return accountSecondaryID;
}
-
public String getAccountHolderName()
{
return accountHolderName;
}
-
public BankAccountType getBankAccountType()
{
return bankAccountType;
}
-
public Currency getCurrency()
{
return currency;
}
-
public Country getCountry()
{
return country;
}
-
+ // we use the accountTitle as unique id
public String getUid()
{
- return uid;
+ return accountTitle;
}
-
public String getAccountTitle()
{
return accountTitle;
}
-
@Override
public String toString()
{
@@ -116,11 +96,9 @@ public String toString()
", accountPrimaryID='" + accountPrimaryID + '\'' +
", accountSecondaryID='" + accountSecondaryID + '\'' +
", accountHolderName='" + accountHolderName + '\'' +
- ", countryLocale=" + country +
+ ", country=" + country +
", currency=" + currency +
- ", uid='" + uid + '\'' +
", accountTitle='" + accountTitle + '\'' +
'}';
}
-
}
diff --git a/src/main/java/io/bitsquare/bank/BankAccountType.java b/src/main/java/io/bitsquare/bank/BankAccountType.java
index 4df67a36a21..59b59275297 100644
--- a/src/main/java/io/bitsquare/bank/BankAccountType.java
+++ b/src/main/java/io/bitsquare/bank/BankAccountType.java
@@ -13,9 +13,7 @@ public enum BankAccountType
PERFECT_MONEY("primary ID", "secondary ID"),
OTHER("primary ID", "secondary ID");
-
private final String primaryId;
-
private final String secondaryId;
BankAccountType(String primaryId, String secondaryId)
@@ -24,19 +22,16 @@ public enum BankAccountType
this.secondaryId = secondaryId;
}
-
public static ArrayList getAllBankAccountTypes()
{
return new ArrayList<>(Arrays.asList(BankAccountType.values()));
}
-
public String getPrimaryId()
{
return primaryId;
}
-
public String getSecondaryId()
{
return secondaryId;
diff --git a/src/main/java/io/bitsquare/btc/BitSquareWallet.java b/src/main/java/io/bitsquare/btc/BitSquareWallet.java
index 9f35712e2e2..cbcc1d4621d 100644
--- a/src/main/java/io/bitsquare/btc/BitSquareWallet.java
+++ b/src/main/java/io/bitsquare/btc/BitSquareWallet.java
@@ -22,5 +22,4 @@ private BitSquareWallet(NetworkParameters params, KeyCrypter keyCrypter)
super(params, keyCrypter);
}
-
}
diff --git a/src/main/java/io/bitsquare/btc/WalletFacade.java b/src/main/java/io/bitsquare/btc/WalletFacade.java
index 31312cbb3ca..aa7a4e22ae9 100644
--- a/src/main/java/io/bitsquare/btc/WalletFacade.java
+++ b/src/main/java/io/bitsquare/btc/WalletFacade.java
@@ -17,7 +17,7 @@
import io.bitsquare.btc.listeners.BalanceListener;
import io.bitsquare.btc.listeners.ConfidenceListener;
import io.bitsquare.crypto.CryptoFacade;
-import io.bitsquare.storage.Storage;
+import io.bitsquare.storage.Persistence;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.*;
@@ -48,12 +48,11 @@ public class WalletFacade
private final ReentrantLock lock = Threading.lock("lock");
- private final String saveAddressEntryListId;
private final NetworkParameters params;
private final BitSquareWalletAppKit walletAppKit;
private final FeePolicy feePolicy;
private final CryptoFacade cryptoFacade;
- private final Storage storage;
+ private final Persistence persistence;
private final List downloadListeners = new ArrayList<>();
private final List confidenceListeners = new ArrayList<>();
private final List balanceListeners = new ArrayList<>();
@@ -68,15 +67,13 @@ public class WalletFacade
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
- public WalletFacade(NetworkParameters params, BitSquareWalletAppKit walletAppKit, FeePolicy feePolicy, CryptoFacade cryptoFacade, Storage storage)
+ public WalletFacade(NetworkParameters params, BitSquareWalletAppKit walletAppKit, FeePolicy feePolicy, CryptoFacade cryptoFacade, Persistence persistence)
{
this.params = params;
this.walletAppKit = walletAppKit;
this.feePolicy = feePolicy;
this.cryptoFacade = cryptoFacade;
- this.storage = storage;
-
- saveAddressEntryListId = this.getClass().getName() + ".addressEntryList";
+ this.persistence = persistence;
}
@@ -173,11 +170,11 @@ public void onScriptsAdded(Wallet wallet, List