Refactor persistence (add Storage class)

This commit is contained in:
Manfred Karrer 2015-03-24 17:16:34 +01:00
parent c4905baef3
commit 917dd3522b
42 changed files with 692 additions and 548 deletions

View File

@ -104,11 +104,22 @@
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.bitcoinj</groupId>
<artifactId>bitcoinj-core</artifactId>
<version>0.13.d13665c-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>net.tomp2p</groupId>
<artifactId>tomp2p-all</artifactId>
<version>5.0-Beta3</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>16.0.1</version>
</dependency>
<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjava</artifactId>

View File

@ -27,8 +27,6 @@ import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.debug.DebugView;
import io.bitsquare.gui.util.ImageUtil;
import io.bitsquare.persistence.Persistence;
import io.bitsquare.user.AccountSettings;
import io.bitsquare.user.User;
import io.bitsquare.util.Utilities;
import com.google.common.base.Throwables;
@ -72,11 +70,11 @@ public class BitsquareApp extends Application {
this.primaryStage = primaryStage;
log.trace("BitsquareApp.start");
bitsquareAppModule = new BitsquareAppModule(env, primaryStage);
injector = Guice.createInjector(bitsquareAppModule);
injector.getInstance(InjectorViewFactory.class).setInjector(injector);
// route uncaught exceptions to a user-facing dialog
Thread.currentThread().setUncaughtExceptionHandler((thread, throwable) ->
@ -84,17 +82,10 @@ public class BitsquareApp extends Application {
// load and apply any stored settings
User user = injector.getInstance(User.class);
AccountSettings accountSettings = injector.getInstance(AccountSettings.class);
Persistence persistence = injector.getInstance(Persistence.class);
persistence.init();
User persistedUser = (User) persistence.read(user);
user.applyPersistedUser(persistedUser);
accountSettings.applyPersistedAccountSettings((AccountSettings) persistence
.read(accountSettings.getClass().getName()));
// load the main view and create the main scene
log.trace("viewLoader.load(MainView.class)");

View File

@ -28,6 +28,7 @@ import io.bitsquare.p2p.tomp2p.TomP2PModule;
import io.bitsquare.offer.OfferModule;
import io.bitsquare.offer.tomp2p.TomP2POfferModule;
import io.bitsquare.persistence.Persistence;
import io.bitsquare.persistence.Storage;
import io.bitsquare.trade.TradeModule;
import io.bitsquare.user.AccountSettings;
import io.bitsquare.user.Preferences;
@ -59,6 +60,9 @@ class BitsquareAppModule extends BitsquareModule {
bind(Preferences.class).in(Singleton.class);
bind(AccountSettings.class).in(Singleton.class);
File storageDir = new File(env.getRequiredProperty(Storage.DIR_KEY));
bind(File.class).annotatedWith(named(Storage.DIR_KEY)).toInstance(storageDir);
File persistenceDir = new File(env.getRequiredProperty(Persistence.DIR_KEY));
bind(File.class).annotatedWith(named(Persistence.DIR_KEY)).toInstance(persistenceDir);
bindConstant().annotatedWith(named(Persistence.PREFIX_KEY)).to(env.getRequiredProperty(Persistence.PREFIX_KEY));

View File

@ -22,6 +22,7 @@ import io.bitsquare.btc.UserAgent;
import io.bitsquare.btc.WalletService;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.persistence.Persistence;
import io.bitsquare.persistence.Storage;
import io.bitsquare.util.Utilities;
import io.bitsquare.util.spring.JOptCommandLinePropertySource;
@ -134,9 +135,11 @@ public class BitsquareEnvironment extends StandardEnvironment {
setProperty(WalletService.DIR_KEY, appDataDir);
setProperty(WalletService.PREFIX_KEY, appName);
setProperty(Persistence.DIR_KEY, appDataDir);
setProperty(Storage.DIR_KEY, Paths.get(appDataDir, "db").toString());
setProperty(Persistence.DIR_KEY, appDataDir);
setProperty(Persistence.PREFIX_KEY, appName + "_pref");
setProperty(MainView.TITLE_KEY, appName);
}});
}

View File

@ -33,20 +33,20 @@ public class AddressEntry implements Serializable {
private static final long serialVersionUID = 5501603992599920416L;
private final String offerId;
private final AddressContext addressContext;
private final Context context;
private transient DeterministicKey keyPair;
private final byte[] pubKey;
private final byte[] pubKeyHash;
private final NetworkParameters params;
public AddressEntry(DeterministicKey keyPair, NetworkParameters params, @SuppressWarnings("SameParameterValue") AddressContext addressContext) {
this(keyPair, params, addressContext, null);
public AddressEntry(DeterministicKey keyPair, NetworkParameters params, @SuppressWarnings("SameParameterValue") Context context) {
this(keyPair, params, context, null);
}
public AddressEntry(DeterministicKey keyPair, NetworkParameters params, AddressContext addressContext, String offerId) {
public AddressEntry(DeterministicKey keyPair, NetworkParameters params, Context context, String offerId) {
this.keyPair = keyPair;
this.params = params;
this.addressContext = addressContext;
this.context = context;
this.offerId = offerId;
pubKey = keyPair.getPubKey();
@ -57,8 +57,8 @@ public class AddressEntry implements Serializable {
return offerId;
}
public AddressContext getAddressContext() {
return addressContext;
public Context getContext() {
return context;
}
public String getAddressString() {
@ -85,7 +85,7 @@ public class AddressEntry implements Serializable {
return pubKey;
}
public static enum AddressContext {
public static enum Context {
REGISTRATION_FEE,
TRADE,
ARBITRATOR_DEPOSIT
@ -95,7 +95,7 @@ public class AddressEntry implements Serializable {
public String toString() {
return "AddressEntry{" +
"offerId='" + offerId +
", addressContext=" + addressContext +
", addressContext=" + context +
", keyPair=" + keyPair +
", pubKey=" + Arrays.toString(pubKey) +
", pubKeyHash=" + Arrays.toString(pubKeyHash) +

View File

@ -0,0 +1,85 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.btc;
import io.bitsquare.persistence.Storage;
import org.bitcoinj.core.Wallet;
import org.bitcoinj.crypto.DeterministicKey;
import com.google.inject.Inject;
import java.io.Serializable;
import java.util.ArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AddressEntryList extends ArrayList<AddressEntry> implements Serializable {
private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(AddressEntryList.class);
transient private Storage<AddressEntryList> storage;
transient private Wallet wallet;
// Persisted fields are in ArrayList superclass
@Inject
public AddressEntryList(Storage<AddressEntryList> storage) {
this.storage = storage;
}
public void init(Wallet wallet) {
this.wallet = wallet;
AddressEntryList persisted = storage.getPersisted(this);
if (persisted != null) {
for (AddressEntry addressEntry : persisted) {
addressEntry.setDeterministicKey((DeterministicKey) wallet.findKeyFromPubHash(addressEntry.getPubKeyHash()));
}
}
else {
// First time create registrationAddressEntry
createRegistrationAddressEntry();
}
}
public AddressEntry getNewAddressEntry(AddressEntry.Context context, String offerId) {
log.trace("getNewAddressEntry called with offerId " + offerId);
DeterministicKey key = wallet.freshReceiveKey();
AddressEntry addressEntry = new AddressEntry(key, wallet.getParams(), context, offerId);
add(addressEntry);
storage.save();
return addressEntry;
}
private void createRegistrationAddressEntry() {
DeterministicKey registrationKey = wallet.currentReceiveKey();
AddressEntry registrationAddressEntry = new AddressEntry(registrationKey, wallet.getParams(), AddressEntry.Context.REGISTRATION_FEE);
add(registrationAddressEntry);
storage.save();
}
public AddressEntry getRegistrationAddressEntry() {
if (isEmpty())
createRegistrationAddressEntry();
return get(0);
}
}

View File

@ -36,7 +36,6 @@ import org.bitcoinj.core.TransactionInput;
import org.bitcoinj.core.TransactionOutput;
import org.bitcoinj.core.Wallet;
import org.bitcoinj.core.WalletEventListener;
import org.bitcoinj.crypto.DeterministicKey;
import org.bitcoinj.kits.WalletAppKit;
import org.bitcoinj.params.MainNetParams;
import org.bitcoinj.params.RegTestParams;
@ -50,7 +49,6 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.Service;
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
@ -97,12 +95,13 @@ public class WalletService {
private final File walletDir;
private final String walletPrefix;
private final UserAgent userAgent;
private final BitcoinNetwork bitcoinNetwork;
private WalletAppKit walletAppKit;
private Wallet wallet;
private AddressEntry registrationAddressEntry;
private AddressEntry arbitratorDepositAddressEntry;
private List<AddressEntry> addressEntryList = new ArrayList<>();
private AddressEntryList addressEntryList;
private TradeWalletService tradeWalletService;
@ -112,8 +111,10 @@ public class WalletService {
@Inject
public WalletService(BitcoinNetwork bitcoinNetwork, FeePolicy feePolicy, SignatureService signatureService,
Persistence persistence, UserAgent userAgent,
Persistence persistence, AddressEntryList addressEntryList, UserAgent userAgent,
@Named(DIR_KEY) File walletDir, @Named(PREFIX_KEY) String walletPrefix) {
this.bitcoinNetwork = bitcoinNetwork;
this.addressEntryList = addressEntryList;
this.params = bitcoinNetwork.getParameters();
this.feePolicy = feePolicy;
this.signatureService = signatureService;
@ -204,23 +205,8 @@ public class WalletService {
wallet = walletAppKit.wallet();
wallet.addEventListener(walletEventListener);
Serializable serializable = persistence.read(this, "addressEntryList");
if (serializable instanceof List<?>) {
List<AddressEntry> persistedAddressEntryList = (List<AddressEntry>) serializable;
for (AddressEntry persistedAddressEntry : persistedAddressEntryList) {
persistedAddressEntry.setDeterministicKey((DeterministicKey) wallet.findKeyFromPubHash(persistedAddressEntry.getPubKeyHash()));
}
addressEntryList = persistedAddressEntryList;
registrationAddressEntry = addressEntryList.get(0);
}
else {
// First time
DeterministicKey registrationKey = wallet.currentReceiveKey();
registrationAddressEntry = new AddressEntry(registrationKey, params,
AddressEntry.AddressContext.REGISTRATION_FEE);
addressEntryList.add(registrationAddressEntry);
saveAddressInfoList();
}
addressEntryList.init(wallet);
registrationAddressEntry = addressEntryList.getRegistrationAddressEntry();
}
public void shutDown() {
@ -285,7 +271,7 @@ public class WalletService {
public AddressEntry getArbitratorDepositAddressEntry() {
if (arbitratorDepositAddressEntry == null)
arbitratorDepositAddressEntry = getNewAddressEntry(AddressEntry.AddressContext.ARBITRATOR_DEPOSIT, null);
arbitratorDepositAddressEntry = addressEntryList.getNewAddressEntry(AddressEntry.Context.ARBITRATOR_DEPOSIT, null);
return arbitratorDepositAddressEntry;
}
@ -297,7 +283,7 @@ public class WalletService {
if (addressEntry.isPresent())
return addressEntry.get();
else
return getNewAddressEntry(AddressEntry.AddressContext.TRADE, offerId);
return addressEntryList.getNewAddressEntry(AddressEntry.Context.TRADE, offerId);
}
@ -305,15 +291,6 @@ public class WalletService {
// Create new AddressInfo objects
///////////////////////////////////////////////////////////////////////////////////////////
private AddressEntry getNewAddressEntry(AddressEntry.AddressContext addressContext, String offerId) {
log.trace("getNewAddressEntry called with offerId " + offerId);
DeterministicKey key = wallet.freshReceiveKey();
AddressEntry addressEntry = new AddressEntry(key, params, addressContext, offerId);
addressEntryList.add(addressEntry);
saveAddressInfoList();
return addressEntry;
}
private Optional<AddressEntry> getAddressEntryByAddressString(String address) {
return getAddressEntryList().stream().filter(e -> address.equals(e.getAddressString())).findFirst();
}
@ -541,10 +518,6 @@ public class WalletService {
// Private methods
///////////////////////////////////////////////////////////////////////////////////////////
private void saveAddressInfoList() {
persistence.write(this, "addressEntryList", addressEntryList);
}
private static void printTxWithInputs(String tracePrefix, Transaction tx) {
log.trace(tracePrefix + ": " + tx.toString());
for (TransactionInput input : tx.getInputs()) {

View File

@ -17,14 +17,22 @@
package io.bitsquare.common.viewfx.view;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class ViewPath extends ArrayList<Class<? extends View>> {
public class ViewPath extends ArrayList<Class<? extends View>> implements Serializable {
private static final long serialVersionUID = 1L;
public ViewPath() {
}
public ViewPath(Collection<? extends Class<? extends View>> c) {
super(c);
}
public static ViewPath to(Class<? extends View>... elements) {
ViewPath path = new ViewPath();
path.addAll(Arrays.asList(elements));

View File

@ -54,7 +54,13 @@ public class EncryptionService<T> {
public EncryptionService() {
}
public KeyPair getKeyPair() throws NoSuchAlgorithmException {
public KeyPair getGeneratedDSAKeyPair() throws NoSuchAlgorithmException {
final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");
keyPairGenerator.initialize(1024);
return keyPairGenerator.genKeyPair();
}
public KeyPair getGeneratedRSAKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGO_ASYM);
keyPairGenerator.initialize(KEY_SIZE_ASYM);
return keyPairGenerator.genKeyPair();

View File

@ -88,7 +88,7 @@ public class FiatAccount implements Serializable {
}
// we use the accountTitle as unique id
public String getUid() {
public String getId() {
return nameOfBank;
}
@ -112,7 +112,7 @@ public class FiatAccount implements Serializable {
if (obj == this) return true;
final FiatAccount other = (FiatAccount) obj;
return nameOfBank.equals(other.getUid());
return nameOfBank.equals(other.getId());
}
@Override

View File

@ -21,7 +21,7 @@ import io.bitsquare.common.viewfx.view.View;
import io.bitsquare.common.viewfx.view.ViewPath;
import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.trade.BuyView;
import io.bitsquare.persistence.Persistence;
import io.bitsquare.persistence.Storage;
import com.google.inject.Inject;
@ -31,28 +31,46 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class Navigation {
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final String CURRENT_PATH_KEY = "currentPath";
public class Navigation implements Serializable {
private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(Navigation.class);
private static final ViewPath DEFAULT_VIEW_PATH = ViewPath.to(MainView.class, BuyView.class);
transient private static final ViewPath DEFAULT_VIEW_PATH = ViewPath.to(MainView.class, BuyView.class);
public interface Listener {
void onNavigationRequested(ViewPath path);
}
// New listeners can be added during iteration so we use CopyOnWriteArrayList to
// prevent invalid array modification
private final List<Listener> listeners = new CopyOnWriteArrayList<>();
private final Persistence persistence;
private ViewPath currentPath;
transient private final List<Listener> listeners = new CopyOnWriteArrayList<>();
transient private final Storage<Navigation> storage;
transient private ViewPath currentPath;
// Used for returning to the last important view. After setup is done we want to
// return to the last opened view (e.g. sell/buy)
private ViewPath returnPath;
transient private ViewPath returnPath;
// Persisted fields
private ViewPath previousPath;
@Inject
public Navigation(Persistence persistence) {
this.persistence = persistence;
public Navigation(Storage<Navigation> storage) {
this.storage = storage;
Navigation persisted = storage.getPersisted(this);
if (persisted != null) {
previousPath = persisted.getPreviousPath();
}
else
previousPath = DEFAULT_VIEW_PATH;
// need to be null initially and not DEFAULT_VIEW_PATH to navigate through all items
currentPath = null;
}
public void navigateTo(Class<? extends View>... viewClasses) {
@ -84,21 +102,16 @@ public class Navigation {
}
currentPath = newPath;
persistence.write(this, CURRENT_PATH_KEY, (List<? extends Serializable>) currentPath);
previousPath = currentPath;
storage.save();
listeners.stream().forEach((e) -> e.onNavigationRequested(currentPath));
}
public void navigateToLastOpenView() {
ViewPath lastPath = (ViewPath) persistence.read(this, CURRENT_PATH_KEY);
public void navigateToPreviousVisitedView() {
if (previousPath == null || previousPath.size() == 0)
previousPath = DEFAULT_VIEW_PATH;
if (lastPath == null || lastPath.size() == 0)
lastPath = DEFAULT_VIEW_PATH;
navigateTo(lastPath);
}
public static interface Listener {
void onNavigationRequested(ViewPath path);
navigateTo(previousPath);
}
public void addListener(Listener listener) {
@ -120,4 +133,8 @@ public class Navigation {
public void setReturnPath(ViewPath returnPath) {
this.returnPath = returnPath;
}
private ViewPath getPreviousPath() {
return previousPath;
}
}

View File

@ -154,7 +154,7 @@ public class MainView extends InitializableView<StackPane, MainViewModel> {
if (newValue) {
bankAccountComboBoxHolder.getChildren().setAll(createBankAccountComboBox());
navigation.navigateToLastOpenView();
navigation.navigateToPreviousVisitedView();
transitions.fadeOutAndRemove(splashScreen, 1500);
}

View File

@ -38,7 +38,7 @@ import io.bitsquare.trade.Trade;
import io.bitsquare.trade.TradeManager;
import io.bitsquare.user.AccountSettings;
import io.bitsquare.user.User;
import io.bitsquare.util.DSAKeyUtil;
import io.bitsquare.util.Utilities;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.ECKey;
@ -129,14 +129,14 @@ class MainViewModel implements ViewModel {
updateProcess.state.addListener((observableValue, oldValue, newValue) -> applyUpdateState(newValue));
applyUpdateState(updateProcess.state.get());
user.getCurrentBankAccount().addListener((observable, oldValue, newValue) -> persistence.write(user));
currentBankAccount.bind(user.currentBankAccountProperty());
user.getFiatAccounts().addListener((ListChangeListener<FiatAccount>) change -> {
user.currentFiatAccountProperty().addListener((observable, oldValue, newValue) -> persistence.write(user));
currentBankAccount.bind(user.currentFiatAccountProperty());
user.fiatAccountsObservableList().addListener((ListChangeListener<FiatAccount>) change -> {
bankAccountsComboBoxDisable.set(change.getList().isEmpty());
bankAccountsComboBoxPrompt.set(change.getList().isEmpty() ? "No accounts" : "");
});
bankAccountsComboBoxDisable.set(user.getFiatAccounts().isEmpty());
bankAccountsComboBoxPrompt.set(user.getFiatAccounts().isEmpty() ? "No accounts" : "");
bankAccountsComboBoxDisable.set(user.fiatAccountsObservableList().isEmpty());
bankAccountsComboBoxPrompt.set(user.fiatAccountsObservableList().isEmpty() ? "No accounts" : "");
}
public void restart() {
@ -214,7 +214,7 @@ class MainViewModel implements ViewModel {
// For alpha version
// uses messageService, so don't call it before backend is ready
if (accountSettings.getAcceptedArbitrators().isEmpty())
addMockArbitrator();
accountSettings.addAcceptedArbitrator(getMockArbitrator());
// For alpha version
if (!user.isRegistered()) {
@ -225,11 +225,10 @@ class MainViewModel implements ViewModel {
"Demo (Account holder name)",
"Demo (E.g. IBAN) ",
"Demo (E.g. BIC) ");
user.setBankAccount(fiatAccount);
user.addFiatAccount(fiatAccount);
persistence.write(user);
user.setAccountID(walletService.getRegistrationAddressEntry().toString());
persistence.write(user.getClass().getName(), user);
}
tradeManager.onAllServicesInitialized();
@ -321,11 +320,11 @@ class MainViewModel implements ViewModel {
}
public ObservableList<FiatAccount> getBankAccounts() {
return user.getFiatAccounts();
return user.fiatAccountsObservableList();
}
public void setCurrentBankAccount(FiatAccount currentFiatAccount) {
user.setCurrentBankAccount(currentFiatAccount);
user.setCurrentFiatAccount(currentFiatAccount);
}
private void updateNumPendingTrades() {
@ -352,34 +351,30 @@ class MainViewModel implements ViewModel {
}
}
private void addMockArbitrator() {
if (accountSettings.getAcceptedArbitrators().isEmpty() && user.getP2pSigKeyPair() != null) {
byte[] pubKey = new ECKey().getPubKey();
String p2pSigPubKeyAsHex = DSAKeyUtil.getHexStringFromPublicKey(user.getP2PSigPubKey());
List<Locale> languages = new ArrayList<>();
languages.add(LanguageUtil.getDefaultLanguageLocale());
List<Arbitrator.METHOD> arbitrationMethods = new ArrayList<>();
arbitrationMethods.add(Arbitrator.METHOD.TLS_NOTARY);
List<Arbitrator.ID_VERIFICATION> idVerifications = new ArrayList<>();
idVerifications.add(Arbitrator.ID_VERIFICATION.PASSPORT);
idVerifications.add(Arbitrator.ID_VERIFICATION.GOV_ID);
private Arbitrator getMockArbitrator() {
byte[] pubKey = new ECKey().getPubKey();
String p2pSigPubKeyAsHex = Utilities.getHexStringFromPublicKey(user.getP2PSigPubKey());
List<Locale> languages = new ArrayList<>();
languages.add(LanguageUtil.getDefaultLanguageLocale());
List<Arbitrator.METHOD> arbitrationMethods = new ArrayList<>();
arbitrationMethods.add(Arbitrator.METHOD.TLS_NOTARY);
List<Arbitrator.ID_VERIFICATION> idVerifications = new ArrayList<>();
idVerifications.add(Arbitrator.ID_VERIFICATION.PASSPORT);
idVerifications.add(Arbitrator.ID_VERIFICATION.GOV_ID);
Arbitrator arbitrator = new Arbitrator(pubKey,
p2pSigPubKeyAsHex,
"Manfred Karrer",
Arbitrator.ID_TYPE.REAL_LIFE_ID,
languages,
new Reputation(),
Coin.parseCoin("0.1"),
arbitrationMethods,
idVerifications,
"https://bitsquare.io",
"Bla bla...");
Arbitrator arbitrator = new Arbitrator(pubKey,
p2pSigPubKeyAsHex,
"Manfred Karrer",
Arbitrator.ID_TYPE.REAL_LIFE_ID,
languages,
new Reputation(),
Coin.parseCoin("0.1"),
arbitrationMethods,
idVerifications,
"https://bitsquare.io",
"Bla bla...");
accountSettings.addAcceptedArbitrator(arbitrator);
persistence.write(accountSettings);
arbitratorService.addArbitrator(arbitrator);
}
arbitratorService.addArbitrator(arbitrator);
return arbitrator;
}
}

View File

@ -29,7 +29,6 @@ import io.bitsquare.locale.BSResources;
import io.bitsquare.locale.LanguageUtil;
import io.bitsquare.persistence.Persistence;
import io.bitsquare.user.User;
import io.bitsquare.util.DSAKeyUtil;
import io.bitsquare.util.Utilities;
import org.bitcoinj.core.Coin;
@ -369,7 +368,7 @@ public class ArbitratorRegistrationView extends ActivatableView<AnchorPane, Void
private Arbitrator getEditedArbitrator() {
byte[] pubKey = walletService.getArbitratorDepositAddressEntry().getPubKey();
String p2pSigPubKeyAsHex = DSAKeyUtil.getHexStringFromPublicKey(user.getP2PSigPubKey());
String p2pSigPubKeyAsHex = Utilities.getHexStringFromPublicKey(user.getP2PSigPubKey());
String name = nameTextField.getText();
Coin fee = formatter.parseToCoin(arbitrationFeeTextField.getText());
String webUrl = webPageTextField.getText();

View File

@ -77,7 +77,7 @@ class FiatAccountDataModel implements Activatable, DataModel {
@Override
public void activate() {
allFiatAccounts.setAll(user.getFiatAccounts());
allFiatAccounts.setAll(user.fiatAccountsObservableList());
}
@Override
@ -94,17 +94,17 @@ class FiatAccountDataModel implements Activatable, DataModel {
holderName.get(),
primaryID.get(),
secondaryID.get());
user.setBankAccount(fiatAccount);
user.addFiatAccount(fiatAccount);
saveUser();
allFiatAccounts.setAll(user.getFiatAccounts());
allFiatAccounts.setAll(user.fiatAccountsObservableList());
countryNotInAcceptedCountriesList.set(!accountSettings.getAcceptedCountries().contains(country.get()));
reset();
}
void removeBankAccount() {
user.removeCurrentBankAccount();
user.removeFiatAccount(user.currentFiatAccountProperty().get());
saveUser();
allFiatAccounts.setAll(user.getFiatAccounts());
allFiatAccounts.setAll(user.fiatAccountsObservableList());
reset();
}
@ -117,7 +117,7 @@ class FiatAccountDataModel implements Activatable, DataModel {
}
void selectBankAccount(FiatAccount fiatAccount) {
user.setCurrentBankAccount(fiatAccount);
user.setCurrentFiatAccount(fiatAccount);
persistence.write(user);
if (fiatAccount != null) {

View File

@ -17,30 +17,20 @@
package io.bitsquare.gui.main.account.content.irc;
import io.bitsquare.arbitration.Arbitrator;
import io.bitsquare.arbitration.ArbitratorService;
import io.bitsquare.arbitration.Reputation;
import io.bitsquare.common.viewfx.model.Activatable;
import io.bitsquare.common.viewfx.model.DataModel;
import io.bitsquare.fiat.FiatAccount;
import io.bitsquare.fiat.FiatAccountType;
import io.bitsquare.locale.CountryUtil;
import io.bitsquare.locale.CurrencyUtil;
import io.bitsquare.locale.LanguageUtil;
import io.bitsquare.persistence.Persistence;
import io.bitsquare.user.AccountSettings;
import io.bitsquare.user.User;
import io.bitsquare.util.DSAKeyUtil;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.ECKey;
import com.google.inject.Inject;
import java.util.ArrayList;
import java.util.Currency;
import java.util.List;
import java.util.Locale;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
@ -73,14 +63,11 @@ class IrcAccountDataModel implements Activatable, DataModel {
this.user = user;
this.accountSettings = accountSettings;
this.messageService = messageService;
if (accountSettings.getAcceptedArbitrators().isEmpty())
addMockArbitrator();
}
@Override
public void activate() {
allFiatAccounts.setAll(user.getFiatAccounts());
allFiatAccounts.setAll(user.fiatAccountsObservableList());
}
@Override
@ -96,9 +83,9 @@ class IrcAccountDataModel implements Activatable, DataModel {
nickName.get(),
"irc",
"irc");
user.setBankAccount(fiatAccount);
user.addFiatAccount(fiatAccount);
saveUser();
allFiatAccounts.setAll(user.getFiatAccounts());
allFiatAccounts.setAll(user.fiatAccountsObservableList());
reset();
}
@ -120,35 +107,4 @@ class IrcAccountDataModel implements Activatable, DataModel {
private void saveUser() {
persistence.write(user);
}
private void addMockArbitrator() {
if (accountSettings.getAcceptedArbitrators().isEmpty() && user.getP2pSigKeyPair() != null) {
byte[] pubKey = new ECKey().getPubKey();
String p2pSigPubKeyAsHex = DSAKeyUtil.getHexStringFromPublicKey(user.getP2PSigPubKey());
List<Locale> languages = new ArrayList<>();
languages.add(LanguageUtil.getDefaultLanguageLocale());
List<Arbitrator.METHOD> arbitrationMethods = new ArrayList<>();
arbitrationMethods.add(Arbitrator.METHOD.TLS_NOTARY);
List<Arbitrator.ID_VERIFICATION> idVerifications = new ArrayList<>();
idVerifications.add(Arbitrator.ID_VERIFICATION.PASSPORT);
idVerifications.add(Arbitrator.ID_VERIFICATION.GOV_ID);
Arbitrator arbitrator = new Arbitrator(pubKey,
p2pSigPubKeyAsHex,
"Manfred Karrer",
Arbitrator.ID_TYPE.REAL_LIFE_ID,
languages,
new Reputation(),
Coin.parseCoin("0.001"),
arbitrationMethods,
idVerifications,
"https://bitsquare.io/",
"Bla bla...");
accountSettings.addAcceptedArbitrator(arbitrator);
persistence.write(accountSettings);
messageService.addArbitrator(arbitrator);
}
}
}

View File

@ -91,7 +91,6 @@ class RegistrationDataModel implements DataModel {
if (getAddressEntry() != null)
user.setAccountID(getAddressEntry().toString());
persistence.write(user.getClass().getName(), user);
payFeeSuccess.set(true);
}
}

View File

@ -19,7 +19,6 @@ package io.bitsquare.gui.main.account.content.restrictions;
import io.bitsquare.arbitration.Arbitrator;
import io.bitsquare.arbitration.ArbitratorService;
import io.bitsquare.arbitration.Reputation;
import io.bitsquare.common.viewfx.model.Activatable;
import io.bitsquare.common.viewfx.model.DataModel;
import io.bitsquare.locale.Country;
@ -29,15 +28,9 @@ import io.bitsquare.locale.Region;
import io.bitsquare.persistence.Persistence;
import io.bitsquare.user.AccountSettings;
import io.bitsquare.user.User;
import io.bitsquare.util.DSAKeyUtil;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.ECKey;
import com.google.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import javafx.collections.FXCollections;
@ -65,28 +58,12 @@ class RestrictionsDataModel implements Activatable, DataModel {
this.accountSettings = accountSettings;
this.persistence = persistence;
this.messageService = messageService;
AccountSettings persistedAccountSettings = (AccountSettings) persistence.read(accountSettings);
if (persistedAccountSettings != null) {
accountSettings.applyPersistedAccountSettings(persistedAccountSettings);
}
else {
if (Locale.getDefault() != null) {
addLanguage(LanguageUtil.getDefaultLanguageLocale());
addCountry(CountryUtil.getDefaultCountry());
}
// Add english as default as well
addLanguage(LanguageUtil.getEnglishLanguageLocale());
}
addMockArbitrator();
}
@Override
public void activate() {
languageList.setAll(accountSettings.getAcceptedLanguageLocales());
countryList.setAll(accountSettings.getAcceptedCountries());
languageList.setAll(accountSettings.getAcceptedLanguageLocales());
arbitratorList.setAll(accountSettings.getAcceptedArbitrators());
}
@ -149,39 +126,4 @@ class RestrictionsDataModel implements Activatable, DataModel {
private void saveSettings() {
persistence.write(accountSettings);
}
// TODO Remove mock later
private void addMockArbitrator() {
if (accountSettings.getAcceptedArbitrators().isEmpty() && user.getP2pSigKeyPair() != null) {
byte[] pubKey = new ECKey().getPubKey();
String p2pSigPubKeyAsHex = DSAKeyUtil.getHexStringFromPublicKey(user.getP2PSigPubKey());
List<Locale> languages = new ArrayList<>();
languages.add(LanguageUtil.getDefaultLanguageLocale());
List<Arbitrator.METHOD> arbitrationMethods = new ArrayList<>();
arbitrationMethods.add(Arbitrator.METHOD.TLS_NOTARY);
List<Arbitrator.ID_VERIFICATION> idVerifications = new ArrayList<>();
idVerifications.add(Arbitrator.ID_VERIFICATION.PASSPORT);
idVerifications.add(Arbitrator.ID_VERIFICATION.GOV_ID);
// TODO use very small sec. dposit to make testing in testnet less expensive
// Revert later to 0.1 BTC again
Arbitrator arbitrator = new Arbitrator(pubKey,
p2pSigPubKeyAsHex,
"Manfred Karrer",
Arbitrator.ID_TYPE.REAL_LIFE_ID,
languages,
new Reputation(),
Coin.parseCoin("0.001"),
arbitrationMethods,
idVerifications,
"http://bitsquare.io/",
"Bla bla...");
arbitratorList.add(arbitrator);
accountSettings.addAcceptedArbitrator(arbitrator);
persistence.write(accountSettings);
messageService.addArbitrator(arbitrator);
}
}
}

View File

@ -127,7 +127,7 @@ public class WithdrawalListItem {
public final String getLabel() {
switch (addressEntry.getAddressContext()) {
switch (addressEntry.getContext()) {
case REGISTRATION_FEE:
return "Registration fee";
case TRADE:

View File

@ -50,7 +50,7 @@ class PreferencesDataModel implements Activatable, DataModel {
public PreferencesDataModel(Preferences preferences) {
this.preferences = preferences;
btcDenominations = FXCollections.observableArrayList(preferences.getBtcDenominations());
btcDenominations = FXCollections.observableArrayList(Preferences.getBtcDenominations());
btcDenominationListener = (ov, oldValue, newValue) -> preferences.setBtcDenomination(newValue);
useAnimationsListener = (ov, oldValue, newValue) -> preferences.setUseAnimations(newValue);
useEffectsListener = (ov, oldValue, newValue) -> preferences.setUseEffects(newValue);

View File

@ -137,9 +137,9 @@ class CreateOfferDataModel implements Activatable, DataModel {
}
if (user != null) {
user.currentBankAccountProperty().addListener((ov, oldValue, newValue) -> applyBankAccount(newValue));
user.currentFiatAccountProperty().addListener((ov, oldValue, newValue) -> applyBankAccount(newValue));
applyBankAccount(user.getCurrentBankAccount().get());
applyBankAccount(user.currentFiatAccountProperty().get());
}
if (accountSettings != null)

View File

@ -99,17 +99,17 @@ class OfferBookDataModel implements Activatable, DataModel {
volumeAsFiat.set(null);
offerBook.addClient();
user.currentBankAccountProperty().addListener(bankAccountChangeListener);
user.currentFiatAccountProperty().addListener(bankAccountChangeListener);
btcCode.bind(preferences.btcDenominationProperty());
setBankAccount(user.getCurrentBankAccount().get());
setBankAccount(user.currentFiatAccountProperty().get());
applyFilter();
}
@Override
public void deactivate() {
offerBook.removeClient();
user.currentBankAccountProperty().removeListener(bankAccountChangeListener);
user.currentFiatAccountProperty().removeListener(bankAccountChangeListener);
btcCode.unbind();
}
@ -149,7 +149,7 @@ class OfferBookDataModel implements Activatable, DataModel {
boolean isTradable(Offer offer) {
// if user has not registered yet we display all
FiatAccount currentFiatAccount = user.getCurrentBankAccount().get();
FiatAccount currentFiatAccount = user.currentFiatAccountProperty().get();
if (currentFiatAccount == null)
return true;
@ -159,7 +159,7 @@ class OfferBookDataModel implements Activatable, DataModel {
if (!countryResult)
restrictionsInfo.set("This offer requires that the payments account resides in one of those countries:\n" +
formatter.countryLocalesToString(offer.getAcceptedCountries()) +
"\n\nThe country of your payments account (" + user.getCurrentBankAccount().get().getCountry()
"\n\nThe country of your payments account (" + user.currentFiatAccountProperty().get().getCountry()
.getName() +
") is not included in that list." +
"\n\n Do you want to edit your preferences now?");

View File

@ -76,12 +76,12 @@ public class BSFormatter {
@Inject
public BSFormatter(User user) {
if (user.currentBankAccountProperty().get() == null)
if (user.currentFiatAccountProperty().get() == null)
setFiatCurrencyCode(CurrencyUtil.getDefaultCurrency().getCurrencyCode());
else if (user.currentBankAccountProperty().get() != null)
setFiatCurrencyCode(user.currentBankAccountProperty().get().getCurrency().getCurrencyCode());
else if (user.currentFiatAccountProperty().get() != null)
setFiatCurrencyCode(user.currentFiatAccountProperty().get().getCurrency().getCurrencyCode());
user.currentBankAccountProperty().addListener((ov, oldValue, newValue) -> {
user.currentFiatAccountProperty().addListener((ov, oldValue, newValue) -> {
if (newValue != null)
setFiatCurrencyCode(newValue.getCurrency().getCurrencyCode());
});

View File

@ -39,12 +39,12 @@ public final class FiatValidator extends NumberValidator {
@Inject
public FiatValidator(User user) {
if (user != null) {
if (user.currentBankAccountProperty().get() == null)
if (user.currentFiatAccountProperty().get() == null)
setFiatCurrencyCode(CurrencyUtil.getDefaultCurrency().getCurrencyCode());
else if (user.currentBankAccountProperty().get() != null)
setFiatCurrencyCode(user.currentBankAccountProperty().get().getCurrency().getCurrencyCode());
else if (user.currentFiatAccountProperty().get() != null)
setFiatCurrencyCode(user.currentFiatAccountProperty().get().getCurrency().getCurrencyCode());
user.currentBankAccountProperty().addListener((ov, oldValue, newValue) -> {
user.currentFiatAccountProperty().addListener((ov, oldValue, newValue) -> {
if (newValue != null)
setFiatCurrencyCode(newValue.getCurrency().getCurrencyCode());
});

View File

@ -39,12 +39,12 @@ public final class OptionalFiatValidator extends NumberValidator {
@Inject
public OptionalFiatValidator(User user) {
if (user != null) {
if (user.currentBankAccountProperty().get() == null)
if (user.currentFiatAccountProperty().get() == null)
setFiatCurrencyCode(CurrencyUtil.getDefaultCurrency().getCurrencyCode());
else if (user.currentBankAccountProperty().get() != null)
setFiatCurrencyCode(user.currentBankAccountProperty().get().getCurrency().getCurrencyCode());
else if (user.currentFiatAccountProperty().get() != null)
setFiatCurrencyCode(user.currentFiatAccountProperty().get().getCurrency().getCurrencyCode());
user.currentBankAccountProperty().addListener((ov, oldValue, newValue) -> {
user.currentFiatAccountProperty().addListener((ov, oldValue, newValue) -> {
if (newValue != null)
setFiatCurrencyCode(newValue.getCurrency().getCurrencyCode());
});

View File

@ -38,7 +38,10 @@ public class LanguageUtil {
}
public static Locale getDefaultLanguageLocale() {
return new Locale(Locale.getDefault().getLanguage(), "");
if (Locale.getDefault() != null)
return new Locale(Locale.getDefault().getLanguage(), "");
else
return getEnglishLanguageLocale();
}
public static Locale getEnglishLanguageLocale() {

View File

@ -150,14 +150,14 @@ public class OfferBook {
private void addListeners() {
log.debug("addListeners ");
user.currentBankAccountProperty().addListener(bankAccountChangeListener);
user.currentFiatAccountProperty().addListener(bankAccountChangeListener);
offerBookService.addListener(offerBookServiceListener);
offerBookService.invalidationTimestampProperty().addListener(invalidationListener);
}
private void removeListeners() {
log.debug("removeListeners ");
user.currentBankAccountProperty().removeListener(bankAccountChangeListener);
user.currentFiatAccountProperty().removeListener(bankAccountChangeListener);
offerBookService.removeListener(offerBookServiceListener);
offerBookService.invalidationTimestampProperty().removeListener(invalidationListener);
}
@ -180,7 +180,7 @@ public class OfferBook {
// TODO Just temporary, will be removed later when we have a push solution
private void startPolling() {
addListeners();
setBankAccount(user.getCurrentBankAccount().get());
setBankAccount(user.currentFiatAccountProperty().get());
pollingTimer = Utilities.setInterval(POLLING_INTERVAL, (animationTimer) -> {
offerBookService.requestInvalidationTimeStampFromDHT(fiatCode);
return null;

View File

@ -96,36 +96,23 @@ public class Persistence {
}
// Map
public void write(String key, Map<String, ? extends Serializable> value) {
write(key, (Serializable) value);
}
public void write(Object classInstance, String propertyKey, Map<String, ? extends Serializable> value) {
write(classInstance.getClass().getName() + "." + propertyKey, value);
}
public void write(Object classInstance, Map<String, ? extends Serializable> value) {
write(classInstance.getClass().getName(), value);
}
// List
public void write(String key, List<? extends Serializable> value) {
write(key, (Serializable) value);
}
public void write(Object classInstance, String propertyKey, List<? extends Serializable> value) {
write(classInstance.getClass().getName() + "." + propertyKey, value);
}
public void write(Object classInstance, List<? extends Serializable> value) {
write(classInstance.getClass().getName(), value);
}
// Serializable
public void write(Object classInstance, String propertyKey, Serializable value) {
write(classInstance.getClass().getName() + "." + propertyKey, value);
}
// not used outside
public void write(String key, Map<String, ? extends Serializable> value) {
write(key, (Serializable) value);
}
public void write(String key, List<? extends Serializable> value) {
write(key, (Serializable) value);
}
// Serializable
public void remove(Object classInstance, String propertyKey) {
try {
lock.lock();
@ -136,9 +123,6 @@ public class Persistence {
}
}
public void write(Object classInstance, Serializable value) {
write(classInstance.getClass().getName(), value);
}
public void write(Serializable classInstance) {
write(classInstance.getClass().getName(), classInstance);
@ -311,4 +295,5 @@ public class Persistence {
throw new IOException("Failed to rename " + tempFile + " to " + file);
}
}
}

View File

@ -0,0 +1,84 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.persistence;
import io.bitsquare.gui.components.Popups;
import io.bitsquare.util.FileUtil;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import javax.inject.Inject;
import javax.inject.Named;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Storage<T extends Serializable> {
private static final Logger log = LoggerFactory.getLogger(Storage.class);
public static final String DIR_KEY = "storage.dir";
private final File dir;
private File storageFile;
private T serializable;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public Storage(@Named(DIR_KEY) File dir) {
this.dir = dir;
}
public void save() {
if (storageFile == null)
throw new RuntimeException("storageFile = null. Call setupFileStorage before using read/write.");
try {
FileUtil.write(serializable, dir, storageFile);
} catch (IOException e) {
e.printStackTrace();
log.error(e.getMessage());
Popups.openErrorPopup("An exception occurred at writing data to disc.", e.getMessage());
}
}
public T getPersisted(T serializable) {
this.serializable = serializable;
storageFile = new File(dir, serializable.getClass().getSimpleName() + ".ser");
if (storageFile == null)
throw new RuntimeException("storageFile = null. Call init before using read/write.");
try {
return (T) FileUtil.read(storageFile);
} catch (FileNotFoundException e) {
log.info("File not available. That is OK for the first run.");
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
log.error(e.getMessage());
Popups.openErrorPopup("An exception occurred at reading data from disc.", e.getMessage());
}
return null;
}
}

View File

@ -19,7 +19,7 @@ package io.bitsquare.trade;
import io.bitsquare.fiat.FiatAccount;
import io.bitsquare.offer.Offer;
import io.bitsquare.util.DSAKeyUtil;
import io.bitsquare.util.Utilities;
import org.bitcoinj.core.Coin;
@ -59,8 +59,8 @@ public class Contract implements Serializable {
this.takerAccountID = takerAccountID;
this.offererFiatAccount = offererFiatAccount;
this.takerFiatAccount = takerFiatAccount;
this.offererP2PSigPubKeyAsString = DSAKeyUtil.getHexStringFromPublicKey(offererP2PSigPubKey);
this.takerP2PSigPubKeyAsString = DSAKeyUtil.getHexStringFromPublicKey(takerP2PSigPubKey);
this.offererP2PSigPubKeyAsString = Utilities.getHexStringFromPublicKey(offererP2PSigPubKey);
this.takerP2PSigPubKeyAsString = Utilities.getHexStringFromPublicKey(takerP2PSigPubKey);
}

View File

@ -174,7 +174,7 @@ public class TradeManager {
TransactionResultHandler resultHandler,
ErrorMessageHandler errorMessageHandler) {
FiatAccount currentFiatAccount = user.getCurrentBankAccount().get();
FiatAccount currentFiatAccount = user.currentFiatAccountProperty().get();
Offer offer = new Offer(id,
user.getP2PSigPubKey(),
direction,
@ -184,7 +184,7 @@ public class TradeManager {
currentFiatAccount.getFiatAccountType(),
currentFiatAccount.getCurrency(),
currentFiatAccount.getCountry(),
currentFiatAccount.getUid(),
currentFiatAccount.getId(),
accountSettings.getAcceptedArbitrators(),
accountSettings.getSecurityDeposit(),
accountSettings.getAcceptedCountries(),

View File

@ -79,7 +79,7 @@ public class OffererAsBuyerModel extends SharedTradeModel implements Serializabl
offerer.registrationPubKey = walletService.getRegistrationAddressEntry().getPubKey();
offerer.registrationKeyPair = walletService.getRegistrationAddressEntry().getKeyPair();
offerer.addressEntry = walletService.getAddressEntry(id);
offerer.fiatAccount = user.getBankAccount(offer.getBankAccountId());
offerer.fiatAccount = user.getFiatAccount(offer.getBankAccountId());
offerer.accountId = user.getAccountId();
offerer.p2pSigPubKey = user.getP2PSigPubKey();
offerer.p2pEncryptPubKey = user.getP2PEncryptPubKey();

View File

@ -83,7 +83,7 @@ public class TakerAsSellerModel extends SharedTradeModel implements Serializable
taker.registrationPubKey = walletService.getRegistrationAddressEntry().getPubKey();
taker.registrationKeyPair = walletService.getRegistrationAddressEntry().getKeyPair();
taker.addressEntry = walletService.getAddressEntry(id);
taker.fiatAccount = user.getBankAccount(offer.getBankAccountId());
taker.fiatAccount = user.getFiatAccount(offer.getBankAccountId());
taker.accountId = user.getAccountId();
taker.p2pSigPubKey = user.getP2PSigPubKey();
taker.p2pEncryptPublicKey = user.getP2PEncryptPubKey();

View File

@ -19,19 +19,28 @@ package io.bitsquare.user;
import io.bitsquare.arbitration.Arbitrator;
import io.bitsquare.locale.Country;
import io.bitsquare.locale.CountryUtil;
import io.bitsquare.locale.LanguageUtil;
import io.bitsquare.persistence.Storage;
import org.bitcoinj.core.Coin;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.OptionalLong;
public class AccountSettings implements Serializable {
private static final long serialVersionUID = 7995048077355006861L;
import javax.inject.Inject;
public class AccountSettings implements Serializable {
private static final long serialVersionUID = 1L;
transient private Storage<AccountSettings> storage;
// Persisted fields
private List<Locale> acceptedLanguageLocales = new ArrayList<>();
private List<Country> acceptedCountryLocales = new ArrayList<>();
private List<Arbitrator> acceptedArbitrators = new ArrayList<>();
@ -41,7 +50,21 @@ public class AccountSettings implements Serializable {
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
public AccountSettings() {
@Inject
public AccountSettings(Storage<AccountSettings> storage) {
this.storage = storage;
AccountSettings persisted = storage.getPersisted(this);
if (persisted != null) {
acceptedLanguageLocales = persisted.getAcceptedLanguageLocales();
acceptedCountryLocales = persisted.getAcceptedCountries();
acceptedArbitrators = persisted.getAcceptedArbitrators();
}
else {
acceptedLanguageLocales = Arrays.asList(LanguageUtil.getDefaultLanguageLocale(), LanguageUtil.getEnglishLanguageLocale());
acceptedCountryLocales = Arrays.asList(CountryUtil.getDefaultCountry());
acceptedArbitrators = new ArrayList<>();
}
}
@ -49,17 +72,11 @@ public class AccountSettings implements Serializable {
// Public API
///////////////////////////////////////////////////////////////////////////////////////////
public void applyPersistedAccountSettings(AccountSettings persistedSettings) {
if (persistedSettings != null) {
acceptedLanguageLocales = persistedSettings.getAcceptedLanguageLocales();
acceptedCountryLocales = persistedSettings.getAcceptedCountries();
acceptedArbitrators = persistedSettings.getAcceptedArbitrators();
}
}
public void addAcceptedLanguageLocale(Locale locale) {
if (!acceptedLanguageLocales.contains(locale)) {
acceptedLanguageLocales.add(locale);
storage.save();
}
}
@ -70,6 +87,7 @@ public class AccountSettings implements Serializable {
public void addAcceptedCountry(Country locale) {
if (!acceptedCountryLocales.contains(locale)) {
acceptedCountryLocales.add(locale);
storage.save();
}
}
@ -80,16 +98,18 @@ public class AccountSettings implements Serializable {
public void addAcceptedArbitrator(Arbitrator arbitrator) {
if (!acceptedArbitrators.contains(arbitrator)) {
acceptedArbitrators.add(arbitrator);
storage.save();
}
}
public void removeAcceptedArbitrator(Arbitrator item) {
acceptedArbitrators.remove(item);
storage.save();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Setters/Getters
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public List<Arbitrator> getAcceptedArbitrators() {

View File

@ -17,7 +17,7 @@
package io.bitsquare.user;
import io.bitsquare.persistence.Persistence;
import io.bitsquare.persistence.Storage;
import org.bitcoinj.utils.MonetaryFormat;
@ -33,23 +33,31 @@ import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Preferences implements Serializable {
private static final long serialVersionUID = 7995048077355006861L;
private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(Preferences.class);
// deactivate mBit for now as most screens are not supporting it yet
private List<String> btcDenominations = Arrays.asList(MonetaryFormat.CODE_BTC/*, MonetaryFormat.CODE_MBTC*/);
// Deactivate mBit for now as most screens are not supporting it yet
transient private static final List<String> BTC_DENOMINATIONS = Arrays.asList(MonetaryFormat.CODE_BTC/*, MonetaryFormat.CODE_MBTC*/);
public static List<String> getBtcDenominations() {
return BTC_DENOMINATIONS;
}
// Needed for persistence as Property objects are transient (not serializable)
// Will be probably removed when we have another persistence solution in place
private String btcDenominationString = MonetaryFormat.CODE_BTC;
private Boolean useAnimationsBoolean = true;
private Boolean useEffectsBoolean = true;
transient private final Storage<Preferences> storage;
final transient StringProperty btcDenomination = new SimpleStringProperty(btcDenominationString);
final transient BooleanProperty useAnimations = new SimpleBooleanProperty(useAnimationsBoolean);
final transient BooleanProperty useEffects = new SimpleBooleanProperty(useEffectsBoolean);
private Persistence persistence;
// Persisted fields
private String _btcDenomination = MonetaryFormat.CODE_BTC;
private Boolean _useAnimations = true;
private Boolean _useEffects = true;
// Observable wrappers
transient private final StringProperty btcDenomination = new SimpleStringProperty(_btcDenomination);
transient private final BooleanProperty useAnimations = new SimpleBooleanProperty(_useAnimations);
transient private final BooleanProperty useEffects = new SimpleBooleanProperty(_useEffects);
///////////////////////////////////////////////////////////////////////////////////////////
@ -57,105 +65,74 @@ public class Preferences implements Serializable {
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public Preferences(Persistence persistence) {
this.persistence = persistence;
public Preferences(Storage<Preferences> storage) {
this.storage = storage;
applyPersistedSettings();
Preferences persisted = storage.getPersisted(this);
if (persisted != null) {
setBtcDenomination(persisted._btcDenomination);
setUseAnimations(persisted._useAnimations);
setUseEffects(persisted._useEffects);
}
// Use that to guarantee update of the serializable field and to make a storage update in case of a change
btcDenomination.addListener((ov) -> {
_btcDenomination = btcDenomination.get();
storage.save();
});
useAnimations.addListener((ov) -> {
_useAnimations = useAnimations.get();
storage.save();
});
useEffects.addListener((ov) -> {
_useEffects = useEffects.get();
storage.save();
});
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public API
// Setter
///////////////////////////////////////////////////////////////////////////////////////////
public void applyPersistedSettings() {
Object data = persistence.read(this, "btcDenomination");
if (data instanceof String) {
btcDenominationString = (String) data;
this.btcDenomination.set(btcDenominationString);
}
public void setBtcDenomination(String btcDenomination) {
this.btcDenomination.set(btcDenomination);
}
data = persistence.read(this, "useEffects");
if (data instanceof Boolean) {
useEffectsBoolean = (Boolean) data;
this.useEffects.set(useEffectsBoolean);
}
public void setUseAnimations(boolean useAnimations) {
this.useAnimations.set(useAnimations);
}
data = persistence.read(this, "useAnimations");
if (data instanceof Boolean) {
useAnimationsBoolean = (Boolean) data;
this.useAnimations.set(useAnimationsBoolean);
}
public void setUseEffects(boolean useEffects) {
this.useEffects.set(useEffects);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Setters/Getters
// Getter
///////////////////////////////////////////////////////////////////////////////////////////
public List<String> getBtcDenominations() {
return btcDenominations;
}
// btcDenomination
public String getBtcDenomination() {
return btcDenomination.get();
}
public boolean getUseEffects() {
return useEffects.get();
}
public boolean getUseAnimations() {
return useAnimations.get();
}
public StringProperty btcDenominationProperty() {
return btcDenomination;
}
public void setBtcDenomination(String btcDenomination) {
persistence.write(this, "btcDenomination", btcDenomination);
btcDenominationString = btcDenomination;
this.btcDenomination.set(btcDenomination);
}
// for persistence
public String getBtcDenominationString() {
return btcDenominationString;
}
// useAnimations
public boolean getUseAnimations() {
return useAnimations.get();
}
public BooleanProperty useAnimationsProperty() {
return useAnimations;
}
public void setUseAnimations(boolean useAnimations) {
persistence.write(this, "useAnimations", useAnimations);
useAnimationsBoolean = useAnimations;
this.useAnimations.set(useAnimations);
}
// for persistence
public boolean getUseAnimationsBooleanBoolean() {
return useAnimationsBoolean;
}
// useEffects
public boolean getUseEffects() {
return useEffects.get();
}
public BooleanProperty useEffectsProperty() {
return useEffects;
}
public void setUseEffects(boolean useEffects) {
persistence.write(this, "useEffects", useEffects);
useEffectsBoolean = useEffects;
this.useEffects.set(useEffects);
}
// for persistence
public boolean getUseEffectsBoolean() {
return useEffectsBoolean;
}
}

View File

@ -19,7 +19,8 @@ package io.bitsquare.user;
import io.bitsquare.crypto.EncryptionService;
import io.bitsquare.fiat.FiatAccount;
import io.bitsquare.util.DSAKeyUtil;
import io.bitsquare.gui.components.Popups;
import io.bitsquare.persistence.Storage;
import java.io.Serializable;
@ -49,78 +50,95 @@ import org.slf4j.LoggerFactory;
* It must never be transmitted over the wire (messageKeyPair contains private key!).
*/
public class User implements Serializable {
private static final long serialVersionUID = 7409078808248518638L;
private static final Logger log = LoggerFactory.getLogger(User.class);
private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(User.class);
transient private Storage<User> storage;
transient private EncryptionService encryptionService;
// Persisted fields
private KeyPair p2pSigKeyPair;
private KeyPair p2pEncryptKeyPair;
private String accountID;
// Used for serialisation (ObservableList cannot be serialized) -> serialisation will change anyway so that is
// only temporary
private List<FiatAccount> _fiatAccounts = new ArrayList<>();
private FiatAccount _currentFiatAccount;
private final transient ObservableList<FiatAccount> fiatAccounts = FXCollections.observableArrayList();
private final transient ObjectProperty<FiatAccount> currentBankAccount = new SimpleObjectProperty<>();
transient private EncryptionService encryptionService;
// Observable wrappers
transient private final ObservableList<FiatAccount> fiatAccounts = FXCollections.observableArrayList();
transient private final ObjectProperty<FiatAccount> currentFiatAccount = new SimpleObjectProperty<>();
@Inject
public User(EncryptionService encryptionService) {
public User(Storage<User> storage, EncryptionService encryptionService) {
this.storage = storage;
this.encryptionService = encryptionService;
// Used for serialisation (ObservableList cannot be serialized) -> serialisation will change anyway so that is
// only temporary
fiatAccounts.addListener((ListChangeListener<FiatAccount>) change -> _fiatAccounts = new ArrayList<>(fiatAccounts));
currentBankAccount.addListener((ov) -> _currentFiatAccount = currentBankAccount.get());
User persisted = storage.getPersisted(this);
if (persisted != null) {
p2pSigKeyPair = persisted.getP2pSigKeyPair();
p2pEncryptKeyPair = persisted.getP2pEncryptKeyPair();
accountID = persisted.getAccountId();
_fiatAccounts = new ArrayList<>(persisted.getFiatAccounts());
fiatAccounts.setAll(_fiatAccounts);
_currentFiatAccount = persisted.getCurrentFiatAccount();
currentFiatAccount.set(_currentFiatAccount);
}
else {
// First time we create key pairs
try {
p2pSigKeyPair = encryptionService.getGeneratedDSAKeyPair();
p2pEncryptKeyPair = encryptionService.getGeneratedRSAKeyPair();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
log.error(e.getMessage());
Popups.openExceptionPopup(e);
}
}
storage.save();
// Use that to guarantee update of the serializable field and to make a storage update in case of a change
fiatAccounts.addListener((ListChangeListener<FiatAccount>) change -> {
_fiatAccounts = new ArrayList<>(fiatAccounts);
storage.save();
});
currentFiatAccount.addListener((ov) -> {
_currentFiatAccount = currentFiatAccount.get();
storage.save();
});
}
// for unit tests
public User() {
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public Methods
///////////////////////////////////////////////////////////////////////////////////////////
public void applyPersistedUser(User persistedUser) {
if (persistedUser != null) {
fiatAccounts.setAll(persistedUser.getSerializedBankAccounts());
setCurrentBankAccount(persistedUser.getSerializedCurrentBankAccount());
p2pSigKeyPair = persistedUser.getP2pSigKeyPair();
p2pEncryptKeyPair = persistedUser.getP2pEncryptKeyPair();
accountID = persistedUser.getAccountId();
}
else {
// First time
p2pSigKeyPair = DSAKeyUtil.generateDSAKeyPair();
try {
p2pEncryptKeyPair = encryptionService.getKeyPair();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
log.error(e.getMessage());
}
}
}
public void setBankAccount(FiatAccount fiatAccount) {
// We use the account title as hashCode
// In case we edit an existing we replace it in the list
/**
* @param fiatAccount
* @return If a Fiat Account with the same name already exists we return false. We use the account title as hashCode.
*/
public boolean addFiatAccount(FiatAccount fiatAccount) {
if (fiatAccounts.contains(fiatAccount))
fiatAccounts.remove(fiatAccount);
return false;
fiatAccounts.add(fiatAccount);
setCurrentBankAccount(fiatAccount);
setCurrentFiatAccount(fiatAccount);
return true;
}
public void removeCurrentBankAccount() {
if (currentBankAccount.get() != null)
fiatAccounts.remove(currentBankAccount.get());
// In case we edit an existing we remove the existing first
public void removeFiatAccount(FiatAccount fiatAccount) {
fiatAccounts.remove(fiatAccount);
if (fiatAccounts.isEmpty())
setCurrentBankAccount(null);
else
setCurrentBankAccount(fiatAccounts.get(0));
if (_currentFiatAccount.equals(fiatAccount)) {
if (fiatAccounts.isEmpty())
setCurrentFiatAccount(null);
else
setCurrentFiatAccount(fiatAccounts.get(0));
}
}
@ -132,19 +150,20 @@ public class User implements Serializable {
// Public key from the input for the registration payment tx (or address) will be used
public void setAccountID(String accountID) {
this.accountID = accountID;
storage.save();
}
public void setCurrentBankAccount(@Nullable FiatAccount fiatAccount) {
currentBankAccount.set(fiatAccount);
public void setCurrentFiatAccount(@Nullable FiatAccount fiatAccount) {
currentFiatAccount.set(fiatAccount);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
// TODO just a first attempt, refine when working on the embedded data for the reg. tx
public String getStringifiedBankAccounts() {
// TODO use steam API
String bankAccountUIDs = "";
for (int i = 0; i < fiatAccounts.size(); i++) {
FiatAccount fiatAccount = fiatAccounts.get(i);
@ -165,17 +184,9 @@ public class User implements Serializable {
return getAccountId() != null;
}
public ObservableList<FiatAccount> getFiatAccounts() {
return fiatAccounts;
}
public ObjectProperty<FiatAccount> getCurrentBankAccount() {
return currentBankAccount;
}
public FiatAccount getBankAccount(String bankAccountId) {
for (final FiatAccount fiatAccount : fiatAccounts) {
if (fiatAccount.getUid().equals(bankAccountId)) {
public FiatAccount getFiatAccount(String fiatAccountId) {
for (FiatAccount fiatAccount : fiatAccounts) {
if (fiatAccount.getId().equals(fiatAccountId)) {
return fiatAccount;
}
}
@ -194,24 +205,28 @@ public class User implements Serializable {
return p2pEncryptKeyPair.getPublic();
}
public ObjectProperty<FiatAccount> currentBankAccountProperty() {
return currentBankAccount;
}
// Used for serialisation (ObservableList cannot be serialized)
List<FiatAccount> getSerializedBankAccounts() {
return _fiatAccounts;
}
FiatAccount getSerializedCurrentBankAccount() {
return _currentFiatAccount;
}
public PrivateKey getP2pEncryptPrivateKey() {
return p2pEncryptKeyPair.getPrivate();
}
KeyPair getP2pEncryptKeyPair() {
private KeyPair getP2pEncryptKeyPair() {
return p2pEncryptKeyPair;
}
private List<FiatAccount> getFiatAccounts() {
return _fiatAccounts;
}
private FiatAccount getCurrentFiatAccount() {
return _currentFiatAccount;
}
public ObjectProperty<FiatAccount> currentFiatAccountProperty() {
return currentFiatAccount;
}
public ObservableList<FiatAccount> fiatAccountsObservableList() {
return fiatAccounts;
}
}

View File

@ -1,49 +0,0 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.util;
import org.bitcoinj.core.Utils;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DSAKeyUtil {
private static final Logger log = LoggerFactory.getLogger(DSAKeyUtil.class);
public static String getHexStringFromPublicKey(PublicKey publicKey) {
final X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey.getEncoded());
return Utils.HEX.encode(x509EncodedKeySpec.getEncoded());
}
public static KeyPair generateDSAKeyPair() {
try {
final KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
keyGen.initialize(1024);
return keyGen.genKeyPair();
} catch (NoSuchAlgorithmException e) {
log.error(e.toString());
}
return null;
}
}

View File

@ -0,0 +1,120 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.util;
import org.bitcoinj.core.Utils;
import org.bitcoinj.utils.Threading;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.concurrent.locks.ReentrantLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FileUtil {
private static final Logger log = LoggerFactory.getLogger(FileUtil.class);
private static final ReentrantLock lock = Threading.lock("FileUtil");
public static void write(Serializable serializable, File dir, File storageFile) throws IOException {
lock.lock();
File tempFile = null;
FileOutputStream fileOutputStream = null;
ObjectOutputStream objectOutputStream = null;
try {
if (!dir.exists())
dir.mkdir();
tempFile = File.createTempFile("temp", null, dir);
// Don't use auto closeable resources in try() as we would need too many try/catch clauses (for tempFile)
// and we need to close it
// manually before replacing file with temp file
fileOutputStream = new FileOutputStream(tempFile);
objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(serializable);
// Attempt to force the bits to hit the disk. In reality the OS or hard disk itself may still decide
// to not write through to physical media for at least a few seconds, but this is the best we can do.
fileOutputStream.flush();
fileOutputStream.getFD().sync();
// Close resources before replacing file with temp file because otherwise it causes problems on windows
// when rename temp file
fileOutputStream.close();
objectOutputStream.close();
writeTempFileToFile(tempFile, storageFile);
} finally {
if (tempFile != null && tempFile.exists()) {
log.warn("Temp file still exists after failed save.");
if (!tempFile.delete()) log.error("Cannot delete temp file.");
}
try {
if (objectOutputStream != null)
objectOutputStream.close();
if (fileOutputStream != null)
fileOutputStream.close();
} catch (IOException e) {
// We swallow that
e.printStackTrace();
log.error("Cannot close resources.");
}
lock.unlock();
}
}
public static Object read(File file) throws IOException, ClassNotFoundException {
lock.lock();
try (final FileInputStream fileInputStream = new FileInputStream(file);
final ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream)) {
return objectInputStream.readObject();
} finally {
lock.unlock();
}
}
private static void writeTempFileToFile(File tempFile, File file) throws IOException {
lock.lock();
try {
if (Utils.isWindows()) {
// Work around an issue on Windows whereby you can't rename over existing files.
final File canonical = file.getCanonicalFile();
if (canonical.exists() && !canonical.delete()) {
throw new IOException("Failed to delete canonical file for replacement with save");
}
if (!tempFile.renameTo(canonical)) {
throw new IOException("Failed to rename " + tempFile + " to " + canonical);
}
}
else if (!tempFile.renameTo(file)) {
throw new IOException("Failed to rename " + tempFile + " to " + file);
}
} finally {
lock.unlock();
}
}
}

View File

@ -17,6 +17,8 @@
package io.bitsquare.util;
import org.bitcoinj.core.Utils;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@ -35,6 +37,9 @@ import java.io.Serializable;
import java.net.URI;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.function.Function;
import javafx.animation.AnimationTimer;
@ -289,4 +294,9 @@ public class Utilities {
animationTimer.start();
return animationTimer;
}
public static String getHexStringFromPublicKey(PublicKey publicKey) {
final X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey.getEncoded());
return Utils.HEX.encode(x509EncodedKeySpec.getEncoded());
}
}

View File

@ -36,7 +36,7 @@ public class EncryptionServiceTests {
@Test
public void testEncryptionWithMailboxMessage() throws Exception {
EncryptionService<MailboxMessage> encryptionService = new EncryptionService<>();
KeyPair p2pEncryptKeyPair = encryptionService.getKeyPair();
KeyPair p2pEncryptKeyPair = encryptionService.getGeneratedRSAKeyPair();
TestMessage message = new TestMessage("test");
EncryptionPackage encryptionPackage = encryptionService.encryptObject(p2pEncryptKeyPair.getPublic(), message);
@ -47,7 +47,7 @@ public class EncryptionServiceTests {
@Test
public void testEncryptionWithInteger() throws Exception {
EncryptionService<Integer> encryptionService = new EncryptionService<>();
KeyPair p2pEncryptKeyPair = encryptionService.getKeyPair();
KeyPair p2pEncryptKeyPair = encryptionService.getGeneratedRSAKeyPair();
int data = 1234;
EncryptionPackage encryptionPackage = encryptionService.encryptObject(p2pEncryptKeyPair.getPublic(), data);
Integer result = encryptionService.decryptToObject(p2pEncryptKeyPair.getPrivate(), encryptionPackage);
@ -57,7 +57,7 @@ public class EncryptionServiceTests {
@Test
public void testEncryptionWithBytes() throws Exception {
EncryptionService encryptionService = new EncryptionService();
KeyPair p2pEncryptKeyPair = encryptionService.getKeyPair();
KeyPair p2pEncryptKeyPair = encryptionService.getGeneratedRSAKeyPair();
byte[] data = new byte[]{0x00, 0x01, 0x02, 0x03, 0x04};
EncryptionPackage encryptionPackage = encryptionService.encrypt(p2pEncryptKeyPair.getPublic(), data);
@ -68,7 +68,7 @@ public class EncryptionServiceTests {
@Test
public void testEncryptionWithLargeData() throws Exception {
EncryptionService encryptionService = new EncryptionService();
KeyPair p2pEncryptKeyPair = encryptionService.getKeyPair();
KeyPair p2pEncryptKeyPair = encryptionService.getGeneratedRSAKeyPair();
byte[] data = new byte[2000];
new Random().nextBytes(data);

View File

@ -18,26 +18,26 @@
package io.bitsquare.trade.protocol.placeoffer;
import io.bitsquare.arbitration.Arbitrator;
import io.bitsquare.fiat.FiatAccountType;
import io.bitsquare.btc.BitcoinNetwork;
import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.UserAgent;
import io.bitsquare.btc.WalletService;
import io.bitsquare.crypto.EncryptionService;
import io.bitsquare.fiat.FiatAccountType;
import io.bitsquare.locale.CountryUtil;
import io.bitsquare.locale.LanguageUtil;
import io.bitsquare.p2p.BootstrapState;
import io.bitsquare.p2p.Node;
import io.bitsquare.p2p.tomp2p.BootstrappedPeerBuilder;
import io.bitsquare.p2p.tomp2p.TomP2PNode;
import io.bitsquare.offer.Direction;
import io.bitsquare.offer.Offer;
import io.bitsquare.offer.OfferBookService;
import io.bitsquare.offer.tomp2p.TomP2POfferBookService;
import io.bitsquare.persistence.Persistence;
import io.bitsquare.p2p.BootstrapState;
import io.bitsquare.p2p.MessageService;
import io.bitsquare.p2p.Node;
import io.bitsquare.p2p.tomp2p.BootstrappedPeerBuilder;
import io.bitsquare.p2p.tomp2p.TomP2PMessageService;
import io.bitsquare.p2p.tomp2p.TomP2PNode;
import io.bitsquare.persistence.Persistence;
import io.bitsquare.user.User;
import io.bitsquare.util.DSAKeyUtil;
import org.bitcoinj.core.Address;
import org.bitcoinj.core.Coin;
@ -46,6 +46,8 @@ import org.bitcoinj.utils.Threading;
import java.io.File;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Currency;
import java.util.concurrent.CountDownLatch;
@ -93,7 +95,11 @@ public class PlaceOfferProtocolTest {
// messageService
Node bootstrapNode = Node.at("localhost", "127.0.0.1");
User user = new User();
user.applyPersistedUser(null);
/* try {
user.initPersistedObject();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}*/
bootstrappedPeerBuilder = new BootstrappedPeerBuilder(Node.DEFAULT_PORT, false, bootstrapNode, "<unspecified>");
tomP2PNode = new TomP2PNode(bootstrappedPeerBuilder);
messageService = new TomP2PMessageService(tomP2PNode, null, null, null);
@ -119,6 +125,7 @@ public class PlaceOfferProtocolTest {
new FeePolicy(BitcoinNetwork.REGTEST),
null,
persistence,
null,
new UserAgent("", ""),
dir,
"Tests"
@ -294,9 +301,9 @@ public class PlaceOfferProtocolTest {
faultHandler);
}*/
private Offer getOffer() {
private Offer getOffer() throws NoSuchAlgorithmException {
return new Offer(OFFER_ID,
DSAKeyUtil.generateDSAKeyPair().getPublic(),
new EncryptionService().getGeneratedDSAKeyPair().getPublic(),
Direction.BUY,
100L,
Coin.CENT,

17
pom.xml
View File

@ -93,23 +93,6 @@
</repositories>
<dependencies>
<dependency>
<groupId>org.bitcoinj</groupId>
<artifactId>bitcoinj-core</artifactId>
<version>0.13.d13665c-SNAPSHOT</version>
</dependency>
<!-- <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.7.7</version>
</dependency>-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>16.0.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>