Add default arbitrator

This commit is contained in:
Manfred Karrer 2015-03-25 20:03:19 +01:00
parent 486c83efaa
commit 312807a6ef
25 changed files with 399 additions and 192 deletions

View file

@ -0,0 +1,132 @@
/*
* 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.arbitration;
import io.bitsquare.locale.LanguageUtil;
import io.bitsquare.storage.Storage;
import io.bitsquare.util.DSAKeyUtil;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Utils;
import com.google.inject.Inject;
import java.io.Serializable;
import java.security.PublicKey;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javafx.collections.FXCollections;
import javafx.collections.MapChangeListener;
import javafx.collections.ObservableMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ArbitrationRepository implements Serializable {
private static final long serialVersionUID = 1L;
transient private static final Logger log = LoggerFactory.getLogger(ArbitrationRepository.class);
transient private Storage<ArbitrationRepository> storage;
transient private ArbitratorService arbitratorService;
transient private Arbitrator defaultArbitrator;
// Persisted fields
private final Map<String, Arbitrator> arbitratorsMap = new HashMap<>();
transient private final ObservableMap<String, Arbitrator> arbitratorsObservableMap = FXCollections.observableHashMap();
transient private boolean allArbitratorsSynced;
@Inject
public ArbitrationRepository(Storage<ArbitrationRepository> storage,
Storage<Arbitrator> arbitratorStorage,
ArbitratorService arbitratorService) {
this.storage = storage;
this.arbitratorService = arbitratorService;
byte[] walletPubKey = Utils.HEX.decode("03a418bf0cb60a35ce217c7f80a2db08a4f5efbe56a0e7602fbc392dea6b63f840");
PublicKey p2pSigPubKey = DSAKeyUtil.decodePubKeyHex
("308201b83082012c06072a8648ce3804013082011f02818100fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c70215009760508f15230bccb292b982a2eb840bf0581cf502818100f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a0381850002818100db47d4cf76e9bfcc0ba1e98c21c19ba45d1440fa2fec732f664dc8fd63e98877e648aac6db8d1035cd640fe5ff2e0030c2f8694ed124e81bd42c5446a1ce5288d5c8b4073d1cd890fe61ee4527f4e3184279f394cb9c2a4e7924cb2e82320a846cc140304eac6d41d4eaebc4d69b92725715497a82890be9f49d348fda20b095");
this.defaultArbitrator = new Arbitrator(arbitratorStorage,
"default-524f-46c0-b96e-de5a11d3475d",
walletPubKey,
p2pSigPubKey,
"Mr. Default",
new Reputation(),
Arbitrator.ID_TYPE.REAL_LIFE_ID,
Arrays.asList(LanguageUtil.getDefaultLanguageLocaleAsCode()),
Coin.parseCoin("0.1"),
Arrays.asList(Arbitrator.METHOD.TLS_NOTARY),
Arrays.asList(Arbitrator.ID_VERIFICATION.PASSPORT),
"https://bitsquare.io",
"Bla bla...");
arbitratorsMap.put(defaultArbitrator.getId(), defaultArbitrator);
ArbitrationRepository persisted = storage.initAndGetPersisted(this);
if (persisted != null) {
arbitratorsMap.putAll(persisted.getArbitratorsMap());
}
arbitratorsObservableMap.putAll(arbitratorsMap);
arbitratorsObservableMap.addListener((MapChangeListener<String, Arbitrator>) change -> storage.save());
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");
arbitratorService.loadAllArbitrators((Map<String, Arbitrator> arbitratorsMap) -> {
log.debug("Arbitrators successful loaded.");
log.debug("arbitratorsMap.size()=" + arbitratorsMap.size());
ArbitrationRepository.this.arbitratorsMap.clear();
ArbitrationRepository.this.arbitratorsMap.put(defaultArbitrator.getId(), defaultArbitrator);
ArbitrationRepository.this.arbitratorsMap.putAll(arbitratorsMap);
ArbitrationRepository.this.arbitratorsObservableMap.clear();
ArbitrationRepository.this.arbitratorsObservableMap.putAll(ArbitrationRepository.this.arbitratorsMap);
allArbitratorsSynced = true;
},
(errorMessage -> log.error(errorMessage)));
}
public Map<String, Arbitrator> getArbitratorsMap() {
return arbitratorsMap;
}
public ObservableMap<String, Arbitrator> getArbitratorsObservableMap() {
return arbitratorsObservableMap;
}
public boolean areAllArbitratorsSynced() {
return allArbitratorsSynced;
}
public Arbitrator getDefaultArbitrator() {
return defaultArbitrator;
}
}

View file

@ -17,23 +17,16 @@
package io.bitsquare.arbitration; package io.bitsquare.arbitration;
import io.bitsquare.locale.LanguageUtil;
import io.bitsquare.storage.Storage; import io.bitsquare.storage.Storage;
import io.bitsquare.user.User;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
import org.bitcoinj.core.ECKey;
import java.io.Serializable; import java.io.Serializable;
import java.security.PublicKey; import java.security.PublicKey;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.UUID;
import javax.inject.Inject;
public class Arbitrator implements Serializable { public class Arbitrator implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -83,22 +76,41 @@ public class Arbitrator implements Serializable {
// editable // editable
private ID_TYPE idType; private ID_TYPE idType;
private List<String> languageCodes; private List<String> languageCodes;
private Coin fee; private Coin fee;
private List<METHOD> arbitrationMethods; private List<METHOD> arbitrationMethods;
private List<ID_VERIFICATION> idVerifications; private List<ID_VERIFICATION> idVerifications;
private String webUrl; private String webUrl;
private String description; private String description;
public Arbitrator(Storage<Arbitrator> storage,
@Inject String id,
public Arbitrator(Storage<Arbitrator> storage, User user) { byte[] pubKey,
PublicKey p2pSigPubKey,
String name,
Reputation reputation,
ID_TYPE idType,
List<String> languageCodes,
Coin fee,
List<METHOD> arbitrationMethods,
List<ID_VERIFICATION> idVerifications,
String webUrl,
String description) {
this.storage = storage; this.storage = storage;
this.id = id;
this.pubKey = pubKey;
this.p2pSigPubKey = p2pSigPubKey;
this.name = name;
this.reputation = reputation;
this.idType = idType;
this.languageCodes = languageCodes;
this.fee = fee;
this.arbitrationMethods = arbitrationMethods;
this.idVerifications = idVerifications;
this.webUrl = webUrl;
this.description = description;
Arbitrator persisted = storage.initAndGetPersisted(this); Arbitrator persisted = storage.initAndGetPersisted(this);
if (persisted != null) { if (persisted != null) {
//TODO for mock arbitrator
id = persisted.getId(); id = persisted.getId();
pubKey = persisted.getPubKey(); pubKey = persisted.getPubKey();
p2pSigPubKey = persisted.getP2pSigPubKey(); p2pSigPubKey = persisted.getP2pSigPubKey();
@ -113,19 +125,8 @@ public class Arbitrator implements Serializable {
description = persisted.getDescription(); description = persisted.getDescription();
} }
else { else {
// Mock // TODO mock
id = UUID.randomUUID().toString();
pubKey = new ECKey().getPubKey();
p2pSigPubKey = user.getP2PSigPubKey();
name = "Mr. Default";
idType = Arbitrator.ID_TYPE.REAL_LIFE_ID;
languageCodes = Arrays.asList(LanguageUtil.getDefaultLanguageLocaleAsCode());
reputation = new Reputation();
fee = Coin.parseCoin("0.1");
arbitrationMethods = Arrays.asList(Arbitrator.METHOD.TLS_NOTARY);
idVerifications = Arrays.asList(ID_VERIFICATION.PASSPORT);
webUrl = "https://bitsquare.io";
description = "Bla bla...";
save(); save();
} }
} }

View file

@ -19,6 +19,8 @@ package io.bitsquare.arbitration;
import io.bitsquare.BitsquareModule; import io.bitsquare.BitsquareModule;
import com.google.inject.Singleton;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
public abstract class ArbitratorModule extends BitsquareModule { public abstract class ArbitratorModule extends BitsquareModule {
@ -29,6 +31,8 @@ public abstract class ArbitratorModule extends BitsquareModule {
@Override @Override
protected final void configure() { protected final void configure() {
bind(ArbitrationRepository.class).in(Singleton.class);
doConfigure(); doConfigure();
} }

View file

@ -18,14 +18,32 @@
package io.bitsquare.arbitration; package io.bitsquare.arbitration;
import io.bitsquare.arbitration.listeners.ArbitratorListener; import io.bitsquare.common.handlers.ErrorMessageHandler;
import io.bitsquare.common.handlers.ResultHandler;
import io.bitsquare.p2p.DHTService; import io.bitsquare.p2p.DHTService;
import java.util.Map;
public interface ArbitratorService extends DHTService { public interface ArbitratorService extends DHTService {
void addArbitrator(Arbitrator arbitrator);
void addArbitratorListener(ArbitratorListener listener); void addListener(Listener listener);
void getArbitrators(String defaultLanguageLocaleCode); void removeListener(Listener listener);
void addArbitrator(Arbitrator arbitrator, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler);
void loadAllArbitrators(ArbitratorMapResultHandler resultHandler, ErrorMessageHandler errorMessageHandler);
interface Listener {
void onArbitratorAdded(Arbitrator arbitrator);
void onAllArbitratorsLoaded(Map<String, Arbitrator> arbitratorsMap);
void onArbitratorRemoved(Arbitrator arbitrator);
}
interface ArbitratorMapResultHandler {
void handleResult(Map<String, Arbitrator> arbitratorsMap);
}
} }

View file

@ -1,31 +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.arbitration.listeners;
import io.bitsquare.arbitration.Arbitrator;
import java.util.List;
// Arbitration is not much developed yet
public interface ArbitratorListener {
void onArbitratorAdded(Arbitrator arbitrator);
void onArbitratorsReceived(List<Arbitrator> arbitrators);
void onArbitratorRemoved(Arbitrator arbitrator);
}

View file

@ -19,15 +19,17 @@ package io.bitsquare.arbitration.tomp2p;
import io.bitsquare.arbitration.Arbitrator; import io.bitsquare.arbitration.Arbitrator;
import io.bitsquare.arbitration.ArbitratorService; import io.bitsquare.arbitration.ArbitratorService;
import io.bitsquare.arbitration.listeners.ArbitratorListener; import io.bitsquare.common.handlers.ErrorMessageHandler;
import io.bitsquare.common.handlers.ResultHandler;
import io.bitsquare.p2p.tomp2p.TomP2PDHTService; import io.bitsquare.p2p.tomp2p.TomP2PDHTService;
import io.bitsquare.p2p.tomp2p.TomP2PNode; import io.bitsquare.p2p.tomp2p.TomP2PNode;
import io.bitsquare.user.User; import io.bitsquare.user.User;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.HashMap;
import java.util.List; import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.inject.Inject; import javax.inject.Inject;
@ -46,53 +48,38 @@ import org.slf4j.LoggerFactory;
public class TomP2PArbitratorService extends TomP2PDHTService implements ArbitratorService { public class TomP2PArbitratorService extends TomP2PDHTService implements ArbitratorService {
private static final Logger log = LoggerFactory.getLogger(TomP2PArbitratorService.class); private static final Logger log = LoggerFactory.getLogger(TomP2PArbitratorService.class);
private static final String ARBITRATORS_ROOT = "ArbitratorsRoot"; private static final Number160 LOCATION_KEY = Number160.createHash("ArbitratorService");
private final List<ArbitratorListener> arbitratorListeners = new ArrayList<>(); private final CopyOnWriteArrayList<Listener> listeners = new CopyOnWriteArrayList<>();
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
public TomP2PArbitratorService(TomP2PNode tomP2PNode, User user) { public TomP2PArbitratorService(TomP2PNode tomP2PNode, User user) {
super(tomP2PNode, user); super(tomP2PNode, user);
} }
public void addArbitrator(Arbitrator arbitrator, ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
///////////////////////////////////////////////////////////////////////////////////////////
// Arbitrators
///////////////////////////////////////////////////////////////////////////////////////////
public void addArbitrator(Arbitrator arbitrator) {
Number160 locationKey = Number160.createHash(ARBITRATORS_ROOT);
try { try {
final Data arbitratorData = new Data(arbitrator); final Data arbitratorData = new Data(arbitrator);
FuturePut addFuture = addProtectedDataToMap(locationKey, arbitratorData); FuturePut addFuture = addProtectedDataToMap(LOCATION_KEY, arbitratorData);
addFuture.addListener(new BaseFutureAdapter<BaseFuture>() { addFuture.addListener(new BaseFutureAdapter<BaseFuture>() {
@Override @Override
public void operationComplete(BaseFuture future) throws Exception { public void operationComplete(BaseFuture future) throws Exception {
executor.execute(() -> arbitratorListeners.stream().forEach(listener ->
{
try {
Object arbitratorDataObject = arbitratorData.object();
if (arbitratorDataObject instanceof Arbitrator) {
listener.onArbitratorAdded((Arbitrator) arbitratorDataObject);
}
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
log.error(e.toString());
}
}));
if (future.isSuccess()) { if (future.isSuccess()) {
log.trace("Add arbitrator to DHT was successful. Stored data: [key: " + locationKey + ", " + log.trace("Add arbitrator to DHT was successful. Stored data: [key: " + LOCATION_KEY + ", " +
"values: " + arbitratorData + "]"); "values: " + arbitratorData + "]");
Object arbitratorDataObject = arbitratorData.object();
if (arbitratorDataObject instanceof Arbitrator) {
Arbitrator result = (Arbitrator) arbitratorDataObject;
executor.execute(() -> {
resultHandler.handleResult();
listeners.stream().forEach(listener -> listener.onArbitratorAdded(result));
});
}
} }
else { else {
log.error("Add arbitrator to DHT failed with reason:" + addFuture.failedReason()); log.error("Add arbitrator to DHT failed with reason:" + addFuture.failedReason());
errorMessageHandler.handleErrorMessage("Add arbitrator to DHT failed with reason:" + addFuture.failedReason());
} }
} }
}); });
@ -102,66 +89,64 @@ public class TomP2PArbitratorService extends TomP2PDHTService implements Arbitra
} }
public void removeArbitrator(Arbitrator arbitrator) throws IOException { public void removeArbitrator(Arbitrator arbitrator) throws IOException {
Number160 locationKey = Number160.createHash(ARBITRATORS_ROOT);
final Data arbitratorData = new Data(arbitrator); final Data arbitratorData = new Data(arbitrator);
FutureRemove removeFuture = removeProtectedDataFromMap(locationKey, arbitratorData); FutureRemove removeFuture = removeProtectedDataFromMap(LOCATION_KEY, arbitratorData);
removeFuture.addListener(new BaseFutureAdapter<BaseFuture>() { removeFuture.addListener(new BaseFutureAdapter<BaseFuture>() {
@Override @Override
public void operationComplete(BaseFuture future) throws Exception { public void operationComplete(BaseFuture future) throws Exception {
executor.execute(() -> arbitratorListeners.stream().forEach(listener -> for (Data arbitratorData : removeFuture.dataMap().values()) {
{ try {
for (Data arbitratorData : removeFuture.dataMap().values()) { Object arbitratorDataObject = arbitratorData.object();
try { if (arbitratorDataObject instanceof Arbitrator) {
Object arbitratorDataObject = arbitratorData.object(); Arbitrator arbitrator = (Arbitrator) arbitratorDataObject;
if (arbitratorDataObject instanceof Arbitrator) { executor.execute(() -> listeners.stream().forEach(listener -> listener.onArbitratorRemoved(arbitrator)));
Arbitrator arbitrator = (Arbitrator) arbitratorDataObject;
listener.onArbitratorRemoved(arbitrator);
}
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
} }
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
} }
})); }
// We don't test futureRemove.isSuccess() as this API does not fit well to that operation, // We don't test futureRemove.isSuccess() as this API does not fit well to that operation,
// it might change in future to something like foundAndRemoved and notFound // it might change in future to something like foundAndRemoved and notFound
// See discussion at: https://github.com/tomp2p/TomP2P/issues/57#issuecomment-62069840 // See discussion at: https://github.com/tomp2p/TomP2P/issues/57#issuecomment-62069840
log.trace("Remove arbitrator from DHT was successful. Stored data: [key: " + locationKey + ", " + log.trace("Remove arbitrator from DHT was successful. Stored data: [key: " + LOCATION_KEY + ", " +
"values: " + arbitratorData + "]"); "values: " + arbitratorData + "]");
} }
}); });
} }
public void getArbitrators(String languageLocaleCode) { public void loadAllArbitrators(ArbitratorMapResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) {
Number160 locationKey = Number160.createHash(ARBITRATORS_ROOT); FutureGet futureGet = getMap(LOCATION_KEY);
FutureGet futureGet = getMap(locationKey);
futureGet.addListener(new BaseFutureAdapter<BaseFuture>() { futureGet.addListener(new BaseFutureAdapter<BaseFuture>() {
@Override @Override
public void operationComplete(BaseFuture future) throws Exception { public void operationComplete(BaseFuture future) throws Exception {
executor.execute(() -> arbitratorListeners.stream().forEach(listener -> if (future.isSuccess()) {
{ log.trace("Get arbitrators from DHT was successful. Stored data: [key: " + LOCATION_KEY + ", " +
List<Arbitrator> arbitrators = new ArrayList<>(); "values: " + futureGet.dataMap() + "]");
final Map<String, Arbitrator> arbitratorsMap = new HashMap<>();
for (Data arbitratorData : futureGet.dataMap().values()) { for (Data arbitratorData : futureGet.dataMap().values()) {
try { try {
Object arbitratorDataObject = arbitratorData.object(); Object arbitratorDataObject = arbitratorData.object();
if (arbitratorDataObject instanceof Arbitrator) { if (arbitratorDataObject instanceof Arbitrator) {
arbitrators.add((Arbitrator) arbitratorDataObject); Arbitrator arbitrator = (Arbitrator) arbitratorDataObject;
arbitratorsMap.put(arbitrator.getId(), arbitrator);
} }
} catch (ClassNotFoundException | IOException e) { } catch (ClassNotFoundException | IOException e) {
e.printStackTrace(); e.printStackTrace();
log.error("Get arbitrators from DHT failed with exception:" + e.getMessage()); log.error("Get arbitrators from DHT failed with exception:" + e.getMessage());
errorMessageHandler.handleErrorMessage("Get arbitrators from DHT failed with exception:" + e.getMessage());
} }
} }
executor.execute(() -> {
listener.onArbitratorsReceived(arbitrators); resultHandler.handleResult(arbitratorsMap);
})); listeners.stream().forEach(listener -> listener.onAllArbitratorsLoaded(arbitratorsMap));
if (future.isSuccess()) { });
log.trace("Get arbitrators from DHT was successful. Stored data: [key: " + locationKey + ", " +
"values: " + futureGet.dataMap() + "]");
} }
else { else {
log.error("Get arbitrators from DHT failed with reason:" + future.failedReason()); log.error("Get arbitrators from DHT failed with reason:" + future.failedReason());
errorMessageHandler.handleErrorMessage("Get arbitrators from DHT failed with reason:" + future.failedReason());
} }
} }
}); });
@ -172,12 +157,12 @@ public class TomP2PArbitratorService extends TomP2PDHTService implements Arbitra
// Event Listeners // Event Listeners
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public void addArbitratorListener(ArbitratorListener listener) { public void addListener(Listener listener) {
arbitratorListeners.add(listener); listeners.add(listener);
} }
public void removeArbitratorListener(ArbitratorListener listener) { public void removeListener(Listener listener) {
arbitratorListeners.remove(listener); listeners.remove(listener);
} }
} }

View file

@ -18,6 +18,7 @@
package io.bitsquare.gui.main; package io.bitsquare.gui.main;
import io.bitsquare.app.UpdateProcess; import io.bitsquare.app.UpdateProcess;
import io.bitsquare.arbitration.ArbitrationRepository;
import io.bitsquare.btc.BitcoinNetwork; import io.bitsquare.btc.BitcoinNetwork;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
import io.bitsquare.common.viewfx.model.ViewModel; import io.bitsquare.common.viewfx.model.ViewModel;
@ -86,17 +87,19 @@ class MainViewModel implements ViewModel {
private final User user; private final User user;
private final WalletService walletService; private final WalletService walletService;
private ArbitrationRepository arbitrationRepository;
private final ClientNode clientNode; private final ClientNode clientNode;
private final TradeManager tradeManager; private final TradeManager tradeManager;
private UpdateProcess updateProcess; private UpdateProcess updateProcess;
private final BSFormatter formatter; private final BSFormatter formatter;
@Inject @Inject
public MainViewModel(User user, WalletService walletService, ClientNode clientNode, public MainViewModel(User user, WalletService walletService, ArbitrationRepository arbitrationRepository, ClientNode clientNode,
TradeManager tradeManager, BitcoinNetwork bitcoinNetwork, UpdateProcess updateProcess, TradeManager tradeManager, BitcoinNetwork bitcoinNetwork, UpdateProcess updateProcess,
BSFormatter formatter) { BSFormatter formatter) {
this.user = user; this.user = user;
this.walletService = walletService; this.walletService = walletService;
this.arbitrationRepository = arbitrationRepository;
this.clientNode = clientNode; this.clientNode = clientNode;
this.tradeManager = tradeManager; this.tradeManager = tradeManager;
this.updateProcess = updateProcess; this.updateProcess = updateProcess;
@ -201,6 +204,10 @@ class MainViewModel implements ViewModel {
user.setAccountID(walletService.getRegistrationAddressEntry().toString()); user.setAccountID(walletService.getRegistrationAddressEntry().toString());
} }
// Load all arbitrators in background. Any class requiring a loaded list of arbitrators need to register itself as listener to handle the async
// operation.
log.debug("loadAllArbitrators");
arbitrationRepository.loadAllArbitrators();
tradeManager.onAllServicesInitialized(); tradeManager.onAllServicesInitialized();
} }

View file

@ -18,7 +18,7 @@
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<AnchorPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.arbitrator.browser.ArbitratorBrowserView" <AnchorPane fx:id="root" fx:controller="io.bitsquare.gui.main.account.arbitrator.browser.BrowserView"
prefHeight="600" prefWidth="800" AnchorPane.bottomAnchor="30.0" AnchorPane.leftAnchor="10.0" prefHeight="600" prefWidth="800" AnchorPane.bottomAnchor="30.0" AnchorPane.leftAnchor="10.0"
AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="10.0"
xmlns:fx="http://javafx.com/fxml"> xmlns:fx="http://javafx.com/fxml">

View file

@ -19,18 +19,17 @@ package io.bitsquare.gui.main.account.arbitrator.browser;
import io.bitsquare.arbitration.Arbitrator; import io.bitsquare.arbitration.Arbitrator;
import io.bitsquare.arbitration.ArbitratorService; import io.bitsquare.arbitration.ArbitratorService;
import io.bitsquare.arbitration.listeners.ArbitratorListener;
import io.bitsquare.common.viewfx.view.ActivatableView; import io.bitsquare.common.viewfx.view.ActivatableView;
import io.bitsquare.common.viewfx.view.CachingViewLoader; import io.bitsquare.common.viewfx.view.CachingViewLoader;
import io.bitsquare.common.viewfx.view.FxmlView; import io.bitsquare.common.viewfx.view.FxmlView;
import io.bitsquare.common.viewfx.view.View; import io.bitsquare.common.viewfx.view.View;
import io.bitsquare.common.viewfx.view.ViewLoader; import io.bitsquare.common.viewfx.view.ViewLoader;
import io.bitsquare.gui.main.account.arbitrator.profile.ArbitratorProfileView; import io.bitsquare.gui.main.account.arbitrator.profile.ArbitratorProfileView;
import io.bitsquare.locale.LanguageUtil;
import io.bitsquare.user.AccountSettings; import io.bitsquare.user.AccountSettings;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
@ -40,7 +39,7 @@ import javafx.scene.layout.*;
import javafx.stage.Stage; import javafx.stage.Stage;
@FxmlView @FxmlView
public class ArbitratorBrowserView extends ActivatableView<Pane, Void> implements ArbitratorListener { public class BrowserView extends ActivatableView<Pane, Void> implements ArbitratorService.Listener {
@FXML Button prevButton, nextButton, selectButton, closeButton; @FXML Button prevButton, nextButton, selectButton, closeButton;
@FXML Pane arbitratorProfile; @FXML Pane arbitratorProfile;
@ -53,20 +52,21 @@ public class ArbitratorBrowserView extends ActivatableView<Pane, Void> implement
private final ViewLoader viewLoader; private final ViewLoader viewLoader;
private final AccountSettings accountSettings; private final AccountSettings accountSettings;
private final ArbitratorService messageService; private final ArbitratorService arbitratorService;
@Inject @Inject
public ArbitratorBrowserView(CachingViewLoader viewLoader, AccountSettings accountSettings, public BrowserView(CachingViewLoader viewLoader, AccountSettings accountSettings,
ArbitratorService messageService) { ArbitratorService arbitratorService) {
this.viewLoader = viewLoader; this.viewLoader = viewLoader;
this.accountSettings = accountSettings; this.accountSettings = accountSettings;
this.messageService = messageService; this.arbitratorService = arbitratorService;
} }
@Override @Override
public void initialize() { public void initialize() {
messageService.addArbitratorListener(this); arbitratorService.addListener(this);
messageService.getArbitrators(LanguageUtil.getDefaultLanguageLocaleAsCode()); /* arbitratorService.loadAllArbitrators(() -> log.debug("Arbitrators successful loaded " + arbitratorService.getAllArbitrators().size()),
(errorMessage -> log.error(errorMessage)));*/
View view = viewLoader.load(ArbitratorProfileView.class); View view = viewLoader.load(ArbitratorProfileView.class);
root.getChildren().set(0, view.getRoot()); root.getChildren().set(0, view.getRoot());
@ -80,7 +80,12 @@ public class ArbitratorBrowserView extends ActivatableView<Pane, Void> implement
} }
@Override @Override
public void onArbitratorsReceived(List<Arbitrator> arbitrators) { public void onAllArbitratorsLoaded(Map<String, Arbitrator> arbitratorsMap) {
}
/*
@Override
public void onAllArbitratorsLoaded(List<Arbitrator> arbitrators) {
allArbitrators.clear(); allArbitrators.clear();
allArbitrators.addAll(arbitrators); allArbitrators.addAll(arbitrators);
@ -90,7 +95,7 @@ public class ArbitratorBrowserView extends ActivatableView<Pane, Void> implement
arbitratorProfileView.applyArbitrator(currentArbitrator); arbitratorProfileView.applyArbitrator(currentArbitrator);
checkButtonState(); checkButtonState();
} }
} }*/
@Override @Override
public void onArbitratorRemoved(Arbitrator arbitrator) { public void onArbitratorRemoved(Arbitrator arbitrator) {

View file

@ -76,18 +76,19 @@ public class ArbitratorRegistrationView extends ActivatableView<AnchorPane, Void
private List<Arbitrator.METHOD> methodList = new ArrayList<>(); private List<Arbitrator.METHOD> methodList = new ArrayList<>();
private List<Arbitrator.ID_VERIFICATION> idVerificationList = new ArrayList<>(); private List<Arbitrator.ID_VERIFICATION> idVerificationList = new ArrayList<>();
private final Arbitrator arbitrator; // TODO not set
private Arbitrator arbitrator;
private final WalletService walletService; private final WalletService walletService;
private final ArbitratorService messageService; private final ArbitratorService arbitratorService;
private final BSFormatter formatter; private final BSFormatter formatter;
@Inject @Inject
private ArbitratorRegistrationView(Arbitrator arbitrator, WalletService walletService, private ArbitratorRegistrationView(WalletService walletService,
ArbitratorService messageService, BSFormatter formatter) { ArbitratorService arbitratorService, BSFormatter formatter) {
this.arbitrator = arbitrator;
this.walletService = walletService; this.walletService = walletService;
this.messageService = messageService; this.arbitratorService = arbitratorService;
this.formatter = formatter; this.formatter = formatter;
} }
@ -257,7 +258,11 @@ public class ArbitratorRegistrationView extends ActivatableView<AnchorPane, Void
accordion.setExpandedPane(paySecurityDepositTitledPane); accordion.setExpandedPane(paySecurityDepositTitledPane);
} }
messageService.addArbitrator(arbitrator); arbitratorService.addArbitrator(arbitrator,
() -> {
// log.debug("arbitrator added successfully " + arbitratorService.getAllArbitrators().size());
},
(errorMessage -> log.error(errorMessage)));
} }
@FXML @FXML

