This commit is contained in:
Manfred Karrer 2015-03-25 21:00:09 +01:00
parent 312807a6ef
commit afe64bea4d
75 changed files with 406 additions and 347 deletions

View File

@ -73,7 +73,7 @@ public class BitsquareApp extends Application {
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) ->
Popups.handleUncaughtExceptions(Throwables.getRootCause(throwable)));

View File

@ -61,10 +61,10 @@ class BitsquareAppModule extends BitsquareModule {
File storageDir = new File(env.getRequiredProperty(Storage.DIR_KEY));
bind(File.class).annotatedWith(named(Storage.DIR_KEY)).toInstance(storageDir);
bind(Environment.class).toInstance(env);
bind(UpdateProcess.class).in(Singleton.class);
install(networkModule());
install(bitcoinModule());
install(cryptoModule());

View File

@ -134,8 +134,8 @@ public class BitsquareEnvironment extends StandardEnvironment {
setProperty(WalletService.DIR_KEY, appDataDir);
setProperty(WalletService.PREFIX_KEY, appName);
setProperty(Storage.DIR_KEY, Paths.get(appDataDir, "db").toString());
setProperty(Storage.DIR_KEY, Paths.get(appDataDir, "db").toString());
setProperty(MainView.TITLE_KEY, appName);
}});
}

View File