View file

@ -24,7 +24,7 @@ import io.bitsquare.common.viewfx.view.FxmlView;
import io.bitsquare.common.viewfx.view.View; import io.bitsquare.common.viewfx.view.View;
import io.bitsquare.common.viewfx.view.ViewLoader; import io.bitsquare.common.viewfx.view.ViewLoader;
import io.bitsquare.common.viewfx.view.Wizard; import io.bitsquare.common.viewfx.view.Wizard;
import io.bitsquare.gui.main.account.arbitrator.browser.ArbitratorBrowserView; import io.bitsquare.gui.main.account.arbitrator.browser.BrowserView;
import io.bitsquare.gui.main.help.Help; import io.bitsquare.gui.main.help.Help;
import io.bitsquare.gui.main.help.HelpId; import io.bitsquare.gui.main.help.HelpId;
import io.bitsquare.gui.util.ImageUtil; import io.bitsquare.gui.util.ImageUtil;
@ -121,7 +121,7 @@ public class RestrictionsView extends ActivatableViewAndModel<GridPane, Restrict
@FXML @FXML
private void onOpenArbitratorScreen() { private void onOpenArbitratorScreen() {
View view = viewLoader.load(ArbitratorBrowserView.class); View view = viewLoader.load(BrowserView.class);
showStage(view); showStage(view);
} }
@ -161,7 +161,7 @@ public class RestrictionsView extends ActivatableViewAndModel<GridPane, Restrict
Scene scene = new Scene((Parent) view.getRoot(), 800, 600); Scene scene = new Scene((Parent) view.getRoot(), 800, 600);
stage.setScene(scene); stage.setScene(scene);
stage.setOnHidden(windowEvent -> { stage.setOnHidden(windowEvent -> {
if (view instanceof ArbitratorBrowserView) if (view instanceof BrowserView)
updateArbitratorList(); updateArbitratorList();
}); });
stage.show(); stage.show();

View file

@ -18,6 +18,7 @@
package io.bitsquare.gui.main.trade.createoffer; package io.bitsquare.gui.main.trade.createoffer;
import io.bitsquare.arbitration.Arbitrator; import io.bitsquare.arbitration.Arbitrator;
import io.bitsquare.arbitration.ArbitratorService;
import io.bitsquare.btc.AddressEntry; import io.bitsquare.btc.AddressEntry;
import io.bitsquare.btc.FeePolicy; import io.bitsquare.btc.FeePolicy;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
@ -68,6 +69,7 @@ class CreateOfferDataModel implements Activatable, DataModel {
private final TradeManager tradeManager; private final TradeManager tradeManager;
private final WalletService walletService; private final WalletService walletService;
private ArbitratorService arbitratorService;
private final AccountSettings accountSettings; private final AccountSettings accountSettings;
private Preferences preferences; private Preferences preferences;
private final BSFormatter formatter; private final BSFormatter formatter;
@ -105,11 +107,11 @@ class CreateOfferDataModel implements Activatable, DataModel {
// non private for testing // non private for testing
@Inject @Inject
public CreateOfferDataModel(TradeManager tradeManager, WalletService walletService, AccountSettings accountSettings, public CreateOfferDataModel(TradeManager tradeManager, WalletService walletService, ArbitratorService arbitratorService,
Preferences preferences, User user, AccountSettings accountSettings, Preferences preferences, User user, BSFormatter formatter) {
BSFormatter formatter) {
this.tradeManager = tradeManager; this.tradeManager = tradeManager;
this.walletService = walletService; this.walletService = walletService;
this.arbitratorService = arbitratorService;
this.accountSettings = accountSettings; this.accountSettings = accountSettings;
this.preferences = preferences; this.preferences = preferences;
this.formatter = formatter; this.formatter = formatter;

View file

@ -314,8 +314,11 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
.countryLocalesToString(dataModel.acceptedCountries))); .countryLocalesToString(dataModel.acceptedCountries)));
dataModel.acceptedLanguageCodes.addListener((Observable o) -> acceptedLanguages.set(formatter dataModel.acceptedLanguageCodes.addListener((Observable o) -> acceptedLanguages.set(formatter
.languageCodesToString(dataModel.acceptedLanguageCodes))); .languageCodesToString(dataModel.acceptedLanguageCodes)));
dataModel.acceptedArbitrators.addListener((Observable o) -> acceptedArbitrators.set(formatter
.arbitratorsToString(dataModel.acceptedArbitrators)));
dataModel.acceptedArbitrators.addListener((Observable o) ->
acceptedArbitrators.set(formatter.arbitratorsToNames(dataModel.acceptedArbitrators)));
} }
private void setupBindings() { private void setupBindings() {

View file

@ -142,7 +142,7 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
bankAccountCountyTextField.setText(model.getBankAccountCounty()); bankAccountCountyTextField.setText(model.getBankAccountCounty());
acceptedCountriesTextField.setText(model.getAcceptedCountries()); acceptedCountriesTextField.setText(model.getAcceptedCountries());
acceptedLanguagesTextField.setText(model.getAcceptedLanguages()); acceptedLanguagesTextField.setText(model.getAcceptedLanguages());
acceptedArbitratorsTextField.setText(model.getAcceptedArbitrators()); acceptedArbitratorsTextField.setText(model.getAcceptedArbitratorIds());
showCheckAvailabilityScreen(); showCheckAvailabilityScreen();
} }