@ -42,6 +42,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ArbitrationRepository implements Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(ArbitrationRepository.class);
@ -91,13 +92,6 @@ public class ArbitrationRepository implements Serializable {
allArbitratorsSynced = false;
}
/* private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
allArbitratorsObservableList = FXCollections.observableArrayList(allArbitrators);
}
*/
// Is called when all services are ready
public void loadAllArbitrators() {
log.debug("loadAllArbitrators");

View File

@ -29,6 +29,7 @@ import java.util.List;
import java.util.Objects;
public class Arbitrator implements Serializable {
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
@ -108,34 +109,12 @@ public class Arbitrator implements Serializable {
this.idVerifications = idVerifications;
this.webUrl = webUrl;
this.description = description;
Arbitrator persisted = storage.initAndGetPersisted(this);
if (persisted != null) {
id = persisted.getId();
pubKey = persisted.getPubKey();
p2pSigPubKey = persisted.getP2pSigPubKey();
name = persisted.getName();
idType = persisted.getIdType();
languageCodes = persisted.getLanguageCodes();
reputation = persisted.getReputation();
fee = persisted.getFee();
arbitrationMethods = persisted.getArbitrationMethods();
idVerifications = persisted.getIdVerifications();
webUrl = persisted.getWebUrl();
description = persisted.getDescription();
}
else {
// TODO mock
save();
}
}
public void save() {
storage.save();
}
@Override
public int hashCode() {
if (id != null) {

View File

@ -25,7 +25,8 @@ import java.io.Serializable;
* Reputation for Arbitrators
*/
public class Reputation implements Serializable {
private static final long serialVersionUID = -3073174320050879490L;
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
//TODO
public Reputation() {

View File

@ -28,7 +28,8 @@ import java.io.Serializable;
* Registration, trade and arbiter deposit.
*/
public class AddressEntry implements Serializable {
private static final long serialVersionUID = 5501603992599920416L;
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
private final String offerId;
private final Context context;

View File

@ -32,6 +32,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AddressEntryList extends ArrayList<AddressEntry> implements Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(AddressEntryList.class);
@ -79,7 +80,7 @@ public class AddressEntryList extends ArrayList<AddressEntry> implements Seriali
public AddressEntry getRegistrationAddressEntry() {
if (isEmpty())
createRegistrationAddressEntry();
return get(0);
}
}

View File

@ -24,6 +24,7 @@ import java.util.Arrays;
import java.util.Collection;
public class ViewPath extends ArrayList<Class<? extends View>> implements Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
public ViewPath() {

View File

@ -19,13 +19,17 @@ package io.bitsquare.crypto;
import java.io.Serializable;
public class EncryptionPackage implements Serializable {
private static final long serialVersionUID = -8709538217388076762L;
import javax.annotation.concurrent.Immutable;
@Immutable
public class Bucket implements Serializable {
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
public final byte[] encryptedKey;
public final byte[] encryptedPayload;
public EncryptionPackage(byte[] encryptedKey, byte[] encryptedPayload) {
public Bucket(byte[] encryptedKey, byte[] encryptedPayload) {
this.encryptedKey = encryptedKey;
this.encryptedPayload = encryptedPayload;
}

View File

@ -66,17 +66,17 @@ public class EncryptionService<T> {
return keyPairGenerator.genKeyPair();
}
public EncryptionPackage encryptObject(PublicKey publicKey, Object object) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException,
public Bucket encryptObject(PublicKey publicKey, Object object) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException,
NoSuchAlgorithmException, NoSuchPaddingException {
return encrypt(publicKey, Utilities.objectToBytArray(object));
}
public T decryptToObject(PrivateKey privateKey, EncryptionPackage encryptionPackage) throws IllegalBlockSizeException, InvalidKeyException,
public T decryptToObject(PrivateKey privateKey, Bucket bucket) throws IllegalBlockSizeException, InvalidKeyException,
BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
return (T) Utilities.byteArrayToObject(decrypt(privateKey, encryptionPackage));
return (T) Utilities.byteArrayToObject(decrypt(privateKey, bucket));
}
public EncryptionPackage encrypt(PublicKey publicKey, byte[] payload) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
public Bucket encrypt(PublicKey publicKey, byte[] payload) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
BadPaddingException, IllegalBlockSizeException {
// Create symmetric key and
KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGO_SYM);
@ -95,13 +95,13 @@ public class EncryptionService<T> {
cipherSym.init(Cipher.ENCRYPT_MODE, keySpec);
log.debug("encrypt payload length: " + payload.length);
byte[] encryptedPayload = cipherSym.doFinal(payload);
return new EncryptionPackage(encryptedKey, encryptedPayload);
return new Bucket(encryptedKey, encryptedPayload);
}
public byte[] decrypt(PrivateKey privateKey, EncryptionPackage encryptionPackage) throws NoSuchPaddingException, NoSuchAlgorithmException,
public byte[] decrypt(PrivateKey privateKey, Bucket bucket) throws NoSuchPaddingException, NoSuchAlgorithmException,
InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
byte[] encryptedPayload = encryptionPackage.encryptedPayload;
byte[] encryptedKey = encryptionPackage.encryptedKey;
byte[] encryptedPayload = bucket.encryptedPayload;
byte[] encryptedKey = bucket.encryptedKey;
// Decrypt secretKey key with asymmetric key
Cipher cipherAsym = Cipher.getInstance(CIPHER_ASYM);

View File

@ -27,7 +27,8 @@ import javax.annotation.concurrent.Immutable;
@Immutable
public class FiatAccount implements Serializable {
private static final long serialVersionUID = 1792577576443221268L;
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
private final FiatAccountType fiatAccountType;
private final String accountPrimaryID; // like IBAN

View File

@ -35,6 +35,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Navigation implements Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(Navigation.class);

View File

@ -159,7 +159,6 @@ textfield */
-fx-progress-color: dimgrey;
}
/*******************************************************************************
* *
* Table *
@ -185,6 +184,7 @@ textfield */
.table-view:focused {
/*-fx-background-color: transparent;*/
}
.table-view:focused {
-fx-background-color: -fx-box-border, -fx-control-inner-background;
-fx-background-insets: 0, 1;
@ -231,7 +231,6 @@ textfield */
-fx-fill: black;
}
/*******************************************************************************
* *
* Icons *
@ -251,7 +250,6 @@ textfield */
-fx-text-fill: #666666;
}
/*******************************************************************************
* *
* Tab pane *
@ -274,7 +272,6 @@ textfield */
-fx-background-color: transparent;
}
#form-header-text {
-fx-font-weight: bold;
-fx-font-size: 14;
@ -283,6 +280,7 @@ textfield */
#form-title {
-fx-font-weight: bold;
}
/* scroll-pane */
.scroll-pane {

View File

@ -110,7 +110,7 @@ class MainViewModel implements ViewModel {
updateProcess.state.addListener((observableValue, oldValue, newValue) -> applyUpdateState(newValue));
applyUpdateState(updateProcess.state.get());
currentBankAccount.bind(user.currentFiatAccountProperty());
currentBankAccount.bind(user.currentFiatAccountPropertyProperty());
user.fiatAccountsObservableList().addListener((ListChangeListener<FiatAccount>) change -> {
bankAccountsComboBoxDisable.set(change.getList().isEmpty());
bankAccountsComboBoxPrompt.set(change.getList().isEmpty() ? "No accounts" : "");
@ -301,7 +301,7 @@ class MainViewModel implements ViewModel {
}
public void setCurrentBankAccount(FiatAccount currentFiatAccount) {
user.setCurrentFiatAccount(currentFiatAccount);
user.setCurrentFiatAccountProperty(currentFiatAccount);
}
private void updateNumPendingTrades() {

View File

@ -81,7 +81,7 @@ public class BrowserView extends ActivatableView<Pane, Void> implements Arbitrat
@Override
public void onAllArbitratorsLoaded(Map<String, Arbitrator> arbitratorsMap) {
}
/*
@Override

View File

@ -59,7 +59,7 @@ public class ArbitratorProfileView extends AbstractView {
nameLabel.setText(name);
nameTextField.setText(arbitrator.getName());
// languagesTextField.setText(formatter.languageLocalesToString(arbitrator.getLanguages()));
// languagesTextField.setText(formatter.languageLocalesToString(arbitrator.getLanguages()));
reputationTextField.setText(arbitrator.getReputation().toString());
feeTextField.setText(String.valueOf(arbitrator.getFee() + " BTC"));
methodsTextField.setText(formatter.arbitrationMethodsToString(arbitrator.getArbitrationMethods()));

View File

@ -260,7 +260,7 @@ public class ArbitratorRegistrationView extends ActivatableView<AnchorPane, Void
arbitratorService.addArbitrator(arbitrator,
() -> {
// log.debug("arbitrator added successfully " + arbitratorService.getAllArbitrators().size());
// log.debug("arbitrator added successfully " + arbitratorService.getAllArbitrators().size());
},
(errorMessage -> log.error(errorMessage)));
}

View File

@ -96,7 +96,7 @@ class FiatAccountDataModel implements Activatable, DataModel {
}
void removeBankAccount() {
user.removeFiatAccount(user.currentFiatAccountProperty().get());
user.removeFiatAccount(user.currentFiatAccountPropertyProperty().get());
allFiatAccounts.setAll(user.fiatAccountsObservableList());
reset();
}
@ -109,7 +109,7 @@ class FiatAccountDataModel implements Activatable, DataModel {
}
void selectBankAccount(FiatAccount fiatAccount) {
user.setCurrentFiatAccount(fiatAccount);
user.setCurrentFiatAccountProperty(fiatAccount);
if (fiatAccount != null) {
title.set(fiatAccount.getNameOfBank());

View File

@ -145,7 +145,7 @@ class FiatAccountViewModel extends ActivatableWithDataModel<FiatAccountDataModel
@Override
public String toString(String currencyCode) {
return currencyCode+ " (" + CurrencyUtil.getDisplayName(currencyCode) + ")";
return currencyCode + " (" + CurrencyUtil.getDisplayName(currencyCode) + ")";
}

View File

@ -102,7 +102,7 @@ public class IrcAccountView extends ActivatableViewAndModel<GridPane, IrcAccount
setGraphic(null);
}
else {
setText(currencyCode+ " (" + CurrencyUtil.getDisplayName(currencyCode) + ")");
setText(currencyCode + " (" + CurrencyUtil.getDisplayName(currencyCode) + ")");
if (!currencyCode.equals("EUR")) {
setOpacity(0.3);

View File

@ -44,8 +44,8 @@ import io.bitsquare.trade.protocol.trade.offerer.tasks.VerifyTakerAccount;
import io.bitsquare.trade.protocol.trade.taker.TakerAsSellerProtocol;
import io.bitsquare.trade.protocol.trade.taker.tasks.CreateAndSignContract;
import io.bitsquare.trade.protocol.trade.taker.tasks.CreateTakeOfferFeeTx;
import io.bitsquare.trade.protocol.trade.taker.tasks.ProcessFiatTransferStartedMessage;
import io.bitsquare.trade.protocol.trade.taker.tasks.ProcessDepositTxPublishedMessage;
import io.bitsquare.trade.protocol.trade.taker.tasks.ProcessFiatTransferStartedMessage;
import io.bitsquare.trade.protocol.trade.taker.tasks.ProcessRequestTakerDepositPaymentMessage;
import io.bitsquare.trade.protocol.trade.taker.tasks.SendPayoutTxToOfferer;
import io.bitsquare.trade.protocol.trade.taker.tasks.SendRequestDepositTxInputsMessage;

View File

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

View File

@ -316,9 +316,9 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
.languageCodesToString(dataModel.acceptedLanguageCodes)));
dataModel.acceptedArbitrators.addListener((Observable o) ->
acceptedArbitrators.set(formatter.arbitratorsToNames(dataModel.acceptedArbitrators)));
dataModel.acceptedArbitrators.addListener((Observable o) ->
acceptedArbitrators.set(formatter.arbitratorsToNames(dataModel.acceptedArbitrators)));
}
private void setupBindings() {

View File

@ -98,17 +98,17 @@ class OfferBookDataModel implements Activatable, DataModel {
volumeAsFiat.set(null);
offerBook.addClient();
user.currentFiatAccountProperty().addListener(bankAccountChangeListener);
user.currentFiatAccountPropertyProperty().addListener(bankAccountChangeListener);
btcCode.bind(preferences.btcDenominationProperty());
setBankAccount(user.currentFiatAccountProperty().get());
setBankAccount(user.currentFiatAccountPropertyProperty().get());
applyFilter();
}
@Override
public void deactivate() {
offerBook.removeClient();
user.currentFiatAccountProperty().removeListener(bankAccountChangeListener);
user.currentFiatAccountPropertyProperty().removeListener(bankAccountChangeListener);
btcCode.unbind();
}
@ -148,7 +148,7 @@ class OfferBookDataModel implements Activatable, DataModel {
boolean isTradable(Offer offer) {
// if user has not registered yet we display all
FiatAccount currentFiatAccount = user.currentFiatAccountProperty().get();
FiatAccount currentFiatAccount = user.currentFiatAccountPropertyProperty().get();
if (currentFiatAccount == null)
return true;
@ -158,7 +158,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.currentFiatAccountProperty().get().getCountry()
"\n\nThe country of your payments account (" + user.currentFiatAccountPropertyProperty().get().getCountry()
.getName() +
") is not included in that list." +
"\n\n Do you want to edit your preferences now?");

View File

@ -79,12 +79,12 @@ public class BSFormatter {
@Inject
public BSFormatter(User user, ArbitrationRepository arbitrationRepository) {
this.arbitrationRepository = arbitrationRepository;
if (user.currentFiatAccountProperty().get() == null)
if (user.currentFiatAccountPropertyProperty().get() == null)
setFiatCurrencyCode(CurrencyUtil.getDefaultCurrencyAsCode());
else if (user.currentFiatAccountProperty().get() != null)
setFiatCurrencyCode(user.currentFiatAccountProperty().get().getCurrencyCode());
else if (user.currentFiatAccountPropertyProperty().get() != null)
setFiatCurrencyCode(user.currentFiatAccountPropertyProperty().get().getCurrencyCode());
user.currentFiatAccountProperty().addListener((ov, oldValue, newValue) -> {
user.currentFiatAccountPropertyProperty().addListener((ov, oldValue, newValue) -> {
if (newValue != null)
setFiatCurrencyCode(newValue.getCurrencyCode());
});

View File

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

View File

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

View File

@ -21,8 +21,12 @@ import java.io.Serializable;
import java.util.Objects;
import javax.annotation.concurrent.Immutable;
@Immutable
public class Country implements Serializable {
private static final long serialVersionUID = -5930294199097793187L;
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
private final String code;
private final String name;

View File

@ -86,7 +86,7 @@ public class CountryUtil {
return new Country(locale.getCountry(), locale.getDisplayCountry(), region);
}
private static List<Country> getAllCountries() {
final List<Country> allCountries = new ArrayList<>();
for (final Locale locale : getAllCountryLocales()) {

View File

@ -21,8 +21,12 @@ import java.io.Serializable;
import java.util.Objects;
import javax.annotation.concurrent.Immutable;
@Immutable
public class Region implements Serializable {
private static final long serialVersionUID = -5930294199097793187L;
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
private final String code;
private final String name;

View File

@ -25,6 +25,7 @@ import org.bitcoinj.core.Coin;
import org.bitcoinj.utils.ExchangeRate;
import org.bitcoinj.utils.Fiat;
import java.io.IOException;
import java.io.Serializable;
import java.security.PublicKey;
@ -41,7 +42,8 @@ import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.*;
public class Offer implements Serializable {
private static final long serialVersionUID = -971164804305475826L;
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
private transient static final Logger log = LoggerFactory.getLogger(Offer.class);
public enum Direction {BUY, SELL}
@ -55,10 +57,11 @@ public class Offer implements Serializable {
FAULT
}
// key attributes for lookup
private final String id;
private final Direction direction;
private final String currencyCode;
private final String id;
private final Date creationDate;
//TODO check with latest bitcoinJ version
@ -66,7 +69,6 @@ public class Offer implements Serializable {
private final long fiatPrice;
private final Coin amount;
private final Coin minAmount;
//TODO use hex string
private final PublicKey p2pSigPubKey;
private final FiatAccountType fiatAccountType;
private final Country bankAccountCountry;
@ -79,11 +81,11 @@ public class Offer implements Serializable {
// Mutable property. Has to be set before offer is save in DHT as it changes the objects hash!
private String offerFeePaymentTxID;
private State state;
private State state = State.UNKNOWN;
// Those state properties are transient and only used at runtime!
// don't access directly as it might be null; use getStateProperty() which creates an object if not instantiated
transient private ObjectProperty<State> stateProperty = new SimpleObjectProperty<>(State.UNKNOWN);
transient private ObjectProperty<State> stateProperty = new SimpleObjectProperty<>(state);
///////////////////////////////////////////////////////////////////////////////////////////
@ -124,6 +126,54 @@ public class Offer implements Serializable {
setState(State.UNKNOWN);
}
// Serialized object does not create our transient objects
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
stateProperty = new SimpleObjectProperty<>(state);
}
public void validate() throws Exception {
checkNotNull(getAcceptedCountries(), "AcceptedCountries is null");
checkNotNull(getAcceptedLanguageCodes(), "AcceptedLanguageLocales is null");
checkNotNull(getAmount(), "Amount is null");
checkNotNull(getArbitratorIds(), "Arbitrator is null");
checkNotNull(getBankAccountId(), "BankAccountId is null");
checkNotNull(getSecurityDeposit(), "SecurityDeposit is null");
checkNotNull(getCreationDate(), "CreationDate is null");
checkNotNull(getCurrencyCode(), "Currency is null");
checkNotNull(getDirection(), "Direction is null");
checkNotNull(getId(), "Id is null");
checkNotNull(getP2PSigPubKey(), "p2pSigPubKey is null");
checkNotNull(getMinAmount(), "MinAmount is null");
checkNotNull(getPrice(), "Price is null");
checkArgument(getMinAmount().compareTo(Restrictions.MIN_TRADE_AMOUNT) >= 0, "MinAmount is less then " + Restrictions.MIN_TRADE_AMOUNT
.toFriendlyString());
checkArgument(getAmount().compareTo(Restrictions.MAX_TRADE_AMOUNT) <= 0, "Amount is larger then " + Restrictions.MAX_TRADE_AMOUNT.toFriendlyString());
checkArgument(getAmount().compareTo(getMinAmount()) >= 0, "MinAmount is larger then Amount");
checkArgument(getSecurityDeposit().compareTo(Restrictions.MIN_SECURITY_DEPOSIT) >= 0,
"SecurityDeposit is less then " + Restrictions.MIN_SECURITY_DEPOSIT.toFriendlyString());
checkArgument(getPrice().isPositive(), "Price is not a positive value");
// TODO check upper and lower bounds for fiat
}
public Fiat getVolumeByAmount(Coin amount) {
if (fiatPrice != 0 && amount != null && !amount.isZero())
return new ExchangeRate(Fiat.valueOf(currencyCode, fiatPrice)).coinToFiat(amount);
else
return null;
}
public Fiat getOfferVolume() {
return getVolumeByAmount(amount);
}
public Fiat getMinOfferVolume() {
return getVolumeByAmount(minAmount);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
@ -138,6 +188,7 @@ public class Offer implements Serializable {
this.offerFeePaymentTxID = offerFeePaymentTxID;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
@ -186,21 +237,6 @@ public class Offer implements Serializable {
return acceptedLanguageCodes;
}
public Fiat getVolumeByAmount(Coin amount) {
if (fiatPrice != 0 && amount != null && !amount.isZero())
return new ExchangeRate(Fiat.valueOf(currencyCode, fiatPrice)).coinToFiat(amount);
else
return null;
}
public Fiat getOfferVolume() {
return getVolumeByAmount(amount);
}
public Fiat getMinOfferVolume() {
return getVolumeByAmount(minAmount);
}
public String getOfferFeePaymentTxID() {
return offerFeePaymentTxID;
}
@ -230,57 +266,30 @@ public class Offer implements Serializable {
}
public ObjectProperty<State> stateProperty() {
if (stateProperty == null)
stateProperty = new SimpleObjectProperty<>(state);
return stateProperty;
}
public void validate() throws Exception {
checkNotNull(getAcceptedCountries(), "AcceptedCountries is null");
checkNotNull(getAcceptedLanguageCodes(), "AcceptedLanguageLocales is null");
checkNotNull(getAmount(), "Amount is null");
checkNotNull(getArbitratorIds(), "Arbitrator is null");
checkNotNull(getBankAccountId(), "BankAccountId is null");
checkNotNull(getSecurityDeposit(), "SecurityDeposit is null");
checkNotNull(getCreationDate(), "CreationDate is null");
checkNotNull(getCurrencyCode(), "Currency is null");
checkNotNull(getDirection(), "Direction is null");
checkNotNull(getId(), "Id is null");
checkNotNull(getP2PSigPubKey(), "p2pSigPubKey is null");
checkNotNull(getMinAmount(), "MinAmount is null");
checkNotNull(getPrice(), "Price is null");
checkArgument(getMinAmount().compareTo(Restrictions.MIN_TRADE_AMOUNT) >= 0, "MinAmount is less then " + Restrictions.MIN_TRADE_AMOUNT
.toFriendlyString());
checkArgument(getAmount().compareTo(Restrictions.MAX_TRADE_AMOUNT) <= 0, "Amount is larger then " + Restrictions.MAX_TRADE_AMOUNT.toFriendlyString());
checkArgument(getAmount().compareTo(getMinAmount()) >= 0, "MinAmount is larger then Amount");
checkArgument(getSecurityDeposit().compareTo(Restrictions.MIN_SECURITY_DEPOSIT) >= 0,
"SecurityDeposit is less then " + Restrictions.MIN_SECURITY_DEPOSIT.toFriendlyString());
checkArgument(getPrice().isPositive(), "Price is not a positive value");
// TODO check upper and lower bounds for fiat
}
@Override
public String toString() {
return "Offer{" +
"id='" + id + '\'' +
", state=" + state +
", direction=" + direction +
", currency=" + currencyCode +
", currencyCode='" + currencyCode + '\'' +
", creationDate=" + creationDate +
", fiatPrice=" + fiatPrice +
", amount=" + amount +
", minAmount=" + minAmount +
", p2pSigPubKey=" + p2pSigPubKey +
", fiatAccountType=" + fiatAccountType +
", bankAccountCountry=" + bankAccountCountry +
", securityDeposit=" + securityDeposit +
", acceptedCountries=" + acceptedCountries +
", acceptedLanguageLocales=" + acceptedLanguageCodes +
", acceptedLanguageCodes=" + acceptedLanguageCodes +
", bankAccountUID='" + bankAccountUID + '\'' +
", arbitrators=" + arbitratorIds +
", arbitratorIds=" + arbitratorIds +
", offerFeePaymentTxID='" + offerFeePaymentTxID + '\'' +
", state=" + state +
", stateProperty=" + stateProperty +
'}';
}
}

View File

@ -150,14 +150,14 @@ public class OfferBook {
private void addListeners() {
log.debug("addListeners ");
user.currentFiatAccountProperty().addListener(bankAccountChangeListener);
user.currentFiatAccountPropertyProperty().addListener(bankAccountChangeListener);
offerBookService.addListener(offerBookServiceListener);
offerBookService.invalidationTimestampProperty().addListener(invalidationListener);
}
private void removeListeners() {
log.debug("removeListeners ");
user.currentFiatAccountProperty().removeListener(bankAccountChangeListener);
user.currentFiatAccountPropertyProperty().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.currentFiatAccountProperty().get());
setBankAccount(user.currentFiatAccountPropertyProperty().get());
pollingTimer = Utilities.setInterval(POLLING_INTERVAL, (animationTimer) -> {
offerBookService.requestInvalidationTimeStampFromDHT(fiatCode);
return null;

View File

@ -30,11 +30,10 @@ public abstract class OfferModule extends BitsquareModule {
}
@Override
protected final void configure()
{
protected final void configure() {
bind(OfferBook.class).in(Singleton.class);
bind(OfferBook.class).in(Singleton.class);
doConfigure();
}

View File

@ -179,7 +179,7 @@ public class TomP2POfferBookService extends TomP2PDHTService implements OfferBoo
} catch (IOException e) {
e.printStackTrace();
}
offers.add((Offer) offerDataObject);
}
} catch (ClassNotFoundException | IOException e) {

View File

@ -22,6 +22,6 @@ import io.bitsquare.p2p.listener.GetPeerAddressListener;
import java.security.PublicKey;
public interface AddressService extends DHTService{
public interface AddressService extends DHTService {
void findPeerAddress(PublicKey p2pSigPubKey, GetPeerAddressListener getPeerAddressListener);
}

View File

@ -17,7 +17,7 @@
package io.bitsquare.p2p;
import io.bitsquare.crypto.EncryptionPackage;
import io.bitsquare.crypto.Bucket;
import java.io.Serializable;
@ -31,13 +31,13 @@ public class EncryptedMailboxMessage implements MailboxMessage, Serializable {
private static final long serialVersionUID = -3111178895546299769L;
private static final Logger log = LoggerFactory.getLogger(EncryptedMailboxMessage.class);
private EncryptionPackage encryptionPackage;
private Bucket bucket;
public EncryptedMailboxMessage(EncryptionPackage encryptionPackage) {
this.encryptionPackage = encryptionPackage;
public EncryptedMailboxMessage(Bucket bucket) {
this.bucket = bucket;
}
public EncryptionPackage getEncryptionPackage() {
return encryptionPackage;
public Bucket getBucket() {
return bucket;
}
}

View File

@ -24,7 +24,7 @@ import java.security.PublicKey;
public interface MailboxService {
void addMessage(PublicKey p2pSigPubKey, EncryptedMailboxMessage message, ResultHandler resultHandler, FaultHandler faultHandler);
void getAllMessages(PublicKey p2pSigPubKey, MailboxMessagesResultHandler resultHandler);
void removeAllMessages(PublicKey p2pSigPubKey, ResultHandler resultHandler, FaultHandler faultHandler);

View File

@ -19,7 +19,7 @@ package io.bitsquare.p2p;
import java.util.concurrent.Executor;
public interface P2PService {
public interface P2PService {
void bootstrapCompleted();
void setExecutor(Executor executor);

View File

@ -17,7 +17,7 @@
package io.bitsquare.p2p.tomp2p;
import io.bitsquare.crypto.EncryptionPackage;
import io.bitsquare.crypto.Bucket;
import io.bitsquare.crypto.EncryptionService;
import io.bitsquare.p2p.EncryptedMailboxMessage;
import io.bitsquare.p2p.MailboxMessage;
@ -121,15 +121,15 @@ public class TomP2PMessageService extends TomP2PService implements MessageServic
}
private void sendMailboxMessage(PublicKey p2pSigPubKey, PublicKey p2pEncryptPubKey, MailboxMessage message, SendMessageListener listener) {
EncryptionPackage encryptionPackage = null;
Bucket bucket = null;
try {
encryptionPackage = encryptionService.encryptObject(p2pEncryptPubKey, message);
bucket = encryptionService.encryptObject(p2pEncryptPubKey, message);
} catch (Throwable t) {
t.printStackTrace();
log.error(t.getMessage());
executor.execute(listener::handleFault);
}
EncryptedMailboxMessage encrypted = new EncryptedMailboxMessage(encryptionPackage);
EncryptedMailboxMessage encrypted = new EncryptedMailboxMessage(bucket);
mailboxService.addMessage(p2pSigPubKey,
encrypted,
() -> {

View File

@ -49,13 +49,13 @@ public class TomP2PModule extends P2PModule {
// Used both ClientNode and TomP2PNode for injection
bind(ClientNode.class).to(TomP2PNode.class).in(Singleton.class);
bind(TomP2PNode.class).in(Singleton.class);
bind(BootstrappedPeerBuilder.class).in(Singleton.class);
bind(AddressService.class).to(TomP2PAddressService.class).in(Singleton.class);
bind(MessageService.class).to(TomP2PMessageService.class).in(Singleton.class);
bind(MailboxService.class).to(TomP2PMailboxService.class).in(Singleton.class);
bind(int.class).annotatedWith(Names.named(Node.PORT_KEY)).toInstance(env.getProperty(Node.PORT_KEY, int.class, Node.DEFAULT_PORT));
bind(boolean.class).annotatedWith(Names.named(USE_MANUAL_PORT_FORWARDING_KEY)).toInstance(
env.getProperty(USE_MANUAL_PORT_FORWARDING_KEY, boolean.class, false));

View File

@ -23,6 +23,8 @@ import com.google.common.base.Objects;
import java.io.Serializable;
import javax.annotation.concurrent.Immutable;
import net.tomp2p.peers.PeerAddress;
/**
@ -30,9 +32,10 @@ import net.tomp2p.peers.PeerAddress;
*
* @author Chris Beams
*/
@Immutable
public class TomP2PPeer implements Peer, Serializable {
private static final long serialVersionUID = -2022551056208230853L;
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
private final PeerAddress peerAddress;

View File

@ -27,11 +27,12 @@ import java.io.Serializable;
import java.security.PublicKey;
//TODO flatten down?
// TODO The relation Offer, Trade and Contract need to be reviewed and might be changed
import javax.annotation.concurrent.Immutable;
@Immutable
public class Contract implements Serializable {
private static final long serialVersionUID = 71472356206100158L;
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
private final Offer offer;
private final String takeOfferFeeTxID;

View File

@ -26,10 +26,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OffererTrade extends Trade implements Serializable {
private static final long serialVersionUID = 1;
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(OffererTrade.class);
public OffererTrade(Offer offer) {
super(offer);
}

View File

@ -26,8 +26,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TakerTrade extends Trade implements Serializable {
private static final long serialVersionUID = 1;
transient private static final Logger log = LoggerFactory.getLogger(TakerTrade.class);
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(TakerTrade.class);
public TakerTrade(Offer offer) {
super(offer);

View File

@ -32,6 +32,7 @@ import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.io.IOException;
import java.io.Serializable;
import java.util.Date;
@ -43,15 +44,17 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Trade implements Serializable {
protected static final long serialVersionUID = 1;
protected static final Logger log = LoggerFactory.getLogger(Trade.class);
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
transient protected static final Logger log = LoggerFactory.getLogger(Trade.class);
///////////////////////////////////////////////////////////////////////////////////////////
// Enum
///////////////////////////////////////////////////////////////////////////////////////////
public static enum LifeCycleState {
public enum LifeCycleState {
OPEN_OFFER,
CANCELED,
PENDING,
@ -59,7 +62,7 @@ public class Trade implements Serializable {
FAILED
}
public static enum ProcessState {
public enum ProcessState {
INIT,
TAKE_OFFER_FEE_PUBLISH_FAILED,
TAKE_OFFER_FEE_TX_CREATED,
@ -105,10 +108,10 @@ public class Trade implements Serializable {
// For changing values we use properties to get binding support in the UI (table)
// When serialized those transient properties are not instantiated, so we instantiate them in the getters at first
// access. Only use the accessor not the protected field.
transient protected ObjectProperty<Coin> _tradeAmount;
transient protected ObjectProperty<Fiat> _tradeVolume;
transient protected ObjectProperty<ProcessState> _processState;
transient protected ObjectProperty<LifeCycleState> _lifeCycleState;
transient protected ObjectProperty<Coin> tradeAmountProperty;
transient protected ObjectProperty<Fiat> tradeVolumeProperty;
transient protected ObjectProperty<ProcessState> processStateProperty;
transient protected ObjectProperty<LifeCycleState> lifeCycleStateProperty;
///////////////////////////////////////////////////////////////////////////////////////////
@ -123,10 +126,26 @@ public class Trade implements Serializable {
log.debug("Trade ");
}
// Serialized object does not create our transient objects
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
tradeAmountProperty = new SimpleObjectProperty<>(tradeAmount);
tradeVolumeProperty = new SimpleObjectProperty<>(getTradeVolume());
processStateProperty = new SimpleObjectProperty<>(processState);
lifeCycleStateProperty = new SimpleObjectProperty<>(lifeCycleState);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Methods
// Protocol
///////////////////////////////////////////////////////////////////////////////////////////
public void setProtocol(Protocol protocol) {
this.protocol = protocol;
if (mailboxMessage != null)
protocol.setMailboxMessage(mailboxMessage);
}
public void disposeProtocol() {
if (protocol != null)
@ -140,19 +159,11 @@ public class Trade implements Serializable {
protocol.setMailboxMessage(mailboxMessage);
}
public void setProtocol(Protocol protocol) {
this.protocol = protocol;
if (mailboxMessage != null)
protocol.setMailboxMessage(mailboxMessage);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
public void setTradingPeer(Peer tradingPeer) {
this.tradingPeer = tradingPeer;
}
@ -206,6 +217,7 @@ public class Trade implements Serializable {
lifeCycleStateProperty().set(lifeCycleState);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
@ -262,34 +274,20 @@ public class Trade implements Serializable {
return tradingPeer;
}
// When serialized those transient properties are not instantiated, so we need to instantiate them at first access
public ObjectProperty<Coin> tradeAmountProperty() {
if (_tradeAmount == null)
_tradeAmount = new SimpleObjectProperty<>(tradeAmount);
return _tradeAmount;
return tradeAmountProperty;
}
public ObjectProperty<Fiat> tradeVolumeProperty() {
if (_tradeVolume == null)
_tradeVolume = new SimpleObjectProperty<>(getTradeVolume());
return _tradeVolume;
return tradeVolumeProperty;
}
public ObjectProperty<ProcessState> processStateProperty() {
if (_processState == null)
_processState = new SimpleObjectProperty<>(processState);
return _processState;
return processStateProperty;
}
public ObjectProperty<LifeCycleState> lifeCycleStateProperty() {
if (_lifeCycleState == null)
_lifeCycleState = new SimpleObjectProperty<>(lifeCycleState);
return _lifeCycleState;
return lifeCycleStateProperty;
}

View File

@ -31,11 +31,19 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TradeList<T> extends ArrayList<T> implements Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(TradeList.class);
transient final private Storage<TradeList> storage;
transient private ObservableList<T> observableList;
// Superclass is ArrayList, which will be persisted
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
public TradeList(File storageDir, String fileName) {
this.storage = new Storage<>(storageDir);
@ -43,11 +51,8 @@ public class TradeList<T> extends ArrayList<T> implements Serializable {
TradeList persisted = storage.initAndGetPersisted(this, fileName);
if (persisted != null) {
this.addAll(persisted);
observableList = FXCollections.observableArrayList(this);
}
else {
observableList = FXCollections.observableArrayList(this);
}
observableList = FXCollections.observableArrayList(this);
}
@Override

View File

@ -165,7 +165,7 @@ public class TradeManager {
TransactionResultHandler resultHandler,
ErrorMessageHandler errorMessageHandler) {
FiatAccount currentFiatAccount = user.currentFiatAccountProperty().get();
FiatAccount currentFiatAccount = user.currentFiatAccountPropertyProperty().get();
Offer offer = new Offer(id,
user.getP2PSigPubKey(),
direction,
@ -469,7 +469,7 @@ public class TradeManager {
log.trace("applyMailboxMessage encryptedMailboxMessage.size=" + encryptedMailboxMessages.size());
for (EncryptedMailboxMessage encrypted : encryptedMailboxMessages) {
try {
MailboxMessage mailboxMessage = encryptionService.decryptToObject(user.getP2pEncryptPrivateKey(), encrypted.getEncryptionPackage());
MailboxMessage mailboxMessage = encryptionService.decryptToObject(user.getP2pEncryptPrivateKey(), encrypted.getBucket());
if (mailboxMessage instanceof TradeMessage) {
String tradeId = ((TradeMessage) mailboxMessage).tradeId;

View File

@ -18,10 +18,10 @@
package io.bitsquare.trade.protocol.availability;
import io.bitsquare.common.taskrunner.SharedTaskModel;
import io.bitsquare.offer.Offer;
import io.bitsquare.p2p.AddressService;
import io.bitsquare.p2p.MessageService;
import io.bitsquare.p2p.Peer;
import io.bitsquare.offer.Offer;
import io.bitsquare.trade.protocol.trade.messages.OfferMessage;
import org.slf4j.Logger;

View File

@ -67,7 +67,7 @@ public class CheckOfferAvailabilityProtocol {
public void checkOfferAvailability() {
// reset
model.offer.setState(Offer.State.UNKNOWN);
model.messageService.addMessageHandler(messageHandler);
taskRunner = new TaskRunner<>(model,

View File

@ -22,12 +22,13 @@ import io.bitsquare.trade.protocol.trade.messages.OfferMessage;
import java.io.Serializable;
public class ReportOfferAvailabilityMessage extends OfferMessage implements Serializable {
private static final long serialVersionUID = 6177387534187739018L;
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
public final boolean isOfferOpen;
public ReportOfferAvailabilityMessage(String offerId, boolean isOfferOpen) {
super.offerId = offerId;
super(offerId);
this.isOfferOpen = isOfferOpen;
}
}

View File

@ -22,11 +22,10 @@ import io.bitsquare.trade.protocol.trade.messages.TradeMessage;
import java.io.Serializable;
public class RequestIsOfferAvailableMessage extends TradeMessage implements Serializable {
private static final long serialVersionUID = 4630151440192191798L;
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
public RequestIsOfferAvailableMessage(String tradeId) {
super.tradeId = tradeId;
super(tradeId);
}
}

View File

@ -19,9 +19,9 @@ package io.bitsquare.trade.protocol.availability.tasks;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.offer.Offer;
import io.bitsquare.p2p.Peer;
import io.bitsquare.p2p.listener.GetPeerAddressListener;
import io.bitsquare.offer.Offer;
import io.bitsquare.trade.protocol.availability.CheckOfferAvailabilityModel;
import org.slf4j.Logger;

View File

@ -19,8 +19,8 @@ package io.bitsquare.trade.protocol.availability.tasks;
import io.bitsquare.common.taskrunner.Task;
import io.bitsquare.common.taskrunner.TaskRunner;
import io.bitsquare.p2p.listener.SendMessageListener;
import io.bitsquare.offer.Offer;
import io.bitsquare.p2p.listener.SendMessageListener;
import io.bitsquare.trade.protocol.availability.CheckOfferAvailabilityModel;
import io.bitsquare.trade.protocol.availability.messages.RequestIsOfferAvailableMessage;

View File

@ -35,7 +35,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SharedTradeModel extends SharedTaskModel implements Serializable {
private static final long serialVersionUID = -2523252022571497157L;
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
protected static final Logger log = LoggerFactory.getLogger(SharedTradeModel.class);
transient public MailboxMessage mailboxMessage;

View File

@ -23,13 +23,17 @@ import org.bitcoinj.core.Transaction;
import java.io.Serializable;
import javax.annotation.concurrent.Immutable;
@Immutable
public class DepositTxPublishedMessage extends TradeMessage implements MailboxMessage, Serializable {
private static final long serialVersionUID = -1532231540167406581L;
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
public final Transaction depositTx;
public DepositTxPublishedMessage(String tradeId, Transaction depositTx) {
this.tradeId = tradeId;
super(tradeId);
this.depositTx = depositTx;
}
}

View File

@ -23,8 +23,12 @@ import org.bitcoinj.core.Coin;
import java.io.Serializable;
import javax.annotation.concurrent.Immutable;
@Immutable
public class FiatTransferStartedMessage extends TradeMessage implements MailboxMessage, Serializable {
private static final long serialVersionUID = -3479634129543632523L;
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
public final byte[] offererSignature;
public final Coin offererPayoutAmount;
@ -36,7 +40,7 @@ public class FiatTransferStartedMessage extends TradeMessage implements MailboxM
Coin offererPayoutAmount,
Coin takerPayoutAmount,
String offererPayoutAddress) {
this.tradeId = tradeId;
super(tradeId);
this.offererSignature = offererSignature;
this.offererPayoutAmount = offererPayoutAmount;
this.takerPayoutAmount = takerPayoutAmount;

View File

@ -21,8 +21,16 @@ import io.bitsquare.p2p.Message;
import java.io.Serializable;
public abstract class OfferMessage implements Message, Serializable {
private static final long serialVersionUID = -89035992124170905L;
import javax.annotation.concurrent.Immutable;
public String offerId;
@Immutable
public abstract class OfferMessage implements Message, Serializable {
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
public final String offerId;
public OfferMessage(String offerId) {
this.offerId = offerId;
}
}

View File

@ -23,13 +23,17 @@ import org.bitcoinj.core.Transaction;
import java.io.Serializable;
import javax.annotation.concurrent.Immutable;
@Immutable
public class PayoutTxPublishedMessage extends TradeMessage implements MailboxMessage, Serializable {
private static final long serialVersionUID = 1288653559218403873L;
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
public final Transaction payoutTx;
public PayoutTxPublishedMessage(String tradeId, Transaction payoutTx) {
this.tradeId = tradeId;
super(tradeId);
this.payoutTx = payoutTx;
}

View File

@ -21,15 +21,19 @@ import org.bitcoinj.core.Coin;
import java.io.Serializable;
import javax.annotation.concurrent.Immutable;
@Immutable
public class RequestDepositTxInputsMessage extends TradeMessage implements Serializable {
private static final long serialVersionUID = -5057935061275354312L;
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
public final Coin tradeAmount;
public final String takeOfferFeeTxId;
public final byte[] takerTradeWalletPubKey;
public RequestDepositTxInputsMessage(String tradeId, String takeOfferFeeTxId, Coin tradeAmount, byte[] takerTradeWalletPubKey) {
this.tradeId = tradeId;
super(tradeId);
this.takeOfferFeeTxId = takeOfferFeeTxId;
this.tradeAmount = tradeAmount;
this.takerTradeWalletPubKey = takerTradeWalletPubKey;

View File

@ -28,8 +28,12 @@ import java.security.PublicKey;
import java.util.List;
import javax.annotation.concurrent.Immutable;
@Immutable
public class RequestOffererPublishDepositTxMessage extends TradeMessage implements Serializable {
private static final long serialVersionUID = 2179683654379803071L;
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
public final FiatAccount takerFiatAccount;
public final String takerAccountId;
@ -53,7 +57,7 @@ public class RequestOffererPublishDepositTxMessage extends TradeMessage implemen
Transaction takersPreparedDepositTx,
List<TransactionOutput> takerConnectedOutputsForAllInputs,
List<TransactionOutput> takerOutputs) {
this.tradeId = tradeId;
super(tradeId);
this.takerFiatAccount = takerFiatAccount;
this.takerAccountId = takerAccountId;
this.takerP2PSigPublicKey = takerP2PSigPublicKey;

View File

@ -27,16 +27,18 @@ import java.security.PublicKey;
import java.util.List;
import javax.annotation.concurrent.Immutable;
@Immutable
public class RequestTakerDepositPaymentMessage extends TradeMessage implements Serializable {
private static final long serialVersionUID = -3988720410493712913L;
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
public final List<TransactionOutput> offererConnectedOutputsForAllInputs;
public final List<TransactionOutput> offererOutputs;
public final byte[] offererTradeWalletPubKey;
public final PublicKey offererP2PSigPublicKey;
public final PublicKey offererP2PEncryptPublicKey;
public final FiatAccount offererFiatAccount;
public final String offererAccountId;
@ -48,9 +50,9 @@ public class RequestTakerDepositPaymentMessage extends TradeMessage implements S
PublicKey offererP2PEncryptPublicKey,
FiatAccount offererFiatAccount,
String offererAccountId) {
super(tradeId);
this.offererP2PSigPublicKey = offererP2PSigPublicKey;
this.offererP2PEncryptPublicKey = offererP2PEncryptPublicKey;
this.tradeId = tradeId;
this.offererConnectedOutputsForAllInputs = offererConnectedOutputsForAllInputs;
this.offererOutputs = offererOutputs;
this.offererTradeWalletPubKey = offererTradeWalletPubKey;

View File

@ -21,8 +21,16 @@ import io.bitsquare.p2p.Message;
import java.io.Serializable;
public abstract class TradeMessage implements Message, Serializable {
private static final long serialVersionUID = 7572470983485004081L;
import javax.annotation.concurrent.Immutable;
public String tradeId;
@Immutable
public abstract class TradeMessage implements Message, Serializable {
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = 1L;
public final String tradeId;
public TradeMessage(String tradeId) {
this.tradeId = tradeId;
}
}

View File

@ -133,7 +133,7 @@ public class OffererAsBuyerProtocol implements Protocol {
checkTradeId(model.id, tradeMessage);
model.setTradeMessage(tradeMessage);
model.trade.setTradingPeer(taker);
TaskRunner<OffererAsBuyerModel> taskRunner = new TaskRunner<>(model,
() -> log.debug("taskRunner at handleTakeOfferFeePayedMessage completed"),
(errorMessage) -> handleTaskRunnerFault(errorMessage));

View File

@ -31,7 +31,8 @@ import java.security.PublicKey;
import java.util.List;
public class Offerer implements Serializable {
private static final long serialVersionUID = -1845177552607819927L;
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
// Those fields are set at constructor but not declared as final because constructor is not called in case model gets created from a persisted model
// Declared transient as they will be provided in any case at construction time

View File

@ -35,7 +35,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OffererAsBuyerModel extends SharedTradeModel implements Serializable {
private static final long serialVersionUID = 5000457153390911569L;
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(OffererAsBuyerModel.class);
transient private Storage<OffererAsBuyerModel> storage;

View File

@ -30,7 +30,8 @@ import java.security.PublicKey;
import java.util.List;
public class Taker implements Serializable {
private static final long serialVersionUID = 2660909397210346486L;
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
// written by tasks
public String accountId;

View File

@ -29,7 +29,8 @@ import java.security.PublicKey;
import java.util.List;
public class Offerer implements Serializable {
private static final long serialVersionUID = 1582902150121576205L;
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
// written by tasks
public byte[] tradeWalletPubKey;

View File

@ -32,7 +32,8 @@ import java.security.PublicKey;
import java.util.List;
public class Taker implements Serializable {
private static long serialVersionUID = -4041809885931756860L;
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
// Those fields are set at constructor but not declared as final because constructor is not called in case model gets created from a persisted model
// Declared transient as they will be provided in any case at construction time

View File

@ -37,7 +37,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TakerAsSellerModel extends SharedTradeModel implements Serializable {
private static final long serialVersionUID = -963501132927618376L;
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(TakerAsSellerModel.class);
transient private Storage<TakerAsSellerModel> storage;

View File

@ -36,21 +36,21 @@ public class SendPayoutTxToOfferer extends Task<TakerAsSellerModel> {
@Override
protected void doRun() {
PayoutTxPublishedMessage tradeMessage = new PayoutTxPublishedMessage(model.id, model.getPayoutTx());
model.messageService.sendMessage(model.trade.getTradingPeer(),
model.messageService.sendMessage(model.trade.getTradingPeer(),
tradeMessage,
model.offerer.p2pSigPublicKey,
model.offerer.p2pEncryptPubKey,
new SendMessageListener() {
@Override
public void handleResult() {
log.trace("PayoutTxPublishedMessage successfully arrived at peer");
complete();
}
@Override
public void handleResult() {
log.trace("PayoutTxPublishedMessage successfully arrived at peer");
complete();
}
@Override
public void handleFault() {
failed("Sending PayoutTxPublishedMessage failed.");
}
});
@Override
public void handleFault() {
failed("Sending PayoutTxPublishedMessage failed.");
}
});
}
}

View File

@ -37,6 +37,7 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
public class AccountSettings implements Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
transient private Storage<AccountSettings> storage;
@ -52,7 +53,7 @@ public class AccountSettings implements Serializable {
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public AccountSettings(Storage<AccountSettings> storage, ArbitrationRepository arbitrationRepository) {
public AccountSettings(Storage<AccountSettings> storage, ArbitrationRepository arbitrationRepository) {
this.storage = storage;
AccountSettings persisted = storage.initAndGetPersisted(this);

View File

@ -37,7 +37,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Preferences implements Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization.
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
@ -50,15 +52,15 @@ public class Preferences implements Serializable {
transient private final Storage<Preferences> storage;
// Persisted fields
private String _btcDenomination = MonetaryFormat.CODE_BTC;
private Boolean _useAnimations = true;
private Boolean _useEffects = true;
private String btcDenomination = MonetaryFormat.CODE_BTC;
private Boolean useAnimations = true;
private Boolean useEffects = true;
private Boolean displaySecurityDepositInfo = 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);
transient private final StringProperty btcDenominationProperty = new SimpleStringProperty(btcDenomination);
transient private final BooleanProperty useAnimationsProperty = new SimpleBooleanProperty(useAnimations);
transient private final BooleanProperty useEffectsProperty = new SimpleBooleanProperty(useEffects);
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
@ -70,23 +72,23 @@ public class Preferences implements Serializable {
Preferences persisted = storage.initAndGetPersisted(this);
if (persisted != null) {
setBtcDenomination(persisted._btcDenomination);
setUseAnimations(persisted._useAnimations);
setUseEffects(persisted._useEffects);
setBtcDenomination(persisted.btcDenomination);
setUseAnimations(persisted.useAnimations);
setUseEffects(persisted.useEffects);
displaySecurityDepositInfo = persisted.getDisplaySecurityDepositInfo();
}
// 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();
btcDenominationProperty.addListener((ov) -> {
btcDenomination = btcDenominationProperty.get();
storage.save();
});
useAnimations.addListener((ov) -> {
_useAnimations = useAnimations.get();
useAnimationsProperty.addListener((ov) -> {
useAnimations = useAnimationsProperty.get();
storage.save();
});
useEffects.addListener((ov) -> {
_useEffects = useEffects.get();
useEffectsProperty.addListener((ov) -> {
useEffects = useEffectsProperty.get();
storage.save();
});
}
@ -96,16 +98,16 @@ public class Preferences implements Serializable {
// Setter
///////////////////////////////////////////////////////////////////////////////////////////
public void setBtcDenomination(String btcDenomination) {
this.btcDenomination.set(btcDenomination);
public void setBtcDenomination(String btcDenominationProperty) {
this.btcDenominationProperty.set(btcDenominationProperty);
}
public void setUseAnimations(boolean useAnimations) {
this.useAnimations.set(useAnimations);
public void setUseAnimations(boolean useAnimationsProperty) {
this.useAnimationsProperty.set(useAnimationsProperty);
}
public void setUseEffects(boolean useEffects) {
this.useEffects.set(useEffects);
public void setUseEffects(boolean useEffectsProperty) {
this.useEffectsProperty.set(useEffectsProperty);
}
public void setDisplaySecurityDepositInfo(Boolean displaySecurityDepositInfo) {
@ -119,15 +121,15 @@ public class Preferences implements Serializable {
///////////////////////////////////////////////////////////////////////////////////////////
public String getBtcDenomination() {
return btcDenomination.get();
return btcDenominationProperty.get();
}
public boolean getUseEffects() {
return useEffects.get();
return useEffectsProperty.get();
}
public boolean getUseAnimations() {
return useAnimations.get();
return useAnimationsProperty.get();
}
public Boolean getDisplaySecurityDepositInfo() {
@ -135,15 +137,15 @@ public class Preferences implements Serializable {
}
public StringProperty btcDenominationProperty() {
return btcDenomination;
return btcDenominationProperty;
}
public BooleanProperty useAnimationsProperty() {
return useAnimations;
return useAnimationsProperty;
}
public BooleanProperty useEffectsProperty() {
return useEffects;
public BooleanProperty useEffectsPropertyProperty() {
return useEffectsProperty;
}

View File

@ -50,7 +50,9 @@ import org.slf4j.LoggerFactory;
* It must never be transmitted over the wire (messageKeyPair contains private key!).
*/
public class User implements Serializable {
// That object is saved to disc. We need to take care of changes to not break deserialization.
private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(User.class);
transient private Storage<User> storage;
@ -60,12 +62,12 @@ public class User implements Serializable {
private KeyPair p2pSigKeyPair;
private KeyPair p2pEncryptKeyPair;
private String accountID;
private List<FiatAccount> _fiatAccounts = new ArrayList<>();
private FiatAccount _currentFiatAccount;
private List<FiatAccount> fiatAccounts = new ArrayList<>();
private FiatAccount currentFiatAccount;
// Observable wrappers
transient private final ObservableList<FiatAccount> fiatAccounts = FXCollections.observableArrayList();
transient private final ObjectProperty<FiatAccount> currentFiatAccount = new SimpleObjectProperty<>();
transient private ObservableList<FiatAccount> fiatAccountsObservableList = FXCollections.observableArrayList(fiatAccounts);
transient private ObjectProperty<FiatAccount> currentFiatAccountProperty = new SimpleObjectProperty<>(currentFiatAccount);
@Inject
public User(Storage<User> storage, EncryptionService encryptionService) {
@ -78,11 +80,11 @@ public class User implements Serializable {
p2pEncryptKeyPair = persisted.getP2pEncryptKeyPair();
accountID = persisted.getAccountId();
_fiatAccounts = new ArrayList<>(persisted.getFiatAccounts());
fiatAccounts.setAll(_fiatAccounts);
fiatAccounts = new ArrayList<>(persisted.getFiatAccounts());
fiatAccountsObservableList.setAll(fiatAccounts);
_currentFiatAccount = persisted.getCurrentFiatAccount();
currentFiatAccount.set(_currentFiatAccount);
currentFiatAccount = persisted.getCurrentFiatAccount();
currentFiatAccountProperty.set(currentFiatAccount);
}
else {
// First time we create key pairs
@ -97,12 +99,12 @@ public class User implements Serializable {
}
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);
fiatAccountsObservableList.addListener((ListChangeListener<FiatAccount>) change -> {
fiatAccounts = new ArrayList<>(fiatAccountsObservableList);
storage.save();
});
currentFiatAccount.addListener((ov) -> {
_currentFiatAccount = currentFiatAccount.get();
currentFiatAccountProperty.addListener((ov) -> {
currentFiatAccount = currentFiatAccountProperty.get();
storage.save();
});
}
@ -110,7 +112,7 @@ public class User implements Serializable {
// for unit tests
public User() {
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public Methods
@ -121,23 +123,23 @@ public class User implements Serializable {
* @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))
if (fiatAccountsObservableList.contains(fiatAccount))
return false;
fiatAccounts.add(fiatAccount);
setCurrentFiatAccount(fiatAccount);
fiatAccountsObservableList.add(fiatAccount);
setCurrentFiatAccountProperty(fiatAccount);
return true;
}
// In case we edit an existing we remove the existing first
public void removeFiatAccount(FiatAccount fiatAccount) {
fiatAccounts.remove(fiatAccount);
fiatAccountsObservableList.remove(fiatAccount);
if (_currentFiatAccount.equals(fiatAccount)) {
if (fiatAccounts.isEmpty())
setCurrentFiatAccount(null);
if (currentFiatAccount.equals(fiatAccount)) {
if (fiatAccountsObservableList.isEmpty())
setCurrentFiatAccountProperty(null);
else
setCurrentFiatAccount(fiatAccounts.get(0));
setCurrentFiatAccountProperty(fiatAccountsObservableList.get(0));
}
}
@ -153,8 +155,8 @@ public class User implements Serializable {
storage.save();
}
public void setCurrentFiatAccount(@Nullable FiatAccount fiatAccount) {
currentFiatAccount.set(fiatAccount);
public void setCurrentFiatAccountProperty(@Nullable FiatAccount fiatAccount) {
currentFiatAccountProperty.set(fiatAccount);
}
@ -165,17 +167,27 @@ public class User implements Serializable {
// TODO just a first attempt, refine when working on the embedded data for the reg. tx
public String getStringifiedBankAccounts() {
String bankAccountUIDs = "";
for (int i = 0; i < fiatAccounts.size(); i++) {
FiatAccount fiatAccount = fiatAccounts.get(i);
for (int i = 0; i < fiatAccountsObservableList.size(); i++) {
FiatAccount fiatAccount = fiatAccountsObservableList.get(i);
bankAccountUIDs += fiatAccount.toString();
if (i < fiatAccounts.size() - 1) {
if (i < fiatAccountsObservableList.size() - 1) {
bankAccountUIDs += ", ";
}
}
return bankAccountUIDs;
}
public FiatAccount getFiatAccount(String fiatAccountId) {
for (FiatAccount fiatAccount : fiatAccountsObservableList) {
if (fiatAccount.getId().equals(fiatAccountId)) {
return fiatAccount;
}
}
return null;
}
public String getAccountId() {
return accountID;
}
@ -184,15 +196,6 @@ public class User implements Serializable {
return getAccountId() != null;
}
public FiatAccount getFiatAccount(String fiatAccountId) {
for (FiatAccount fiatAccount : fiatAccounts) {
if (fiatAccount.getId().equals(fiatAccountId)) {
return fiatAccount;
}
}
return null;
}
public KeyPair getP2pSigKeyPair() {
return p2pSigKeyPair;
}
@ -214,19 +217,19 @@ public class User implements Serializable {
}
private List<FiatAccount> getFiatAccounts() {
return _fiatAccounts;
}
private FiatAccount getCurrentFiatAccount() {
return _currentFiatAccount;
}
public ObjectProperty<FiatAccount> currentFiatAccountProperty() {
return currentFiatAccount;
}
public ObservableList<FiatAccount> fiatAccountsObservableList() {
return fiatAccounts;
}
private FiatAccount getCurrentFiatAccount() {
return currentFiatAccount;
}
public ObjectProperty<FiatAccount> currentFiatAccountPropertyProperty() {
return currentFiatAccountProperty;
}
public ObservableList<FiatAccount> fiatAccountsObservableList() {
return fiatAccountsObservableList;
}
}

View File

@ -39,8 +39,8 @@ public class EncryptionServiceTests {
KeyPair p2pEncryptKeyPair = encryptionService.getGeneratedRSAKeyPair();
TestMessage message = new TestMessage("test");
EncryptionPackage encryptionPackage = encryptionService.encryptObject(p2pEncryptKeyPair.getPublic(), message);
MailboxMessage result = encryptionService.decryptToObject(p2pEncryptKeyPair.getPrivate(), encryptionPackage);
Bucket bucket = encryptionService.encryptObject(p2pEncryptKeyPair.getPublic(), message);
MailboxMessage result = encryptionService.decryptToObject(p2pEncryptKeyPair.getPrivate(), bucket);
assertEquals("", message.data, ((TestMessage) result).data);
}
@ -49,8 +49,8 @@ public class EncryptionServiceTests {
EncryptionService<Integer> encryptionService = new EncryptionService<>();
KeyPair p2pEncryptKeyPair = encryptionService.getGeneratedRSAKeyPair();
int data = 1234;
EncryptionPackage encryptionPackage = encryptionService.encryptObject(p2pEncryptKeyPair.getPublic(), data);
Integer result = encryptionService.decryptToObject(p2pEncryptKeyPair.getPrivate(), encryptionPackage);
Bucket bucket = encryptionService.encryptObject(p2pEncryptKeyPair.getPublic(), data);
Integer result = encryptionService.decryptToObject(p2pEncryptKeyPair.getPrivate(), bucket);
assertEquals("", data, result);
}
@ -60,8 +60,8 @@ public class EncryptionServiceTests {
KeyPair p2pEncryptKeyPair = encryptionService.getGeneratedRSAKeyPair();
byte[] data = new byte[]{0x00, 0x01, 0x02, 0x03, 0x04};
EncryptionPackage encryptionPackage = encryptionService.encrypt(p2pEncryptKeyPair.getPublic(), data);
byte[] result = encryptionService.decrypt(p2pEncryptKeyPair.getPrivate(), encryptionPackage);
Bucket bucket = encryptionService.encrypt(p2pEncryptKeyPair.getPublic(), data);
byte[] result = encryptionService.decrypt(p2pEncryptKeyPair.getPrivate(), bucket);
assertEquals("", result, data);
}
@ -73,8 +73,8 @@ public class EncryptionServiceTests {
byte[] data = new byte[2000];
new Random().nextBytes(data);
EncryptionPackage encryptionPackage = encryptionService.encrypt(p2pEncryptKeyPair.getPublic(), data);
byte[] result = encryptionService.decrypt(p2pEncryptKeyPair.getPrivate(), encryptionPackage);
Bucket bucket = encryptionService.encrypt(p2pEncryptKeyPair.getPublic(), data);
byte[] result = encryptionService.decrypt(p2pEncryptKeyPair.getPrivate(), bucket);
assertEquals("", result, data);
}
}