View file

@ -63,7 +63,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
private String bankAccountCounty; private String bankAccountCounty;
private String acceptedCountries; private String acceptedCountries;
private String acceptedLanguages; private String acceptedLanguages;
private String acceptedArbitrators; private String acceptedArbitratorIds;
private String addressAsString; private String addressAsString;
private String paymentLabel; private String paymentLabel;
@ -141,7 +141,7 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
acceptedCountries = formatter.countryLocalesToString(offer.getAcceptedCountries()); acceptedCountries = formatter.countryLocalesToString(offer.getAcceptedCountries());
acceptedLanguages = formatter.languageCodesToString(offer.getAcceptedLanguageCodes()); acceptedLanguages = formatter.languageCodesToString(offer.getAcceptedLanguageCodes());
acceptedArbitrators = formatter.arbitratorsToString(offer.getArbitrators()); acceptedArbitratorIds = formatter.arbitratorIdsToNames(offer.getArbitratorIds());
bankAccountType = BSResources.get(offer.getFiatAccountType().toString()); bankAccountType = BSResources.get(offer.getFiatAccountType().toString());
bankAccountCurrency = BSResources.get(CurrencyUtil.getDisplayName(offer.getCurrencyCode())); bankAccountCurrency = BSResources.get(CurrencyUtil.getDisplayName(offer.getCurrencyCode()));
bankAccountCounty = BSResources.get(offer.getBankAccountCountry().getName()); bankAccountCounty = BSResources.get(offer.getBankAccountCountry().getName());
@ -347,8 +347,8 @@ class TakeOfferViewModel extends ActivatableWithDataModel<TakeOfferDataModel> im
return acceptedLanguages; return acceptedLanguages;
} }
String getAcceptedArbitrators() { String getAcceptedArbitratorIds() {
return acceptedArbitrators; return acceptedArbitratorIds;
} }
String getAddressAsString() { String getAddressAsString() {

View file

@ -17,6 +17,7 @@
package io.bitsquare.gui.util; package io.bitsquare.gui.util;
import io.bitsquare.arbitration.ArbitrationRepository;
import io.bitsquare.arbitration.Arbitrator; import io.bitsquare.arbitration.Arbitrator;
import io.bitsquare.locale.BSResources; import io.bitsquare.locale.BSResources;
import io.bitsquare.locale.Country; import io.bitsquare.locale.Country;
@ -72,10 +73,12 @@ public class BSFormatter {
// format is like: 1,00 never more then 2 decimals // format is like: 1,00 never more then 2 decimals
private final MonetaryFormat fiatFormat = MonetaryFormat.FIAT.repeatOptionalDecimals(0, 0).code(0, currencyCode); private final MonetaryFormat fiatFormat = MonetaryFormat.FIAT.repeatOptionalDecimals(0, 0).code(0, currencyCode);
private ArbitrationRepository arbitrationRepository;
@Inject @Inject
public BSFormatter(User user) { public BSFormatter(User user, ArbitrationRepository arbitrationRepository) {
this.arbitrationRepository = arbitrationRepository;
if (user.currentFiatAccountProperty().get() == null) if (user.currentFiatAccountProperty().get() == null)
setFiatCurrencyCode(CurrencyUtil.getDefaultCurrencyAsCode()); setFiatCurrencyCode(CurrencyUtil.getDefaultCurrencyAsCode());
else if (user.currentFiatAccountProperty().get() != null) else if (user.currentFiatAccountProperty().get() != null)
@ -313,8 +316,12 @@ public class BSFormatter {
return countries.stream().map(Country::getName).collect(Collectors.joining(", ")); return countries.stream().map(Country::getName).collect(Collectors.joining(", "));
} }
public String arbitratorsToString(List<Arbitrator> arbitrators) { public String arbitratorsToNames(List<Arbitrator> arbitrators) {
return arbitrators.stream().map(Arbitrator::getName).collect(Collectors.joining(", ")); return arbitrators.stream().map(e -> e.getName()).collect(Collectors.joining(", "));
}
public String arbitratorIdsToNames(List<String> ids) {
return ids.stream().map(e -> arbitrationRepository.getArbitratorsMap().get(e).getName()).collect(Collectors.joining(", "));
} }
public String languageCodesToString(List<String> languageLocales) { public String languageCodesToString(List<String> languageLocales) {

View file

@ -17,7 +17,6 @@
package io.bitsquare.offer; package io.bitsquare.offer;
import io.bitsquare.arbitration.Arbitrator;
import io.bitsquare.btc.Restrictions; import io.bitsquare.btc.Restrictions;
import io.bitsquare.fiat.FiatAccountType; import io.bitsquare.fiat.FiatAccountType;
import io.bitsquare.locale.Country; import io.bitsquare.locale.Country;
@ -76,7 +75,7 @@ public class Offer implements Serializable {
private final List<Country> acceptedCountries; private final List<Country> acceptedCountries;
private final List<String> acceptedLanguageCodes; private final List<String> acceptedLanguageCodes;
private final String bankAccountUID; private final String bankAccountUID;
private final List<Arbitrator> arbitrators; private final List<String> arbitratorIds;
// Mutable property. Has to be set before offer is save in DHT as it changes the objects hash! // Mutable property. Has to be set before offer is save in DHT as it changes the objects hash!
private String offerFeePaymentTxID; private String offerFeePaymentTxID;
@ -101,7 +100,7 @@ public class Offer implements Serializable {
String currencyCode, String currencyCode,
Country bankAccountCountry, Country bankAccountCountry,
String bankAccountUID, String bankAccountUID,
List<Arbitrator> arbitrators, List<String> arbitratorIds,
Coin securityDeposit, Coin securityDeposit,
List<Country> acceptedCountries, List<Country> acceptedCountries,
List<String> acceptedLanguageCodes) { List<String> acceptedLanguageCodes) {
@ -115,7 +114,7 @@ public class Offer implements Serializable {
this.currencyCode = currencyCode; this.currencyCode = currencyCode;
this.bankAccountCountry = bankAccountCountry; this.bankAccountCountry = bankAccountCountry;
this.bankAccountUID = bankAccountUID; this.bankAccountUID = bankAccountUID;
this.arbitrators = arbitrators; this.arbitratorIds = arbitratorIds;
this.securityDeposit = securityDeposit; this.securityDeposit = securityDeposit;
this.acceptedCountries = acceptedCountries; this.acceptedCountries = acceptedCountries;
@ -206,8 +205,8 @@ public class Offer implements Serializable {
return offerFeePaymentTxID; return offerFeePaymentTxID;
} }
public List<Arbitrator> getArbitrators() { public List<String> getArbitratorIds() {
return arbitrators; return arbitratorIds;
} }
public Coin getSecurityDeposit() { public Coin getSecurityDeposit() {
@ -240,7 +239,7 @@ public class Offer implements Serializable {
checkNotNull(getAcceptedCountries(), "AcceptedCountries is null"); checkNotNull(getAcceptedCountries(), "AcceptedCountries is null");
checkNotNull(getAcceptedLanguageCodes(), "AcceptedLanguageLocales is null"); checkNotNull(getAcceptedLanguageCodes(), "AcceptedLanguageLocales is null");
checkNotNull(getAmount(), "Amount is null"); checkNotNull(getAmount(), "Amount is null");
checkNotNull(getArbitrators(), "Arbitrator is null"); checkNotNull(getArbitratorIds(), "Arbitrator is null");
checkNotNull(getBankAccountId(), "BankAccountId is null"); checkNotNull(getBankAccountId(), "BankAccountId is null");
checkNotNull(getSecurityDeposit(), "SecurityDeposit is null"); checkNotNull(getSecurityDeposit(), "SecurityDeposit is null");
checkNotNull(getCreationDate(), "CreationDate is null"); checkNotNull(getCreationDate(), "CreationDate is null");
@ -280,7 +279,7 @@ public class Offer implements Serializable {
", acceptedCountries=" + acceptedCountries + ", acceptedCountries=" + acceptedCountries +
", acceptedLanguageLocales=" + acceptedLanguageCodes + ", acceptedLanguageLocales=" + acceptedLanguageCodes +
", bankAccountUID='" + bankAccountUID + '\'' + ", bankAccountUID='" + bankAccountUID + '\'' +
", arbitrators=" + arbitrators + ", arbitrators=" + arbitratorIds +
", offerFeePaymentTxID='" + offerFeePaymentTxID + '\'' + ", offerFeePaymentTxID='" + offerFeePaymentTxID + '\'' +
'}'; '}';
} }

View file

@ -17,6 +17,7 @@
package io.bitsquare.trade; package io.bitsquare.trade;
import io.bitsquare.arbitration.ArbitrationRepository;
import io.bitsquare.btc.BlockChainService; import io.bitsquare.btc.BlockChainService;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
import io.bitsquare.common.handlers.ErrorMessageHandler; import io.bitsquare.common.handlers.ErrorMessageHandler;
@ -80,6 +81,7 @@ public class TradeManager {
private final SignatureService signatureService; private final SignatureService signatureService;
private EncryptionService<MailboxMessage> encryptionService; private EncryptionService<MailboxMessage> encryptionService;
private final OfferBookService offerBookService; private final OfferBookService offerBookService;
private ArbitrationRepository arbitrationRepository;
private File storageDir; private File storageDir;
private final Map<String, CheckOfferAvailabilityProtocol> checkOfferAvailabilityProtocolMap = new HashMap<>(); private final Map<String, CheckOfferAvailabilityProtocol> checkOfferAvailabilityProtocolMap = new HashMap<>();
@ -97,7 +99,7 @@ public class TradeManager {
public TradeManager(User user, AccountSettings accountSettings, public TradeManager(User user, AccountSettings accountSettings,
MessageService messageService, MailboxService mailboxService, AddressService addressService, BlockChainService blockChainService, MessageService messageService, MailboxService mailboxService, AddressService addressService, BlockChainService blockChainService,
WalletService walletService, SignatureService signatureService, EncryptionService<MailboxMessage> encryptionService, WalletService walletService, SignatureService signatureService, EncryptionService<MailboxMessage> encryptionService,
OfferBookService offerBookService, @Named("storage.dir") File storageDir) { OfferBookService offerBookService, ArbitrationRepository arbitrationRepository, @Named("storage.dir") File storageDir) {
this.user = user; this.user = user;
this.accountSettings = accountSettings; this.accountSettings = accountSettings;
this.messageService = messageService; this.messageService = messageService;
@ -108,6 +110,7 @@ public class TradeManager {
this.signatureService = signatureService; this.signatureService = signatureService;
this.encryptionService = encryptionService; this.encryptionService = encryptionService;
this.offerBookService = offerBookService; this.offerBookService = offerBookService;
this.arbitrationRepository = arbitrationRepository;
this.storageDir = storageDir; this.storageDir = storageDir;
this.openOfferTrades = new TradeList<>(storageDir, "OpenOfferTrades"); this.openOfferTrades = new TradeList<>(storageDir, "OpenOfferTrades");
@ -173,7 +176,7 @@ public class TradeManager {
currentFiatAccount.getCurrencyCode(), currentFiatAccount.getCurrencyCode(),
currentFiatAccount.getCountry(), currentFiatAccount.getCountry(),
currentFiatAccount.getId(), currentFiatAccount.getId(),
accountSettings.getAcceptedArbitrators(), accountSettings.getAcceptedArbitratorIds(),
accountSettings.getSecurityDeposit(), accountSettings.getSecurityDeposit(),
accountSettings.getAcceptedCountries(), accountSettings.getAcceptedCountries(),
accountSettings.getAcceptedLanguageLocaleCodes()); accountSettings.getAcceptedLanguageLocaleCodes());
@ -184,7 +187,7 @@ public class TradeManager {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
PlaceOfferModel model = new PlaceOfferModel(offer, walletService, offerBookService); PlaceOfferModel model = new PlaceOfferModel(offer, walletService, offerBookService);
PlaceOfferProtocol placeOfferProtocol = new PlaceOfferProtocol( PlaceOfferProtocol placeOfferProtocol = new PlaceOfferProtocol(
@ -398,6 +401,7 @@ public class TradeManager {
walletService, walletService,
blockChainService, blockChainService,
signatureService, signatureService,
arbitrationRepository,
user, user,
storageDir); storageDir);
@ -413,6 +417,7 @@ public class TradeManager {
walletService, walletService,
blockChainService, blockChainService,
signatureService, signatureService,
arbitrationRepository,
user, user,
storageDir); storageDir);

View file

@ -17,6 +17,7 @@
package io.bitsquare.trade.protocol.trade; package io.bitsquare.trade.protocol.trade;
import io.bitsquare.arbitration.ArbitrationRepository;
import io.bitsquare.btc.BlockChainService; import io.bitsquare.btc.BlockChainService;
import io.bitsquare.btc.TradeWalletService; import io.bitsquare.btc.TradeWalletService;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
@ -37,6 +38,7 @@ public class SharedTradeModel extends SharedTaskModel implements Serializable {
private static final long serialVersionUID = -2523252022571497157L; private static final long serialVersionUID = -2523252022571497157L;
protected static final Logger log = LoggerFactory.getLogger(SharedTradeModel.class); protected static final Logger log = LoggerFactory.getLogger(SharedTradeModel.class);
transient public MailboxMessage mailboxMessage;
// provided // provided
transient public final Offer offer; transient public final Offer offer;
transient public final MessageService messageService; transient public final MessageService messageService;
@ -45,12 +47,12 @@ public class SharedTradeModel extends SharedTaskModel implements Serializable {
transient public final BlockChainService blockChainService; transient public final BlockChainService blockChainService;
transient public final SignatureService signatureService; transient public final SignatureService signatureService;
transient public MailboxMessage mailboxMessage;
// derived // derived
transient public final String id; transient public final String id;
transient public final TradeWalletService tradeWalletService; transient public final TradeWalletService tradeWalletService;
transient public final byte[] arbitratorPubKey;
// get set async when arbitrators are loaded from arbitratorService
transient public byte[] arbitratorPubKey;
// data written/read by tasks // data written/read by tasks
transient private TradeMessage tradeMessage; transient private TradeMessage tradeMessage;
@ -60,7 +62,8 @@ public class SharedTradeModel extends SharedTaskModel implements Serializable {
MailboxService mailboxService, MailboxService mailboxService,
WalletService walletService, WalletService walletService,
BlockChainService blockChainService, BlockChainService blockChainService,
SignatureService signatureService) { SignatureService signatureService,
ArbitrationRepository arbitrationRepository) {
this.offer = offer; this.offer = offer;
this.messageService = messageService; this.messageService = messageService;
this.mailboxService = mailboxService; this.mailboxService = mailboxService;
@ -70,9 +73,7 @@ public class SharedTradeModel extends SharedTaskModel implements Serializable {
id = offer.getId(); id = offer.getId();
tradeWalletService = walletService.getTradeWalletService(); tradeWalletService = walletService.getTradeWalletService();
//TODO use default arbitrator for now arbitratorPubKey = arbitrationRepository.getDefaultArbitrator().getPubKey();
arbitratorPubKey = offer.getArbitrators().get(0).getPubKey();
} }
public void setTradeMessage(TradeMessage tradeMessage) { public void setTradeMessage(TradeMessage tradeMessage) {

View file

@ -17,6 +17,7 @@
package io.bitsquare.trade.protocol.trade.offerer.models; package io.bitsquare.trade.protocol.trade.offerer.models;
import io.bitsquare.arbitration.ArbitrationRepository;
import io.bitsquare.btc.BlockChainService; import io.bitsquare.btc.BlockChainService;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
import io.bitsquare.crypto.SignatureService; import io.bitsquare.crypto.SignatureService;
@ -52,6 +53,7 @@ public class OffererAsBuyerModel extends SharedTradeModel implements Serializabl
WalletService walletService, WalletService walletService,
BlockChainService blockChainService, BlockChainService blockChainService,
SignatureService signatureService, SignatureService signatureService,
ArbitrationRepository arbitrationRepository,
User user, User user,
File storageDir) { File storageDir) {
super(trade.getOffer(), super(trade.getOffer(),
@ -59,7 +61,8 @@ public class OffererAsBuyerModel extends SharedTradeModel implements Serializabl
mailboxService, mailboxService,
walletService, walletService,
blockChainService, blockChainService,
signatureService); signatureService,
arbitrationRepository);
this.trade = trade; this.trade = trade;
this.storage = new Storage<>(storageDir); this.storage = new Storage<>(storageDir);

View file

@ -17,6 +17,7 @@
package io.bitsquare.trade.protocol.trade.taker.models; package io.bitsquare.trade.protocol.trade.taker.models;
import io.bitsquare.arbitration.ArbitrationRepository;
import io.bitsquare.btc.BlockChainService; import io.bitsquare.btc.BlockChainService;
import io.bitsquare.btc.WalletService; import io.bitsquare.btc.WalletService;
import io.bitsquare.crypto.SignatureService; import io.bitsquare.crypto.SignatureService;
@ -55,6 +56,7 @@ public class TakerAsSellerModel extends SharedTradeModel implements Serializable
WalletService walletService, WalletService walletService,
BlockChainService blockChainService, BlockChainService blockChainService,
SignatureService signatureService, SignatureService signatureService,
ArbitrationRepository arbitrationRepository,
User user, User user,
File storageDir) { File storageDir) {
super(trade.getOffer(), super(trade.getOffer(),
@ -62,7 +64,8 @@ public class TakerAsSellerModel extends SharedTradeModel implements Serializable
mailboxService, mailboxService,
walletService, walletService,
blockChainService, blockChainService,
signatureService); signatureService,
arbitrationRepository);
this.trade = trade; this.trade = trade;
this.storage = new Storage<>(storageDir); this.storage = new Storage<>(storageDir);

View file

@ -17,6 +17,7 @@
package io.bitsquare.user; package io.bitsquare.user;
import io.bitsquare.arbitration.ArbitrationRepository;
import io.bitsquare.arbitration.Arbitrator; import io.bitsquare.arbitration.Arbitrator;
import io.bitsquare.locale.Country; import io.bitsquare.locale.Country;
import io.bitsquare.locale.CountryUtil; import io.bitsquare.locale.CountryUtil;
@ -31,6 +32,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.OptionalLong; import java.util.OptionalLong;
import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
@ -50,7 +52,7 @@ public class AccountSettings implements Serializable {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
public AccountSettings(Storage<AccountSettings> storage, Arbitrator defaultArbitrator) { public AccountSettings(Storage<AccountSettings> storage, ArbitrationRepository arbitrationRepository) {
this.storage = storage; this.storage = storage;
AccountSettings persisted = storage.initAndGetPersisted(this); AccountSettings persisted = storage.initAndGetPersisted(this);
@ -62,7 +64,7 @@ public class AccountSettings implements Serializable {
else { else {
acceptedLanguageLocaleCodes = Arrays.asList(LanguageUtil.getDefaultLanguageLocaleAsCode(), LanguageUtil.getEnglishLanguageLocaleCode()); acceptedLanguageLocaleCodes = Arrays.asList(LanguageUtil.getDefaultLanguageLocaleAsCode(), LanguageUtil.getEnglishLanguageLocaleCode());
acceptedCountryLocales = Arrays.asList(CountryUtil.getDefaultCountry()); acceptedCountryLocales = Arrays.asList(CountryUtil.getDefaultCountry());
acceptedArbitrators = Arrays.asList(defaultArbitrator); acceptedArbitrators = Arrays.asList(arbitrationRepository.getDefaultArbitrator());
} }
} }
@ -115,6 +117,10 @@ public class AccountSettings implements Serializable {
return acceptedArbitrators; return acceptedArbitrators;
} }
public List<String> getAcceptedArbitratorIds() {
return acceptedArbitrators.stream().map(e -> e.getId()).collect(Collectors.toList());
}
public List<String> getAcceptedLanguageLocaleCodes() { public List<String> getAcceptedLanguageLocaleCodes() {
return acceptedLanguageLocaleCodes; return acceptedLanguageLocaleCodes;
} }

View file

@ -0,0 +1,52 @@
/*
* 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.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
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 PublicKey decodePubKeyHex(String pubKeyHex) {
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(Utils.HEX.decode(pubKeyHex));
try {
KeyFactory keyFactory = KeyFactory.getInstance("DSA");
return keyFactory.generatePublic(pubKeySpec);
} catch (NoSuchAlgorithmException e) {
log.error("could not find algorithm", e);
return null;
} catch (InvalidKeySpecException e) {
log.error("wrong keyspec", e);
return null;
}
}
public static String encodePubKeyToHex(PublicKey pubKey) {
return Utils.HEX.encode(pubKey.getEncoded());
}
}

View file

@ -41,10 +41,10 @@ public class CreateOfferViewModelTest {
@Before @Before
public void setup() { public void setup() {
BSFormatter formatter = new BSFormatter(new User()); BSFormatter formatter = new BSFormatter(new User(), null);
formatter.setLocale(Locale.US); formatter.setLocale(Locale.US);
formatter.setFiatCurrencyCode("USD"); formatter.setFiatCurrencyCode("USD");
model = new CreateOfferDataModel(null, null, null, null, null, formatter); model = new CreateOfferDataModel(null, null, null, null, null, null, formatter);
presenter = new CreateOfferViewModel(model, new FiatValidator(null), new BtcValidator(), formatter); presenter = new CreateOfferViewModel(model, new FiatValidator(null), new BtcValidator(), formatter);
} }

View file

@ -31,7 +31,7 @@ public class BSFormatterTest {
@Test @Test
public void testParseToBtc() { public void testParseToBtc() {
BSFormatter formatter = new BSFormatter(new User()); BSFormatter formatter = new BSFormatter(new User(), null);
formatter.useMilliBitFormat(false); formatter.useMilliBitFormat(false);
assertEquals(Coin.ZERO, formatter.parseToCoin("0")); assertEquals(Coin.ZERO, formatter.parseToCoin("0"));
assertEquals(Coin.COIN, formatter.parseToCoin("1")); assertEquals(Coin.COIN, formatter.parseToCoin("1"));
@ -64,7 +64,7 @@ public class BSFormatterTest {
@Test @Test
public void testFormatCoin() { public void testFormatCoin() {
BSFormatter formatter = new BSFormatter(new User()); BSFormatter formatter = new BSFormatter(new User(), null);
formatter.useMilliBitFormat(false); formatter.useMilliBitFormat(false);
assertEquals("1.00", formatter.formatCoin(Coin.COIN)); assertEquals("1.00", formatter.formatCoin(Coin.COIN));
assertEquals("1.0120", formatter.formatCoin(Coin.parseCoin("1.012"))); assertEquals("1.0120", formatter.formatCoin(Coin.parseCoin("1.012")));
@ -97,7 +97,7 @@ public class BSFormatterTest {
@Test @Test
public void testFormatCoinWithCode() { public void testFormatCoinWithCode() {
BSFormatter formatter = new BSFormatter(new User()); BSFormatter formatter = new BSFormatter(new User(), null);
formatter.useMilliBitFormat(false); formatter.useMilliBitFormat(false);
assertEquals("1.00 BTC", formatter.formatCoinWithCode(Coin.COIN)); assertEquals("1.00 BTC", formatter.formatCoinWithCode(Coin.COIN));
assertEquals("1.01 BTC", formatter.formatCoinWithCode(Coin.parseCoin("1.01"))); assertEquals("1.01 BTC", formatter.formatCoinWithCode(Coin.parseCoin("1.01")));
@ -132,7 +132,7 @@ public class BSFormatterTest {
@Test @Test
public void testParseToBtcWith4Decimals() { public void testParseToBtcWith4Decimals() {
BSFormatter formatter = new BSFormatter(new User()); BSFormatter formatter = new BSFormatter(new User(), null);
formatter.useMilliBitFormat(false); formatter.useMilliBitFormat(false);
assertEquals(Coin.parseCoin("0"), formatter.parseToCoinWith4Decimals("0")); assertEquals(Coin.parseCoin("0"), formatter.parseToCoinWith4Decimals("0"));
assertEquals(Coin.parseCoin("0"), formatter.parseToCoinWith4Decimals(null)); assertEquals(Coin.parseCoin("0"), formatter.parseToCoinWith4Decimals(null));
@ -143,7 +143,7 @@ public class BSFormatterTest {
@Test @Test
public void testHasBtcValidDecimals() { public void testHasBtcValidDecimals() {
BSFormatter formatter = new BSFormatter(new User()); BSFormatter formatter = new BSFormatter(new User(), null);
formatter.useMilliBitFormat(false); formatter.useMilliBitFormat(false);
formatter.setLocale(Locale.GERMAN); formatter.setLocale(Locale.GERMAN);
assertTrue(formatter.hasBtcValidDecimals(null)); assertTrue(formatter.hasBtcValidDecimals(null));
@ -159,7 +159,7 @@ public class BSFormatterTest {
@Test @Test
public void testParseToFiatWith2Decimals() { public void testParseToFiatWith2Decimals() {
BSFormatter formatter = new BSFormatter(new User()); BSFormatter formatter = new BSFormatter(new User(), null);
formatter.useMilliBitFormat(false); formatter.useMilliBitFormat(false);
formatter.setLocale(Locale.GERMAN); formatter.setLocale(Locale.GERMAN);
assertEquals("0", formatter.parseToFiatWith2Decimals("0").toPlainString()); assertEquals("0", formatter.parseToFiatWith2Decimals("0").toPlainString());
@ -172,7 +172,7 @@ public class BSFormatterTest {
@Test @Test
public void testHasFiatValidDecimals() { public void testHasFiatValidDecimals() {
BSFormatter formatter = new BSFormatter(new User()); BSFormatter formatter = new BSFormatter(new User(), null);
formatter.useMilliBitFormat(false); formatter.useMilliBitFormat(false);
formatter.setLocale(Locale.GERMAN); formatter.setLocale(Locale.GERMAN);
assertTrue(formatter.hasFiatValidDecimals(null)); assertTrue(formatter.hasFiatValidDecimals(null));