Wrap lines at 120 chars

This commit is contained in:
Chris Beams 2014-08-26 09:22:38 +02:00
parent 23b2cabf19
commit 1ad1d318e8
No known key found for this signature in database
GPG key ID: 3D214F8F5BC5ED73
85 changed files with 742 additions and 369 deletions

View file

@ -4,10 +4,12 @@
<option name="PER_PROJECT_SETTINGS"> <option name="PER_PROJECT_SETTINGS">
<value> <value>
<option name="LINE_SEPARATOR" value="&#10;" /> <option name="LINE_SEPARATOR" value="&#10;" />
<option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" />
<XML> <XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" /> <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML> </XML>
<codeStyleSettings language="JAVA"> <codeStyleSettings language="JAVA">
<option name="WRAP_LONG_LINES" value="true" />
<option name="FIELD_ANNOTATION_WRAP" value="0" /> <option name="FIELD_ANNOTATION_WRAP" value="0" />
</codeStyleSettings> </codeStyleSettings>
</value> </value>

View file

@ -79,9 +79,11 @@ public class BitSquare extends Application {
Profiler.printMsgWithTime("BitSquare.start called"); Profiler.printMsgWithTime("BitSquare.start called");
BitSquare.primaryStage = primaryStage; BitSquare.primaryStage = primaryStage;
Thread.currentThread().setUncaughtExceptionHandler((thread, throwable) -> Popups.handleUncaughtExceptions(Throwables.getRootCause(throwable))); Thread.currentThread().setUncaughtExceptionHandler((thread, throwable) -> Popups.handleUncaughtExceptions
(Throwables.getRootCause(throwable)));
StorageDirectory.setStorageDirectory(new File(StorageDirectory.getApplicationDirectory().getCanonicalPath() + "/data")); StorageDirectory.setStorageDirectory(new File(StorageDirectory.getApplicationDirectory().getCanonicalPath() +
"/data"));
// currently there is not SystemTray support for java fx (planned for version 3) so we use the old AWT // currently there is not SystemTray support for java fx (planned for version 3) so we use the old AWT
AWTSystemTray.createSystemTray(primaryStage); AWTSystemTray.createSystemTray(primaryStage);
@ -108,7 +110,8 @@ public class BitSquare extends Application {
GuiceFXMLLoader.setInjector(injector); GuiceFXMLLoader.setInjector(injector);
final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(NavigationItem.MAIN.getFxmlUrl()), false); final GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(NavigationItem.MAIN.getFxmlUrl()),
false);
final Parent view = loader.load(); final Parent view = loader.load();
final Scene scene = new Scene(view, 1000, 750); final Scene scene = new Scene(view, 1000, 750);
scene.getStylesheets().setAll(getClass().getResource("/io/bitsquare/gui/bitsquare.css").toExternalForm()); scene.getStylesheets().setAll(getClass().getResource("/io/bitsquare/gui/bitsquare.css").toExternalForm());

View file

@ -42,14 +42,17 @@ import org.slf4j.LoggerFactory;
* Well known node which is reachable for all peers for bootstrapping. * Well known node which is reachable for all peers for bootstrapping.
* There will be several SeedNodes running on several servers. * There will be several SeedNodes running on several servers.
* <p/> * <p/>
* TODO: Alternative bootstrap methods will follow later (save locally list of known nodes reported form other peers,...) * TODO: Alternative bootstrap methods will follow later (save locally list of known nodes reported form other peers,
* ...)
*/ */
public class SeedNode extends Thread { public class SeedNode extends Thread {
private static final Logger log = LoggerFactory.getLogger(SeedNode.class); private static final Logger log = LoggerFactory.getLogger(SeedNode.class);
private static final List<SeedNodeAddress.StaticSeedNodeAddresses> staticSedNodeAddresses = SeedNodeAddress.StaticSeedNodeAddresses.getAllSeedNodeAddresses(); private static final List<SeedNodeAddress.StaticSeedNodeAddresses> staticSedNodeAddresses = SeedNodeAddress
.StaticSeedNodeAddresses.getAllSeedNodeAddresses();
/** /**
* @param args If no args passed we use localhost, otherwise the param is used as index for selecting an address from seedNodeAddresses * @param args If no args passed we use localhost, otherwise the param is used as index for selecting an address
* from seedNodeAddresses
*/ */
public static void main(String[] args) { public static void main(String[] args) {
int index = 0; int index = 0;
@ -106,7 +109,8 @@ public class SeedNode extends Thread {
public Peer startupPeer() { public Peer startupPeer() {
Peer peer = null; Peer peer = null;
try { try {
peer = new PeerBuilder(Number160.createHash(seedNodeAddress.getId())).ports(seedNodeAddress.getPort()).start(); peer = new PeerBuilder(Number160.createHash(seedNodeAddress.getId())).ports(seedNodeAddress.getPort())
.start();
// Need to add all features the clients will use (otherwise msg type is UNKNOWN_ID) // Need to add all features the clients will use (otherwise msg type is UNKNOWN_ID)
new PeerBuilderDHT(peer).start(); new PeerBuilderDHT(peer).start();

View file

@ -34,11 +34,13 @@ public class BankAccount implements Serializable {
private final String accountHolderName; private final String accountHolderName;
private final Country country; // where bank is registered private final Country country; // where bank is registered
// The main currency if account support multiple currencies. // The main currency if account support multiple currencies.
// The user can create multiple bank accounts with same bank account but other currency if his bank account support that. // The user can create multiple bank accounts with same bank account but other currency if his bank account
// support that.
private final Currency currency; private final Currency currency;
private final String accountTitle; private final String accountTitle;
public BankAccount(BankAccountType bankAccountType, Currency currency, Country country, String accountTitle, String accountHolderName, String accountPrimaryID, String accountSecondaryID) { public BankAccount(BankAccountType bankAccountType, Currency currency, Country country, String accountTitle,
String accountHolderName, String accountPrimaryID, String accountSecondaryID) {
this.bankAccountType = bankAccountType; this.bankAccountType = bankAccountType;
this.currency = currency; this.currency = currency;
this.country = country; this.country = country;

View file

@ -90,7 +90,8 @@ public class AddressBasedCoinSelector extends DefaultCoinSelector {
// Pick chain-included transactions and transactions that are pending. // Pick chain-included transactions and transactions that are pending.
TransactionConfidence confidence = tx.getConfidence(); TransactionConfidence confidence = tx.getConfidence();
TransactionConfidence.ConfidenceType type = confidence.getConfidenceType(); TransactionConfidence.ConfidenceType type = confidence.getConfidenceType();
return type.equals(TransactionConfidence.ConfidenceType.BUILDING) || type.equals(TransactionConfidence.ConfidenceType.PENDING) && return type.equals(TransactionConfidence.ConfidenceType.BUILDING) || type.equals(TransactionConfidence
.ConfidenceType.PENDING) &&
// In regtest mode we expect to have only one peer, so we won't see transactions propagate. // In regtest mode we expect to have only one peer, so we won't see transactions propagate.
// TODO: The value 1 below dates from a time when transactions we broadcast *to* were counted, set to 0 // TODO: The value 1 below dates from a time when transactions we broadcast *to* were counted, set to 0
(confidence.numBroadcastPeers() > 1 || tx.getParams() == RegTestParams.get()); (confidence.numBroadcastPeers() > 1 || tx.getParams() == RegTestParams.get());
@ -116,7 +117,8 @@ public class AddressBasedCoinSelector extends DefaultCoinSelector {
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
protected boolean matchesRequiredAddress(TransactionOutput transactionOutput) { protected boolean matchesRequiredAddress(TransactionOutput transactionOutput) {
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH()) { if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH
()) {
Address addressOutput = transactionOutput.getScriptPubKey().getToAddress(params); Address addressOutput = transactionOutput.getScriptPubKey().getToAddress(params);
if (addressEntry != null && addressOutput.equals(addressEntry.getAddress())) { if (addressEntry != null && addressOutput.equals(addressEntry.getAddress())) {
return true; return true;
@ -168,7 +170,8 @@ public class AddressBasedCoinSelector extends DefaultCoinSelector {
type.equals(TransactionConfidence.ConfidenceType.PENDING) && type.equals(TransactionConfidence.ConfidenceType.PENDING) &&
confidence.getSource().equals(TransactionConfidence.Source.SELF) && confidence.getSource().equals(TransactionConfidence.Source.SELF) &&
// In regtest mode we expect to have only one peer, so we won't see transactions propagate. // In regtest mode we expect to have only one peer, so we won't see transactions propagate.
// TODO: The value 1 below dates from a time when transactions we broadcast *to* were counted, set to 0 // TODO: The value 1 below dates from a time when transactions we broadcast *to* were
counted, set to 0
(confidence.numBroadcastPeers() > 1 || tx.getParams() == RegTestParams.get()); (confidence.numBroadcastPeers() > 1 || tx.getParams() == RegTestParams.get());
} }
*/ */

View file

@ -41,7 +41,8 @@ public class FeePolicy {
this.params = params; this.params = params;
} }
//TODO other users or dev address? use donation option list? (dev, other users, wikileaks, tor, sub projects (bitcoinj, tomp2p,...)...) //TODO other users or dev address? use donation option list? (dev, other users, wikileaks, tor,
// sub projects (bitcoinj, tomp2p,...)...)
public Address getAddressForRegistrationFee() { public Address getAddressForRegistrationFee() {
try { try {

View file

@ -91,7 +91,8 @@ public class WalletFacade {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
public WalletFacade(NetworkParameters params, FeePolicy feePolicy, CryptoFacade cryptoFacade, Persistence persistence) { public WalletFacade(NetworkParameters params, FeePolicy feePolicy, CryptoFacade cryptoFacade,
Persistence persistence) {
this.params = params; this.params = params;
this.feePolicy = feePolicy; this.feePolicy = feePolicy;
this.cryptoFacade = cryptoFacade; this.cryptoFacade = cryptoFacade;
@ -199,14 +200,16 @@ public class WalletFacade {
List<AddressEntry> persistedAddressEntryList = (List<AddressEntry>) serializable; List<AddressEntry> persistedAddressEntryList = (List<AddressEntry>) serializable;
if (serializable instanceof List) { if (serializable instanceof List) {
for (AddressEntry persistedAddressEntry : persistedAddressEntryList) { for (AddressEntry persistedAddressEntry : persistedAddressEntryList) {
persistedAddressEntry.setDeterministicKey((DeterministicKey) wallet.findKeyFromPubHash(persistedAddressEntry.getPubKeyHash())); persistedAddressEntry.setDeterministicKey((DeterministicKey) wallet.findKeyFromPubHash
(persistedAddressEntry.getPubKeyHash()));
} }
addressEntryList = persistedAddressEntryList; addressEntryList = persistedAddressEntryList;
registrationAddressEntry = addressEntryList.get(0); registrationAddressEntry = addressEntryList.get(0);
} else { } else {
lock.lock(); lock.lock();
DeterministicKey registrationKey = wallet.currentReceiveKey(); DeterministicKey registrationKey = wallet.currentReceiveKey();
registrationAddressEntry = new AddressEntry(registrationKey, params, AddressEntry.AddressContext.REGISTRATION_FEE); registrationAddressEntry = new AddressEntry(registrationKey, params,
AddressEntry.AddressContext.REGISTRATION_FEE);
addressEntryList.add(registrationAddressEntry); addressEntryList.add(registrationAddressEntry);
lock.unlock(); lock.unlock();
saveAddressInfoList(); saveAddressInfoList();
@ -276,7 +279,8 @@ public class WalletFacade {
} }
public AddressEntry getAddressInfoByTradeID(String offerId) { public AddressEntry getAddressInfoByTradeID(String offerId) {
Optional<AddressEntry> addressEntry = getAddressEntryList().stream().filter(e -> offerId.equals(e.getOfferId())).findFirst(); Optional<AddressEntry> addressEntry = getAddressEntryList().stream().filter(e -> offerId.equals(e.getOfferId
())).findFirst();
if (addressEntry.isPresent()) if (addressEntry.isPresent())
return addressEntry.get(); return addressEntry.get();
@ -314,7 +318,8 @@ public class WalletFacade {
List<TransactionConfidence> transactionConfidenceList = new ArrayList<>(); List<TransactionConfidence> transactionConfidenceList = new ArrayList<>();
Set<Transaction> transactions = wallet.getTransactions(true); Set<Transaction> transactions = wallet.getTransactions(true);
if (transactions != null) { if (transactions != null) {
transactionConfidenceList.addAll(transactions.stream().map(tx -> getTransactionConfidence(tx, address)).collect(Collectors.toList())); transactionConfidenceList.addAll(transactions.stream().map(tx -> getTransactionConfidence(tx,
address)).collect(Collectors.toList()));
/* same as: /* same as:
for (Transaction tx : transactions) for (Transaction tx : transactions)
{ {
@ -340,7 +345,8 @@ public class WalletFacade {
List<TransactionOutput> mergedOutputs = getOutputsWithConnectedOutputs(tx); List<TransactionOutput> mergedOutputs = getOutputsWithConnectedOutputs(tx);
List<TransactionConfidence> transactionConfidenceList = new ArrayList<>(); List<TransactionConfidence> transactionConfidenceList = new ArrayList<>();
mergedOutputs.stream().filter(e -> e.getScriptPubKey().isSentToAddress() || e.getScriptPubKey().isSentToP2SH()).forEach(transactionOutput -> { mergedOutputs.stream().filter(e -> e.getScriptPubKey().isSentToAddress() || e.getScriptPubKey().isSentToP2SH
()).forEach(transactionOutput -> {
Address outputAddress = transactionOutput.getScriptPubKey().getToAddress(params); Address outputAddress = transactionOutput.getScriptPubKey().getToAddress(params);
if (address.equals(outputAddress)) { if (address.equals(outputAddress)) {
transactionConfidenceList.add(tx.getConfidence()); transactionConfidenceList.add(tx.getConfidence());
@ -350,7 +356,8 @@ public class WalletFacade {
same as: same as:
for (TransactionOutput transactionOutput : mergedOutputs) for (TransactionOutput transactionOutput : mergedOutputs)
{ {
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH()) if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey()
.isSentToP2SH())
{ {
Address outputAddress = transactionOutput.getScriptPubKey().getToAddress(params); Address outputAddress = transactionOutput.getScriptPubKey().getToAddress(params);
if (address.equals(outputAddress)) if (address.equals(outputAddress))
@ -391,7 +398,8 @@ public class WalletFacade {
if (transactionConfidence == null || if (transactionConfidence == null ||
confidence.getConfidenceType().equals(TransactionConfidence.ConfidenceType.PENDING) || confidence.getConfidenceType().equals(TransactionConfidence.ConfidenceType.PENDING) ||
(confidence.getConfidenceType().equals(TransactionConfidence.ConfidenceType.BUILDING) && (confidence.getConfidenceType().equals(TransactionConfidence.ConfidenceType.BUILDING) &&
transactionConfidence.getConfidenceType().equals(TransactionConfidence.ConfidenceType.BUILDING) && transactionConfidence.getConfidenceType().equals(TransactionConfidence.ConfidenceType
.BUILDING) &&
confidence.getDepthInBlocks() < transactionConfidence.getDepthInBlocks())) { confidence.getDepthInBlocks() < transactionConfidence.getDepthInBlocks())) {
transactionConfidence = confidence; transactionConfidence = confidence;
} }
@ -407,7 +415,8 @@ public class WalletFacade {
if (getRegistrationAddressEntry() != null) { if (getRegistrationAddressEntry() != null) {
transactionConfidence = getConfidenceForAddress(getRegistrationAddressEntry().getAddress()); transactionConfidence = getConfidenceForAddress(getRegistrationAddressEntry().getAddress());
} }
return transactionConfidence != null && transactionConfidence.getConfidenceType().equals(TransactionConfidence.ConfidenceType.BUILDING); return transactionConfidence != null && transactionConfidence.getConfidenceType().equals
(TransactionConfidence.ConfidenceType.BUILDING);
} }
@ -422,7 +431,8 @@ public class WalletFacade {
private Coin getBalance(LinkedList<TransactionOutput> transactionOutputs, Address address) { private Coin getBalance(LinkedList<TransactionOutput> transactionOutputs, Address address) {
Coin balance = Coin.ZERO; Coin balance = Coin.ZERO;
for (TransactionOutput transactionOutput : transactionOutputs) { for (TransactionOutput transactionOutput : transactionOutputs) {
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isSentToP2SH()) { if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey()
.isSentToP2SH()) {
Address addressOutput = transactionOutput.getScriptPubKey().getToAddress(params); Address addressOutput = transactionOutput.getScriptPubKey().getToAddress(params);
if (addressOutput.equals(address)) { if (addressOutput.equals(address)) {
balance = balance.add(transactionOutput.getValue()); balance = balance.add(transactionOutput.getValue());
@ -490,22 +500,26 @@ public class WalletFacade {
// Transactions // Transactions
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public void payRegistrationFee(String stringifiedBankAccounts, FutureCallback<Transaction> callback) throws InsufficientMoneyException { public void payRegistrationFee(String stringifiedBankAccounts, FutureCallback<Transaction> callback) throws
InsufficientMoneyException {
log.debug("payRegistrationFee"); log.debug("payRegistrationFee");
log.trace("stringifiedBankAccounts " + stringifiedBankAccounts); log.trace("stringifiedBankAccounts " + stringifiedBankAccounts);
Transaction tx = new Transaction(params); Transaction tx = new Transaction(params);
byte[] data = cryptoFacade.getEmbeddedAccountRegistrationData(getRegistrationAddressEntry().getKey(), stringifiedBankAccounts); byte[] data = cryptoFacade.getEmbeddedAccountRegistrationData(getRegistrationAddressEntry().getKey(),
stringifiedBankAccounts);
tx.addOutput(Transaction.MIN_NONDUST_OUTPUT, new ScriptBuilder().op(OP_RETURN).data(data).build()); tx.addOutput(Transaction.MIN_NONDUST_OUTPUT, new ScriptBuilder().op(OP_RETURN).data(data).build());
Coin fee = FeePolicy.ACCOUNT_REGISTRATION_FEE.subtract(Transaction.MIN_NONDUST_OUTPUT).subtract(FeePolicy.TX_FEE); Coin fee = FeePolicy.ACCOUNT_REGISTRATION_FEE.subtract(Transaction.MIN_NONDUST_OUTPUT).subtract(FeePolicy
.TX_FEE);
log.trace("fee: " + fee.toFriendlyString()); log.trace("fee: " + fee.toFriendlyString());
tx.addOutput(fee, feePolicy.getAddressForRegistrationFee()); tx.addOutput(fee, feePolicy.getAddressForRegistrationFee());
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx); Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx);
sendRequest.shuffleOutputs = false; sendRequest.shuffleOutputs = false;
// we don't allow spending of unconfirmed tx as with fake registrations we would open up doors for spam and market manipulation with fake offers // we don't allow spending of unconfirmed tx as with fake registrations we would open up doors for spam and
// market manipulation with fake offers
// so set includePending to false // so set includePending to false
sendRequest.coinSelector = new AddressBasedCoinSelector(params, getRegistrationAddressEntry(), false); sendRequest.coinSelector = new AddressBasedCoinSelector(params, getRegistrationAddressEntry(), false);
sendRequest.changeAddress = getRegistrationAddressEntry().getAddress(); sendRequest.changeAddress = getRegistrationAddressEntry().getAddress();
@ -539,7 +553,8 @@ public class WalletFacade {
// printInputs("payCreateOfferFee", tx); // printInputs("payCreateOfferFee", tx);
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx); Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx);
sendRequest.shuffleOutputs = false; sendRequest.shuffleOutputs = false;
// we allow spending of unconfirmed tx (double spend risk is low and usability would suffer if we need to wait for 1 confirmation) // we allow spending of unconfirmed tx (double spend risk is low and usability would suffer if we need to
// wait for 1 confirmation)
sendRequest.coinSelector = new AddressBasedCoinSelector(params, getAddressInfoByTradeID(offerId), true); sendRequest.coinSelector = new AddressBasedCoinSelector(params, getAddressInfoByTradeID(offerId), true);
sendRequest.changeAddress = getAddressInfoByTradeID(offerId).getAddress(); sendRequest.changeAddress = getAddressInfoByTradeID(offerId).getAddress();
wallet.completeTx(sendRequest); wallet.completeTx(sendRequest);
@ -547,13 +562,15 @@ public class WalletFacade {
return tx; return tx;
} }
public void broadcastCreateOfferFeeTx(Transaction tx, FutureCallback<Transaction> callback) throws InsufficientMoneyException { public void broadcastCreateOfferFeeTx(Transaction tx, FutureCallback<Transaction> callback) throws
InsufficientMoneyException {
log.trace("broadcast tx"); log.trace("broadcast tx");
ListenableFuture<Transaction> future = walletAppKit.peerGroup().broadcastTransaction(tx); ListenableFuture<Transaction> future = walletAppKit.peerGroup().broadcastTransaction(tx);
Futures.addCallback(future, callback); Futures.addCallback(future, callback);
} }
public String payTakeOfferFee(String offerId, FutureCallback<Transaction> callback) throws InsufficientMoneyException { public String payTakeOfferFee(String offerId, FutureCallback<Transaction> callback) throws
InsufficientMoneyException {
Transaction tx = new Transaction(params); Transaction tx = new Transaction(params);
Coin fee = FeePolicy.TAKE_OFFER_FEE.subtract(FeePolicy.TX_FEE); Coin fee = FeePolicy.TAKE_OFFER_FEE.subtract(FeePolicy.TX_FEE);
log.trace("fee: " + fee.toFriendlyString()); log.trace("fee: " + fee.toFriendlyString());
@ -561,7 +578,8 @@ public class WalletFacade {
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx); Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx);
sendRequest.shuffleOutputs = false; sendRequest.shuffleOutputs = false;
// we allow spending of unconfirmed tx (double spend risk is low and usability would suffer if we need to wait for 1 confirmation) // we allow spending of unconfirmed tx (double spend risk is low and usability would suffer if we need to
// wait for 1 confirmation)
sendRequest.coinSelector = new AddressBasedCoinSelector(params, getAddressInfoByTradeID(offerId), true); sendRequest.coinSelector = new AddressBasedCoinSelector(params, getAddressInfoByTradeID(offerId), true);
sendRequest.changeAddress = getAddressInfoByTradeID(offerId).getAddress(); sendRequest.changeAddress = getAddressInfoByTradeID(offerId).getAddress();
Wallet.SendResult sendResult = wallet.sendCoins(sendRequest); Wallet.SendResult sendResult = wallet.sendCoins(sendRequest);
@ -583,13 +601,15 @@ public class WalletFacade {
String withdrawToAddress, String withdrawToAddress,
String changeAddress, String changeAddress,
Coin amount, Coin amount,
FutureCallback<Transaction> callback) throws AddressFormatException, InsufficientMoneyException, IllegalArgumentException { FutureCallback<Transaction> callback) throws AddressFormatException,
InsufficientMoneyException, IllegalArgumentException {
Transaction tx = new Transaction(params); Transaction tx = new Transaction(params);
tx.addOutput(amount.subtract(FeePolicy.TX_FEE), new Address(params, withdrawToAddress)); tx.addOutput(amount.subtract(FeePolicy.TX_FEE), new Address(params, withdrawToAddress));
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx); Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx);
sendRequest.shuffleOutputs = false; sendRequest.shuffleOutputs = false;
// we allow spending of unconfirmed tx (double spend risk is low and usability would suffer if we need to wait for 1 confirmation) // we allow spending of unconfirmed tx (double spend risk is low and usability would suffer if we need to
// wait for 1 confirmation)
Optional<AddressEntry> addressEntry = getAddressEntryByAddressString(withdrawFromAddress); Optional<AddressEntry> addressEntry = getAddressEntryByAddressString(withdrawFromAddress);
if (!addressEntry.isPresent()) if (!addressEntry.isPresent())
@ -646,7 +666,8 @@ public class WalletFacade {
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx); Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx);
sendRequest.shuffleOutputs = false; sendRequest.shuffleOutputs = false;
AddressEntry addressEntry = getAddressInfoByTradeID(tradeId); AddressEntry addressEntry = getAddressInfoByTradeID(tradeId);
// we allow spending of unconfirmed tx (double spend risk is low and usability would suffer if we need to wait for 1 confirmation) // we allow spending of unconfirmed tx (double spend risk is low and usability would suffer if we need to
// wait for 1 confirmation)
sendRequest.coinSelector = new AddressBasedCoinSelector(params, addressEntry, true); sendRequest.coinSelector = new AddressBasedCoinSelector(params, addressEntry, true);
sendRequest.changeAddress = addressEntry.getAddress(); sendRequest.changeAddress = addressEntry.getAddress();
wallet.completeTx(sendRequest); wallet.completeTx(sendRequest);
@ -693,7 +714,8 @@ public class WalletFacade {
// We pay the btc tx fee 2 times to the deposit tx: // We pay the btc tx fee 2 times to the deposit tx:
// 1. will be spent to miners when publishing the deposit tx // 1. will be spent to miners when publishing the deposit tx
// 2. will be as added to the MS amount, so when spending the payout tx the fee is already there and the outputs are not changed by fee reduction // 2. will be as added to the MS amount, so when spending the payout tx the fee is already there and the
// outputs are not changed by fee reduction
// Both traders pay 1 times a fee, so it is equally split between them // Both traders pay 1 times a fee, so it is equally split between them
// We do exactly the same as in the 1. step but with the takers input. // We do exactly the same as in the 1. step but with the takers input.
@ -704,14 +726,16 @@ public class WalletFacade {
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tempTx); Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tempTx);
sendRequest.shuffleOutputs = false; sendRequest.shuffleOutputs = false;
AddressEntry addressEntry = getAddressInfoByTradeID(tradeId); AddressEntry addressEntry = getAddressInfoByTradeID(tradeId);
// we allow spending of unconfirmed tx (double spend risk is low and usability would suffer if we need to wait for 1 confirmation) // we allow spending of unconfirmed tx (double spend risk is low and usability would suffer if we need to
// wait for 1 confirmation)
sendRequest.coinSelector = new AddressBasedCoinSelector(params, addressEntry, true); sendRequest.coinSelector = new AddressBasedCoinSelector(params, addressEntry, true);
sendRequest.changeAddress = addressEntry.getAddress(); sendRequest.changeAddress = addressEntry.getAddress();
wallet.completeTx(sendRequest); wallet.completeTx(sendRequest);
printInputs("tempTx", tempTx); printInputs("tempTx", tempTx);
log.trace("tempTx=" + tempTx); log.trace("tempTx=" + tempTx);
// That tx has signed input, but we don't need to remove it as we don't send that tx out, it is just used temporary. // That tx has signed input, but we don't need to remove it as we don't send that tx out,
// it is just used temporary.
// The created tempTx looks like: // The created tempTx looks like:
/* /*
@ -807,7 +831,8 @@ public class WalletFacade {
log.trace("takersSignedScriptSigAsHex=" + takersSignedScriptSigAsHex); log.trace("takersSignedScriptSigAsHex=" + takersSignedScriptSigAsHex);
log.trace("callback=" + callback); log.trace("callback=" + callback);
// We create an empty tx (did not find a way to manipulate a tx input, otherwise the takers tx could be used directly and add the offerers input and output) // We create an empty tx (did not find a way to manipulate a tx input, otherwise the takers tx could be used
// directly and add the offerers input and output)
Transaction tx = new Transaction(params); Transaction tx = new Transaction(params);
// offerers first tx // offerers first tx
@ -817,11 +842,16 @@ public class WalletFacade {
log.trace("offerersFirstTx = " + offerersFirstTx); log.trace("offerersFirstTx = " + offerersFirstTx);
// add input // add input
Transaction offerersFirstTxConnOut = wallet.getTransaction(offerersFirstTx.getInput(0).getOutpoint().getHash()); // pass that around! Transaction offerersFirstTxConnOut = wallet.getTransaction(offerersFirstTx.getInput(0).getOutpoint().getHash
TransactionOutPoint offerersFirstTxOutPoint = new TransactionOutPoint(params, offererTxOutIndex, offerersFirstTxConnOut); ()); // pass that around!
//TransactionInput offerersFirstTxInput = new TransactionInput(params, tx, offerersFirstTx.getInput(0).getScriptBytes(), offerersFirstTxOutPoint); // pass that around! getScriptBytes = TransactionOutPoint offerersFirstTxOutPoint = new TransactionOutPoint(params, offererTxOutIndex,
offerersFirstTxConnOut);
//TransactionInput offerersFirstTxInput = new TransactionInput(params, tx,
// offerersFirstTx.getInput(0).getScriptBytes(), offerersFirstTxOutPoint); // pass that around!
// getScriptBytes =
// empty bytes array // empty bytes array
TransactionInput offerersFirstTxInput = new TransactionInput(params, tx, new byte[]{}, offerersFirstTxOutPoint); // pass that around! getScriptBytes = empty bytes array TransactionInput offerersFirstTxInput = new TransactionInput(params, tx, new byte[]{},
offerersFirstTxOutPoint); // pass that around! getScriptBytes = empty bytes array
offerersFirstTxInput.setParent(tx); offerersFirstTxInput.setParent(tx);
tx.addInput(offerersFirstTxInput); tx.addInput(offerersFirstTxInput);
@ -833,8 +863,10 @@ public class WalletFacade {
// add input // add input
Transaction takersSignedTxConnOut = new Transaction(params, Utils.parseAsHexOrBase58(takersSignedConnOutAsHex)); Transaction takersSignedTxConnOut = new Transaction(params, Utils.parseAsHexOrBase58(takersSignedConnOutAsHex));
TransactionOutPoint takersSignedTxOutPoint = new TransactionOutPoint(params, takerTxOutIndex, takersSignedTxConnOut); TransactionOutPoint takersSignedTxOutPoint = new TransactionOutPoint(params, takerTxOutIndex,
TransactionInput takersSignedTxInput = new TransactionInput(params, tx, Utils.parseAsHexOrBase58(takersSignedScriptSigAsHex), takersSignedTxOutPoint); takersSignedTxConnOut);
TransactionInput takersSignedTxInput = new TransactionInput(params, tx,
Utils.parseAsHexOrBase58(takersSignedScriptSigAsHex), takersSignedTxOutPoint);
takersSignedTxInput.setParent(tx); takersSignedTxInput.setParent(tx);
tx.addInput(takersSignedTxInput); tx.addInput(takersSignedTxInput);
@ -933,7 +965,8 @@ public class WalletFacade {
Coin offererPaybackAmount, Coin offererPaybackAmount,
Coin takerPaybackAmount, Coin takerPaybackAmount,
String takerAddress, String takerAddress,
String tradeID) throws AddressFormatException { String tradeID) throws
AddressFormatException {
log.debug("offererCreatesAndSignsPayoutTx"); log.debug("offererCreatesAndSignsPayoutTx");
log.trace("inputs: "); log.trace("inputs: ");
log.trace("depositTxID=" + depositTxID); log.trace("depositTxID=" + depositTxID);
@ -946,7 +979,8 @@ public class WalletFacade {
String depositTxAsHex = Utils.HEX.encode(depositTx.bitcoinSerialize()); String depositTxAsHex = Utils.HEX.encode(depositTx.bitcoinSerialize());
// We create the payout tx // We create the payout tx
Transaction tx = createPayoutTx(depositTxAsHex, offererPaybackAmount, takerPaybackAmount, getAddressInfoByTradeID(tradeID).getAddressString(), takerAddress); Transaction tx = createPayoutTx(depositTxAsHex, offererPaybackAmount, takerPaybackAmount,
getAddressInfoByTradeID(tradeID).getAddressString(), takerAddress);
// We create the signature for that tx // We create the signature for that tx
TransactionOutput multiSigOutput = tx.getInput(0).getConnectedOutput(); TransactionOutput multiSigOutput = tx.getInput(0).getConnectedOutput();
@ -982,7 +1016,8 @@ public class WalletFacade {
log.trace("callback=" + callback); log.trace("callback=" + callback);
// We create the payout tx // We create the payout tx
Transaction tx = createPayoutTx(depositTxAsHex, offererPaybackAmount, takerPaybackAmount, offererAddress, getAddressInfoByTradeID(tradeID).getAddressString()); Transaction tx = createPayoutTx(depositTxAsHex, offererPaybackAmount, takerPaybackAmount, offererAddress,
getAddressInfoByTradeID(tradeID).getAddressString());
// We sign that tx with our key and apply the signature form the offerer // We sign that tx with our key and apply the signature form the offerer
TransactionOutput multiSigOutput = tx.getInput(0).getConnectedOutput(); TransactionOutput multiSigOutput = tx.getInput(0).getConnectedOutput();
@ -993,7 +1028,8 @@ public class WalletFacade {
ECKey.ECDSASignature takerSignature = getAddressInfoByTradeID(tradeID).getKey().sign(sigHash); ECKey.ECDSASignature takerSignature = getAddressInfoByTradeID(tradeID).getKey().sign(sigHash);
TransactionSignature takerTxSig = new TransactionSignature(takerSignature, Transaction.SigHash.ALL, false); TransactionSignature takerTxSig = new TransactionSignature(takerSignature, Transaction.SigHash.ALL, false);
ECKey.ECDSASignature offererSignature = new ECKey.ECDSASignature(new BigInteger(offererSignatureR), new BigInteger(offererSignatureS)); ECKey.ECDSASignature offererSignature = new ECKey.ECDSASignature(new BigInteger(offererSignatureR),
new BigInteger(offererSignatureS));
TransactionSignature offererTxSig = new TransactionSignature(offererSignature, Transaction.SigHash.ALL, false); TransactionSignature offererTxSig = new TransactionSignature(offererSignature, Transaction.SigHash.ALL, false);
Script inputScript = ScriptBuilder.createMultiSigInputScript(ImmutableList.of(offererTxSig, takerTxSig)); Script inputScript = ScriptBuilder.createMultiSigInputScript(ImmutableList.of(offererTxSig, takerTxSig));
@ -1043,7 +1079,8 @@ public class WalletFacade {
} }
private Transaction createPayoutTx(String depositTxAsHex, Coin offererPaybackAmount, Coin takerPaybackAmount, String offererAddress, String takerAddress) throws AddressFormatException { private Transaction createPayoutTx(String depositTxAsHex, Coin offererPaybackAmount, Coin takerPaybackAmount,
String offererAddress, String takerAddress) throws AddressFormatException {
log.trace("createPayoutTx"); log.trace("createPayoutTx");
log.trace("inputs: "); log.trace("inputs: ");
log.trace("depositTxAsHex=" + depositTxAsHex); log.trace("depositTxAsHex=" + depositTxAsHex);
@ -1067,7 +1104,8 @@ public class WalletFacade {
if (input.getConnectedOutput() != null) { if (input.getConnectedOutput() != null) {
log.trace(tracePrefix + " input value : " + input.getConnectedOutput().getValue().toFriendlyString()); log.trace(tracePrefix + " input value : " + input.getConnectedOutput().getValue().toFriendlyString());
} else { } else {
log.trace(tracePrefix + ": " + "Transaction already has inputs but we don't have the connected outputs, so we don't know the value."); log.trace(tracePrefix + ": " + "Transaction already has inputs but we don't have the connected " +
"outputs, so we don't know the value.");
} }
} }
} }

View file

@ -70,7 +70,8 @@ public class CryptoFacade {
public byte[] getEmbeddedAccountRegistrationData(ECKey registrationKey, String stringifiedBankAccounts) { public byte[] getEmbeddedAccountRegistrationData(ECKey registrationKey, String stringifiedBankAccounts) {
String signedBankAccountIDs = signMessage(registrationKey, stringifiedBankAccounts, null); String signedBankAccountIDs = signMessage(registrationKey, stringifiedBankAccounts, null);
return Utils.sha256hash160(concatenateChunks(stringifiedBankAccounts, signedBankAccountIDs).getBytes(Charsets.UTF_8)); return Utils.sha256hash160(concatenateChunks(stringifiedBankAccounts, signedBankAccountIDs).getBytes(Charsets
.UTF_8));
} }
public String signContract(ECKey key, String contractAsJson) { public String signContract(ECKey key, String contractAsJson) {

View file

@ -74,8 +74,10 @@ public class BitSquareModule extends AbstractModule {
// bind(Boolean.class).annotatedWith(Names.named("useDiskStorage")).toInstance(new Boolean(true)); // bind(Boolean.class).annotatedWith(Names.named("useDiskStorage")).toInstance(new Boolean(true));
bind(Boolean.class).annotatedWith(Names.named("useDiskStorage")).toInstance(new Boolean(false)); bind(Boolean.class).annotatedWith(Names.named("useDiskStorage")).toInstance(new Boolean(false));
bind(SeedNodeAddress.StaticSeedNodeAddresses.class).annotatedWith(Names.named("defaultSeedNode")).toInstance(SeedNodeAddress.StaticSeedNodeAddresses.LOCALHOST); bind(SeedNodeAddress.StaticSeedNodeAddresses.class).annotatedWith(Names.named("defaultSeedNode")).toInstance
// bind(SeedNodeAddress.StaticSeedNodeAddresses.class).annotatedWith(Names.named("defaultSeedNode")).toInstance(SeedNodeAddress.StaticSeedNodeAddresses.DIGITAL_OCEAN); (SeedNodeAddress.StaticSeedNodeAddresses.LOCALHOST);
// bind(SeedNodeAddress.StaticSeedNodeAddresses.class).annotatedWith(Names.named("defaultSeedNode"))
// .toInstance(SeedNodeAddress.StaticSeedNodeAddresses.DIGITAL_OCEAN);
} }
} }

View file

@ -24,7 +24,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* If caching is used for loader we use the CachedViewController for turning the controller into sleep mode if not active and awake it at reactivation. * If caching is used for loader we use the CachedViewController for turning the controller into sleep mode if not
* active and awake it at reactivation.
*/ */
public abstract class CachedViewController extends ViewController { public abstract class CachedViewController extends ViewController {
private static final Logger log = LoggerFactory.getLogger(CachedViewController.class); private static final Logger log = LoggerFactory.getLogger(CachedViewController.class);
@ -43,7 +44,8 @@ public abstract class CachedViewController extends ViewController {
root.sceneProperty().addListener((ov, oldValue, newValue) -> { root.sceneProperty().addListener((ov, oldValue, newValue) -> {
// we got removed from the scene // we got removed from the scene
// lets terminate // lets terminate
log.trace("Lifecycle: sceneProperty changed: " + this.getClass().getSimpleName() + " / oldValue=" + oldValue + " / newValue=" + newValue); log.trace("Lifecycle: sceneProperty changed: " + this.getClass().getSimpleName() + " / oldValue=" +
oldValue + " / newValue=" + newValue);
if (oldValue == null && newValue != null) activate(); if (oldValue == null && newValue != null) activate();
else if (oldValue != null && newValue == null) deactivate(); else if (oldValue != null && newValue == null) deactivate();
}); });

View file

@ -59,8 +59,10 @@ import org.slf4j.LoggerFactory;
/** /**
* Holds the splash screen and the application views. * Holds the splash screen and the application views.
* It builds up all the views and initializes the facades. * It builds up all the views and initializes the facades.
* We use a sequence of Platform.runLater cascaded calls to make the startup more smooth, otherwise the rendering is frozen for too long. * We use a sequence of Platform.runLater cascaded calls to make the startup more smooth,
* Pre-loading of views is not implemented yet, and after a quick test it seemed that it does not give much improvements. * otherwise the rendering is frozen for too long.
* Pre-loading of views is not implemented yet, and after a quick test it seemed that it does not give much
* improvements.
*/ */
public class MainController extends ViewController { public class MainController extends ViewController {
private static final Logger log = LoggerFactory.getLogger(MainController.class); private static final Logger log = LoggerFactory.getLogger(MainController.class);
@ -97,7 +99,8 @@ public class MainController extends ViewController {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
private MainController(User user, WalletFacade walletFacade, MessageFacade messageFacade, TradeManager tradeManager, Persistence persistence) { private MainController(User user, WalletFacade walletFacade, MessageFacade messageFacade,
TradeManager tradeManager, Persistence persistence) {
this.user = user; this.user = user;
this.walletFacade = walletFacade; this.walletFacade = walletFacade;
this.messageFacade = messageFacade; this.messageFacade = messageFacade;
@ -279,9 +282,11 @@ public class MainController extends ViewController {
user.getBankAccountsSizeProperty().addListener((observableValue, oldValue, newValue) -> { user.getBankAccountsSizeProperty().addListener((observableValue, oldValue, newValue) -> {
if ((int) newValue == 2) if ((int) newValue == 2)
viewBuilder.rightNavPane.getChildren().add(1, accountComboBoxHolder);// accountComboBoxHolder.setVisible(true); viewBuilder.rightNavPane.getChildren().add(1, accountComboBoxHolder);// accountComboBoxHolder
// .setVisible(true);
else if ((int) newValue < 2) else if ((int) newValue < 2)
viewBuilder.rightNavPane.getChildren().remove(accountComboBoxHolder);//accountComboBoxHolder.setVisible(false); viewBuilder.rightNavPane.getChildren().remove(accountComboBoxHolder);//accountComboBoxHolder
// .setVisible(false);
}); });
settingsButton = addNavButton(viewBuilder.rightNavPane, "Settings", NavigationItem.SETTINGS); settingsButton = addNavButton(viewBuilder.rightNavPane, "Settings", NavigationItem.SETTINGS);
@ -382,7 +387,8 @@ public class MainController extends ViewController {
} }
private void addAccountComboBox(Pane parent) { private void addAccountComboBox(Pane parent) {
final ComboBox<BankAccount> accountComboBox = new ComboBox<>(FXCollections.observableArrayList(user.getBankAccounts())); final ComboBox<BankAccount> accountComboBox = new ComboBox<>(FXCollections.observableArrayList(user
.getBankAccounts()));
accountComboBox.setId("nav-account-combo-box"); accountComboBox.setId("nav-account-combo-box");
accountComboBox.setLayoutY(12); accountComboBox.setLayoutY(12);
if (user.getCurrentBankAccount() != null) if (user.getCurrentBankAccount() != null)
@ -400,7 +406,8 @@ public class MainController extends ViewController {
} }
}); });
user.getSelectedBankAccountIndexProperty().addListener(observable -> accountComboBox.getSelectionModel().select(user.getCurrentBankAccount())); user.getSelectedBankAccountIndexProperty().addListener(observable -> accountComboBox.getSelectionModel()
.select(user.getCurrentBankAccount()));
user.getBankAccountsSizeProperty().addListener(observable -> { user.getBankAccountsSizeProperty().addListener(observable -> {
accountComboBox.setItems(FXCollections.observableArrayList(user.getBankAccounts())); accountComboBox.setItems(FXCollections.observableArrayList(user.getBankAccounts()));
// need to delay it a bit otherwise it will not be set // need to delay it a bit otherwise it will not be set

View file

@ -54,7 +54,8 @@ public abstract class ViewController implements Initializable {
} }
/** /**
* Called automatically when view gets removed. Used for house keeping (removing listeners, stopping timers or animations,...). * Called automatically when view gets removed. Used for house keeping (removing listeners,
* stopping timers or animations,...).
*/ */
public void terminate() { public void terminate() {
log.trace("Lifecycle: terminate " + this.getClass().getSimpleName()); log.trace("Lifecycle: terminate " + this.getClass().getSimpleName());
@ -62,10 +63,12 @@ public abstract class ViewController implements Initializable {
} }
/** /**
* @param parentController Controller who has created this.getClass().getSimpleName() instance (via navigateToView/FXMLLoader). * @param parentController Controller who has created this.getClass().getSimpleName() instance (via
* navigateToView/FXMLLoader).
*/ */
public void setParentController(ViewController parentController) { public void setParentController(ViewController parentController) {
log.trace("Lifecycle: setParentController " + this.getClass().getSimpleName() + " / parent = " + parentController); log.trace("Lifecycle: setParentController " + this.getClass().getSimpleName() + " / parent = " +
parentController);
this.parentController = parentController; this.parentController = parentController;
} }
@ -74,7 +77,8 @@ public abstract class ViewController implements Initializable {
* @return The ViewController of the loaded view. * @return The ViewController of the loaded view.
*/ */
public ViewController loadViewAndGetChildController(NavigationItem navigationItem) { public ViewController loadViewAndGetChildController(NavigationItem navigationItem) {
log.trace("Lifecycle: loadViewAndGetChildController " + this.getClass().getSimpleName() + " / navigationItem = " + navigationItem); log.trace("Lifecycle: loadViewAndGetChildController " + this.getClass().getSimpleName() + " / navigationItem " +
"= " + navigationItem);
return null; return null;
} }

View file

@ -44,7 +44,8 @@ public class ArbitratorProfileController extends CachedViewController {
@FXML private Label nameLabel; @FXML private Label nameLabel;
@FXML private TextField nameTextField, languagesTextField, reputationTextField, maxTradeVolumeTextField, passiveServiceFeeTextField, arbitrationFeeTextField, methodsTextField, @FXML private TextField nameTextField, languagesTextField, reputationTextField, maxTradeVolumeTextField,
passiveServiceFeeTextField, arbitrationFeeTextField, methodsTextField,
idVerificationsTextField, webPageTextField; idVerificationsTextField, webPageTextField;
@FXML private TextArea descriptionTextArea; @FXML private TextArea descriptionTextArea;
@ -127,10 +128,13 @@ public class ArbitratorProfileController extends CachedViewController {
languagesTextField.setText(BitSquareFormatter.languageLocalesToString(arbitrator.getLanguages())); languagesTextField.setText(BitSquareFormatter.languageLocalesToString(arbitrator.getLanguages()));
reputationTextField.setText(arbitrator.getReputation().toString()); reputationTextField.setText(arbitrator.getReputation().toString());
maxTradeVolumeTextField.setText(String.valueOf(arbitrator.getMaxTradeVolume()) + " BTC"); maxTradeVolumeTextField.setText(String.valueOf(arbitrator.getMaxTradeVolume()) + " BTC");
passiveServiceFeeTextField.setText(String.valueOf(arbitrator.getPassiveServiceFee()) + " % (Min. " + String.valueOf(arbitrator.getMinPassiveServiceFee()) + " BTC)"); passiveServiceFeeTextField.setText(String.valueOf(arbitrator.getPassiveServiceFee()) + " % (Min. " +
arbitrationFeeTextField.setText(String.valueOf(arbitrator.getArbitrationFee()) + " % (Min. " + String.valueOf(arbitrator.getMinArbitrationFee()) + " BTC)"); String.valueOf(arbitrator.getMinPassiveServiceFee()) + " BTC)");
arbitrationFeeTextField.setText(String.valueOf(arbitrator.getArbitrationFee()) + " % (Min. " + String
.valueOf(arbitrator.getMinArbitrationFee()) + " BTC)");
methodsTextField.setText(BitSquareFormatter.arbitrationMethodsToString(arbitrator.getArbitrationMethods())); methodsTextField.setText(BitSquareFormatter.arbitrationMethodsToString(arbitrator.getArbitrationMethods()));
idVerificationsTextField.setText(BitSquareFormatter.arbitrationIDVerificationsToString(arbitrator.getIdVerifications())); idVerificationsTextField.setText(BitSquareFormatter.arbitrationIDVerificationsToString(arbitrator
.getIdVerifications()));
webPageTextField.setText(arbitrator.getWebUrl()); webPageTextField.setText(arbitrator.getWebUrl());
descriptionTextArea.setText(arbitrator.getDescription()); descriptionTextArea.setText(arbitrator.getDescription());
} }

View file

@ -83,8 +83,10 @@ public class ArbitratorRegistrationController extends CachedViewController {
@FXML private ComboBox<Arbitrator.ID_TYPE> idTypeComboBox; @FXML private ComboBox<Arbitrator.ID_TYPE> idTypeComboBox;
@FXML private ComboBox<Arbitrator.METHOD> methodsComboBox; @FXML private ComboBox<Arbitrator.METHOD> methodsComboBox;
@FXML private ComboBox<Arbitrator.ID_VERIFICATION> idVerificationsComboBox; @FXML private ComboBox<Arbitrator.ID_VERIFICATION> idVerificationsComboBox;
@FXML private TextField nameTextField, idTypeTextField, languagesTextField, maxTradeVolumeTextField, passiveServiceFeeTextField, minPassiveServiceFeeTextField, arbitrationFeeTextField, @FXML private TextField nameTextField, idTypeTextField, languagesTextField, maxTradeVolumeTextField,
minArbitrationFeeTextField, methodsTextField, idVerificationsTextField, webPageTextField, collateralAddressTextField, balanceTextField; passiveServiceFeeTextField, minPassiveServiceFeeTextField, arbitrationFeeTextField,
minArbitrationFeeTextField, methodsTextField, idVerificationsTextField, webPageTextField,
collateralAddressTextField, balanceTextField;
@FXML private TextArea descriptionTextArea; @FXML private TextArea descriptionTextArea;
@FXML private ConfidenceProgressIndicator progressIndicator; @FXML private ConfidenceProgressIndicator progressIndicator;
@ -94,7 +96,8 @@ public class ArbitratorRegistrationController extends CachedViewController {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
private ArbitratorRegistrationController(Persistence persistence, WalletFacade walletFacade, MessageFacade messageFacade, User user) { private ArbitratorRegistrationController(Persistence persistence, WalletFacade walletFacade,
MessageFacade messageFacade, User user) {
this.persistence = persistence; this.persistence = persistence;
this.walletFacade = walletFacade; this.walletFacade = walletFacade;
this.messageFacade = messageFacade; this.messageFacade = messageFacade;
@ -135,7 +138,8 @@ public class ArbitratorRegistrationController extends CachedViewController {
} }
}); });
idTypeComboBox.setItems(FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.ID_TYPE.class)))); idTypeComboBox.setItems(FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.ID_TYPE
.class))));
idTypeComboBox.setConverter(new StringConverter<Arbitrator.ID_TYPE>() { idTypeComboBox.setConverter(new StringConverter<Arbitrator.ID_TYPE>() {
@Override @Override
@ -150,7 +154,8 @@ public class ArbitratorRegistrationController extends CachedViewController {
} }
}); });
methodsComboBox.setItems(FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.METHOD.class)))); methodsComboBox.setItems(FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.METHOD
.class))));
methodsComboBox.setConverter(new StringConverter<Arbitrator.METHOD>() { methodsComboBox.setConverter(new StringConverter<Arbitrator.METHOD>() {
@Override @Override
@ -165,7 +170,8 @@ public class ArbitratorRegistrationController extends CachedViewController {
} }
}); });
idVerificationsComboBox.setItems(FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator.ID_VERIFICATION.class)))); idVerificationsComboBox.setItems(FXCollections.observableArrayList(new ArrayList<>(EnumSet.allOf(Arbitrator
.ID_VERIFICATION.class))));
idVerificationsComboBox.setConverter(new StringConverter<Arbitrator.ID_VERIFICATION>() { idVerificationsComboBox.setConverter(new StringConverter<Arbitrator.ID_VERIFICATION>() {
@Override @Override
@ -294,7 +300,8 @@ public class ArbitratorRegistrationController extends CachedViewController {
if (idVerification != null) { if (idVerification != null) {
if (!idVerificationList.contains(idVerification)) { if (!idVerificationList.contains(idVerification)) {
idVerificationList.add(idVerification); idVerificationList.add(idVerification);
idVerificationsTextField.setText(BitSquareFormatter.arbitrationIDVerificationsToString(idVerificationList)); idVerificationsTextField.setText(BitSquareFormatter.arbitrationIDVerificationsToString
(idVerificationList));
} }
} }
@ -336,14 +343,18 @@ public class ArbitratorRegistrationController extends CachedViewController {
private void setupPayCollateralScreen() { private void setupPayCollateralScreen() {
infoLabel.setText("You need to pay 10 x the max. trading volume as collateral.\n\n" + infoLabel.setText("You need to pay 10 x the max. trading volume as collateral.\n\n" +
"That payment will be locked into a MultiSig fund and be refunded when you leave the arbitration pool.\n" + "That payment will be locked into a MultiSig fund and be refunded when you leave the arbitration pool" +
"In case of fraud (collusion, not fulfilling the min. dispute quality requirements) you will lose your collateral.\n" + ".\n" +
"In case of fraud (collusion, not fulfilling the min. dispute quality requirements) you will lose " +
"your collateral.\n" +
"If you have a negative feedback from your clients you will lose a part of the collateral,\n" + "If you have a negative feedback from your clients you will lose a part of the collateral,\n" +
"depending on the overall relation of negative to positive ratings you received after a dispute resolution.\n\n" + "depending on the overall relation of negative to positive ratings you received after a dispute " +
"resolution.\n\n" +
"Please pay in " + arbitrator.getMaxTradeVolume() * 10 + " BTC"); "Please pay in " + arbitrator.getMaxTradeVolume() * 10 + " BTC");
String collateralAddress = walletFacade.getRegistrationAddressEntry() != null ? walletFacade.getRegistrationAddressEntry().toString() : ""; String collateralAddress = walletFacade.getRegistrationAddressEntry() != null ? walletFacade
.getRegistrationAddressEntry().toString() : "";
collateralAddressTextField.setText(collateralAddress); collateralAddressTextField.setText(collateralAddress);
AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY); AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY);
@ -354,7 +365,8 @@ public class ArbitratorRegistrationController extends CachedViewController {
clipboard.setContent(content); clipboard.setContent(content);
}); });
confidenceDisplay = new ConfidenceDisplay(walletFacade.getWallet(), confirmationLabel, balanceTextField, progressIndicator); confidenceDisplay = new ConfidenceDisplay(walletFacade.getWallet(), confirmationLabel, balanceTextField,
progressIndicator);
paymentDoneButton.setDisable(walletFacade.getArbitratorDepositBalance().isZero()); paymentDoneButton.setDisable(walletFacade.getArbitratorDepositBalance().isZero());
log.debug("getArbitratorDepositBalance " + walletFacade.getArbitratorDepositBalance()); log.debug("getArbitratorDepositBalance " + walletFacade.getArbitratorDepositBalance());
walletFacade.getWallet().addEventListener(new WalletEventListener() { walletFacade.getWallet().addEventListener(new WalletEventListener() {
@ -420,7 +432,8 @@ public class ArbitratorRegistrationController extends CachedViewController {
arbitrationFeeTextField.setText(String.valueOf(arbitrator.getArbitrationFee())); arbitrationFeeTextField.setText(String.valueOf(arbitrator.getArbitrationFee()));
minArbitrationFeeTextField.setText(String.valueOf(arbitrator.getMinArbitrationFee())); minArbitrationFeeTextField.setText(String.valueOf(arbitrator.getMinArbitrationFee()));
methodsTextField.setText(BitSquareFormatter.arbitrationMethodsToString(arbitrator.getArbitrationMethods())); methodsTextField.setText(BitSquareFormatter.arbitrationMethodsToString(arbitrator.getArbitrationMethods()));
idVerificationsTextField.setText(BitSquareFormatter.arbitrationIDVerificationsToString(arbitrator.getIdVerifications())); idVerificationsTextField.setText(BitSquareFormatter.arbitrationIDVerificationsToString(arbitrator
.getIdVerifications()));
webPageTextField.setText(arbitrator.getWebUrl()); webPageTextField.setText(arbitrator.getWebUrl());
descriptionTextArea.setText(arbitrator.getDescription()); descriptionTextArea.setText(arbitrator.getDescription());
@ -434,7 +447,8 @@ public class ArbitratorRegistrationController extends CachedViewController {
private Arbitrator getEditedArbitrator() { private Arbitrator getEditedArbitrator() {
try { try {
BitSquareValidator.textFieldsNotEmptyWithReset(nameTextField, idTypeTextField, languagesTextField, methodsTextField, idVerificationsTextField); BitSquareValidator.textFieldsNotEmptyWithReset(nameTextField, idTypeTextField, languagesTextField,
methodsTextField, idVerificationsTextField);
BitSquareValidator.textFieldsHasDoubleValueWithReset(maxTradeVolumeTextField, BitSquareValidator.textFieldsHasDoubleValueWithReset(maxTradeVolumeTextField,
passiveServiceFeeTextField, passiveServiceFeeTextField,
minPassiveServiceFeeTextField, minPassiveServiceFeeTextField,

View file

@ -38,7 +38,8 @@ public class Popups {
} }
public static void openInformationPopup(String title, String message, String masthead) { public static void openInformationPopup(String title, String message, String masthead) {
Dialogs.create().owner(BitSquare.getPrimaryStage()).title(title).message(message).masthead(masthead).showInformation(); Dialogs.create().owner(BitSquare.getPrimaryStage()).title(title).message(message).masthead(masthead)
.showInformation();
} }
// Confirm // Confirm
@ -54,7 +55,8 @@ public class Popups {
} }
public static Action openConfirmPopup(String title, String message, String masthead, List<Action> actions) { public static Action openConfirmPopup(String title, String message, String masthead, List<Action> actions) {
return Dialogs.create().owner(BitSquare.getPrimaryStage()).title(title).message(message).masthead(masthead).actions(actions).showConfirm(); return Dialogs.create().owner(BitSquare.getPrimaryStage()).title(title).message(message).masthead(masthead)
.actions(actions).showConfirm();
} }
// Warning // Warning
@ -67,7 +69,8 @@ public class Popups {
} }
public static void openWarningPopup(String title, String message, String masthead) { public static void openWarningPopup(String title, String message, String masthead) {
Dialogs.create().owner(BitSquare.getPrimaryStage()).title(title).message(message).masthead(masthead).showWarning(); Dialogs.create().owner(BitSquare.getPrimaryStage()).title(title).message(message).masthead(masthead)
.showWarning();
} }
// Error // Error
@ -80,7 +83,8 @@ public class Popups {
} }
public static Action openErrorPopup(String title, String message, String masthead) { public static Action openErrorPopup(String title, String message, String masthead) {
return Dialogs.create().owner(BitSquare.getPrimaryStage()).title(title).message(message).masthead(masthead).showError(); return Dialogs.create().owner(BitSquare.getPrimaryStage()).title(title).message(message).masthead(masthead)
.showError();
} }
// Exception // Exception
@ -93,7 +97,8 @@ public class Popups {
} }
public static Action openExceptionPopup(Throwable throwable, String title, String message, String masthead) { public static Action openExceptionPopup(Throwable throwable, String title, String message, String masthead) {
return Dialogs.create().owner(BitSquare.getPrimaryStage()).title(title).message(message).masthead(masthead).showException(throwable); return Dialogs.create().owner(BitSquare.getPrimaryStage()).title(title).message(message).masthead(masthead)
.showException(throwable);
} }
// Support handling of uncaught exception from any thread (also non gui thread) // Support handling of uncaught exception from any thread (also non gui thread)
@ -104,10 +109,13 @@ public class Popups {
Runnable runnable = () -> { Runnable runnable = () -> {
if (Throwables.getRootCause(throwable) instanceof BlockStoreException) { if (Throwables.getRootCause(throwable) instanceof BlockStoreException) {
Action response = Popups.openErrorPopup("Application already running", "This application is already running and cannot be started twice.", ""); Action response = Popups.openErrorPopup("Application already running",
"This application is already running and cannot be started twice.", "");
if (response == Dialog.Actions.OK) Platform.exit(); if (response == Dialog.Actions.OK) Platform.exit();
} else { } else {
Action response = Popups.openExceptionPopup(throwable, "Exception", "", "A critical error has occurred.\nPlease copy the exception details and send a bug report to bugs@bitsquare.io."); Action response = Popups.openExceptionPopup(throwable, "Exception", "",
"A critical error has occurred.\nPlease copy the exception details and send a bug report to " +
"bugs@bitsquare.io.");
if (response == Dialog.Actions.OK) Platform.exit(); if (response == Dialog.Actions.OK) Platform.exit();
} }
}; };
@ -118,10 +126,13 @@ public class Popups {
// custom // custom
public static void openInsufficientMoneyPopup() { public static void openInsufficientMoneyPopup() {
openWarningPopup("Not enough money available", "There is not enough money available. Please pay in first to your wallet.", null); openWarningPopup("Not enough money available", "There is not enough money available. Please pay in first to " +
"your wallet.", null);
} }
public static Action openRegistrationMissingPopup(String title, String message, String masthead, List<Dialogs.CommandLink> commandLinks, int selectedIndex) { public static Action openRegistrationMissingPopup(String title, String message, String masthead,
return Dialogs.create().owner(BitSquare.getPrimaryStage()).title(title).message(message).masthead(masthead).showCommandLinks(commandLinks.get(selectedIndex), commandLinks); List<Dialogs.CommandLink> commandLinks, int selectedIndex) {
return Dialogs.create().owner(BitSquare.getPrimaryStage()).title(title).message(message).masthead(masthead)
.showCommandLinks(commandLinks.get(selectedIndex), commandLinks);
} }
} }

View file

@ -135,7 +135,8 @@ public class ValidatingTextField extends TextField {
}); });
focusedProperty().addListener((ov, oldValue, newValue) -> { focusedProperty().addListener((ov, oldValue, newValue) -> {
if (validateOnFocusOut && needsValidationOnFocusOut && !newValue && getScene() != null && getScene().getWindow().isFocused()) if (validateOnFocusOut && needsValidationOnFocusOut && !newValue && getScene() != null && getScene()
.getWindow().isFocused())
validate(getText()); validate(getText());
}); });

View file

@ -147,7 +147,8 @@ public class AddressTextField extends AnchorPane {
private String getBitcoinURI() { private String getBitcoinURI() {
Coin d = BitSquareFormatter.parseToCoin(amountToPay); Coin d = BitSquareFormatter.parseToCoin(amountToPay);
return BitcoinURI.convertToBitcoinURI(address, BitSquareFormatter.parseToCoin(amountToPay), BitSquare.getAppName(), null); return BitcoinURI.convertToBitcoinURI(address, BitSquareFormatter.parseToCoin(amountToPay),
BitSquare.getAppName(), null);
} }

View file

@ -127,7 +127,8 @@ public class BalanceTextField extends AnchorPane {
progressIndicator.setProgress(0); progressIndicator.setProgress(0);
break; break;
case PENDING: case PENDING:
progressIndicatorTooltip.setText("Seen by " + confidence.numBroadcastPeers() + " peer(s) / 0 confirmations"); progressIndicatorTooltip.setText("Seen by " + confidence.numBroadcastPeers() + " peer(s) / 0 " +
"confirmations");
progressIndicator.setProgress(-1.0); progressIndicator.setProgress(-1.0);
break; break;
case BUILDING: case BUILDING:

View file

@ -80,7 +80,8 @@ import javafx.scene.transform.Scale;
import javafx.util.Duration; import javafx.util.Duration;
@SuppressWarnings({"WeakerAccess", "SameReturnValue"}) @SuppressWarnings({"WeakerAccess", "SameReturnValue"})
public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<ConfidenceProgressIndicator, ConfidenceProgressIndicatorBehavior<ConfidenceProgressIndicator>> { public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<ConfidenceProgressIndicator,
ConfidenceProgressIndicatorBehavior<ConfidenceProgressIndicator>> {
/** /**
* ************************************************************************ * ************************************************************************
@ -226,7 +227,8 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
public void invalidated(Observable valueModel) { public void invalidated(Observable valueModel) {
if (getSkinnable().isIndeterminate() && timelineNulled && spinner == null) { if (getSkinnable().isIndeterminate() && timelineNulled && spinner == null) {
timelineNulled = false; timelineNulled = false;
spinner = new IndeterminateSpinner(getSkinnable(), ConfidenceProgressIndicatorSkin.this, spinEnabled.get(), progressColor.get()); spinner = new IndeterminateSpinner(getSkinnable(), ConfidenceProgressIndicatorSkin.this,
spinEnabled.get(), progressColor.get());
getChildren().add(spinner); getChildren().add(spinner);
} }
@ -258,7 +260,8 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
} else { } else {
if (getSkinnable().getScene() != null && getSkinnable().isIndeterminate()) { if (getSkinnable().getScene() != null && getSkinnable().isIndeterminate()) {
timelineNulled = false; timelineNulled = false;
spinner = new IndeterminateSpinner(getSkinnable(), ConfidenceProgressIndicatorSkin.this, spinEnabled.get(), progressColor.get()); spinner = new IndeterminateSpinner(getSkinnable(), ConfidenceProgressIndicatorSkin.this,
spinEnabled.get(), progressColor.get());
getChildren().add(spinner); getChildren().add(spinner);
if (getSkinnable().impl_isTreeVisible()) { if (getSkinnable().impl_isTreeVisible()) {
spinner.indeterminateTimeline.play(); spinner.indeterminateTimeline.play();
@ -303,7 +306,8 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
spinner = null; spinner = null;
} }
// create determinateIndicator // create determinateIndicator
determinateIndicator = new ConfidenceProgressIndicatorSkin.DeterminateIndicator(control, this, progressColor.get()); determinateIndicator = new ConfidenceProgressIndicatorSkin.DeterminateIndicator(control, this,
progressColor.get());
getChildren().clear(); getChildren().clear();
getChildren().add(determinateIndicator); getChildren().add(determinateIndicator);
} }
@ -373,7 +377,8 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
// only update pie arc to nearest degree // only update pie arc to nearest degree
private int degProgress; private int degProgress;
public DeterminateIndicator(ConfidenceProgressIndicator control, ConfidenceProgressIndicatorSkin s, Paint fillOverride) { public DeterminateIndicator(ConfidenceProgressIndicator control, ConfidenceProgressIndicatorSkin s,
Paint fillOverride) {
this.control = control; this.control = control;
getStyleClass().add("determinate-indicator"); getStyleClass().add("determinate-indicator");
@ -423,7 +428,9 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
private void setFillOverride(Paint fillOverride) { private void setFillOverride(Paint fillOverride) {
if (fillOverride instanceof Color) { if (fillOverride instanceof Color) {
Color c = (Color) fillOverride; Color c = (Color) fillOverride;
progress.setStyle("-fx-background-color: rgba(" + ((int) (255 * c.getRed())) + "," + ((int) (255 * c.getGreen())) + "," + ((int) (255 * c.getBlue())) + "," + c.getOpacity() + ");"); progress.setStyle("-fx-background-color: rgba(" + ((int) (255 * c.getRed())) + "," +
"" + ((int) (255 * c.getGreen())) + "," + ((int) (255 * c.getBlue())) + "," +
"" + c.getOpacity() + ");");
} else { } else {
progress.setStyle(null); progress.setStyle(null);
} }
@ -474,7 +481,8 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
final double iRight = snapSize(indicatorInsets.getRight()); final double iRight = snapSize(indicatorInsets.getRight());
final double iTop = snapSize(indicatorInsets.getTop()); final double iTop = snapSize(indicatorInsets.getTop());
final double iBottom = snapSize(indicatorInsets.getBottom()); final double iBottom = snapSize(indicatorInsets.getBottom());
final double progressRadius = snapSize(Math.min(Math.min(radius - iLeft, radius - iRight), Math.min(radius - iTop, radius - iBottom))); final double progressRadius = snapSize(Math.min(Math.min(radius - iLeft, radius - iRight),
Math.min(radius - iTop, radius - iBottom)));
indicatorCircle.setRadius(radius); indicatorCircle.setRadius(radius);
indicator.setLayoutX(centerX); indicator.setLayoutX(centerX);
@ -491,7 +499,8 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
final double pRight = snapSize(progressInsets.getRight()); final double pRight = snapSize(progressInsets.getRight());
final double pTop = snapSize(progressInsets.getTop()); final double pTop = snapSize(progressInsets.getTop());
final double pBottom = snapSize(progressInsets.getBottom()); final double pBottom = snapSize(progressInsets.getBottom());
final double indicatorRadius = snapSize(Math.min(Math.min(progressRadius - pLeft, progressRadius - pRight), Math.min(progressRadius - pTop, progressRadius - pBottom))); final double indicatorRadius = snapSize(Math.min(Math.min(progressRadius - pLeft,
progressRadius - pRight), Math.min(progressRadius - pTop, progressRadius - pBottom)));
// find size of spare box that fits inside indicator radius // find size of spare box that fits inside indicator radius
double squareBoxHalfWidth = Math.ceil(Math.sqrt((indicatorRadius * indicatorRadius) / 2)); double squareBoxHalfWidth = Math.ceil(Math.sqrt((indicatorRadius * indicatorRadius) / 2));
@ -594,7 +603,8 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
private Paint fillOverride = null; private Paint fillOverride = null;
public IndeterminateSpinner(ConfidenceProgressIndicator control, ConfidenceProgressIndicatorSkin s, boolean spinEnabled, Paint fillOverride) { public IndeterminateSpinner(ConfidenceProgressIndicator control, ConfidenceProgressIndicatorSkin s,
boolean spinEnabled, Paint fillOverride) {
this.control = control; this.control = control;
this.skin = s; this.skin = s;
this.spinEnabled = spinEnabled; this.spinEnabled = spinEnabled;
@ -675,7 +685,9 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
region.getStyleClass().addAll("segment", "segment" + i); region.getStyleClass().addAll("segment", "segment" + i);
if (fillOverride instanceof Color) { if (fillOverride instanceof Color) {
Color c = (Color) fillOverride; Color c = (Color) fillOverride;
region.setStyle("-fx-background-color: rgba(" + ((int) (255 * c.getRed())) + "," + ((int) (255 * c.getGreen())) + "," + ((int) (255 * c.getBlue())) + "," + c.getOpacity() + ");"); region.setStyle("-fx-background-color: rgba(" + ((int) (255 * c.getRed())) + "," +
"" + ((int) (255 * c.getGreen())) + "," + ((int) (255 * c.getBlue())) + "," +
"" + c.getOpacity() + ");");
} else { } else {
region.setStyle(null); region.setStyle(null);
} }
@ -751,7 +763,8 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
getChildren().stream().filter(child -> child instanceof Region).forEach(child -> { getChildren().stream().filter(child -> child instanceof Region).forEach(child -> {
Region region = (Region) child; Region region = (Region) child;
if (region.getShape() != null) { if (region.getShape() != null) {
region.resize(region.getShape().getLayoutBounds().getMaxX(), region.getShape().getLayoutBounds().getMaxY()); region.resize(region.getShape().getLayoutBounds().getMaxX(),
region.getShape().getLayoutBounds().getMaxY());
region.getTransforms().setAll(new Scale(scale, scale, 0, 0)); region.getTransforms().setAll(new Scale(scale, scale, 0, 0));
} else { } else {
region.autosize(); region.autosize();
@ -768,7 +781,8 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
private static class StyleableProperties { private static class StyleableProperties {
public static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES; public static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
private static final CssMetaData<ConfidenceProgressIndicator, Paint> PROGRESS_COLOR = new CssMetaData<ConfidenceProgressIndicator, Paint>("-fx-progress-color", private static final CssMetaData<ConfidenceProgressIndicator, Paint> PROGRESS_COLOR = new
CssMetaData<ConfidenceProgressIndicator, Paint>("-fx-progress-color",
PaintConverter.getInstance(), PaintConverter.getInstance(),
null) { null) {
@ -787,7 +801,8 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
}; };
private static final CssMetaData<ConfidenceProgressIndicator, Number> INDETERMINATE_SEGMENT_COUNT = new CssMetaData<ConfidenceProgressIndicator, Number>("-fx-indeterminate-segment-count", private static final CssMetaData<ConfidenceProgressIndicator, Number> INDETERMINATE_SEGMENT_COUNT = new
CssMetaData<ConfidenceProgressIndicator, Number>("-fx-indeterminate-segment-count",
SizeConverter.getInstance(), SizeConverter.getInstance(),
8) { 8) {
@ -810,7 +825,8 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
} }
}; };
private static final CssMetaData<ConfidenceProgressIndicator, Boolean> SPIN_ENABLED = new CssMetaData<ConfidenceProgressIndicator, Boolean>("-fx-spin-enabled", private static final CssMetaData<ConfidenceProgressIndicator, Boolean> SPIN_ENABLED = new
CssMetaData<ConfidenceProgressIndicator, Boolean>("-fx-spin-enabled",
BooleanConverter.getInstance(), BooleanConverter.getInstance(),
Boolean.FALSE) { Boolean.FALSE) {
@ -829,7 +845,8 @@ public class ConfidenceProgressIndicatorSkin extends BehaviorSkinBase<Confidence
}; };
static { static {
final List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<>(SkinBase.getClassCssMetaData()); final List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList<>(SkinBase.getClassCssMetaData
());
styleables.add(PROGRESS_COLOR); styleables.add(PROGRESS_COLOR);
styleables.add(INDETERMINATE_SEGMENT_COUNT); styleables.add(INDETERMINATE_SEGMENT_COUNT);
styleables.add(SPIN_ENABLED); styleables.add(SPIN_ENABLED);

View file

@ -133,12 +133,14 @@ class ProcessStepBarSkin<T> extends BehaviorSkinBase<ProcessStepBar<T>, Behavior
this.setShape(createButtonShape()); this.setShape(createButtonShape());
BorderStroke borderStroke = new BorderStroke(Color.LIGHTGRAY, BorderStrokeStyle.SOLID, null, new BorderWidths(borderWidth, borderWidth, borderWidth, borderWidth), Insets.EMPTY); BorderStroke borderStroke = new BorderStroke(Color.LIGHTGRAY, BorderStrokeStyle.SOLID, null,
new BorderWidths(borderWidth, borderWidth, borderWidth, borderWidth), Insets.EMPTY);
this.setBorder(new Border(borderStroke)); this.setBorder(new Border(borderStroke));
} }
public void select() { public void select() {
BorderStroke borderStroke = new BorderStroke(processStepItem.getColor(), BorderStrokeStyle.SOLID, null, new BorderWidths(borderWidth, borderWidth, borderWidth, borderWidth), Insets.EMPTY); BorderStroke borderStroke = new BorderStroke(processStepItem.getColor(), BorderStrokeStyle.SOLID, null,
new BorderWidths(borderWidth, borderWidth, borderWidth, borderWidth), Insets.EMPTY);
this.setBorder(new Border(borderStroke)); this.setBorder(new Border(borderStroke));
setTextFill(processStepItem.getColor()); setTextFill(processStepItem.getColor());
} }

View file

@ -33,7 +33,8 @@ public class ProcessStepItem {
this(label, color, false); this(label, color, false);
} }
private ProcessStepItem(String label, Paint color, @SuppressWarnings("SameParameterValue") boolean hasProgressIndicator) { private ProcessStepItem(String label, Paint color, @SuppressWarnings("SameParameterValue") boolean
hasProgressIndicator) {
this.label = label; this.label = label;
this.color = color; this.color = color;
this.progressIndicator = hasProgressIndicator; this.progressIndicator = hasProgressIndicator;

View file

@ -54,7 +54,8 @@ public class FundsController extends CachedViewController {
public void initialize(URL url, ResourceBundle rb) { public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb); super.initialize(url, rb);
((CachingTabPane) root).initialize(this, persistence, NavigationItem.DEPOSIT.getFxmlUrl(), NavigationItem.WITHDRAWAL.getFxmlUrl(), NavigationItem.TRANSACTIONS.getFxmlUrl()); ((CachingTabPane) root).initialize(this, persistence, NavigationItem.DEPOSIT.getFxmlUrl(),
NavigationItem.WITHDRAWAL.getFxmlUrl(), NavigationItem.TRANSACTIONS.getFxmlUrl());
} }
@Override @Override

View file

@ -49,7 +49,8 @@ public class DepositController extends CachedViewController {
private ObservableList<DepositListItem> addressList; private ObservableList<DepositListItem> addressList;
@FXML private TableView<DepositListItem> tableView; @FXML private TableView<DepositListItem> tableView;
@FXML private TableColumn<String, DepositListItem> labelColumn, addressColumn, balanceColumn, copyColumn, confidenceColumn; @FXML private TableColumn<String, DepositListItem> labelColumn, addressColumn, balanceColumn, copyColumn,
confidenceColumn;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -92,7 +93,8 @@ public class DepositController extends CachedViewController {
List<AddressEntry> addressEntryList = walletFacade.getAddressEntryList(); List<AddressEntry> addressEntryList = walletFacade.getAddressEntryList();
addressList = FXCollections.observableArrayList(); addressList = FXCollections.observableArrayList();
addressList.addAll(addressEntryList.stream().map(anAddressEntryList -> new DepositListItem(anAddressEntryList, walletFacade)).collect(Collectors.toList())); addressList.addAll(addressEntryList.stream().map(anAddressEntryList -> new DepositListItem
(anAddressEntryList, walletFacade)).collect(Collectors.toList()));
tableView.setItems(addressList); tableView.setItems(addressList);
} }
@ -114,7 +116,8 @@ public class DepositController extends CachedViewController {
private void setLabelColumnCellFactory() { private void setLabelColumnCellFactory() {
labelColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue())); labelColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
labelColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String, DepositListItem>>() { labelColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String,
DepositListItem>>() {
@Override @Override
public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column) { public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column) {
@ -133,7 +136,8 @@ public class DepositController extends CachedViewController {
Tooltip tooltip = new Tooltip(item.getAddressEntry().getOfferId()); Tooltip tooltip = new Tooltip(item.getAddressEntry().getOfferId());
Tooltip.install(hyperlink, tooltip); Tooltip.install(hyperlink, tooltip);
hyperlink.setOnAction(event -> log.info("Show trade details " + item.getAddressEntry().getOfferId())); hyperlink.setOnAction(event -> log.info("Show trade details " + item.getAddressEntry
().getOfferId()));
} }
setGraphic(hyperlink); setGraphic(hyperlink);
} else { } else {
@ -148,7 +152,8 @@ public class DepositController extends CachedViewController {
private void setBalanceColumnCellFactory() { private void setBalanceColumnCellFactory() {
balanceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue())); balanceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
balanceColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String, DepositListItem>>() { balanceColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String,
DepositListItem>>() {
@Override @Override
public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column) { public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column) {
@ -170,7 +175,8 @@ public class DepositController extends CachedViewController {
private void setCopyColumnCellFactory() { private void setCopyColumnCellFactory() {
copyColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue())); copyColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
copyColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String, DepositListItem>>() { copyColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String,
DepositListItem>>() {
@Override @Override
public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column) { public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column) {
@ -206,8 +212,10 @@ public class DepositController extends CachedViewController {
} }
private void setConfidenceColumnCellFactory() { private void setConfidenceColumnCellFactory() {
confidenceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue())); confidenceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue
confidenceColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String, DepositListItem>>() { ()));
confidenceColumn.setCellFactory(new Callback<TableColumn<String, DepositListItem>, TableCell<String,
DepositListItem>>() {
@Override @Override
public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column) { public TableCell<String, DepositListItem> call(TableColumn<String, DepositListItem> column) {

View file

@ -45,7 +45,8 @@ public class TransactionsController extends CachedViewController {
private ObservableList<TransactionsListItem> transactionsListItems; private ObservableList<TransactionsListItem> transactionsListItems;
@FXML private TableView<TransactionsListItem> tableView; @FXML private TableView<TransactionsListItem> tableView;
@FXML private TableColumn<String, TransactionsListItem> dateColumn, addressColumn, amountColumn, typeColumn, confidenceColumn; @FXML private TableColumn<String, TransactionsListItem> dateColumn, addressColumn, amountColumn, typeColumn,
confidenceColumn;
@FXML private Button addNewAddressButton; @FXML private Button addNewAddressButton;
@ -87,7 +88,8 @@ public class TransactionsController extends CachedViewController {
List<Transaction> transactions = walletFacade.getWallet().getRecentTransactions(10000, true); List<Transaction> transactions = walletFacade.getWallet().getRecentTransactions(10000, true);
transactionsListItems = FXCollections.observableArrayList(); transactionsListItems = FXCollections.observableArrayList();
transactionsListItems.addAll(transactions.stream().map(transaction -> new TransactionsListItem(transaction, walletFacade)).collect(Collectors.toList())); transactionsListItems.addAll(transactions.stream().map(transaction -> new TransactionsListItem(transaction,
walletFacade)).collect(Collectors.toList()));
tableView.setItems(transactionsListItems); tableView.setItems(transactionsListItems);
} }
@ -109,7 +111,8 @@ public class TransactionsController extends CachedViewController {
private void setAddressColumnCellFactory() { private void setAddressColumnCellFactory() {
addressColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue())); addressColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
addressColumn.setCellFactory(new Callback<TableColumn<String, TransactionsListItem>, TableCell<String, TransactionsListItem>>() { addressColumn.setCellFactory(new Callback<TableColumn<String, TransactionsListItem>, TableCell<String,
TransactionsListItem>>() {
@Override @Override
public TableCell<String, TransactionsListItem> call(TableColumn<String, TransactionsListItem> column) { public TableCell<String, TransactionsListItem> call(TableColumn<String, TransactionsListItem> column) {
@ -136,8 +139,10 @@ public class TransactionsController extends CachedViewController {
} }
private void setConfidenceColumnCellFactory() { private void setConfidenceColumnCellFactory() {
confidenceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue())); confidenceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue
confidenceColumn.setCellFactory(new Callback<TableColumn<String, TransactionsListItem>, TableCell<String, TransactionsListItem>>() { ()));
confidenceColumn.setCellFactory(new Callback<TableColumn<String, TransactionsListItem>, TableCell<String,
TransactionsListItem>>() {
@Override @Override
public TableCell<String, TransactionsListItem> call(TableColumn<String, TransactionsListItem> column) { public TableCell<String, TransactionsListItem> call(TableColumn<String, TransactionsListItem> column) {

View file

@ -56,8 +56,10 @@ public class TransactionsListItem {
if (!transactionOutput.isMine(walletFacade.getWallet())) { if (!transactionOutput.isMine(walletFacade.getWallet())) {
type.set("Sent to"); type.set("Sent to");
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isPayToScriptHash()) { if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey()
address = transactionOutput.getScriptPubKey().getToAddress(walletFacade.getWallet().getParams()); .isPayToScriptHash()) {
address = transactionOutput.getScriptPubKey().getToAddress(walletFacade.getWallet().getParams
());
addressString = address.toString(); addressString = address.toString();
} else { } else {
addressString = "No sent to address script used."; addressString = "No sent to address script used.";
@ -71,8 +73,10 @@ public class TransactionsListItem {
for (TransactionOutput transactionOutput : transaction.getOutputs()) { for (TransactionOutput transactionOutput : transaction.getOutputs()) {
if (transactionOutput.isMine(walletFacade.getWallet())) { if (transactionOutput.isMine(walletFacade.getWallet())) {
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isPayToScriptHash()) { if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey()
address = transactionOutput.getScriptPubKey().getToAddress(walletFacade.getWallet().getParams()); .isPayToScriptHash()) {
address = transactionOutput.getScriptPubKey().getToAddress(walletFacade.getWallet().getParams
());
addressString = address.toString(); addressString = address.toString();
} else { } else {
addressString = "No sent to address script used."; addressString = "No sent to address script used.";
@ -87,8 +91,10 @@ public class TransactionsListItem {
for (TransactionOutput transactionOutput : transaction.getOutputs()) { for (TransactionOutput transactionOutput : transaction.getOutputs()) {
if (!transactionOutput.isMine(walletFacade.getWallet())) { if (!transactionOutput.isMine(walletFacade.getWallet())) {
outgoing = true; outgoing = true;
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isPayToScriptHash()) { if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey()
address = transactionOutput.getScriptPubKey().getToAddress(walletFacade.getWallet().getParams()); .isPayToScriptHash()) {
address = transactionOutput.getScriptPubKey().getToAddress(walletFacade.getWallet().getParams
());
addressString = address.toString(); addressString = address.toString();
} else { } else {
addressString = "No sent to address script used."; addressString = "No sent to address script used.";
@ -134,7 +140,8 @@ public class TransactionsListItem {
private void updateConfidence(TransactionConfidence confidence) { private void updateConfidence(TransactionConfidence confidence) {
if (confidence != null) { if (confidence != null) {
//log.debug("Type numBroadcastPeers getDepthInBlocks " + confidence.getConfidenceType() + " / " + confidence.numBroadcastPeers() + " / " + confidence.getDepthInBlocks()); //log.debug("Type numBroadcastPeers getDepthInBlocks " + confidence.getConfidenceType() + " / " +
// confidence.numBroadcastPeers() + " / " + confidence.getDepthInBlocks());
switch (confidence.getConfidenceType()) { switch (confidence.getConfidenceType()) {
case UNKNOWN: case UNKNOWN:
tooltip.setText("Unknown transaction status"); tooltip.setText("Unknown transaction status");

View file

@ -62,7 +62,8 @@ public class WithdrawalController extends CachedViewController {
private ObservableList<WithdrawalListItem> addressList; private ObservableList<WithdrawalListItem> addressList;
@FXML private TableView<WithdrawalListItem> tableView; @FXML private TableView<WithdrawalListItem> tableView;
@FXML private TableColumn<String, WithdrawalListItem> labelColumn, addressColumn, balanceColumn, copyColumn, confidenceColumn; @FXML private TableColumn<String, WithdrawalListItem> labelColumn, addressColumn, balanceColumn, copyColumn,
confidenceColumn;
@FXML private Button addNewAddressButton; @FXML private Button addNewAddressButton;
@FXML private TextField withdrawFromTextField, withdrawToTextField, amountTextField, changeAddressTextField; @FXML private TextField withdrawFromTextField, withdrawToTextField, amountTextField, changeAddressTextField;
@ -106,7 +107,8 @@ public class WithdrawalController extends CachedViewController {
tableView.getSelectionModel().selectedItemProperty().addListener((observableValue, oldValue, newValue) -> { tableView.getSelectionModel().selectedItemProperty().addListener((observableValue, oldValue, newValue) -> {
if (newValue != null) { if (newValue != null) {
BitSquareValidator.resetTextFields(withdrawFromTextField, withdrawToTextField, amountTextField, changeAddressTextField); BitSquareValidator.resetTextFields(withdrawFromTextField, withdrawToTextField, amountTextField,
changeAddressTextField);
if (Coin.ZERO.compareTo(newValue.getBalance()) <= 0) { if (Coin.ZERO.compareTo(newValue.getBalance()) <= 0) {
amountTextField.setText(newValue.getBalance().toPlainString()); amountTextField.setText(newValue.getBalance().toPlainString());
@ -123,7 +125,8 @@ public class WithdrawalController extends CachedViewController {
List<AddressEntry> addressEntryList = walletFacade.getAddressEntryList(); List<AddressEntry> addressEntryList = walletFacade.getAddressEntryList();
addressList = FXCollections.observableArrayList(); addressList = FXCollections.observableArrayList();
addressList.addAll(addressEntryList.stream().map(anAddressEntryList -> new WithdrawalListItem(anAddressEntryList, walletFacade)).collect(Collectors.toList())); addressList.addAll(addressEntryList.stream().map(anAddressEntryList -> new WithdrawalListItem
(anAddressEntryList, walletFacade)).collect(Collectors.toList()));
tableView.setItems(addressList); tableView.setItems(addressList);
} }
@ -136,7 +139,8 @@ public class WithdrawalController extends CachedViewController {
@FXML @FXML
public void onWithdraw() { public void onWithdraw() {
try { try {
BitSquareValidator.textFieldsNotEmpty(amountTextField, withdrawFromTextField, withdrawToTextField, changeAddressTextField); BitSquareValidator.textFieldsNotEmpty(amountTextField, withdrawFromTextField, withdrawToTextField,
changeAddressTextField);
BitSquareValidator.textFieldsHasDoubleValueWithReset(amountTextField); BitSquareValidator.textFieldsHasDoubleValueWithReset(amountTextField);
Coin amount = BitSquareFormatter.parseToCoin(amountTextField.getText()); Coin amount = BitSquareFormatter.parseToCoin(amountTextField.getText());
@ -144,7 +148,8 @@ public class WithdrawalController extends CachedViewController {
FutureCallback<Transaction> callback = new FutureCallback<Transaction>() { FutureCallback<Transaction> callback = new FutureCallback<Transaction>() {
@Override @Override
public void onSuccess(@javax.annotation.Nullable Transaction transaction) { public void onSuccess(@javax.annotation.Nullable Transaction transaction) {
BitSquareValidator.resetTextFields(withdrawFromTextField, withdrawToTextField, amountTextField, changeAddressTextField); BitSquareValidator.resetTextFields(withdrawFromTextField, withdrawToTextField,
amountTextField, changeAddressTextField);
if (transaction != null) { if (transaction != null) {
log.info("onWithdraw onSuccess txid:" + transaction.getHashAsString()); log.info("onWithdraw onSuccess txid:" + transaction.getHashAsString());
} }
@ -156,18 +161,22 @@ public class WithdrawalController extends CachedViewController {
} }
}; };
Action response = Popups.openConfirmPopup("Withdrawal request", "Confirm your request", "Your withdrawal request:\n\n" + Action response = Popups.openConfirmPopup("Withdrawal request", "Confirm your request",
"Your withdrawal request:\n\n" +
"Amount: " + amountTextField.getText() + " BTC\n" + "Amount: " + amountTextField.getText() + " BTC\n" +
"Sending address: " + withdrawFromTextField.getText() + "\n" + "Sending address: " + withdrawFromTextField.getText() + "\n" +
"Receiving address: " + withdrawToTextField.getText() + "\n" + "Receiving address: " + withdrawToTextField.getText() + "\n" +
"Transaction fee: " + BitSquareFormatter.formatCoinWithCode(FeePolicy.TX_FEE) + "\n" + "Transaction fee: " + BitSquareFormatter.formatCoinWithCode(FeePolicy.TX_FEE) + "\n" +
"You receive in total: " + BitSquareFormatter.formatCoinWithCode(amount.subtract(FeePolicy.TX_FEE)) + " BTC\n\n" + "You receive in total: " + BitSquareFormatter.formatCoinWithCode(amount.subtract(FeePolicy
.TX_FEE)) + " BTC\n\n" +
"Are you sure you withdraw that amount?"); "Are you sure you withdraw that amount?");
if (response == Dialog.Actions.OK) { if (response == Dialog.Actions.OK) {
try { try {
walletFacade.sendFunds(withdrawFromTextField.getText(), withdrawToTextField.getText(), changeAddressTextField.getText(), amount, callback); walletFacade.sendFunds(withdrawFromTextField.getText(), withdrawToTextField.getText(),
changeAddressTextField.getText(), amount, callback);
} catch (AddressFormatException e) { } catch (AddressFormatException e) {
Popups.openErrorPopup("Address invalid", "The address is not correct. Please check the address format."); Popups.openErrorPopup("Address invalid", "The address is not correct. Please check the " +
"address format.");
} catch (InsufficientMoneyException e) { } catch (InsufficientMoneyException e) {
Popups.openInsufficientMoneyPopup(); Popups.openInsufficientMoneyPopup();
@ -177,7 +186,8 @@ public class WithdrawalController extends CachedViewController {
} }
} else { } else {
Popups.openErrorPopup("Insufficient amount", "The amount to transfer is lower the the transaction fee and the min. possible tx value."); Popups.openErrorPopup("Insufficient amount", "The amount to transfer is lower the the transaction fee" +
" and the min. possible tx value.");
} }
} catch (BitSquareValidator.ValidationException e) { } catch (BitSquareValidator.ValidationException e) {
@ -197,7 +207,8 @@ public class WithdrawalController extends CachedViewController {
private void setLabelColumnCellFactory() { private void setLabelColumnCellFactory() {
labelColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue())); labelColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
labelColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String, WithdrawalListItem>>() { labelColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String,
WithdrawalListItem>>() {
@Override @Override
public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column) { public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column) {
@ -216,7 +227,8 @@ public class WithdrawalController extends CachedViewController {
Tooltip tooltip = new Tooltip(item.getAddressEntry().getOfferId()); Tooltip tooltip = new Tooltip(item.getAddressEntry().getOfferId());
Tooltip.install(hyperlink, tooltip); Tooltip.install(hyperlink, tooltip);
hyperlink.setOnAction(event -> log.info("Show trade details " + item.getAddressEntry().getOfferId())); hyperlink.setOnAction(event -> log.info("Show trade details " + item.getAddressEntry
().getOfferId()));
} }
setGraphic(hyperlink); setGraphic(hyperlink);
} else { } else {
@ -231,7 +243,8 @@ public class WithdrawalController extends CachedViewController {
private void setBalanceColumnCellFactory() { private void setBalanceColumnCellFactory() {
balanceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue())); balanceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
balanceColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String, WithdrawalListItem>>() { balanceColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String,
WithdrawalListItem>>() {
@Override @Override
public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column) { public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column) {
@ -248,7 +261,8 @@ public class WithdrawalController extends CachedViewController {
private void setCopyColumnCellFactory() { private void setCopyColumnCellFactory() {
copyColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue())); copyColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue()));
copyColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String, WithdrawalListItem>>() { copyColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String,
WithdrawalListItem>>() {
@Override @Override
public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column) { public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column) {
@ -284,8 +298,10 @@ public class WithdrawalController extends CachedViewController {
} }
private void setConfidenceColumnCellFactory() { private void setConfidenceColumnCellFactory() {
confidenceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue())); confidenceColumn.setCellValueFactory((addressListItem) -> new ReadOnlyObjectWrapper(addressListItem.getValue
confidenceColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String, WithdrawalListItem>>() { ()));
confidenceColumn.setCellFactory(new Callback<TableColumn<String, WithdrawalListItem>, TableCell<String,
WithdrawalListItem>>() {
@Override @Override
public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column) { public TableCell<String, WithdrawalListItem> call(TableColumn<String, WithdrawalListItem> column) {

View file

@ -99,7 +99,8 @@ public class WithdrawalListItem {
private void updateConfidence(TransactionConfidence confidence) { private void updateConfidence(TransactionConfidence confidence) {
if (confidence != null) { if (confidence != null) {
//log.debug("Type numBroadcastPeers getDepthInBlocks " + confidence.getConfidenceType() + " / " + confidence.numBroadcastPeers() + " / " + confidence.getDepthInBlocks()); //log.debug("Type numBroadcastPeers getDepthInBlocks " + confidence.getConfidenceType() + " / " +
// confidence.numBroadcastPeers() + " / " + confidence.getDepthInBlocks());
switch (confidence.getConfidenceType()) { switch (confidence.getConfidenceType()) {
case UNKNOWN: case UNKNOWN:
tooltip.setText("Unknown transaction status"); tooltip.setText("Unknown transaction status");

View file

@ -58,7 +58,8 @@ public class OrdersController extends CachedViewController {
public void initialize(URL url, ResourceBundle rb) { public void initialize(URL url, ResourceBundle rb) {
super.initialize(url, rb); super.initialize(url, rb);
((CachingTabPane) root).initialize(this, persistence, NavigationItem.OFFER.getFxmlUrl(), NavigationItem.PENDING_TRADE.getFxmlUrl(), NavigationItem.CLOSED_TRADE.getFxmlUrl()); ((CachingTabPane) root).initialize(this, persistence, NavigationItem.OFFER.getFxmlUrl(),
NavigationItem.PENDING_TRADE.getFxmlUrl(), NavigationItem.CLOSED_TRADE.getFxmlUrl());
} }
@Override @Override

View file

@ -48,7 +48,8 @@ public class OfferController extends CachedViewController {
private final TradeManager tradeManager; private final TradeManager tradeManager;
private ObservableList<OfferListItem> offerListItems; private ObservableList<OfferListItem> offerListItems;
@FXML private TableColumn<String, OfferListItem> offerIdColumn, dateColumn, amountColumn, priceColumn, volumeColumn, removeColumn; @FXML private TableColumn<String, OfferListItem> offerIdColumn, dateColumn, amountColumn, priceColumn,
volumeColumn, removeColumn;
@FXML private TableView<OfferListItem> offerTable; @FXML private TableView<OfferListItem> offerTable;
@ -116,7 +117,8 @@ public class OfferController extends CachedViewController {
private void setOfferIdColumnColumnCellFactory() { private void setOfferIdColumnColumnCellFactory() {
offerIdColumn.setCellValueFactory((offerListItem) -> new ReadOnlyObjectWrapper(offerListItem.getValue())); offerIdColumn.setCellValueFactory((offerListItem) -> new ReadOnlyObjectWrapper(offerListItem.getValue()));
offerIdColumn.setCellFactory(new Callback<TableColumn<String, OfferListItem>, TableCell<String, OfferListItem>>() { offerIdColumn.setCellFactory(new Callback<TableColumn<String, OfferListItem>, TableCell<String,
OfferListItem>>() {
@Override @Override
public TableCell<String, OfferListItem> call(TableColumn<String, OfferListItem> column) { public TableCell<String, OfferListItem> call(TableColumn<String, OfferListItem> column) {
@ -146,7 +148,8 @@ public class OfferController extends CachedViewController {
private void setRemoveColumnCellFactory() { private void setRemoveColumnCellFactory() {
removeColumn.setCellValueFactory((offerListItem) -> new ReadOnlyObjectWrapper(offerListItem.getValue())); removeColumn.setCellValueFactory((offerListItem) -> new ReadOnlyObjectWrapper(offerListItem.getValue()));
removeColumn.setCellFactory(new Callback<TableColumn<String, OfferListItem>, TableCell<String, OfferListItem>>() { removeColumn.setCellFactory(new Callback<TableColumn<String, OfferListItem>, TableCell<String,
OfferListItem>>() {
@Override @Override
public TableCell<String, OfferListItem> call(TableColumn<String, OfferListItem> directionColumn) { public TableCell<String, OfferListItem> call(TableColumn<String, OfferListItem> directionColumn) {

View file

@ -37,8 +37,10 @@ public class OfferListItem {
this.date.set(BitSquareFormatter.formatDateTime(offer.getCreationDate())); this.date.set(BitSquareFormatter.formatDateTime(offer.getCreationDate()));
this.price.set(BitSquareFormatter.formatPrice(offer.getPrice())); this.price.set(BitSquareFormatter.formatPrice(offer.getPrice()));
this.amount.set(BitSquareFormatter.formatCoin(offer.getAmount()) + " (" + BitSquareFormatter.formatCoin(offer.getMinAmount()) + ")"); this.amount.set(BitSquareFormatter.formatCoin(offer.getAmount()) + " (" + BitSquareFormatter.formatCoin(offer
this.volume.set(BitSquareFormatter.formatVolumeWithMinVolume(offer.getOfferVolume(), offer.getMinOfferVolume())); .getMinAmount()) + ")");
this.volume.set(BitSquareFormatter.formatVolumeWithMinVolume(offer.getOfferVolume(),
offer.getMinOfferVolume()));
this.offerId = offer.getId(); this.offerId = offer.getId();
} }

View file

@ -75,14 +75,18 @@ public class PendingTradeController extends CachedViewController {
@FXML @FXML
private TableView openTradesTable; private TableView openTradesTable;
@FXML @FXML
private TableColumn<String, PendingTradesListItem> directionColumn, countryColumn, bankAccountTypeColumn, priceColumn, amountColumn, volumeColumn, statusColumn, selectColumn; private TableColumn<String, PendingTradesListItem> directionColumn, countryColumn, bankAccountTypeColumn,
priceColumn, amountColumn, volumeColumn, statusColumn, selectColumn;
@FXML @FXML
private ConfidenceProgressIndicator progressIndicator; private ConfidenceProgressIndicator progressIndicator;
@FXML @FXML
private Label txTitleLabel, txHeaderLabel, confirmationLabel, txIDCopyIcon, holderNameCopyIcon, primaryBankAccountIDCopyIcon, secondaryBankAccountIDCopyIcon, bankAccountDetailsHeaderLabel, private Label txTitleLabel, txHeaderLabel, confirmationLabel, txIDCopyIcon, holderNameCopyIcon,
bankAccountTypeTitleLabel, holderNameTitleLabel, primaryBankAccountIDTitleLabel, secondaryBankAccountIDTitleLabel; primaryBankAccountIDCopyIcon, secondaryBankAccountIDCopyIcon, bankAccountDetailsHeaderLabel,
bankAccountTypeTitleLabel, holderNameTitleLabel, primaryBankAccountIDTitleLabel,
secondaryBankAccountIDTitleLabel;
@FXML @FXML
private TextField txTextField, bankAccountTypeTextField, holderNameTextField, primaryBankAccountIDTextField, secondaryBankAccountIDTextField; private TextField txTextField, bankAccountTypeTextField, holderNameTextField, primaryBankAccountIDTextField,
secondaryBankAccountIDTextField;
@FXML @FXML
private Button bankTransferInitedButton; private Button bankTransferInitedButton;
@ -132,7 +136,8 @@ public class PendingTradeController extends CachedViewController {
openTradesTable.setItems(tradeItems); openTradesTable.setItems(tradeItems);
openTradesTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); openTradesTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
openTradesTable.getSelectionModel().selectedItemProperty().addListener((observableValue, oldValue, newValue) -> { openTradesTable.getSelectionModel().selectedItemProperty().addListener((observableValue, oldValue,
newValue) -> {
if (newValue instanceof PendingTradesListItem) { if (newValue instanceof PendingTradesListItem) {
showTradeDetails((PendingTradesListItem) newValue); showTradeDetails((PendingTradesListItem) newValue);
} }
@ -149,7 +154,8 @@ public class PendingTradeController extends CachedViewController {
// select // select
Optional<PendingTradesListItem> currentTradeItemOptional = tradeItems.stream() Optional<PendingTradesListItem> currentTradeItemOptional = tradeItems.stream()
.filter((e) -> tradeManager.getPendingTrade() != null && e.getTrade().getId().equals(tradeManager.getPendingTrade().getId())) .filter((e) -> tradeManager.getPendingTrade() != null && e.getTrade().getId().equals(tradeManager
.getPendingTrade().getId()))
.findFirst(); .findFirst();
if (currentTradeItemOptional.isPresent()) { if (currentTradeItemOptional.isPresent()) {
openTradesTable.getSelectionModel().select(currentTradeItemOptional.get()); openTradesTable.getSelectionModel().select(currentTradeItemOptional.get());
@ -187,7 +193,8 @@ public class PendingTradeController extends CachedViewController {
private void updateTx(Transaction transaction) { private void updateTx(Transaction transaction) {
txTextField.setText(transaction.getHashAsString()); txTextField.setText(transaction.getHashAsString());
confidenceDisplay = new ConfidenceDisplay(walletFacade.getWallet(), confirmationLabel, transaction, progressIndicator); confidenceDisplay = new ConfidenceDisplay(walletFacade.getWallet(), confirmationLabel, transaction,
progressIndicator);
int depthInBlocks = transaction.getConfidence().getDepthInBlocks(); int depthInBlocks = transaction.getConfidence().getDepthInBlocks();
bankTransferInitedButton.setDisable(depthInBlocks == 0); bankTransferInitedButton.setDisable(depthInBlocks == 0);
@ -231,7 +238,8 @@ public class PendingTradeController extends CachedViewController {
currentTrade = trade; currentTrade = trade;
Transaction transaction = trade.getDepositTransaction(); Transaction transaction = trade.getDepositTransaction();
if (transaction == null) { if (transaction == null) {
trade.depositTxChangedProperty().addListener((observableValue, aBoolean, aBoolean2) -> updateTx(trade.getDepositTransaction())); trade.depositTxChangedProperty().addListener((observableValue, aBoolean,
aBoolean2) -> updateTx(trade.getDepositTransaction()));
} else { } else {
updateTx(trade.getDepositTransaction()); updateTx(trade.getDepositTransaction());
} }
@ -252,7 +260,8 @@ public class PendingTradeController extends CachedViewController {
Transaction transaction = trade.getPayoutTransaction(); Transaction transaction = trade.getPayoutTransaction();
confidenceDisplay.destroy(); confidenceDisplay.destroy();
confidenceDisplay = new ConfidenceDisplay(walletFacade.getWallet(), confirmationLabel, transaction, progressIndicator); confidenceDisplay = new ConfidenceDisplay(walletFacade.getWallet(), confirmationLabel, transaction,
progressIndicator);
txTextField.setText(transaction.getHashAsString()); txTextField.setText(transaction.getHashAsString());
@ -267,7 +276,8 @@ public class PendingTradeController extends CachedViewController {
bankAccountTypeTextField.setText(BitSquareFormatter.formatCoinWithCode(trade.getTradeAmount())); bankAccountTypeTextField.setText(BitSquareFormatter.formatCoinWithCode(trade.getTradeAmount()));
holderNameTextField.setText(BitSquareFormatter.formatVolume(trade.getTradeVolume())); holderNameTextField.setText(BitSquareFormatter.formatVolume(trade.getTradeVolume()));
primaryBankAccountIDTextField.setText(BitSquareFormatter.formatCoinWithCode(FeePolicy.CREATE_OFFER_FEE.add(FeePolicy.TX_FEE))); primaryBankAccountIDTextField.setText(BitSquareFormatter.formatCoinWithCode(FeePolicy.CREATE_OFFER_FEE
.add(FeePolicy.TX_FEE)));
secondaryBankAccountIDTextField.setText(BitSquareFormatter.formatCoinWithCode(trade.getCollateralAmount())); secondaryBankAccountIDTextField.setText(BitSquareFormatter.formatCoinWithCode(trade.getCollateralAmount()));
holderNameCopyIcon.setVisible(false); holderNameCopyIcon.setVisible(false);
@ -329,9 +339,11 @@ public class PendingTradeController extends CachedViewController {
private void setCountryColumnCellFactory() { private void setCountryColumnCellFactory() {
countryColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue())); countryColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
countryColumn.setCellFactory(new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String, PendingTradesListItem>>() { countryColumn.setCellFactory(new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String,
PendingTradesListItem>>() {
@Override @Override
public TableCell<String, PendingTradesListItem> call(TableColumn<String, PendingTradesListItem> directionColumn) { public TableCell<String, PendingTradesListItem> call(TableColumn<String,
PendingTradesListItem> directionColumn) {
return new TableCell<String, PendingTradesListItem>() { return new TableCell<String, PendingTradesListItem>() {
final HBox hBox = new HBox(); final HBox hBox = new HBox();
@ -349,10 +361,12 @@ public class PendingTradeController extends CachedViewController {
if (tradesTableItem != null) { if (tradesTableItem != null) {
Country country = tradesTableItem.getTrade().getOffer().getBankAccountCountry(); Country country = tradesTableItem.getTrade().getOffer().getBankAccountCountry();
try { try {
hBox.getChildren().add(ImageUtil.getIconImageView("/images/countries/" + country.getCode().toLowerCase() + ".png")); hBox.getChildren().add(ImageUtil.getIconImageView("/images/countries/" + country
.getCode().toLowerCase() + ".png"));
} catch (Exception e) { } catch (Exception e) {
log.warn("Country icon not found: " + "/images/countries/" + country.getCode().toLowerCase() + ".png country name: " + country.getName()); log.warn("Country icon not found: " + "/images/countries/" + country.getCode()
.toLowerCase() + ".png country name: " + country.getName());
} }
Tooltip.install(this, new Tooltip(country.getName())); Tooltip.install(this, new Tooltip(country.getName()));
} }
@ -364,16 +378,19 @@ public class PendingTradeController extends CachedViewController {
private void setBankAccountTypeColumnCellFactory() { private void setBankAccountTypeColumnCellFactory() {
bankAccountTypeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue())); bankAccountTypeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
bankAccountTypeColumn.setCellFactory(new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String, PendingTradesListItem>>() { bankAccountTypeColumn.setCellFactory(new Callback<TableColumn<String, PendingTradesListItem>,
TableCell<String, PendingTradesListItem>>() {
@Override @Override
public TableCell<String, PendingTradesListItem> call(TableColumn<String, PendingTradesListItem> directionColumn) { public TableCell<String, PendingTradesListItem> call(TableColumn<String,
PendingTradesListItem> directionColumn) {
return new TableCell<String, PendingTradesListItem>() { return new TableCell<String, PendingTradesListItem>() {
@Override @Override
public void updateItem(final PendingTradesListItem tradesTableItem, boolean empty) { public void updateItem(final PendingTradesListItem tradesTableItem, boolean empty) {
super.updateItem(tradesTableItem, empty); super.updateItem(tradesTableItem, empty);
if (tradesTableItem != null) { if (tradesTableItem != null) {
BankAccountType bankAccountType = tradesTableItem.getTrade().getOffer().getBankAccountType(); BankAccountType bankAccountType = tradesTableItem.getTrade().getOffer()
.getBankAccountType();
setText(Localisation.get(bankAccountType.toString())); setText(Localisation.get(bankAccountType.toString()));
} else { } else {
setText(""); setText("");
@ -386,9 +403,11 @@ public class PendingTradeController extends CachedViewController {
private void setDirectionColumnCellFactory() { private void setDirectionColumnCellFactory() {
directionColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue())); directionColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
directionColumn.setCellFactory(new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String, PendingTradesListItem>>() { directionColumn.setCellFactory(new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String,
PendingTradesListItem>>() {
@Override @Override
public TableCell<String, PendingTradesListItem> call(TableColumn<String, PendingTradesListItem> directionColumn) { public TableCell<String, PendingTradesListItem> call(TableColumn<String,
PendingTradesListItem> directionColumn) {
return new TableCell<String, PendingTradesListItem>() { return new TableCell<String, PendingTradesListItem>() {
final ImageView iconView = new ImageView(); final ImageView iconView = new ImageView();
final Button button = new Button(); final Button button = new Button();
@ -429,9 +448,11 @@ public class PendingTradeController extends CachedViewController {
private void setSelectColumnCellFactory() { private void setSelectColumnCellFactory() {
selectColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue())); selectColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
selectColumn.setCellFactory(new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String, PendingTradesListItem>>() { selectColumn.setCellFactory(new Callback<TableColumn<String, PendingTradesListItem>, TableCell<String,
PendingTradesListItem>>() {
@Override @Override
public TableCell<String, PendingTradesListItem> call(TableColumn<String, PendingTradesListItem> directionColumn) { public TableCell<String, PendingTradesListItem> call(TableColumn<String,
PendingTradesListItem> directionColumn) {
return new TableCell<String, PendingTradesListItem>() { return new TableCell<String, PendingTradesListItem>() {
final Button button = new Button("Select"); final Button button = new Button("Select");

View file

@ -80,7 +80,8 @@ public class SettingsController extends CachedViewController {
@FXML private ComboBox<Locale> languageComboBox; @FXML private ComboBox<Locale> languageComboBox;
@FXML private ComboBox<Region> regionComboBox, bankAccountRegionComboBox; @FXML private ComboBox<Region> regionComboBox, bankAccountRegionComboBox;
@FXML private ComboBox<Country> countryComboBox, bankAccountCountryComboBox; @FXML private ComboBox<Country> countryComboBox, bankAccountCountryComboBox;
@FXML private TextField bankAccountTitleTextField, bankAccountHolderNameTextField, bankAccountPrimaryIDTextField, bankAccountSecondaryIDTextField; @FXML private TextField bankAccountTitleTextField, bankAccountHolderNameTextField, bankAccountPrimaryIDTextField,
bankAccountSecondaryIDTextField;
@FXML private Button saveBankAccountButton, addBankAccountButton; @FXML private Button saveBankAccountButton, addBankAccountButton;
@FXML private ComboBox<BankAccount> bankAccountComboBox; @FXML private ComboBox<BankAccount> bankAccountComboBox;
@FXML private ComboBox<BankAccountType> bankAccountTypesComboBox; @FXML private ComboBox<BankAccountType> bankAccountTypesComboBox;
@ -251,7 +252,8 @@ public class SettingsController extends CachedViewController {
public void onSelectBankAccountRegion() { public void onSelectBankAccountRegion() {
bankAccountCountryComboBox.setVisible(true); bankAccountCountryComboBox.setVisible(true);
Region selectedBankAccountRegion = bankAccountRegionComboBox.getSelectionModel().getSelectedItem(); Region selectedBankAccountRegion = bankAccountRegionComboBox.getSelectionModel().getSelectedItem();
bankAccountCountryComboBox.setItems(FXCollections.observableArrayList(CountryUtil.getAllCountriesFor(selectedBankAccountRegion))); bankAccountCountryComboBox.setItems(FXCollections.observableArrayList(CountryUtil.getAllCountriesFor
(selectedBankAccountRegion)));
} }
@FXML @FXML
@ -520,7 +522,8 @@ public class SettingsController extends CachedViewController {
bankAccountCurrencyComboBox.getSelectionModel().selectFirst(); bankAccountCurrencyComboBox.getSelectionModel().selectFirst();
bankAccountRegionComboBox.getSelectionModel().select(3); bankAccountRegionComboBox.getSelectionModel().select(3);
Optional<Country> country = bankAccountCountryComboBox.getItems().stream().filter(e -> e.getCode().equals(CountryUtil.getDefaultCountry().getCode())).findFirst(); Optional<Country> country = bankAccountCountryComboBox.getItems().stream().filter(e -> e.getCode().equals
(CountryUtil.getDefaultCountry().getCode())).findFirst();
if (country.isPresent()) if (country.isPresent())
bankAccountCountryComboBox.getSelectionModel().select(country.get()); bankAccountCountryComboBox.getSelectionModel().select(country.get());
@ -680,7 +683,8 @@ public class SettingsController extends CachedViewController {
actions.add(Dialog.Actions.NO); actions.add(Dialog.Actions.NO);
Action response = Popups.openConfirmPopup("Warning", Action response = Popups.openConfirmPopup("Warning",
"The country of your bank account is not included in the accepted countries in the general settings.\n\nDo you want to add it automatically?", "The country of your bank account is not included in the accepted countries in the general " +
"settings.\n\nDo you want to add it automatically?",
null, null,
actions); actions);
if (response == Dialog.Actions.YES) if (response == Dialog.Actions.YES)
@ -699,13 +703,16 @@ public class SettingsController extends CachedViewController {
private boolean verifyBankAccountData() { private boolean verifyBankAccountData() {
try { try {
BitSquareValidator.textFieldsNotEmptyWithReset(bankAccountTitleTextField, bankAccountHolderNameTextField, bankAccountPrimaryIDTextField, bankAccountSecondaryIDTextField); BitSquareValidator.textFieldsNotEmptyWithReset(bankAccountTitleTextField, bankAccountHolderNameTextField,
bankAccountPrimaryIDTextField, bankAccountSecondaryIDTextField);
BankAccountType bankAccountTypeInfo = bankAccountTypesComboBox.getSelectionModel().getSelectedItem(); BankAccountType bankAccountTypeInfo = bankAccountTypesComboBox.getSelectionModel().getSelectedItem();
BitSquareValidator.textFieldBankAccountPrimaryIDIsValid(bankAccountPrimaryIDTextField, bankAccountTypeInfo); BitSquareValidator.textFieldBankAccountPrimaryIDIsValid(bankAccountPrimaryIDTextField, bankAccountTypeInfo);
BitSquareValidator.textFieldBankAccountSecondaryIDIsValid(bankAccountSecondaryIDTextField, bankAccountTypeInfo); BitSquareValidator.textFieldBankAccountSecondaryIDIsValid(bankAccountSecondaryIDTextField,
bankAccountTypeInfo);
return bankAccountTypesComboBox.getSelectionModel().getSelectedItem() != null && bankAccountCountryComboBox.getSelectionModel() return bankAccountTypesComboBox.getSelectionModel().getSelectedItem() != null &&
bankAccountCountryComboBox.getSelectionModel()
.getSelectedItem() != null && bankAccountCurrencyComboBox.getSelectionModel() .getSelectedItem() != null && bankAccountCurrencyComboBox.getSelectionModel()
.getSelectedItem() != .getSelectedItem() !=
null; null;

View file

@ -73,7 +73,8 @@ public class TradeController extends CachedViewController {
// TODO find better solution // TODO find better solution
// Textfield focus out triggers validation, use runLater as quick fix... // Textfield focus out triggers validation, use runLater as quick fix...
((TabPane) root).getSelectionModel().selectedIndexProperty().addListener((observableValue) -> Platform.runLater(() -> ValidatingTextField.hidePopover())); ((TabPane) root).getSelectionModel().selectedIndexProperty().addListener((observableValue) -> Platform
.runLater(() -> ValidatingTextField.hidePopover()));
} }
@ -87,7 +88,8 @@ public class TradeController extends CachedViewController {
if (navigationItem == NavigationItem.ORDER_BOOK) { if (navigationItem == NavigationItem.ORDER_BOOK) {
checkArgument(orderBookLoader == null); checkArgument(orderBookLoader == null);
// Orderbook must not be cached by GuiceFXMLLoader as we use 2 instances for sell and buy screens. // Orderbook must not be cached by GuiceFXMLLoader as we use 2 instances for sell and buy screens.
orderBookLoader = new GuiceFXMLLoader(getClass().getResource(NavigationItem.ORDER_BOOK.getFxmlUrl()), false); orderBookLoader = new GuiceFXMLLoader(getClass().getResource(NavigationItem.ORDER_BOOK.getFxmlUrl()),
false);
try { try {
final Parent view = orderBookLoader.load(); final Parent view = orderBookLoader.load();
final Tab tab = new Tab("Orderbook"); final Tab tab = new Tab("Orderbook");
@ -103,7 +105,8 @@ public class TradeController extends CachedViewController {
} else if (navigationItem == NavigationItem.CREATE_OFFER) { } else if (navigationItem == NavigationItem.CREATE_OFFER) {
checkArgument(createOfferController == null); checkArgument(createOfferController == null);
// CreateOffer and TakeOffer must not be cached by GuiceFXMLLoader as we cannot use a view multiple times in different graphs // CreateOffer and TakeOffer must not be cached by GuiceFXMLLoader as we cannot use a view multiple times
// in different graphs
GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), false); GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), false);
try { try {
final Parent view = loader.load(); final Parent view = loader.load();
@ -121,7 +124,8 @@ public class TradeController extends CachedViewController {
} else if (navigationItem == NavigationItem.TAKE_OFFER) { } else if (navigationItem == NavigationItem.TAKE_OFFER) {
checkArgument(takerOfferController == null); checkArgument(takerOfferController == null);
// CreateOffer and TakeOffer must not be cached by GuiceFXMLLoader as we cannot use a view multiple times in different graphs // CreateOffer and TakeOffer must not be cached by GuiceFXMLLoader as we cannot use a view multiple times
// in different graphs
GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), false); GuiceFXMLLoader loader = new GuiceFXMLLoader(getClass().getResource(navigationItem.getFxmlUrl()), false);
try { try {
final Parent view = loader.load(); final Parent view = loader.load();

View file

@ -79,7 +79,9 @@ public class CreateOfferController extends CachedViewController {
@FXML private ValidatingTextField amountTextField, minAmountTextField, priceTextField, volumeTextField; @FXML private ValidatingTextField amountTextField, minAmountTextField, priceTextField, volumeTextField;
@FXML private Button placeOfferButton, closeButton; @FXML private Button placeOfferButton, closeButton;
@FXML private TextField totalsTextField, collateralTextField, bankAccountTypeTextField, bankAccountCurrencyTextField, bankAccountCountyTextField, acceptedCountriesTextField, acceptedLanguagesTextField, @FXML private TextField totalsTextField, collateralTextField, bankAccountTypeTextField,
bankAccountCurrencyTextField, bankAccountCountyTextField, acceptedCountriesTextField,
acceptedLanguagesTextField,
feeLabel, transactionIdTextField; feeLabel, transactionIdTextField;
@FXML private ConfidenceProgressIndicator progressIndicator; @FXML private ConfidenceProgressIndicator progressIndicator;
@FXML private AddressTextField addressTextField; @FXML private AddressTextField addressTextField;
@ -105,7 +107,8 @@ public class CreateOfferController extends CachedViewController {
viewModel.bankAccountCounty.set(bankAccount.getCountry().getName()); viewModel.bankAccountCounty.set(bankAccount.getCountry().getName());
} }
viewModel.acceptedCountries.set(BitSquareFormatter.countryLocalesToString(settings.getAcceptedCountries())); viewModel.acceptedCountries.set(BitSquareFormatter.countryLocalesToString(settings.getAcceptedCountries()));
viewModel.acceptedLanguages.set(BitSquareFormatter.languageLocalesToString(settings.getAcceptedLanguageLocales())); viewModel.acceptedLanguages.set(BitSquareFormatter.languageLocalesToString(settings
.getAcceptedLanguageLocales()));
viewModel.feeLabel.set(BitSquareFormatter.formatCoinWithCode(FeePolicy.CREATE_OFFER_FEE.add(FeePolicy.TX_FEE))); viewModel.feeLabel.set(BitSquareFormatter.formatCoinWithCode(FeePolicy.CREATE_OFFER_FEE.add(FeePolicy.TX_FEE)));
offerId = UUID.randomUUID().toString(); offerId = UUID.randomUUID().toString();
@ -179,7 +182,8 @@ public class CreateOfferController extends CachedViewController {
//balanceTextField.getBalance() //balanceTextField.getBalance()
if (amountTextField.getIsValid() && minAmountTextField.getIsValid() && volumeTextField.getIsValid() && amountTextField.getIsValid()) { if (amountTextField.getIsValid() && minAmountTextField.getIsValid() && volumeTextField.getIsValid() &&
amountTextField.getIsValid()) {
viewModel.isPlaceOfferButtonDisabled.set(true); viewModel.isPlaceOfferButtonDisabled.set(true);
tradeManager.requestPlaceOffer(offerId, tradeManager.requestPlaceOffer(offerId,
@ -217,7 +221,8 @@ public class CreateOfferController extends CachedViewController {
double price = BitSquareFormatter.parseToDouble(viewModel.price.get()); double price = BitSquareFormatter.parseToDouble(viewModel.price.get());
double volume = amount * price; double volume = amount * price;
viewModel.volume.set(BitSquareFormatter.formatVolume(volume)); viewModel.volume.set(BitSquareFormatter.formatVolume(volume));
viewModel.totals.set(BitSquareFormatter.formatTotalsAsBtc(viewModel.amount.get(), collateral, FeePolicy.CREATE_OFFER_FEE.add(FeePolicy.TX_FEE))); viewModel.totals.set(BitSquareFormatter.formatTotalsAsBtc(viewModel.amount.get(), collateral,
FeePolicy.CREATE_OFFER_FEE.add(FeePolicy.TX_FEE)));
viewModel.collateral.set(BitSquareFormatter.formatCollateralAsBtc(viewModel.amount.get(), collateral)); viewModel.collateral.set(BitSquareFormatter.formatCollateralAsBtc(viewModel.amount.get(), collateral));
}); });
@ -234,7 +239,8 @@ public class CreateOfferController extends CachedViewController {
if (price != 0) { if (price != 0) {
double amount = volume / price; double amount = volume / price;
viewModel.amount.set(BitSquareFormatter.formatVolume(amount)); viewModel.amount.set(BitSquareFormatter.formatVolume(amount));
viewModel.totals.set(BitSquareFormatter.formatTotalsAsBtc(viewModel.amount.get(), collateral, FeePolicy.CREATE_OFFER_FEE.add(FeePolicy.TX_FEE))); viewModel.totals.set(BitSquareFormatter.formatTotalsAsBtc(viewModel.amount.get(), collateral,
FeePolicy.CREATE_OFFER_FEE.add(FeePolicy.TX_FEE)));
viewModel.collateral.set(BitSquareFormatter.formatCollateralAsBtc(viewModel.amount.get(), collateral)); viewModel.collateral.set(BitSquareFormatter.formatCollateralAsBtc(viewModel.amount.get(), collateral));
} }
}); });
@ -242,7 +248,9 @@ public class CreateOfferController extends CachedViewController {
volumeTextField.focusedProperty().addListener((observableValue, oldValue, newValue) -> { volumeTextField.focusedProperty().addListener((observableValue, oldValue, newValue) -> {
if (oldValue && !newValue) { if (oldValue && !newValue) {
if (!volumeTextField.getText().equals(viewModel.volume.get())) { if (!volumeTextField.getText().equals(viewModel.volume.get())) {
Popups.openWarningPopup("Warning", "The total volume you have entered leads to invalid fractional Bitcoin amounts.\nThe amount has been adjusted and a new total volume be calculated from it."); Popups.openWarningPopup("Warning", "The total volume you have entered leads to invalid fractional" +
" Bitcoin amounts.\nThe amount has been adjusted and a new total volume be calculated " +
"from it.");
volumeTextField.setText(viewModel.volume.get()); volumeTextField.setText(viewModel.volume.get());
} }
} }

View file

@ -103,7 +103,8 @@ public class OrderBookController extends CachedViewController {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
private OrderBookController(OrderBook orderBook, User user, MessageFacade messageFacade, WalletFacade walletFacade, Settings settings, Persistence persistence) { private OrderBookController(OrderBook orderBook, User user, MessageFacade messageFacade,
WalletFacade walletFacade, Settings settings, Persistence persistence) {
this.orderBook = orderBook; this.orderBook = orderBook;
this.user = user; this.user = user;
this.messageFacade = messageFacade; this.messageFacade = messageFacade;
@ -254,14 +255,16 @@ public class OrderBookController extends CachedViewController {
selectedIndex = 2; selectedIndex = 2;
} else { } else {
Action response = Popups.openErrorPopup("Registration fee not confirmed yet", Action response = Popups.openErrorPopup("Registration fee not confirmed yet",
"The registration fee transaction has not been confirmed yet in the blockchain. Please wait until it has at least 1 confirmation."); "The registration fee transaction has not been confirmed yet in the blockchain. " +
"Please wait until it has at least 1 confirmation.");
if (response == Dialog.Actions.OK) { if (response == Dialog.Actions.OK) {
MainController.GET_INSTANCE().loadViewAndGetChildController(NavigationItem.FUNDS); MainController.GET_INSTANCE().loadViewAndGetChildController(NavigationItem.FUNDS);
} }
} }
} else { } else {
Action response = Popups.openErrorPopup("Missing registration fee", Action response = Popups.openErrorPopup("Missing registration fee",
"You have not funded the full registration fee of " + BitSquareFormatter.formatCoinWithCode(FeePolicy.ACCOUNT_REGISTRATION_FEE) + " BTC."); "You have not funded the full registration fee of " + BitSquareFormatter
.formatCoinWithCode(FeePolicy.ACCOUNT_REGISTRATION_FEE) + " BTC.");
if (response == Dialog.Actions.OK) { if (response == Dialog.Actions.OK) {
MainController.GET_INSTANCE().loadViewAndGetChildController(NavigationItem.FUNDS); MainController.GET_INSTANCE().loadViewAndGetChildController(NavigationItem.FUNDS);
} }
@ -274,13 +277,17 @@ public class OrderBookController extends CachedViewController {
} }
if (selectedIndex >= 0) { if (selectedIndex >= 0) {
Dialogs.CommandLink settingsCommandLink = new Dialogs.CommandLink("Open settings", "You need to configure your settings before you can actively trade."); Dialogs.CommandLink settingsCommandLink = new Dialogs.CommandLink("Open settings",
"You need to configure your settings before you can actively trade.");
Dialogs.CommandLink depositFeeCommandLink = new Dialogs.CommandLink("Deposit funds", Dialogs.CommandLink depositFeeCommandLink = new Dialogs.CommandLink("Deposit funds",
"You need to pay the registration fee before you can actively trade. That is needed as prevention against fraud."); "You need to pay the registration fee before you can actively trade. That is needed as prevention" +
" against fraud.");
Dialogs.CommandLink sendRegistrationCommandLink = new Dialogs.CommandLink("Publish registration", Dialogs.CommandLink sendRegistrationCommandLink = new Dialogs.CommandLink("Publish registration",
"When settings are configured and the fee deposit is done your registration transaction will be published to " "When settings are configured and the fee deposit is done your registration transaction will be " +
"published to "
+ "the Bitcoin \nnetwork."); + "the Bitcoin \nnetwork.");
List<Dialogs.CommandLink> commandLinks = Arrays.asList(settingsCommandLink, depositFeeCommandLink, sendRegistrationCommandLink); List<Dialogs.CommandLink> commandLinks = Arrays.asList(settingsCommandLink, depositFeeCommandLink,
sendRegistrationCommandLink);
Action registrationMissingAction = Popups.openRegistrationMissingPopup("Not registered yet", Action registrationMissingAction = Popups.openRegistrationMissingPopup("Not registered yet",
"Please follow these steps:", "Please follow these steps:",
"You need to register before you can place an offer.", "You need to register before you can place an offer.",
@ -325,7 +332,8 @@ public class OrderBookController extends CachedViewController {
private void takeOffer(Offer offer) { private void takeOffer(Offer offer) {
if (isRegistered()) { if (isRegistered()) {
TakerOfferController takerOfferController = (TakerOfferController) parentController.loadViewAndGetChildController(NavigationItem.TAKE_OFFER); TakerOfferController takerOfferController = (TakerOfferController) parentController
.loadViewAndGetChildController(NavigationItem.TAKE_OFFER);
Coin requestedAmount; Coin requestedAmount;
if (!"".equals(amount.getText())) { if (!"".equals(amount.getText())) {
@ -349,7 +357,8 @@ public class OrderBookController extends CachedViewController {
private void applyOffers() { private void applyOffers() {
orderBook.applyFilter(orderBookFilter); orderBook.applyFilter(orderBookFilter);
priceColumn.setSortType((orderBookFilter.getDirection() == Direction.BUY) ? TableColumn.SortType.ASCENDING : TableColumn.SortType.DESCENDING); priceColumn.setSortType((orderBookFilter.getDirection() == Direction.BUY) ? TableColumn.SortType.ASCENDING :
TableColumn.SortType.DESCENDING);
orderBookTable.sort(); orderBookTable.sort();
if (orderBookTable.getItems() != null) { if (orderBookTable.getItems() != null) {
@ -377,7 +386,8 @@ public class OrderBookController extends CachedViewController {
private void setDirectionColumnCellFactory() { private void setDirectionColumnCellFactory() {
directionColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue())); directionColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
directionColumn.setCellFactory(new Callback<TableColumn<String, OrderBookListItem>, TableCell<String, OrderBookListItem>>() { directionColumn.setCellFactory(new Callback<TableColumn<String, OrderBookListItem>, TableCell<String,
OrderBookListItem>>() {
@Override @Override
public TableCell<String, OrderBookListItem> call(TableColumn<String, OrderBookListItem> directionColumn) { public TableCell<String, OrderBookListItem> call(TableColumn<String, OrderBookListItem> directionColumn) {
@ -431,7 +441,8 @@ public class OrderBookController extends CachedViewController {
private void setCountryColumnCellFactory() { private void setCountryColumnCellFactory() {
countryColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue())); countryColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
countryColumn.setCellFactory(new Callback<TableColumn<String, OrderBookListItem>, TableCell<String, OrderBookListItem>>() { countryColumn.setCellFactory(new Callback<TableColumn<String, OrderBookListItem>, TableCell<String,
OrderBookListItem>>() {
@Override @Override
public TableCell<String, OrderBookListItem> call(TableColumn<String, OrderBookListItem> directionColumn) { public TableCell<String, OrderBookListItem> call(TableColumn<String, OrderBookListItem> directionColumn) {
@ -452,10 +463,12 @@ public class OrderBookController extends CachedViewController {
if (orderBookListItem != null) { if (orderBookListItem != null) {
Country country = orderBookListItem.getOffer().getBankAccountCountry(); Country country = orderBookListItem.getOffer().getBankAccountCountry();
try { try {
hBox.getChildren().add(ImageUtil.getIconImageView("/images/countries/" + country.getCode().toLowerCase() + ".png")); hBox.getChildren().add(ImageUtil.getIconImageView("/images/countries/" + country
.getCode().toLowerCase() + ".png"));
} catch (Exception e) { } catch (Exception e) {
log.warn("Country icon not found: " + "/images/countries/" + country.getCode().toLowerCase() + ".png country name: " + country.getName()); log.warn("Country icon not found: " + "/images/countries/" + country.getCode()
.toLowerCase() + ".png country name: " + country.getName());
} }
Tooltip.install(this, new Tooltip(country.getName())); Tooltip.install(this, new Tooltip(country.getName()));
} }
@ -467,7 +480,8 @@ public class OrderBookController extends CachedViewController {
private void setBankAccountTypeColumnCellFactory() { private void setBankAccountTypeColumnCellFactory() {
bankAccountTypeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue())); bankAccountTypeColumn.setCellValueFactory((offer) -> new ReadOnlyObjectWrapper(offer.getValue()));
bankAccountTypeColumn.setCellFactory(new Callback<TableColumn<String, OrderBookListItem>, TableCell<String, OrderBookListItem>>() { bankAccountTypeColumn.setCellFactory(new Callback<TableColumn<String, OrderBookListItem>, TableCell<String,
OrderBookListItem>>() {
@Override @Override
public TableCell<String, OrderBookListItem> call(TableColumn<String, OrderBookListItem> directionColumn) { public TableCell<String, OrderBookListItem> call(TableColumn<String, OrderBookListItem> directionColumn) {

View file

@ -34,8 +34,10 @@ public class OrderBookListItem {
public OrderBookListItem(Offer offer) { public OrderBookListItem(Offer offer) {
this.offer = offer; this.offer = offer;
this.price.set(BitSquareFormatter.formatPrice(offer.getPrice())); this.price.set(BitSquareFormatter.formatPrice(offer.getPrice()));
this.amount.set(BitSquareFormatter.formatCoin(offer.getAmount()) + " (" + BitSquareFormatter.formatCoin(offer.getMinAmount()) + ")"); this.amount.set(BitSquareFormatter.formatCoin(offer.getAmount()) + " (" + BitSquareFormatter.formatCoin(offer
this.volume.set(BitSquareFormatter.formatVolumeWithMinVolume(offer.getOfferVolume(), offer.getMinOfferVolume())); .getMinAmount()) + ")");
this.volume.set(BitSquareFormatter.formatVolumeWithMinVolume(offer.getOfferVolume(),
offer.getMinOfferVolume()));
} }

View file

@ -63,8 +63,10 @@ public class TakerOfferController extends CachedViewController {
@FXML @FXML
private ValidatedTextField amountTextField; private ValidatedTextField amountTextField;
@FXML @FXML
private TextField priceTextField, volumeTextField, collateralTextField, feeTextField, totalTextField, bankAccountTypeTextField, countryTextField, arbitratorsTextField, private TextField priceTextField, volumeTextField, collateralTextField, feeTextField, totalTextField,
supportedLanguagesTextField, supportedCountriesTextField, depositTxIdTextField, summaryPaidTextField, summaryReceivedTextField, summaryFeesTextField, summaryCollateralTextField, bankAccountTypeTextField, countryTextField, arbitratorsTextField,
supportedLanguagesTextField, supportedCountriesTextField, depositTxIdTextField, summaryPaidTextField,
summaryReceivedTextField, summaryFeesTextField, summaryCollateralTextField,
summaryDepositTxIdTextField, summaryPayoutTxIdTextField; summaryDepositTxIdTextField, summaryPayoutTxIdTextField;
@FXML @FXML
private Label infoLabel, headLineLabel, collateralLabel; private Label infoLabel, headLineLabel, collateralLabel;
@ -120,7 +122,8 @@ public class TakerOfferController extends CachedViewController {
public void applyData() { public void applyData() {
amountTextField.setText(requestedAmount.toPlainString()); amountTextField.setText(requestedAmount.toPlainString());
amountTextField.setPromptText(BitSquareFormatter.formatCoinWithCode(offer.getMinAmount()) + " - " + BitSquareFormatter.formatCoinWithCode(offer.getAmount())); amountTextField.setPromptText(BitSquareFormatter.formatCoinWithCode(offer.getMinAmount()) + " - " +
BitSquareFormatter.formatCoinWithCode(offer.getAmount()));
priceTextField.setText(BitSquareFormatter.formatPrice(offer.getPrice())); priceTextField.setText(BitSquareFormatter.formatPrice(offer.getPrice()));
applyVolume(); applyVolume();
collateralLabel.setText("Collateral (" + getCollateralAsPercent() + "):"); collateralLabel.setText("Collateral (" + getCollateralAsPercent() + "):");
@ -135,7 +138,8 @@ public class TakerOfferController extends CachedViewController {
//todo list //todo list
// arbitratorsTextField.setText(offer.getArbitrator().getName()); // arbitratorsTextField.setText(offer.getArbitrator().getName());
supportedLanguagesTextField.setText(BitSquareFormatter.languageLocalesToString(offer.getAcceptedLanguageLocales())); supportedLanguagesTextField.setText(BitSquareFormatter.languageLocalesToString(offer
.getAcceptedLanguageLocales()));
supportedCountriesTextField.setText(BitSquareFormatter.countryLocalesToString(offer.getAcceptedCountries())); supportedCountriesTextField.setText(BitSquareFormatter.countryLocalesToString(offer.getAcceptedCountries()));
amountTextField.textProperty().addListener(e -> { amountTextField.textProperty().addListener(e -> {
@ -158,11 +162,14 @@ public class TakerOfferController extends CachedViewController {
if (amountTextField.isInvalid()) { if (amountTextField.isInvalid()) {
Popups.openErrorPopup("Invalid input", "The requested amount you entered is not a valid amount."); Popups.openErrorPopup("Invalid input", "The requested amount you entered is not a valid amount.");
} else if (BitSquareValidator.tradeAmountOutOfRange(amount, offer)) { } else if (BitSquareValidator.tradeAmountOutOfRange(amount, offer)) {
Popups.openErrorPopup("Invalid input", "The requested amount you entered is outside of the range of the offered amount."); Popups.openErrorPopup("Invalid input", "The requested amount you entered is outside of the range of the " +
} else if (addressEntry == null || getTotal().compareTo(walletFacade.getBalanceForAddress(addressEntry.getAddress())) > 0) { "offered amount.");
} else if (addressEntry == null || getTotal().compareTo(walletFacade.getBalanceForAddress(addressEntry
.getAddress())) > 0) {
Popups.openErrorPopup("Insufficient money", "You don't have enough funds for that trade."); Popups.openErrorPopup("Insufficient money", "You don't have enough funds for that trade.");
} else if (tradeManager.isOfferAlreadyInTrades(offer)) { } else if (tradeManager.isOfferAlreadyInTrades(offer)) {
Popups.openErrorPopup("Offer previously accepted", "You have that offer already taken. Open the offer section to find that trade."); Popups.openErrorPopup("Offer previously accepted", "You have that offer already taken. Open the offer " +
"section to find that trade.");
} else { } else {
takeOfferButton.setDisable(true); takeOfferButton.setDisable(true);
amountTextField.setEditable(false); amountTextField.setEditable(false);
@ -191,8 +198,10 @@ public class TakerOfferController extends CachedViewController {
summaryPaidTextField.setText(BitSquareFormatter.formatCoinWithCode(trade.getTradeAmount())); summaryPaidTextField.setText(BitSquareFormatter.formatCoinWithCode(trade.getTradeAmount()));
summaryReceivedTextField.setText(BitSquareFormatter.formatVolume(trade.getTradeVolume())); summaryReceivedTextField.setText(BitSquareFormatter.formatVolume(trade.getTradeVolume()));
summaryFeesTextField.setText(BitSquareFormatter.formatCoinWithCode(FeePolicy.TAKE_OFFER_FEE.add(FeePolicy.TX_FEE))); summaryFeesTextField.setText(BitSquareFormatter.formatCoinWithCode(FeePolicy.TAKE_OFFER_FEE.add
summaryCollateralTextField.setText(BitSquareFormatter.formatCoinWithCode(trade.getCollateralAmount())); (FeePolicy.TX_FEE)));
summaryCollateralTextField.setText(BitSquareFormatter.formatCoinWithCode(trade
.getCollateralAmount()));
summaryDepositTxIdTextField.setText(depositTxId); summaryDepositTxIdTextField.setText(depositTxId);
summaryPayoutTxIdTextField.setText(payoutTxId); summaryPayoutTxIdTextField.setText(payoutTxId);
} }
@ -200,7 +209,8 @@ public class TakerOfferController extends CachedViewController {
@Override @Override
public void onFault(Throwable throwable, ProtocolForTakerAsSeller.State state) { public void onFault(Throwable throwable, ProtocolForTakerAsSeller.State state) {
log.error("Error while executing trade process at state: " + state + " / " + throwable); log.error("Error while executing trade process at state: " + state + " / " + throwable);
Popups.openErrorPopup("Error while executing trade process", "Error while executing trade process at state: " + state + " / " + throwable); Popups.openErrorPopup("Error while executing trade process", "Error while executing trade process" +
" at state: " + state + " / " + throwable);
} }
@Override @Override
@ -217,7 +227,8 @@ public class TakerOfferController extends CachedViewController {
public void onTakeOfferRequestRejected(Trade trade) { public void onTakeOfferRequestRejected(Trade trade) {
log.error("Take offer request rejected"); log.error("Take offer request rejected");
Popups.openErrorPopup("Take offer request rejected", Popups.openErrorPopup("Take offer request rejected",
"Your take offer request has been rejected. It might be that the offerer got another request shortly before your request arrived."); "Your take offer request has been rejected. It might be that the offerer got another " +
"request shortly before your request arrived.");
} }
}); });
} }

View file

@ -98,7 +98,8 @@ public class BitSquareFormatter {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
/** /**
* @param input String to be converted to a double. Both decimal points "." and "," are supported. Thousands separator is not supported. * @param input String to be converted to a double. Both decimal points "." and ",
* " are supported. Thousands separator is not supported.
* @return Returns a double value. Any invalid value returns Double.NEGATIVE_INFINITY. * @return Returns a double value. Any invalid value returns Double.NEGATIVE_INFINITY.
*/ */
public static double parseToDouble(String input) { public static double parseToDouble(String input) {

View file

@ -115,7 +115,8 @@ public class BitSquareValidator {
//TODO //TODO
@SuppressWarnings("UnusedParameters") @SuppressWarnings("UnusedParameters")
public static void textFieldBankAccountPrimaryIDIsValid(TextField textField, BankAccountType bankAccountType) throws ValidationException { public static void textFieldBankAccountPrimaryIDIsValid(TextField textField, BankAccountType bankAccountType)
throws ValidationException {
if (!validateStringNotEmpty(textField.getText())) { if (!validateStringNotEmpty(textField.getText())) {
textField.setEffect(invalidEffect); textField.setEffect(invalidEffect);
textField.setStyle(invalidStyle); textField.setStyle(invalidStyle);
@ -125,7 +126,9 @@ public class BitSquareValidator {
//TODO //TODO
@SuppressWarnings("UnusedParameters") @SuppressWarnings("UnusedParameters")
public static void textFieldBankAccountSecondaryIDIsValid(TextField textField, BankAccountType bankAccountType) throws ValidationException { public static void textFieldBankAccountSecondaryIDIsValid(TextField textField,
BankAccountType bankAccountType) throws
ValidationException {
if (!validateStringNotEmpty(textField.getText())) { if (!validateStringNotEmpty(textField.getText())) {
textField.setEffect(invalidEffect); textField.setEffect(invalidEffect);
textField.setStyle(invalidStyle); textField.setStyle(invalidStyle);

View file

@ -78,7 +78,8 @@ public class BtcValidator extends NumberValidator {
BigDecimal bd = new BigDecimal(input); BigDecimal bd = new BigDecimal(input);
final BigDecimal satoshis = bd.movePointRight(8); final BigDecimal satoshis = bd.movePointRight(8);
if (satoshis.scale() > 0) if (satoshis.scale() > 0)
return new ValidationResult(false, "Input results in a Bitcoin value with a fraction of the smallest unit (Satoshi).", ErrorType.FRACTIONAL_SATOSHI); return new ValidationResult(false, "Input results in a Bitcoin value with a fraction of the smallest unit" +
" (Satoshi).", ErrorType.FRACTIONAL_SATOSHI);
else else
return new ValidationResult(true); return new ValidationResult(true);
} }
@ -87,7 +88,8 @@ public class BtcValidator extends NumberValidator {
BigDecimal bd = new BigDecimal(input); BigDecimal bd = new BigDecimal(input);
final BigDecimal satoshis = bd.movePointRight(8); final BigDecimal satoshis = bd.movePointRight(8);
if (satoshis.longValue() > NetworkParameters.MAX_MONEY.longValue()) if (satoshis.longValue() > NetworkParameters.MAX_MONEY.longValue())
return new ValidationResult(false, "Input larger as maximum possible Bitcoin value is not allowed.", ErrorType.EXCEEDS_MAX_BTC_VALUE); return new ValidationResult(false, "Input larger as maximum possible Bitcoin value is not allowed.",
ErrorType.EXCEEDS_MAX_BTC_VALUE);
else else
return new ValidationResult(true); return new ValidationResult(true);
} }

View file

@ -45,7 +45,8 @@ public class ConfidenceDisplay {
private ConfidenceProgressIndicator progressIndicator; private ConfidenceProgressIndicator progressIndicator;
public ConfidenceDisplay(Wallet wallet, Label confirmationLabel, TextField balanceTextField, ConfidenceProgressIndicator progressIndicator) { public ConfidenceDisplay(Wallet wallet, Label confirmationLabel, TextField balanceTextField,
ConfidenceProgressIndicator progressIndicator) {
this.wallet = wallet; this.wallet = wallet;
this.confirmationLabel = confirmationLabel; this.confirmationLabel = confirmationLabel;
this.balanceTextField = balanceTextField; this.balanceTextField = balanceTextField;
@ -98,7 +99,8 @@ public class ConfidenceDisplay {
wallet.addEventListener(walletEventListener); wallet.addEventListener(walletEventListener);
} }
public ConfidenceDisplay(Wallet wallet, Label confirmationLabel, final Transaction transaction, ConfidenceProgressIndicator progressIndicator) { public ConfidenceDisplay(Wallet wallet, Label confirmationLabel, final Transaction transaction,
ConfidenceProgressIndicator progressIndicator) {
this.wallet = wallet; this.wallet = wallet;
this.confirmationLabel = confirmationLabel; this.confirmationLabel = confirmationLabel;
this.transaction = transaction; this.transaction = transaction;
@ -184,7 +186,8 @@ public class ConfidenceDisplay {
latestTransaction = transaction; latestTransaction = transaction;
} }
} }
if (latestTransaction != null && (transaction == null || latestTransaction.getHashAsString().equals(transaction.getHashAsString()))) { if (latestTransaction != null && (transaction == null || latestTransaction.getHashAsString().equals
(transaction.getHashAsString()))) {
updateConfidence(latestTransaction); updateConfidence(latestTransaction);
} }
} }

View file

@ -63,7 +63,8 @@ public class FiatValidator extends NumberValidator {
protected ValidationResult validateIfNotExceedsMinFiatValue(String input) { protected ValidationResult validateIfNotExceedsMinFiatValue(String input) {
double d = Double.parseDouble(input); double d = Double.parseDouble(input);
if (d < MIN_FIAT_VALUE) if (d < MIN_FIAT_VALUE)
return new ValidationResult(false, "Input smaller as minimum possible Fiat value is not allowed..", ErrorType.UNDERCUT_MIN_FIAT_VALUE); return new ValidationResult(false, "Input smaller as minimum possible Fiat value is not allowed..",
ErrorType.UNDERCUT_MIN_FIAT_VALUE);
else else
return new ValidationResult(true); return new ValidationResult(true);
} }
@ -71,7 +72,8 @@ public class FiatValidator extends NumberValidator {
protected ValidationResult validateIfNotExceedsMaxFiatValue(String input) { protected ValidationResult validateIfNotExceedsMaxFiatValue(String input) {
double d = Double.parseDouble(input); double d = Double.parseDouble(input);
if (d > MAX_FIAT_VALUE) if (d > MAX_FIAT_VALUE)
return new ValidationResult(false, "Input larger as maximum possible Fiat value is not allowed.", ErrorType.EXCEEDS_MAX_FIAT_VALUE); return new ValidationResult(false, "Input larger as maximum possible Fiat value is not allowed.",
ErrorType.EXCEEDS_MAX_FIAT_VALUE);
else else
return new ValidationResult(true); return new ValidationResult(true);
} }

View file

@ -23,7 +23,8 @@ import org.slf4j.LoggerFactory;
/** /**
* NumberValidator for validating basic number values. * NumberValidator for validating basic number values.
* Localisation not supported at the moment * Localisation not supported at the moment
* The decimal mark can be either "." or ",". Thousand separators are not supported yet, but might be added alter with Local support. * The decimal mark can be either "." or ",". Thousand separators are not supported yet,
* but might be added alter with Local support.
* <p/> * <p/>
* That class implements just what we need for the moment. It is not intended as a general purpose library class. * That class implements just what we need for the moment. It is not intended as a general purpose library class.
*/ */
@ -87,7 +88,8 @@ public abstract class NumberValidator {
ZERO_NUMBER, ZERO_NUMBER,
NEGATIVE_NUMBER, NEGATIVE_NUMBER,
FRACTIONAL_SATOSHI, FRACTIONAL_SATOSHI,
EXCEEDS_MAX_FIAT_VALUE, UNDERCUT_MIN_FIAT_VALUE, AMOUNT_LESS_THAN_MIN_AMOUNT, MIN_AMOUNT_LARGER_THAN_MIN_AMOUNT, EXCEEDS_MAX_BTC_VALUE EXCEEDS_MAX_FIAT_VALUE, UNDERCUT_MIN_FIAT_VALUE, AMOUNT_LESS_THAN_MIN_AMOUNT,
MIN_AMOUNT_LARGER_THAN_MIN_AMOUNT, EXCEEDS_MAX_BTC_VALUE
} }

View file

@ -37,7 +37,8 @@ public class Profiler {
public static void printMsgWithTime(String msg) { public static void printMsgWithTime(String msg) {
final long elapsed = threadStopwatch.get().elapsed(TimeUnit.MILLISECONDS); final long elapsed = threadStopwatch.get().elapsed(TimeUnit.MILLISECONDS);
log.trace("Msg: {} elapsed: {}ms / total time:[globalStopwatch: {}ms / threadStopwatch: {}ms / currentTimeMillis: {}ms]", log.trace("Msg: {} elapsed: {}ms / total time:[globalStopwatch: {}ms / threadStopwatch: {}ms / " +
"currentTimeMillis: {}ms]",
msg, msg,
elapsed - last.get(), elapsed - last.get(),
globalStopwatch.elapsed(TimeUnit.MILLISECONDS), globalStopwatch.elapsed(TimeUnit.MILLISECONDS),

View file

@ -55,7 +55,8 @@ public class ValidationHelper {
minAmountTextField.focusedProperty().addListener((ov, oldValue, newValue) -> { minAmountTextField.focusedProperty().addListener((ov, oldValue, newValue) -> {
// only on focus out and ignore focus loss from window // only on focus out and ignore focus loss from window
if (!newValue && minAmountTextField.getScene() != null && minAmountTextField.getScene().getWindow().isFocused()) if (!newValue && minAmountTextField.getScene() != null && minAmountTextField.getScene().getWindow()
.isFocused())
validateMinAmount(amountTextField, validateMinAmount(amountTextField,
minAmountTextField, minAmountTextField,
amount, amount,
@ -86,7 +87,9 @@ public class ValidationHelper {
if (currentTextField == amountTextField) { if (currentTextField == amountTextField) {
if (Double.parseDouble(amountCleaned) < Double.parseDouble(minAmountCleaned)) { if (Double.parseDouble(amountCleaned) < Double.parseDouble(minAmountCleaned)) {
amountValidator.overrideResult(new NumberValidator.ValidationResult(false, "Amount cannot be smaller than minimum amount.", NumberValidator.ErrorType.AMOUNT_LESS_THAN_MIN_AMOUNT)); amountValidator.overrideResult(new NumberValidator.ValidationResult(false,
"Amount cannot be smaller than minimum amount.",
NumberValidator.ErrorType.AMOUNT_LESS_THAN_MIN_AMOUNT));
amountTextField.reValidate(); amountTextField.reValidate();
} else { } else {
amountValidator.overrideResult(null); amountValidator.overrideResult(null);
@ -94,7 +97,9 @@ public class ValidationHelper {
} }
} else if (currentTextField == minAmountTextField) { } else if (currentTextField == minAmountTextField) {
if (Double.parseDouble(minAmountCleaned) > Double.parseDouble(amountCleaned)) { if (Double.parseDouble(minAmountCleaned) > Double.parseDouble(amountCleaned)) {
minAmountValidator.overrideResult(new NumberValidator.ValidationResult(false, "Minimum amount cannot be larger than amount.", NumberValidator.ErrorType.MIN_AMOUNT_LARGER_THAN_MIN_AMOUNT)); minAmountValidator.overrideResult(new NumberValidator.ValidationResult(false,
"Minimum amount cannot be larger than amount.",
NumberValidator.ErrorType.MIN_AMOUNT_LARGER_THAN_MIN_AMOUNT));
minAmountTextField.reValidate(); minAmountTextField.reValidate();
} else { } else {
minAmountValidator.overrideResult(null); minAmountValidator.overrideResult(null);

View file

@ -24,17 +24,24 @@ import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class CountryUtil { public class CountryUtil {
private static final String[] countryCodes = new String[]{"AE", "AL", "AR", "AT", "AU", "BA", "BE", "BG", "BH", "BO", "BR", "BY", "CA", "CH", "CL", "CN", "CO", "CR", "CS", "CU", "CY", "CZ", private static final String[] countryCodes = new String[]{"AE", "AL", "AR", "AT", "AU", "BA", "BE", "BG", "BH",
"DE", "DK", "DO", "DZ", "EC", "EE", "EG", "ES", "FI", "FR", "GB", "GR", "GT", "HK", "HN", "HR", "HU", "ID", "IE", "IL", "IN", "IQ", "IS", "IT", "JO", "JP", "KR", "KW", "LB", "LT", "LU", "BO", "BR", "BY", "CA", "CH", "CL", "CN", "CO", "CR", "CS", "CU", "CY", "CZ",
"LV", "LY", "MA", "ME", "MK", "MT", "MX", "MY", "NI", "NL", "NO", "NZ", "OM", "PA", "PE", "PH", "PL", "PR", "PT", "PY", "QA", "RO", "RS", "RU", "SA", "SD", "SE", "SG", "SI", "SK", "SV", "DE", "DK", "DO", "DZ", "EC", "EE", "EG", "ES", "FI", "FR", "GB", "GR", "GT", "HK", "HN", "HR", "HU",
"ID", "IE", "IL", "IN", "IQ", "IS", "IT", "JO", "JP", "KR", "KW", "LB", "LT", "LU",
"LV", "LY", "MA", "ME", "MK", "MT", "MX", "MY", "NI", "NL", "NO", "NZ", "OM", "PA", "PE", "PH", "PL",
"PR", "PT", "PY", "QA", "RO", "RS", "RU", "SA", "SD", "SE", "SG", "SI", "SK", "SV",
"SY", "TH", "TN", "TR", "TW", "UA", "US", "UY", "VE", "VN", "YE", "ZA"}; "SY", "TH", "TN", "TR", "TW", "UA", "US", "UY", "VE", "VN", "YE", "ZA"};
private static final List<String> countryCodeList = Arrays.asList(countryCodes); private static final List<String> countryCodeList = Arrays.asList(countryCodes);
private static final String[] regionCodes = new String[]{"AS", "EU", "SA", "EU", "OC", "EU", "EU", "EU", "AS", "SA", "SA", "EU", "NA", "EU", "SA", "AS", "SA", "NA", "EU", "NA", "AS", "EU", private static final String[] regionCodes = new String[]{"AS", "EU", "SA", "EU", "OC", "EU", "EU", "EU", "AS",
"EU", "EU", "NA", "AF", "SA", "EU", "AF", "EU", "EU", "EU", "EU", "EU", "NA", "AS", "NA", "EU", "EU", "AS", "EU", "AS", "AS", "AS", "EU", "EU", "AS", "AS", "AS", "AS", "AS", "EU", "EU", "SA", "SA", "EU", "NA", "EU", "SA", "AS", "SA", "NA", "EU", "NA", "AS", "EU",
"EU", "AF", "AF", "EU", "EU", "EU", "NA", "AS", "NA", "EU", "EU", "OC", "AS", "NA", "SA", "AS", "EU", "NA", "EU", "SA", "AS", "EU", "EU", "EU", "AS", "AF", "EU", "AS", "EU", "EU", "NA", "EU", "EU", "NA", "AF", "SA", "EU", "AF", "EU", "EU", "EU", "EU", "EU", "NA", "AS", "NA", "EU", "EU",
"AS", "EU", "AS", "AS", "AS", "EU", "EU", "AS", "AS", "AS", "AS", "AS", "EU", "EU",
"EU", "AF", "AF", "EU", "EU", "EU", "NA", "AS", "NA", "EU", "EU", "OC", "AS", "NA", "SA", "AS", "EU",
"NA", "EU", "SA", "AS", "EU", "EU", "EU", "AS", "AF", "EU", "AS", "EU", "EU", "NA",
"AS", "AS", "AF", "AS", "AS", "EU", "NA", "SA", "SA", "AS", "AS", "AF"}; "AS", "AS", "AF", "AS", "AS", "EU", "NA", "SA", "SA", "AS", "AS", "AF"};
private static final List<String> regionCodeList = Arrays.asList(regionCodes); private static final List<String> regionCodeList = Arrays.asList(regionCodes);
private static final String[][] regionCodeToName = new String[][]{{"NA", "North America"}, {"SA", "South America"}, {"AF", "Africa"}, {"EU", "Europe"}, {"AS", "Asia"}, {"OC", "Oceania"}}; private static final String[][] regionCodeToName = new String[][]{{"NA", "North America"}, {"SA",
"South America"}, {"AF", "Africa"}, {"EU", "Europe"}, {"AS", "Asia"}, {"OC", "Oceania"}};
public static List<Region> getAllRegions() { public static List<Region> getAllRegions() {
@ -68,7 +75,8 @@ public class CountryUtil {
} }
public static List<Country> getAllCountriesFor(Region selectedRegion) { public static List<Country> getAllCountriesFor(Region selectedRegion) {
return Lists.newArrayList(Collections2.filter(getAllCountries(), country -> selectedRegion != null && country != null && selectedRegion.equals(country.getRegion()))); return Lists.newArrayList(Collections2.filter(getAllCountries(), country -> selectedRegion != null && country
!= null && selectedRegion.equals(country.getRegion())));
} }
@ -104,7 +112,8 @@ public class CountryUtil {
private static List<Locale> getAllCountryLocales() { private static List<Locale> getAllCountryLocales() {
List<Locale> allLocales = Arrays.asList(Locale.getAvailableLocales()); List<Locale> allLocales = Arrays.asList(Locale.getAvailableLocales());
Set<Locale> allLocalesAsSet = allLocales.stream().filter(locale -> !"".equals(locale.getCountry())).map(locale -> new Locale("", locale.getCountry(), "")).collect(Collectors.toSet()); Set<Locale> allLocalesAsSet = allLocales.stream().filter(locale -> !"".equals(locale.getCountry())).map
(locale -> new Locale("", locale.getCountry(), "")).collect(Collectors.toSet());
/* /*
same as: same as:
Set<Locale> allLocalesAsSet = new HashSet<>(); Set<Locale> allLocalesAsSet = new HashSet<>();

View file

@ -41,7 +41,8 @@ public class LanguageUtil {
public static List<Locale> getAllLanguageLocales() { public static List<Locale> getAllLanguageLocales() {
List<Locale> allLocales = Arrays.asList(Locale.getAvailableLocales()); List<Locale> allLocales = Arrays.asList(Locale.getAvailableLocales());
final Set<Locale> allLocalesAsSet = allLocales.stream().filter(locale -> !"".equals(locale.getLanguage())).map(locale -> new Locale(locale.getLanguage(), "")).collect(Collectors.toSet()); final Set<Locale> allLocalesAsSet = allLocales.stream().filter(locale -> !"".equals(locale.getLanguage()))
.map(locale -> new Locale(locale.getLanguage(), "")).collect(Collectors.toSet());
allLocales = new ArrayList<>(); allLocales = new ArrayList<>();
allLocales.addAll(allLocalesAsSet); allLocales.addAll(allLocalesAsSet);
allLocales.sort((locale1, locale2) -> locale1.getDisplayLanguage().compareTo(locale2.getDisplayLanguage())); allLocales.sort((locale1, locale2) -> locale1.getDisplayLanguage().compareTo(locale2.getDisplayLanguage()));

View file

@ -57,7 +57,8 @@ public class Localisation {
class UTF8Control extends ResourceBundle.Control { class UTF8Control extends ResourceBundle.Control {
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException { public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader,
boolean reload) throws IllegalAccessException, InstantiationException, IOException {
// The below is a copy of the default implementation. // The below is a copy of the default implementation.
final String bundleName = toBundleName(baseName, locale); final String bundleName = toBundleName(baseName, locale);
final String resourceName = toResourceName(bundleName, "properties"); final String resourceName = toResourceName(bundleName, "properties");

View file

@ -73,7 +73,8 @@ public class BootstrappedPeerFactory {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
public BootstrappedPeerFactory(Persistence persistence, @Named("defaultSeedNode") SeedNodeAddress.StaticSeedNodeAddresses defaultStaticSeedNodeAddresses) { public BootstrappedPeerFactory(Persistence persistence, @Named("defaultSeedNode") SeedNodeAddress
.StaticSeedNodeAddresses defaultStaticSeedNodeAddresses) {
this.persistence = persistence; this.persistence = persistence;
this.seedNodeAddress = new SeedNodeAddress(defaultStaticSeedNodeAddresses); this.seedNodeAddress = new SeedNodeAddress(defaultStaticSeedNodeAddresses);
} }
@ -129,7 +130,7 @@ public class BootstrappedPeerFactory {
} }
}); });
// We save last successful bootstrap method. // We save last successful bootstrap method.
// Reset it to "default" after 5 start ups. // Reset it to "default" after 5 start ups.
Object lastSuccessfulBootstrapCounterObject = persistence.read(this, "lastSuccessfulBootstrapCounter"); Object lastSuccessfulBootstrapCounterObject = persistence.read(this, "lastSuccessfulBootstrapCounter");
int lastSuccessfulBootstrapCounter = 0; int lastSuccessfulBootstrapCounter = 0;
@ -153,7 +154,8 @@ public class BootstrappedPeerFactory {
bootstrapWithRelay(peerDHT, nodeBehindNat); bootstrapWithRelay(peerDHT, nodeBehindNat);
break; break;
case "startPortForwarding": case "startPortForwarding":
FutureDiscover futureDiscover = peerDHT.peer().discover().peerAddress(getBootstrapAddress()).start(); FutureDiscover futureDiscover = peerDHT.peer().discover().peerAddress(getBootstrapAddress())
.start();
bootstrapWithPortForwarding(peerDHT, futureDiscover); bootstrapWithPortForwarding(peerDHT, futureDiscover);
break; break;
case "default": case "default":
@ -190,14 +192,16 @@ public class BootstrappedPeerFactory {
public void operationComplete(BaseFuture future) throws Exception { public void operationComplete(BaseFuture future) throws Exception {
if (future.isSuccess()) { if (future.isSuccess()) {
// We are not behind a NAT and reachable to other peers // We are not behind a NAT and reachable to other peers
log.debug("We are not behind a NAT and reachable to other peers: My address visible to the outside is " + futureDiscover.peerAddress()); log.debug("We are not behind a NAT and reachable to other peers: My address visible to the " +
"outside is " + futureDiscover.peerAddress());
requestBootstrapPeerMap(); requestBootstrapPeerMap();
settableFuture.set(peerDHT); settableFuture.set(peerDHT);
persistence.write(ref, "lastSuccessfulBootstrap", "default"); persistence.write(ref, "lastSuccessfulBootstrap", "default");
} else { } else {
log.warn("Discover has failed. Reason: " + futureDiscover.failedReason()); log.warn("Discover has failed. Reason: " + futureDiscover.failedReason());
log.warn("We are probably behind a NAT and not reachable to other peers. We try port forwarding as next step."); log.warn("We are probably behind a NAT and not reachable to other peers. We try port forwarding " +
"as next step.");
bootstrapWithPortForwarding(peerDHT, futureDiscover); bootstrapWithPortForwarding(peerDHT, futureDiscover);
} }
@ -223,7 +227,8 @@ public class BootstrappedPeerFactory {
public void operationComplete(BaseFuture future) throws Exception { public void operationComplete(BaseFuture future) throws Exception {
if (future.isSuccess()) { if (future.isSuccess()) {
// Port forwarding has succeed // Port forwarding has succeed
log.debug("Port forwarding was successful. My address visible to the outside is " + futureNAT.peerAddress()); log.debug("Port forwarding was successful. My address visible to the outside is " + futureNAT
.peerAddress());
requestBootstrapPeerMap(); requestBootstrapPeerMap();
settableFuture.set(peerDHT); settableFuture.set(peerDHT);

View file

@ -172,15 +172,18 @@ public class MessageFacade implements MessageBroker {
if (future.isSuccess()) { if (future.isSuccess()) {
Platform.runLater(() -> { Platform.runLater(() -> {
addOfferListener.onComplete(); addOfferListener.onComplete();
orderBookListeners.stream().forEach(listener -> listener.onOfferAdded(data, future.isSuccess())); orderBookListeners.stream().forEach(listener -> listener.onOfferAdded(data,
future.isSuccess()));
// TODO will be removed when we don't use polling anymore // TODO will be removed when we don't use polling anymore
setDirty(locationKey); setDirty(locationKey);
log.trace("Add offer to DHT was successful. Stored data: [key: " + locationKey + ", value: " + data + "]"); log.trace("Add offer to DHT was successful. Stored data: [key: " + locationKey + ", " +
"value: " + data + "]");
}); });
} else { } else {
Platform.runLater(() -> { Platform.runLater(() -> {
addOfferListener.onFailed("Add offer to DHT failed.", new Exception("Add offer to DHT failed. Reason: " + future.failedReason())); addOfferListener.onFailed("Add offer to DHT failed.",
new Exception("Add offer to DHT failed. Reason: " + future.failedReason()));
log.error("Add offer to DHT failed. Reason: " + future.failedReason()); log.error("Add offer to DHT failed. Reason: " + future.failedReason());
}); });
} }
@ -211,11 +214,13 @@ public class MessageFacade implements MessageBroker {
@Override @Override
public void operationComplete(BaseFuture future) throws Exception { public void operationComplete(BaseFuture future) throws Exception {
Platform.runLater(() -> { Platform.runLater(() -> {
orderBookListeners.stream().forEach(orderBookListener -> orderBookListener.onOfferRemoved(data, future.isSuccess())); orderBookListeners.stream().forEach(orderBookListener -> orderBookListener.onOfferRemoved
(data, future.isSuccess()));
setDirty(locationKey); setDirty(locationKey);
}); });
if (future.isSuccess()) { if (future.isSuccess()) {
log.trace("Remove offer from DHT was successful. Stored data: [key: " + locationKey + ", value: " + data + "]"); log.trace("Remove offer from DHT was successful. Stored data: [key: " + locationKey + ", " +
"value: " + data + "]");
} else { } else {
log.error("Remove offer from DHT failed. Reason: " + future.failedReason()); log.error("Remove offer from DHT failed. Reason: " + future.failedReason());
} }
@ -237,9 +242,11 @@ public class MessageFacade implements MessageBroker {
futureGet.addListener(new BaseFutureAdapter<BaseFuture>() { futureGet.addListener(new BaseFutureAdapter<BaseFuture>() {
@Override @Override
public void operationComplete(BaseFuture baseFuture) throws Exception { public void operationComplete(BaseFuture baseFuture) throws Exception {
Platform.runLater(() -> orderBookListeners.stream().forEach(orderBookListener -> orderBookListener.onOffersReceived(futureGet.dataMap(), baseFuture.isSuccess()))); Platform.runLater(() -> orderBookListeners.stream().forEach(orderBookListener -> orderBookListener
.onOffersReceived(futureGet.dataMap(), baseFuture.isSuccess())));
if (baseFuture.isSuccess()) { if (baseFuture.isSuccess()) {
//log.trace("Get offers from DHT was successful. Stored data: [key: " + locationKey + ", values: " + futureGet.dataMap() + "]"); //log.trace("Get offers from DHT was successful. Stored data: [key: " + locationKey + ",
// values: " + futureGet.dataMap() + "]");
} else { } else {
log.error("Get offers from DHT failed with reason:" + baseFuture.failedReason()); log.error("Get offers from DHT failed with reason:" + baseFuture.failedReason());
} }
@ -252,7 +259,8 @@ public class MessageFacade implements MessageBroker {
// Trade process // Trade process
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public void sendTradeMessage(PeerAddress peerAddress, TradeMessage tradeMessage, OutgoingTradeMessageListener listener) { public void sendTradeMessage(PeerAddress peerAddress, TradeMessage tradeMessage,
OutgoingTradeMessageListener listener) {
FutureDirect futureDirect = p2pNode.sendData(peerAddress, tradeMessage); FutureDirect futureDirect = p2pNode.sendData(peerAddress, tradeMessage);
futureDirect.addListener(new BaseFutureListener<BaseFuture>() { futureDirect.addListener(new BaseFutureListener<BaseFuture>() {
@Override @Override
@ -285,9 +293,11 @@ public class MessageFacade implements MessageBroker {
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 {
Platform.runLater(() -> arbitratorListeners.stream().forEach(listener -> listener.onArbitratorAdded(arbitratorData, addFuture.isSuccess()))); Platform.runLater(() -> arbitratorListeners.stream().forEach(listener -> listener
.onArbitratorAdded(arbitratorData, addFuture.isSuccess())));
if (addFuture.isSuccess()) { if (addFuture.isSuccess()) {
log.trace("Add arbitrator to DHT was successful. Stored data: [key: " + locationKey + ", values: " + arbitratorData + "]"); log.trace("Add arbitrator to DHT was successful. Stored data: [key: " + locationKey + ", " +
"values: " + arbitratorData + "]");
} else { } else {
log.error("Add arbitrator to DHT failed with reason:" + addFuture.failedReason()); log.error("Add arbitrator to DHT failed with reason:" + addFuture.failedReason());
} }
@ -307,9 +317,11 @@ public class MessageFacade implements MessageBroker {
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 {
Platform.runLater(() -> arbitratorListeners.stream().forEach(listener -> listener.onArbitratorRemoved(arbitratorData, removeFuture.isSuccess()))); Platform.runLater(() -> arbitratorListeners.stream().forEach(listener -> listener.onArbitratorRemoved
(arbitratorData, removeFuture.isSuccess())));
if (removeFuture.isSuccess()) { if (removeFuture.isSuccess()) {
log.trace("Remove arbitrator from DHT was successful. Stored data: [key: " + locationKey + ", values: " + arbitratorData + "]"); log.trace("Remove arbitrator from DHT was successful. Stored data: [key: " + locationKey + ", " +
"values: " + arbitratorData + "]");
} else { } else {
log.error("Remove arbitrators from DHT failed with reason:" + removeFuture.failedReason()); log.error("Remove arbitrators from DHT failed with reason:" + removeFuture.failedReason());
} }
@ -323,9 +335,11 @@ public class MessageFacade implements MessageBroker {
futureGet.addListener(new BaseFutureAdapter<BaseFuture>() { futureGet.addListener(new BaseFutureAdapter<BaseFuture>() {
@Override @Override
public void operationComplete(BaseFuture baseFuture) throws Exception { public void operationComplete(BaseFuture baseFuture) throws Exception {
Platform.runLater(() -> arbitratorListeners.stream().forEach(listener -> listener.onArbitratorsReceived(futureGet.dataMap(), baseFuture.isSuccess()))); Platform.runLater(() -> arbitratorListeners.stream().forEach(listener -> listener
.onArbitratorsReceived(futureGet.dataMap(), baseFuture.isSuccess())));
if (baseFuture.isSuccess()) { if (baseFuture.isSuccess()) {
log.trace("Get arbitrators from DHT was successful. Stored data: [key: " + locationKey + ", values: " + futureGet.dataMap() + "]"); 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:" + baseFuture.failedReason()); log.error("Get arbitrators from DHT failed with reason:" + baseFuture.failedReason());
} }
@ -424,7 +438,8 @@ public class MessageFacade implements MessageBroker {
} }
public void setDirty(Number160 locationKey) { public void setDirty(Number160 locationKey) {
// we don't want to get an update from dirty for own changes, so update the lastTimeStamp to omit a change trigger // we don't want to get an update from dirty for own changes, so update the lastTimeStamp to omit a change
// trigger
lastTimeStamp = System.currentTimeMillis(); lastTimeStamp = System.currentTimeMillis();
try { try {
FuturePut putFuture = p2pNode.putData(getDirtyLocationKey(locationKey), new Data(lastTimeStamp)); FuturePut putFuture = p2pNode.putData(getDirtyLocationKey(locationKey), new Data(lastTimeStamp));
@ -457,7 +472,8 @@ public class MessageFacade implements MessageBroker {
public void handleMessage(Object message, PeerAddress peerAddress) { public void handleMessage(Object message, PeerAddress peerAddress) {
if (message instanceof TradeMessage) { if (message instanceof TradeMessage) {
log.error("####################"); log.error("####################");
Platform.runLater(() -> incomingTradeMessageListeners.stream().forEach(e -> e.onMessage((TradeMessage) message, peerAddress))); Platform.runLater(() -> incomingTradeMessageListeners.stream().forEach(e -> e.onMessage((TradeMessage)
message, peerAddress)));
} }
} }
} }

View file

@ -50,7 +50,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* The fully bootstrapped P2PNode which is responsible himself for his availability in the messaging system. It saves for instance the IP address periodically. * The fully bootstrapped P2PNode which is responsible himself for his availability in the messaging system. It saves
* for instance the IP address periodically.
* This class is offering generic functionality of TomP2P needed for Bitsquare, like data and domain protection. * This class is offering generic functionality of TomP2P needed for Bitsquare, like data and domain protection.
* It does not handle any domain aspects of Bitsquare. * It does not handle any domain aspects of Bitsquare.
*/ */
@ -63,8 +64,10 @@ public class P2PNode {
// just for lightweight client test // just for lightweight client test
/* public static void main(String[] args) /* public static void main(String[] args)
{ {
P2PNode p2pNode = new P2PNode(DSAKeyUtil.generateKeyPair(), false, SeedNodeAddress.StaticSeedNodeAddresses.DIGITAL_OCEAN, P2PNode p2pNode = new P2PNode(DSAKeyUtil.generateKeyPair(), false, SeedNodeAddress.StaticSeedNodeAddresses
(message, peerAddress) -> log.debug("handleMessage: message= " + message + "/ peerAddress=" + peerAddress)); .DIGITAL_OCEAN,
(message, peerAddress) -> log.debug("handleMessage: message= " + message + "/
peerAddress=" + peerAddress));
p2pNode.start(new FutureCallback<PeerDHT>() p2pNode.start(new FutureCallback<PeerDHT>()
{ {
@Override @Override
@ -158,7 +161,8 @@ public class P2PNode {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// The data and the domain are protected by that key pair. // The data and the domain are protected by that key pair.
public FuturePut putDomainProtectedData(Number160 locationKey, Data data) throws IOException, ClassNotFoundException { public FuturePut putDomainProtectedData(Number160 locationKey, Data data) throws IOException,
ClassNotFoundException {
data.protectEntry(keyPair); data.protectEntry(keyPair);
final Number160 ownerKeyHash = Utils.makeSHAHash(keyPair.getPublic().getEncoded()); final Number160 ownerKeyHash = Utils.makeSHAHash(keyPair.getPublic().getEncoded());
return peerDHT.put(locationKey).data(data).keyPair(keyPair).domainKey(ownerKeyHash).protectDomain().start(); return peerDHT.put(locationKey).data(data).keyPair(keyPair).domainKey(ownerKeyHash).protectDomain().start();
@ -170,7 +174,8 @@ public class P2PNode {
} }
// Not public readable. Only users with the public key of the peer who stored the data can read that data // Not public readable. Only users with the public key of the peer who stored the data can read that data
public FutureGet getDomainProtectedData(Number160 locationKey, PublicKey publicKey) throws IOException, ClassNotFoundException { public FutureGet getDomainProtectedData(Number160 locationKey, PublicKey publicKey) throws IOException,
ClassNotFoundException {
final Number160 ownerKeyHash = Utils.makeSHAHash(publicKey.getEncoded()); final Number160 ownerKeyHash = Utils.makeSHAHash(publicKey.getEncoded());
return peerDHT.get(locationKey).domainKey(ownerKeyHash).start(); return peerDHT.get(locationKey).domainKey(ownerKeyHash).start();
} }
@ -308,7 +313,8 @@ public class P2PNode {
if (useDiscStorage) { if (useDiscStorage) {
try { try {
File path = new File(StorageDirectory.getStorageDirectory().getCanonicalPath() + "/" + BitSquare.getAppName() + "_tomP2P"); File path = new File(StorageDirectory.getStorageDirectory().getCanonicalPath() + "/" + BitSquare
.getAppName() + "_tomP2P");
if (!path.exists()) { if (!path.exists()) {
boolean created = path.mkdir(); boolean created = path.mkdir();
if (!created) if (!created)

View file

@ -202,7 +202,8 @@ public class Persistence {
try { try {
tempFile = FileUtil.getTempFile(prefix); tempFile = FileUtil.getTempFile(prefix);
// Don't use auto closeable resources in try() as we would need too many try/catch clauses (for tempFile) and we need to close it // Don't use auto closeable resources in try() as we would need too many try/catch clauses (for tempFile)
// and we need to close it
// manually before replacing file with temp file // manually before replacing file with temp file
fileOutputStream = new FileOutputStream(tempFile); fileOutputStream = new FileOutputStream(tempFile);
objectOutputStream = new ObjectOutputStream(fileOutputStream); objectOutputStream = new ObjectOutputStream(fileOutputStream);
@ -214,7 +215,8 @@ public class Persistence {
fileOutputStream.flush(); fileOutputStream.flush();
fileOutputStream.getFD().sync(); fileOutputStream.getFD().sync();
// Close resources before replacing file with temp file because otherwise it causes problems on windows when rename temp file // Close resources before replacing file with temp file because otherwise it causes problems on windows
// when rename temp file
fileOutputStream.close(); fileOutputStream.close();
objectOutputStream.close(); objectOutputStream.close();

View file

@ -84,7 +84,8 @@ public class TradeManager {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
public TradeManager(User user, Settings settings, Persistence persistence, MessageFacade messageFacade, BlockChainFacade blockChainFacade, WalletFacade walletFacade, CryptoFacade cryptoFacade) { public TradeManager(User user, Settings settings, Persistence persistence, MessageFacade messageFacade,
BlockChainFacade blockChainFacade, WalletFacade walletFacade, CryptoFacade cryptoFacade) {
this.user = user; this.user = user;
this.settings = settings; this.settings = settings;
this.persistence = persistence; this.persistence = persistence;
@ -161,7 +162,8 @@ public class TradeManager {
settings.getAcceptedLanguageLocales()); settings.getAcceptedLanguageLocales());
if (createOfferCoordinatorMap.containsKey(offer.getId())) { if (createOfferCoordinatorMap.containsKey(offer.getId())) {
errorMessageHandler.onFault("A createOfferCoordinator for the offer with the id " + offer.getId() + " already exists."); errorMessageHandler.onFault("A createOfferCoordinator for the offer with the id " + offer.getId() + " " +
"already exists.");
} else { } else {
CreateOfferCoordinator createOfferCoordinator = new CreateOfferCoordinator(persistence, CreateOfferCoordinator createOfferCoordinator = new CreateOfferCoordinator(persistence,
offer, offer,
@ -212,7 +214,8 @@ public class TradeManager {
Trade trade = createTrade(offer); Trade trade = createTrade(offer);
trade.setTradeAmount(amount); trade.setTradeAmount(amount);
ProtocolForTakerAsSeller protocolForTakerAsSeller = new ProtocolForTakerAsSeller(trade, listener, messageFacade, walletFacade, blockChainFacade, cryptoFacade, user); ProtocolForTakerAsSeller protocolForTakerAsSeller = new ProtocolForTakerAsSeller(trade, listener,
messageFacade, walletFacade, blockChainFacade, cryptoFacade, user);
takerAsSellerProtocolMap.put(trade.getId(), protocolForTakerAsSeller); takerAsSellerProtocolMap.put(trade.getId(), protocolForTakerAsSeller);
protocolForTakerAsSeller.start(); protocolForTakerAsSeller.start();
@ -330,7 +333,8 @@ public class TradeManager {
if (!offererAsBuyerProtocolMap.containsKey(trade.getId())) { if (!offererAsBuyerProtocolMap.containsKey(trade.getId())) {
offererAsBuyerProtocolMap.put(trade.getId(), protocolForOffererAsBuyer); offererAsBuyerProtocolMap.put(trade.getId(), protocolForOffererAsBuyer);
} else { } else {
// We don't store the protocol in case we have already a pending offer. The protocol is only temporary used to reply with a reject message. // We don't store the protocol in case we have already a pending offer. The protocol is only
// temporary used to reply with a reject message.
log.trace("offererAsBuyerProtocol not stored as offer is already pending."); log.trace("offererAsBuyerProtocol not stored as offer is already pending.");
} }
@ -362,13 +366,16 @@ public class TradeManager {
createOffererAsBuyerProtocol(tradeId, sender); createOffererAsBuyerProtocol(tradeId, sender);
takeOfferRequestListeners.stream().forEach(e -> e.onTakeOfferRequested(tradeId, sender)); takeOfferRequestListeners.stream().forEach(e -> e.onTakeOfferRequested(tradeId, sender));
} else if (tradeMessage instanceof RespondToTakeOfferRequestMessage) { } else if (tradeMessage instanceof RespondToTakeOfferRequestMessage) {
takerAsSellerProtocolMap.get(tradeId).onRespondToTakeOfferRequestMessage((RespondToTakeOfferRequestMessage) tradeMessage); takerAsSellerProtocolMap.get(tradeId).onRespondToTakeOfferRequestMessage(
(RespondToTakeOfferRequestMessage) tradeMessage);
} else if (tradeMessage instanceof TakeOfferFeePayedMessage) { } else if (tradeMessage instanceof TakeOfferFeePayedMessage) {
offererAsBuyerProtocolMap.get(tradeId).onTakeOfferFeePayedMessage((TakeOfferFeePayedMessage) tradeMessage); offererAsBuyerProtocolMap.get(tradeId).onTakeOfferFeePayedMessage((TakeOfferFeePayedMessage) tradeMessage);
} else if (tradeMessage instanceof RequestTakerDepositPaymentMessage) { } else if (tradeMessage instanceof RequestTakerDepositPaymentMessage) {
takerAsSellerProtocolMap.get(tradeId).onRequestTakerDepositPaymentMessage((RequestTakerDepositPaymentMessage) tradeMessage); takerAsSellerProtocolMap.get(tradeId).onRequestTakerDepositPaymentMessage(
(RequestTakerDepositPaymentMessage) tradeMessage);
} else if (tradeMessage instanceof RequestOffererPublishDepositTxMessage) { } else if (tradeMessage instanceof RequestOffererPublishDepositTxMessage) {
offererAsBuyerProtocolMap.get(tradeId).onRequestOffererPublishDepositTxMessage((RequestOffererPublishDepositTxMessage) tradeMessage); offererAsBuyerProtocolMap.get(tradeId).onRequestOffererPublishDepositTxMessage(
(RequestOffererPublishDepositTxMessage) tradeMessage);
} else if (tradeMessage instanceof DepositTxPublishedMessage) { } else if (tradeMessage instanceof DepositTxPublishedMessage) {
takerAsSellerProtocolMap.get(tradeId).onDepositTxPublishedMessage((DepositTxPublishedMessage) tradeMessage); takerAsSellerProtocolMap.get(tradeId).onDepositTxPublishedMessage((DepositTxPublishedMessage) tradeMessage);
} else if (tradeMessage instanceof BankTransferInitedMessage) { } else if (tradeMessage instanceof BankTransferInitedMessage) {

View file

@ -118,7 +118,8 @@ public class OrderBook implements OrderBookListener {
boolean countryResult = countryInList(offer.getBankAccountCountry(), settings.getAcceptedCountries()); boolean countryResult = countryInList(offer.getBankAccountCountry(), settings.getAcceptedCountries());
// One of the supported languages from the settings must match one of the offer languages (n to n) // One of the supported languages from the settings must match one of the offer languages (n to n)
boolean languageResult = languagesInList(settings.getAcceptedLanguageLocales(), offer.getAcceptedLanguageLocales()); boolean languageResult = languagesInList(settings.getAcceptedLanguageLocales(),
offer.getAcceptedLanguageLocales());
// Apply applyFilter only if there is a valid value set // Apply applyFilter only if there is a valid value set
// The requested amount must be lower or equal then the offer amount // The requested amount must be lower or equal then the offer amount
@ -139,14 +140,16 @@ public class OrderBook implements OrderBookListener {
} }
} }
// The arbitrator defined in the offer must match one of the accepted arbitrators defined in the settings (1 to n) // The arbitrator defined in the offer must match one of the accepted arbitrators defined in the settings
// (1 to n)
boolean arbitratorResult = arbitratorInList(offer.getArbitrator(), settings.getAcceptedArbitrators()); boolean arbitratorResult = arbitratorInList(offer.getArbitrator(), settings.getAcceptedArbitrators());
//noinspection UnnecessaryLocalVariable //noinspection UnnecessaryLocalVariable
boolean result = currencyResult && countryResult && languageResult && amountResult && directionResult && priceResult && arbitratorResult; boolean result = currencyResult && countryResult && languageResult && amountResult && directionResult &&
priceResult && arbitratorResult;
/* /*
log.debug("result = " + result + log.debug("result = " + result +
", currencyResult = " + currencyResult + ", currencyResult = " + currencyResult +
", countryResult = " + countryResult + ", countryResult = " + countryResult +
@ -163,7 +166,8 @@ public class OrderBook implements OrderBookListener {
", settings.getAcceptedCountries() = " + settings.getAcceptedCountries().toString()); ", settings.getAcceptedCountries() = " + settings.getAcceptedCountries().toString());
log.debug("settings.getAcceptedLanguageLocales() = " + settings.getAcceptedLanguageLocales() + log.debug("settings.getAcceptedLanguageLocales() = " + settings.getAcceptedLanguageLocales() +
", offer.getAcceptedLanguageLocales() = " + offer.getAcceptedLanguageLocales()); ", offer.getAcceptedLanguageLocales() = " + offer.getAcceptedLanguageLocales());
log.debug("currentBankAccount.getBankAccountType().getType() = " + currentBankAccount.getBankAccountType().getType() + log.debug("currentBankAccount.getBankAccountType().getType() = " + currentBankAccount.getBankAccountType
().getType() +
", offer.getBankAccountTypeEnum() = " + offer.getBankAccountTypeEnum()); ", offer.getBankAccountTypeEnum() = " + offer.getBankAccountTypeEnum());
log.debug("orderBookFilter.getAmount() = " + orderBookFilter.getAmount() + log.debug("orderBookFilter.getAmount() = " + orderBookFilter.getAmount() +
", offer.getAmount() = " + offer.getAmount()); ", offer.getAmount() = " + offer.getAmount());

View file

@ -60,7 +60,7 @@ public class CreateOfferCoordinator {
private final Persistence persistence; private final Persistence persistence;
private State state; private State state;
//TODO use tx id //TODO use tx id
Transaction transaction; Transaction transaction;
Model(Persistence persistence) { Model(Persistence persistence) {
@ -74,7 +74,8 @@ public class CreateOfferCoordinator {
public void setState(State state) { public void setState(State state) {
this.state = state; this.state = state;
//TODO will have performance issues, but could be handled inside the persistence solution (queue up save requests and exec. them on dedicated thread) //TODO will have performance issues, but could be handled inside the persistence solution (queue up save
// requests and exec. them on dedicated thread)
persistence.write(this, "state", state); persistence.write(this, "state", state);
} }
} }
@ -88,12 +89,15 @@ public class CreateOfferCoordinator {
private final FaultHandler faultHandler; private final FaultHandler faultHandler;
private final Model model; private final Model model;
public CreateOfferCoordinator(Persistence persistence, Offer offer, WalletFacade walletFacade, MessageFacade messageFacade, TransactionResultHandler resultHandler, FaultHandler faultHandler) { public CreateOfferCoordinator(Persistence persistence, Offer offer, WalletFacade walletFacade,
MessageFacade messageFacade, TransactionResultHandler resultHandler,
FaultHandler faultHandler) {
this(offer, walletFacade, messageFacade, resultHandler, faultHandler, new Model(persistence)); this(offer, walletFacade, messageFacade, resultHandler, faultHandler, new Model(persistence));
} }
// for recovery from model // for recovery from model
public CreateOfferCoordinator(Offer offer, WalletFacade walletFacade, MessageFacade messageFacade, TransactionResultHandler resultHandler, FaultHandler faultHandler, Model model) { public CreateOfferCoordinator(Offer offer, WalletFacade walletFacade, MessageFacade messageFacade,
TransactionResultHandler resultHandler, FaultHandler faultHandler, Model model) {
this.offer = offer; this.offer = offer;
this.walletFacade = walletFacade; this.walletFacade = walletFacade;
this.messageFacade = messageFacade; this.messageFacade = messageFacade;
@ -138,7 +142,7 @@ public class CreateOfferCoordinator {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Recovery // Recovery
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public void recover() { public void recover() {
@ -151,7 +155,7 @@ public class CreateOfferCoordinator {
start(); start();
break; break;
case OFFER_FEE_BROAD_CASTED: case OFFER_FEE_BROAD_CASTED:
// actually the only replay case here, tx publish was successful but storage to dht failed. // actually the only replay case here, tx publish was successful but storage to dht failed.
// Republish the offer to DHT // Republish the offer to DHT
PublishOfferToDHT.run(this::onOfferPublishedToDHT, this::onFailed, messageFacade, offer); PublishOfferToDHT.run(this::onOfferPublishedToDHT, this::onFailed, messageFacade, offer);
break; break;

View file

@ -30,7 +30,8 @@ import org.slf4j.LoggerFactory;
public class BroadCastOfferFeeTx { public class BroadCastOfferFeeTx {
private static final Logger log = LoggerFactory.getLogger(BroadCastOfferFeeTx.class); private static final Logger log = LoggerFactory.getLogger(BroadCastOfferFeeTx.class);
public static void run(ResultHandler resultHandler, FaultHandler faultHandler, WalletFacade walletFacade, Transaction tx) { public static void run(ResultHandler resultHandler, FaultHandler faultHandler, WalletFacade walletFacade,
Transaction tx) {
try { try {
walletFacade.broadcastCreateOfferFeeTx(tx, new FutureCallback<Transaction>() { walletFacade.broadcastCreateOfferFeeTx(tx, new FutureCallback<Transaction>() {
@Override @Override
@ -43,7 +44,8 @@ public class BroadCastOfferFeeTx {
faultHandler.onFault("Offer fee payment failed.", e); faultHandler.onFault("Offer fee payment failed.", e);
} }
} else { } else {
faultHandler.onFault("Offer fee payment failed.", new Exception("Offer fee payment failed. Transaction = null.")); faultHandler.onFault("Offer fee payment failed.", new Exception("Offer fee payment failed. " +
"Transaction = null."));
} }
} }
@ -53,7 +55,8 @@ public class BroadCastOfferFeeTx {
} }
}); });
} catch (InsufficientMoneyException e) { } catch (InsufficientMoneyException e) {
faultHandler.onFault("Offer fee payment failed because there is insufficient money in the trade pocket. ", e); faultHandler.onFault("Offer fee payment failed because there is insufficient money in the trade pocket. " +
"", e);
} catch (Throwable t) { } catch (Throwable t) {
faultHandler.onFault("Offer fee payment failed because of an exception occurred. ", t); faultHandler.onFault("Offer fee payment failed because of an exception occurred. ", t);
} }

View file

@ -27,11 +27,13 @@ import org.slf4j.LoggerFactory;
public class CreateOfferFeeTx { public class CreateOfferFeeTx {
private static final Logger log = LoggerFactory.getLogger(CreateOfferFeeTx.class); private static final Logger log = LoggerFactory.getLogger(CreateOfferFeeTx.class);
public static void run(TransactionResultHandler resultHandler, FaultHandler faultHandler, WalletFacade walletFacade, String offerId) { public static void run(TransactionResultHandler resultHandler, FaultHandler faultHandler,
WalletFacade walletFacade, String offerId) {
try { try {
resultHandler.onResult(walletFacade.createOfferFeeTx(offerId)); resultHandler.onResult(walletFacade.createOfferFeeTx(offerId));
} catch (InsufficientMoneyException e) { } catch (InsufficientMoneyException e) {
faultHandler.onFault("Offer fee payment failed because there is insufficient money in the trade pocket. ", e); faultHandler.onFault("Offer fee payment failed because there is insufficient money in the trade pocket. " +
"", e);
} catch (Throwable t) { } catch (Throwable t) {
faultHandler.onFault("Offer fee payment failed because of an exception occurred. ", t); faultHandler.onFault("Offer fee payment failed because of an exception occurred. ", t);
} }

View file

@ -27,7 +27,8 @@ import org.slf4j.LoggerFactory;
public class PublishOfferToDHT { public class PublishOfferToDHT {
private static final Logger log = LoggerFactory.getLogger(PublishOfferToDHT.class); private static final Logger log = LoggerFactory.getLogger(PublishOfferToDHT.class);
public static void run(ResultHandler resultHandler, FaultHandler faultHandler, MessageFacade messageFacade, Offer offer) { public static void run(ResultHandler resultHandler, FaultHandler faultHandler, MessageFacade messageFacade,
Offer offer) {
messageFacade.addOffer(offer, new MessageFacade.AddOfferListener() { messageFacade.addOffer(offer, new MessageFacade.AddOfferListener() {
@Override @Override
public void onComplete() { public void onComplete() {

View file

@ -39,7 +39,8 @@ public class CreateDepositTx {
log.trace("Run task"); log.trace("Run task");
try { try {
String offererPubKey = walletFacade.getAddressInfoByTradeID(tradeId).getPubKeyAsHexString(); String offererPubKey = walletFacade.getAddressInfoByTradeID(tradeId).getPubKeyAsHexString();
Transaction transaction = walletFacade.offererCreatesMSTxAndAddPayment(offererInputAmount, offererPubKey, takerMultiSigPubKey, arbitratorPubKeyAsHex, tradeId); Transaction transaction = walletFacade.offererCreatesMSTxAndAddPayment(offererInputAmount, offererPubKey,
takerMultiSigPubKey, arbitratorPubKeyAsHex, tradeId);
String preparedOffererDepositTxAsHex = Utils.HEX.encode(transaction.bitcoinSerialize()); String preparedOffererDepositTxAsHex = Utils.HEX.encode(transaction.bitcoinSerialize());
long offererTxOutIndex = transaction.getInput(0).getOutpoint().getIndex(); long offererTxOutIndex = transaction.getInput(0).getOutpoint().getIndex();
@ -47,7 +48,8 @@ public class CreateDepositTx {
resultHandler.onResult(offererPubKey, preparedOffererDepositTxAsHex, offererTxOutIndex); resultHandler.onResult(offererPubKey, preparedOffererDepositTxAsHex, offererTxOutIndex);
} catch (InsufficientMoneyException e) { } catch (InsufficientMoneyException e) {
log.error("Create deposit tx faultHandler.onFault due InsufficientMoneyException " + e); log.error("Create deposit tx faultHandler.onFault due InsufficientMoneyException " + e);
exceptionHandler.onError(new Exception("Create deposit tx faultHandler.onFault due InsufficientMoneyException " + e)); exceptionHandler.onError(new Exception("Create deposit tx faultHandler.onFault due " +
"InsufficientMoneyException " + e));
} }
} }

View file

@ -28,13 +28,15 @@ import org.slf4j.LoggerFactory;
public class HandleTakeOfferRequest { public class HandleTakeOfferRequest {
private static final Logger log = LoggerFactory.getLogger(HandleTakeOfferRequest.class); private static final Logger log = LoggerFactory.getLogger(HandleTakeOfferRequest.class);
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, PeerAddress peerAddress, MessageFacade messageFacade, Trade.State tradeState, String tradeId) { public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, PeerAddress peerAddress,
MessageFacade messageFacade, Trade.State tradeState, String tradeId) {
log.trace("Run task"); log.trace("Run task");
boolean takeOfferRequestAccepted = tradeState == Trade.State.OPEN; boolean takeOfferRequestAccepted = tradeState == Trade.State.OPEN;
if (!takeOfferRequestAccepted) { if (!takeOfferRequestAccepted) {
log.info("Received take offer request but the offer not marked as open anymore."); log.info("Received take offer request but the offer not marked as open anymore.");
} }
messageFacade.sendTradeMessage(peerAddress, new RespondToTakeOfferRequestMessage(tradeId, takeOfferRequestAccepted), new OutgoingTradeMessageListener() { messageFacade.sendTradeMessage(peerAddress, new RespondToTakeOfferRequestMessage(tradeId,
takeOfferRequestAccepted), new OutgoingTradeMessageListener() {
@Override @Override
public void onResult() { public void onResult() {
log.trace("RespondToTakeOfferRequestMessage successfully arrived at peer"); log.trace("RespondToTakeOfferRequestMessage successfully arrived at peer");

View file

@ -45,7 +45,8 @@ import static com.google.common.base.Preconditions.*;
import static io.bitsquare.util.Validator.*; import static io.bitsquare.util.Validator.*;
/** /**
* Responsible for the correct execution of the sequence of tasks, message passing to the peer and message processing from the peer. * Responsible for the correct execution of the sequence of tasks, message passing to the peer and message processing
* from the peer.
* <p/> * <p/>
* This class handles the role of the offerer as the Bitcoin buyer. * This class handles the role of the offerer as the Bitcoin buyer.
* <p/> * <p/>
@ -158,7 +159,8 @@ public class ProtocolForOffererAsBuyer {
public void start() { public void start() {
log.debug("start called " + step++); log.debug("start called " + step++);
state = State.HandleTakeOfferRequest; state = State.HandleTakeOfferRequest;
HandleTakeOfferRequest.run(this::onResultHandleTakeOfferRequest, this::onFault, peerAddress, messageFacade, trade.getState(), tradeId); HandleTakeOfferRequest.run(this::onResultHandleTakeOfferRequest, this::onFault, peerAddress, messageFacade,
trade.getState(), tradeId);
} }
public void onResultHandleTakeOfferRequest(boolean takeOfferRequestAccepted) { public void onResultHandleTakeOfferRequest(boolean takeOfferRequestAccepted) {
@ -198,7 +200,8 @@ public class ProtocolForOffererAsBuyer {
// next task // next task
state = State.VerifyTakeOfferFeePayment; state = State.VerifyTakeOfferFeePayment;
VerifyTakeOfferFeePayment.run(this::onResultVerifyTakeOfferFeePayment, this::onFault, walletFacade, this.takeOfferFeeTxId); VerifyTakeOfferFeePayment.run(this::onResultVerifyTakeOfferFeePayment, this::onFault, walletFacade,
this.takeOfferFeeTxId);
} }
public void onResultVerifyTakeOfferFeePayment() { public void onResultVerifyTakeOfferFeePayment() {
@ -207,10 +210,12 @@ public class ProtocolForOffererAsBuyer {
Coin collateral = trade.getCollateralAmount(); Coin collateral = trade.getCollateralAmount();
Coin offererInputAmount = collateral.add(FeePolicy.TX_FEE); Coin offererInputAmount = collateral.add(FeePolicy.TX_FEE);
state = State.CreateDepositTx; state = State.CreateDepositTx;
CreateDepositTx.run(this::onResultCreateDepositTx, this::onFault, walletFacade, tradeId, offererInputAmount, takerPubKey, arbitratorPubKey); CreateDepositTx.run(this::onResultCreateDepositTx, this::onFault, walletFacade, tradeId, offererInputAmount,
takerPubKey, arbitratorPubKey);
} }
public void onResultCreateDepositTx(String offererPubKey, String preparedOffererDepositTxAsHex, long offererTxOutIndex) { public void onResultCreateDepositTx(String offererPubKey, String preparedOffererDepositTxAsHex,
long offererTxOutIndex) {
log.debug("onResultCreateDepositTx called " + step++); log.debug("onResultCreateDepositTx called " + step++);
this.preparedOffererDepositTxAsHex = preparedOffererDepositTxAsHex; this.preparedOffererDepositTxAsHex = preparedOffererDepositTxAsHex;
this.offererTxOutIndex = offererTxOutIndex; this.offererTxOutIndex = offererTxOutIndex;
@ -269,7 +274,8 @@ public class ProtocolForOffererAsBuyer {
// next task // next task
state = State.VerifyTakerAccount; state = State.VerifyTakerAccount;
VerifyTakerAccount.run(this::onResultVerifyTakerAccount, this::onFault, blockChainFacade, this.peersAccountId, this.peersBankAccount); VerifyTakerAccount.run(this::onResultVerifyTakerAccount, this::onFault, blockChainFacade,
this.peersAccountId, this.peersBankAccount);
} }
public void onResultVerifyTakerAccount() { public void onResultVerifyTakerAccount() {
@ -318,14 +324,16 @@ public class ProtocolForOffererAsBuyer {
listener.onDepositTxPublished(depositTransaction.getHashAsString()); listener.onDepositTxPublished(depositTransaction.getHashAsString());
state = State.SendDepositTxIdToTaker; state = State.SendDepositTxIdToTaker;
SendDepositTxIdToTaker.run(this::onResultSendDepositTxIdToTaker, this::onFault, peerAddress, messageFacade, tradeId, depositTransaction); SendDepositTxIdToTaker.run(this::onResultSendDepositTxIdToTaker, this::onFault, peerAddress, messageFacade,
tradeId, depositTransaction);
} }
public void onResultSendDepositTxIdToTaker() { public void onResultSendDepositTxIdToTaker() {
log.debug("onResultSendDepositTxIdToTaker called " + step++); log.debug("onResultSendDepositTxIdToTaker called " + step++);
state = State.SetupListenerForBlockChainConfirmation; state = State.SetupListenerForBlockChainConfirmation;
SetupListenerForBlockChainConfirmation.run(this::onResultSetupListenerForBlockChainConfirmation, this::onFault, trade.getDepositTransaction(), listener); SetupListenerForBlockChainConfirmation.run(this::onResultSetupListenerForBlockChainConfirmation,
this::onFault, trade.getDepositTransaction(), listener);
} }
public void onResultSetupListenerForBlockChainConfirmation() { public void onResultSetupListenerForBlockChainConfirmation() {
@ -346,7 +354,8 @@ public class ProtocolForOffererAsBuyer {
log.debug("state " + state); log.debug("state " + state);
// validation // validation
checkState(state.ordinal() >= State.SignAndPublishDepositTx.ordinal() && state.ordinal() <= State.onResultSetupListenerForBlockChainConfirmation.ordinal()); checkState(state.ordinal() >= State.SignAndPublishDepositTx.ordinal() && state.ordinal() <= State
.onResultSetupListenerForBlockChainConfirmation.ordinal());
state = State.onUIEventBankTransferInited; state = State.onUIEventBankTransferInited;

View file

@ -40,7 +40,8 @@ public class RequestTakerDepositPayment {
String preparedOffererDepositTxAsHex, String preparedOffererDepositTxAsHex,
long offererTxOutIndex) { long offererTxOutIndex) {
log.trace("Run task"); log.trace("Run task");
RequestTakerDepositPaymentMessage tradeMessage = new RequestTakerDepositPaymentMessage(tradeId, bankAccount, accountId, offererPubKey, preparedOffererDepositTxAsHex, offererTxOutIndex); RequestTakerDepositPaymentMessage tradeMessage = new RequestTakerDepositPaymentMessage(tradeId, bankAccount,
accountId, offererPubKey, preparedOffererDepositTxAsHex, offererTxOutIndex);
messageFacade.sendTradeMessage(peerAddress, tradeMessage, new OutgoingTradeMessageListener() { messageFacade.sendTradeMessage(peerAddress, tradeMessage, new OutgoingTradeMessageListener() {
@Override @Override
public void onResult() { public void onResult() {

View file

@ -32,7 +32,9 @@ public class RequestTakerDepositPaymentMessage implements Serializable, TradeMes
private String preparedOffererDepositTxAsHex; private String preparedOffererDepositTxAsHex;
private long offererTxOutIndex; private long offererTxOutIndex;
public RequestTakerDepositPaymentMessage(String tradeId, BankAccount bankAccount, String accountID, String offererPubKey, String preparedOffererDepositTxAsHex, long offererTxOutIndex) { public RequestTakerDepositPaymentMessage(String tradeId, BankAccount bankAccount, String accountID,
String offererPubKey, String preparedOffererDepositTxAsHex,
long offererTxOutIndex) {
this.tradeId = tradeId; this.tradeId = tradeId;
this.bankAccount = bankAccount; this.bankAccount = bankAccount;
this.accountID = accountID; this.accountID = accountID;

View file

@ -30,9 +30,11 @@ import org.slf4j.LoggerFactory;
public class SendDepositTxIdToTaker { public class SendDepositTxIdToTaker {
private static final Logger log = LoggerFactory.getLogger(SendDepositTxIdToTaker.class); private static final Logger log = LoggerFactory.getLogger(SendDepositTxIdToTaker.class);
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, PeerAddress peerAddress, MessageFacade messageFacade, String tradeId, Transaction depositTransaction) { public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, PeerAddress peerAddress,
MessageFacade messageFacade, String tradeId, Transaction depositTransaction) {
log.trace("Run task"); log.trace("Run task");
DepositTxPublishedMessage tradeMessage = new DepositTxPublishedMessage(tradeId, Utils.HEX.encode(depositTransaction.bitcoinSerialize())); DepositTxPublishedMessage tradeMessage = new DepositTxPublishedMessage(tradeId,
Utils.HEX.encode(depositTransaction.bitcoinSerialize()));
messageFacade.sendTradeMessage(peerAddress, tradeMessage, new OutgoingTradeMessageListener() { messageFacade.sendTradeMessage(peerAddress, tradeMessage, new OutgoingTradeMessageListener() {
@Override @Override
public void onResult() { public void onResult() {

View file

@ -48,7 +48,8 @@ public class SendSignedPayoutTx {
Coin offererPaybackAmount = tradeAmount.add(collateral); Coin offererPaybackAmount = tradeAmount.add(collateral);
Coin takerPaybackAmount = collateral; Coin takerPaybackAmount = collateral;
Pair<ECKey.ECDSASignature, String> result = walletFacade.offererCreatesAndSignsPayoutTx(depositTransactionId, offererPaybackAmount, takerPaybackAmount, takerPayoutAddress, tradeId); Pair<ECKey.ECDSASignature, String> result = walletFacade.offererCreatesAndSignsPayoutTx
(depositTransactionId, offererPaybackAmount, takerPaybackAmount, takerPayoutAddress, tradeId);
ECKey.ECDSASignature offererSignature = result.getKey(); ECKey.ECDSASignature offererSignature = result.getKey();
String offererSignatureR = offererSignature.r.toString(); String offererSignatureR = offererSignature.r.toString();

View file

@ -27,7 +27,8 @@ import org.slf4j.LoggerFactory;
public class SetupListenerForBlockChainConfirmation { public class SetupListenerForBlockChainConfirmation {
private static final Logger log = LoggerFactory.getLogger(SetupListenerForBlockChainConfirmation.class); private static final Logger log = LoggerFactory.getLogger(SetupListenerForBlockChainConfirmation.class);
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, Transaction depositTransaction, ProtocolForOffererAsBuyerListener listener) { public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler,
Transaction depositTransaction, ProtocolForOffererAsBuyerListener listener) {
log.trace("Run task"); log.trace("Run task");
//TODO //TODO
// sharedModel.offererPaymentProtocolListener.onDepositTxConfirmedInBlockchain(); // sharedModel.offererPaymentProtocolListener.onDepositTxConfirmedInBlockchain();
@ -39,7 +40,8 @@ public class SetupListenerForBlockChainConfirmation {
if (reason == ChangeReason.SEEN_PEERS) { if (reason == ChangeReason.SEEN_PEERS) {
listener.onDepositTxConfirmedUpdate(tx.getConfidence()); listener.onDepositTxConfirmedUpdate(tx.getConfidence());
} }
if (reason == ChangeReason.TYPE && tx.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING) { if (reason == ChangeReason.TYPE && tx.getConfidence().getConfidenceType() == TransactionConfidence
.ConfidenceType.BUILDING) {
listener.onDepositTxConfirmedInBlockchain(); listener.onDepositTxConfirmedInBlockchain();
depositTransaction.getConfidence().removeEventListener(this); depositTransaction.getConfidence().removeEventListener(this);
log.trace("Tx is in blockchain"); log.trace("Tx is in blockchain");

View file

@ -49,7 +49,8 @@ public class VerifyAndSignContract {
String peersContractAsJson, String peersContractAsJson,
ECKey registrationKey) { ECKey registrationKey) {
log.trace("Run task"); log.trace("Run task");
Contract contract = new Contract(offer, tradeAmount, takeOfferFeeTxId, accountId, peersAccountId, bankAccount, peersBankAccount, messagePublicKey, takerMessagePublicKey); Contract contract = new Contract(offer, tradeAmount, takeOfferFeeTxId, accountId, peersAccountId,
bankAccount, peersBankAccount, messagePublicKey, takerMessagePublicKey);
String contractAsJson = Utilities.objectToJson(contract); String contractAsJson = Utilities.objectToJson(contract);
// log.trace("Offerer contract created: " + contract); // log.trace("Offerer contract created: " + contract);

View file

@ -26,7 +26,8 @@ import org.slf4j.LoggerFactory;
public class VerifyTakeOfferFeePayment { public class VerifyTakeOfferFeePayment {
private static final Logger log = LoggerFactory.getLogger(VerifyTakeOfferFeePayment.class); private static final Logger log = LoggerFactory.getLogger(VerifyTakeOfferFeePayment.class);
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, WalletFacade walletFacade, String takeOfferFeeTxId) { public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, WalletFacade walletFacade,
String takeOfferFeeTxId) {
log.trace("Run task"); log.trace("Run task");
//TODO mocked yet, need a confidence listeners //TODO mocked yet, need a confidence listeners
int numOfPeersSeenTx = walletFacade.getNumOfPeersSeenTx(takeOfferFeeTxId); int numOfPeersSeenTx = walletFacade.getNumOfPeersSeenTx(takeOfferFeeTxId);

View file

@ -28,7 +28,8 @@ import org.slf4j.LoggerFactory;
public class VerifyTakerAccount { public class VerifyTakerAccount {
private static final Logger log = LoggerFactory.getLogger(VerifyTakerAccount.class); private static final Logger log = LoggerFactory.getLogger(VerifyTakerAccount.class);
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, BlockChainFacade blockChainFacade, String peersAccountId, BankAccount peersBankAccount) { public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler,
BlockChainFacade blockChainFacade, String peersAccountId, BankAccount peersBankAccount) {
log.trace("Run task"); log.trace("Run task");
VerifyPeerAccount.run(resultHandler, exceptionHandler, blockChainFacade, peersAccountId, peersBankAccount); VerifyPeerAccount.run(resultHandler, exceptionHandler, blockChainFacade, peersAccountId, peersBankAccount);
} }

View file

@ -27,7 +27,8 @@ import org.slf4j.LoggerFactory;
public class VerifyPeerAccount { public class VerifyPeerAccount {
private static final Logger log = LoggerFactory.getLogger(VerifyPeerAccount.class); private static final Logger log = LoggerFactory.getLogger(VerifyPeerAccount.class);
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, BlockChainFacade blockChainFacade, String peersAccountId, BankAccount peersBankAccount) { public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler,
BlockChainFacade blockChainFacade, String peersAccountId, BankAccount peersBankAccount) {
//TODO mocked yet //TODO mocked yet
if (blockChainFacade.verifyAccountRegistration()) { if (blockChainFacade.verifyAccountRegistration()) {
if (blockChainFacade.isAccountBlackListed(peersAccountId, peersBankAccount)) { if (blockChainFacade.isAccountBlackListed(peersAccountId, peersBankAccount)) {

View file

@ -49,7 +49,8 @@ public class CreateAndSignContract {
ECKey registrationKey) { ECKey registrationKey) {
log.trace("Run task"); log.trace("Run task");
try { try {
Contract contract = new Contract(offer, tradeAmount, takeOfferFeeTxId, peersAccountId, accountId, peersBankAccount, bankAccount, peersMessagePublicKey, messagePublicKey); Contract contract = new Contract(offer, tradeAmount, takeOfferFeeTxId, peersAccountId, accountId,
peersBankAccount, bankAccount, peersMessagePublicKey, messagePublicKey);
String contractAsJson = Utilities.objectToJson(contract); String contractAsJson = Utilities.objectToJson(contract);
String signature = cryptoFacade.signContract(registrationKey, contractAsJson); String signature = cryptoFacade.signContract(registrationKey, contractAsJson);

View file

@ -30,7 +30,8 @@ import org.slf4j.LoggerFactory;
public class GetPeerAddress { public class GetPeerAddress {
private static final Logger log = LoggerFactory.getLogger(GetPeerAddress.class); private static final Logger log = LoggerFactory.getLogger(GetPeerAddress.class);
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, MessageFacade messageFacade, PublicKey messagePublicKey) { public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler,
MessageFacade messageFacade, PublicKey messagePublicKey) {
log.trace("Run task"); log.trace("Run task");
messageFacade.getPeerAddress(messagePublicKey, new GetPeerAddressListener() { messageFacade.getPeerAddress(messagePublicKey, new GetPeerAddressListener() {
@Override @Override

View file

@ -55,7 +55,8 @@ public class PayDeposit {
resultHandler.onResult(signedTakerDepositTx); resultHandler.onResult(signedTakerDepositTx);
} catch (InsufficientMoneyException e) { } catch (InsufficientMoneyException e) {
log.error("Pay deposit faultHandler.onFault due InsufficientMoneyException " + e); log.error("Pay deposit faultHandler.onFault due InsufficientMoneyException " + e);
exceptionHandler.onError(new Exception("Pay deposit faultHandler.onFault due InsufficientMoneyException " + e)); exceptionHandler.onError(new Exception("Pay deposit faultHandler.onFault due InsufficientMoneyException "
+ e));
} }
} }

View file

@ -28,7 +28,8 @@ import org.slf4j.LoggerFactory;
public class PayTakeOfferFee { public class PayTakeOfferFee {
private static final Logger log = LoggerFactory.getLogger(PayTakeOfferFee.class); private static final Logger log = LoggerFactory.getLogger(PayTakeOfferFee.class);
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, WalletFacade walletFacade, String tradeId) { public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, WalletFacade walletFacade,
String tradeId) {
log.trace("Run task"); log.trace("Run task");
try { try {
walletFacade.payTakeOfferFee(tradeId, new FutureCallback<Transaction>() { walletFacade.payTakeOfferFee(tradeId, new FutureCallback<Transaction>() {
@ -41,12 +42,14 @@ public class PayTakeOfferFee {
@Override @Override
public void onFailure(Throwable t) { public void onFailure(Throwable t) {
log.error("Take offer fee paid faultHandler.onFault with exception: " + t); log.error("Take offer fee paid faultHandler.onFault with exception: " + t);
exceptionHandler.onError(new Exception("Take offer fee paid faultHandler.onFault with exception: " + t)); exceptionHandler.onError(new Exception("Take offer fee paid faultHandler.onFault with exception: " +
"" + t));
} }
}); });
} catch (InsufficientMoneyException e) { } catch (InsufficientMoneyException e) {
log.error("Take offer fee paid faultHandler.onFault due InsufficientMoneyException " + e); log.error("Take offer fee paid faultHandler.onFault due InsufficientMoneyException " + e);
exceptionHandler.onError(new Exception("Take offer fee paid faultHandler.onFault due InsufficientMoneyException " + e)); exceptionHandler.onError(new Exception("Take offer fee paid faultHandler.onFault due " +
"InsufficientMoneyException " + e));
} }
} }

View file

@ -44,7 +44,8 @@ import static com.google.common.base.Preconditions.*;
import static io.bitsquare.util.Validator.*; import static io.bitsquare.util.Validator.*;
/** /**
* Responsible for the correct execution of the sequence of tasks, message passing to the peer and message processing from the peer. * Responsible for the correct execution of the sequence of tasks, message passing to the peer and message processing
* from the peer.
* That class handles the role of the taker as the Bitcoin seller. * That class handles the role of the taker as the Bitcoin seller.
* It uses sub tasks to not pollute the main class too much with all the async result/fault handling. * It uses sub tasks to not pollute the main class too much with all the async result/fault handling.
* Any data from incoming messages as well data used to send to the peer need to be validated before further processing. * Any data from incoming messages as well data used to send to the peer need to be validated before further processing.
@ -195,7 +196,8 @@ public class ProtocolForTakerAsSeller {
trade.setTakeOfferFeeTxID(takeOfferFeeTxId); trade.setTakeOfferFeeTxID(takeOfferFeeTxId);
state = State.SendTakeOfferFeePayedTxId; state = State.SendTakeOfferFeePayedTxId;
SendTakeOfferFeePayedTxId.run(this::onResultSendTakeOfferFeePayedTxId, this::onFault, peerAddress, messageFacade, tradeId, takeOfferFeeTxId, tradeAmount, pubKeyForThatTrade); SendTakeOfferFeePayedTxId.run(this::onResultSendTakeOfferFeePayedTxId, this::onFault, peerAddress,
messageFacade, tradeId, takeOfferFeeTxId, tradeAmount, pubKeyForThatTrade);
} }
public void onResultSendTakeOfferFeePayedTxId() { public void onResultSendTakeOfferFeePayedTxId() {
@ -231,7 +233,8 @@ public class ProtocolForTakerAsSeller {
// next task // next task
state = State.VerifyOffererAccount; state = State.VerifyOffererAccount;
VerifyOffererAccount.run(this::onResultVerifyOffererAccount, this::onFault, blockChainFacade, peersAccountId, peersBankAccount); VerifyOffererAccount.run(this::onResultVerifyOffererAccount, this::onFault, blockChainFacade, peersAccountId,
peersBankAccount);
} }
public void onResultVerifyOffererAccount() { public void onResultVerifyOffererAccount() {
@ -261,7 +264,8 @@ public class ProtocolForTakerAsSeller {
trade.setContractTakerSignature(signature); trade.setContractTakerSignature(signature);
state = State.PayDeposit; state = State.PayDeposit;
PayDeposit.run(this::onResultPayDeposit, this::onFault, walletFacade, collateral, tradeAmount, tradeId, pubKeyForThatTrade, arbitratorPubKey, peersPubKey, preparedPeersDepositTxAsHex); PayDeposit.run(this::onResultPayDeposit, this::onFault, walletFacade, collateral, tradeAmount, tradeId,
pubKeyForThatTrade, arbitratorPubKey, peersPubKey, preparedPeersDepositTxAsHex);
} }
public void onResultPayDeposit(Transaction signedTakerDepositTx) { public void onResultPayDeposit(Transaction signedTakerDepositTx) {
@ -314,7 +318,8 @@ public class ProtocolForTakerAsSeller {
log.debug("onBankTransferInitedMessage called " + step++); log.debug("onBankTransferInitedMessage called " + step++);
log.debug("state " + state); log.debug("state " + state);
// validate // validate
checkState(state.ordinal() >= State.SendSignedTakerDepositTxAsHex.ordinal() && state.ordinal() < State.SignAndPublishPayoutTx.ordinal()); checkState(state.ordinal() >= State.SendSignedTakerDepositTxAsHex.ordinal() && state.ordinal() < State
.SignAndPublishPayoutTx.ordinal());
checkArgument(tradeId.equals(message.getTradeId())); checkArgument(tradeId.equals(message.getTradeId()));
String depositTxAsHex = nonEmptyStringOf(message.getDepositTxAsHex()); String depositTxAsHex = nonEmptyStringOf(message.getDepositTxAsHex());
String offererSignatureR = nonEmptyStringOf(message.getOffererSignatureR()); String offererSignatureR = nonEmptyStringOf(message.getOffererSignatureR());
@ -364,7 +369,8 @@ public class ProtocolForTakerAsSeller {
listener.onPayoutTxPublished(trade, transactionId); listener.onPayoutTxPublished(trade, transactionId);
state = State.SendPayoutTxToOfferer; state = State.SendPayoutTxToOfferer;
SendPayoutTxToOfferer.run(this::onResultSendPayoutTxToOfferer, this::onFault, peerAddress, messageFacade, tradeId, payoutTxAsHex); SendPayoutTxToOfferer.run(this::onResultSendPayoutTxToOfferer, this::onFault, peerAddress, messageFacade,
tradeId, payoutTxAsHex);
} }
public void onResultSendPayoutTxToOfferer() { public void onResultSendPayoutTxToOfferer() {

View file

@ -28,9 +28,11 @@ import org.slf4j.LoggerFactory;
public class RequestTakeOffer { public class RequestTakeOffer {
private static final Logger log = LoggerFactory.getLogger(RequestTakeOffer.class); private static final Logger log = LoggerFactory.getLogger(RequestTakeOffer.class);
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, PeerAddress peerAddress, MessageFacade messageFacade, String tradeId) { public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, PeerAddress peerAddress,
MessageFacade messageFacade, String tradeId) {
log.trace("Run task"); log.trace("Run task");
messageFacade.sendTradeMessage(peerAddress, new RequestTakeOfferMessage(tradeId), new OutgoingTradeMessageListener() { messageFacade.sendTradeMessage(peerAddress, new RequestTakeOfferMessage(tradeId),
new OutgoingTradeMessageListener() {
@Override @Override
public void onResult() { public void onResult() {
log.trace("RequestTakeOfferMessage successfully arrived at peer"); log.trace("RequestTakeOfferMessage successfully arrived at peer");

View file

@ -28,7 +28,8 @@ import org.slf4j.LoggerFactory;
public class SendPayoutTxToOfferer { public class SendPayoutTxToOfferer {
private static final Logger log = LoggerFactory.getLogger(SendPayoutTxToOfferer.class); private static final Logger log = LoggerFactory.getLogger(SendPayoutTxToOfferer.class);
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, PeerAddress peerAddress, MessageFacade messageFacade, String tradeId, String payoutTxAsHex) { public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, PeerAddress peerAddress,
MessageFacade messageFacade, String tradeId, String payoutTxAsHex) {
log.trace("Run task"); log.trace("Run task");
PayoutTxPublishedMessage tradeMessage = new PayoutTxPublishedMessage(tradeId, payoutTxAsHex); PayoutTxPublishedMessage tradeMessage = new PayoutTxPublishedMessage(tradeId, payoutTxAsHex);
messageFacade.sendTradeMessage(peerAddress, tradeMessage, new OutgoingTradeMessageListener() { messageFacade.sendTradeMessage(peerAddress, tradeMessage, new OutgoingTradeMessageListener() {

View file

@ -76,7 +76,8 @@ public class SendSignedTakerDepositTxAsHex {
@Override @Override
public void onFailed() { public void onFailed() {
log.error("RequestOffererDepositPublicationMessage did not arrive at peer"); log.error("RequestOffererDepositPublicationMessage did not arrive at peer");
exceptionHandler.onError(new Exception("RequestOffererDepositPublicationMessage did not arrive at peer")); exceptionHandler.onError(new Exception("RequestOffererDepositPublicationMessage did not arrive at " +
"peer"));
} }
}); });
} }

View file

@ -38,7 +38,8 @@ public class SendTakeOfferFeePayedTxId {
Coin tradeAmount, Coin tradeAmount,
String pubKeyForThatTradeAsHex) { String pubKeyForThatTradeAsHex) {
log.trace("Run task"); log.trace("Run task");
TakeOfferFeePayedMessage msg = new TakeOfferFeePayedMessage(tradeId, takeOfferFeeTxId, tradeAmount, pubKeyForThatTradeAsHex); TakeOfferFeePayedMessage msg = new TakeOfferFeePayedMessage(tradeId, takeOfferFeeTxId, tradeAmount,
pubKeyForThatTradeAsHex);
messageFacade.sendTradeMessage(peerAddress, msg, new OutgoingTradeMessageListener() { messageFacade.sendTradeMessage(peerAddress, msg, new OutgoingTradeMessageListener() {
@Override @Override

View file

@ -28,7 +28,8 @@ import org.slf4j.LoggerFactory;
public class VerifyOffererAccount { public class VerifyOffererAccount {
private static final Logger log = LoggerFactory.getLogger(VerifyOffererAccount.class); private static final Logger log = LoggerFactory.getLogger(VerifyOffererAccount.class);
public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler, BlockChainFacade blockChainFacade, String peersAccountId, BankAccount peersBankAccount) { public static void run(ResultHandler resultHandler, ExceptionHandler exceptionHandler,
BlockChainFacade blockChainFacade, String peersAccountId, BankAccount peersBankAccount) {
log.trace("Run task"); log.trace("Run task");
VerifyPeerAccount.run(resultHandler, exceptionHandler, blockChainFacade, peersAccountId, peersBankAccount); VerifyPeerAccount.run(resultHandler, exceptionHandler, blockChainFacade, peersAccountId, peersBankAccount);
} }

View file

@ -39,7 +39,8 @@ public class FileUtil {
/* /*
public static String getApplicationFileName() public static String getApplicationFileName()
{ {
File executionRoot = new File(StorageDirectory.class.getProtectionDomain().getCodeSource().getLocation().getFile()); File executionRoot = new File(StorageDirectory.class.getProtectionDomain().getCodeSource().getLocation()
.getFile());
try try
{ {
log.trace("getApplicationFileName " + executionRoot.getCanonicalPath()); log.trace("getApplicationFileName " + executionRoot.getCanonicalPath());
@ -50,7 +51,8 @@ public class FileUtil {
// check if it is packed into a mac app (e.g.: "/Users/mk/Desktop/bitsquare.app/Contents/Java/bitsquare.jar") // check if it is packed into a mac app (e.g.: "/Users/mk/Desktop/bitsquare.app/Contents/Java/bitsquare.jar")
try try
{ {
if (executionRoot.getCanonicalPath().endsWith(".app/Contents/Java/bitsquare.jar") && System.getProperty("os.name").startsWith("Mac")) if (executionRoot.getCanonicalPath().endsWith(".app/Contents/Java/bitsquare.jar") && System.getProperty
("os.name").startsWith("Mac"))
{ {
File appFile = executionRoot.getParentFile().getParentFile().getParentFile(); File appFile = executionRoot.getParentFile().getParentFile().getParentFile();
try try
@ -66,7 +68,7 @@ public class FileUtil {
{ {
e.printStackTrace(); e.printStackTrace();
} }
// fallback use AppName // fallback use AppName
return BitSquare.getAppName(); return BitSquare.getAppName();
} }

View file

@ -52,17 +52,22 @@ public class StorageDirectory {
} }
public static File getApplicationDirectory() { public static File getApplicationDirectory() {
File executionRoot = new File(StorageDirectory.class.getProtectionDomain().getCodeSource().getLocation().getFile()); File executionRoot = new File(StorageDirectory.class.getProtectionDomain().getCodeSource().getLocation()
.getFile());
try { try {
log.trace("executionRoot " + executionRoot.getCanonicalPath()); log.trace("executionRoot " + executionRoot.getCanonicalPath());
// check if it is packed into a mac app (e.g.: "/Users/mk/Desktop/bitsquare.app/Contents/Java/bitsquare.jar") // check if it is packed into a mac app (e.g.: "/Users/mk/Desktop/bitsquare.app/Contents/Java/bitsquare
if (executionRoot.getCanonicalPath().endsWith(".app/Contents/Java/bitsquare.jar") && System.getProperty("os.name").startsWith("Mac")) // .jar")
if (executionRoot.getCanonicalPath().endsWith(".app/Contents/Java/bitsquare.jar") && System.getProperty
("os.name").startsWith("Mac"))
return executionRoot.getParentFile().getParentFile().getParentFile().getParentFile(); return executionRoot.getParentFile().getParentFile().getParentFile().getParentFile();
else if (executionRoot.getCanonicalPath().endsWith(File.separator + "target" + File.separator + "classes")) else if (executionRoot.getCanonicalPath().endsWith(File.separator + "target" + File.separator + "classes"))
return executionRoot.getParentFile(); // dev e.g.: /Users/mk/Documents/_intellij/bitsquare/target/classes -> use target as root return executionRoot.getParentFile(); // dev e.g.:
// /Users/mk/Documents/_intellij/bitsquare/target/classes -> use target as root
else if (executionRoot.getCanonicalPath().endsWith(File.separator + "bitsquare.jar")) else if (executionRoot.getCanonicalPath().endsWith(File.separator + "bitsquare.jar"))
return executionRoot.getParentFile(); // dev with jar e.g.: Users/mk/Documents/_intellij/bitsquare/out/artifacts/bitsquare2/bitsquare.jar -> use target as root return executionRoot.getParentFile(); // dev with jar e.g.:
// Users/mk/Documents/_intellij/bitsquare/out/artifacts/bitsquare2/bitsquare.jar -> use target as root
else else
return executionRoot; return executionRoot;
} catch (IOException e) { } catch (IOException e) {
@ -86,7 +91,8 @@ public class StorageDirectory {
if (!storageDirectory.exists()) { if (!storageDirectory.exists()) {
boolean created = storageDirectory.mkdir(); boolean created = storageDirectory.mkdir();
if (!created) if (!created)
throw new RuntimeException("Could not create the application data directory of '" + storageDirectory + "'"); throw new RuntimeException("Could not create the application data directory of '" + storageDirectory
+ "'");
} }
} }
} }

View file

@ -35,12 +35,14 @@ public class Utilities {
private static long lastTimeStamp = System.currentTimeMillis(); private static long lastTimeStamp = System.currentTimeMillis();
public static String objectToJson(Object object) { public static String objectToJson(Object object) {
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).setPrettyPrinting().create(); Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).setPrettyPrinting()
.create();
return gson.toJson(object); return gson.toJson(object);
} }
public static <T> T jsonToObject(String jsonString, Class<T> classOfT) { public static <T> T jsonToObject(String jsonString, Class<T> classOfT) {
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).setPrettyPrinting().create(); Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).setPrettyPrinting()
.create();
return gson.fromJson(jsonString, classOfT); return gson.fromJson(jsonString, classOfT);
} }

View file

@ -146,7 +146,8 @@ public class P2PNodeTest {
data.protectEntry(keyPairOtherPeer); data.protectEntry(keyPairOtherPeer);
// he use the pub key from the client // he use the pub key from the client
final Number160 keyHash = Utils.makeSHAHash(keyPairClient.getPublic().getEncoded()); final Number160 keyHash = Utils.makeSHAHash(keyPairClient.getPublic().getEncoded());
futurePut = otherPeer.put(locationKey).data(data).keyPair(keyPairOtherPeer).domainKey(keyHash).protectDomain().start(); futurePut = otherPeer.put(locationKey).data(data).keyPair(keyPairOtherPeer).domainKey(keyHash).protectDomain
().start();
futurePut.awaitUninterruptibly(); futurePut.awaitUninterruptibly();
assertFalse(futurePut.isSuccess()); assertFalse(futurePut.isSuccess());
@ -168,7 +169,8 @@ public class P2PNodeTest {
} }
@Test @Test
public void testChangeEntryProtectionKey() throws IOException, ClassNotFoundException, NoSuchAlgorithmException, InterruptedException, InvalidKeyException, SignatureException { public void testChangeEntryProtectionKey() throws IOException, ClassNotFoundException, NoSuchAlgorithmException,
InterruptedException, InvalidKeyException, SignatureException {
KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA"); KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");
KeyPair keyPair1 = gen.generateKeyPair(); KeyPair keyPair1 = gen.generateKeyPair();
@ -189,7 +191,8 @@ public class P2PNodeTest {
Data data2 = new Data().protectEntry(keyPair2); Data data2 = new Data().protectEntry(keyPair2);
data2.publicKey(keyPair2.getPublic()); data2.publicKey(keyPair2.getPublic());
FuturePut fp3 = p1.put(Number160.createHash("key1")).sign().putMeta().data(data2).start().awaitUninterruptibly(); FuturePut fp3 = p1.put(Number160.createHash("key1")).sign().putMeta().data(data2).start()
.awaitUninterruptibly();
Assert.assertTrue(fp3.isSuccess()); Assert.assertTrue(fp3.isSuccess());
FuturePut fp4 = p2.put(Number160.createHash("key1")).sign().data(data).start().awaitUninterruptibly(); FuturePut fp4 = p2.put(Number160.createHash("key1")).sign().data(data).start().awaitUninterruptibly();
@ -267,7 +270,8 @@ public class P2PNodeTest {
// other peer tried to overwrite that entry // other peer tried to overwrite that entry
// but will not succeed, instead he will add a new entry. // but will not succeed, instead he will add a new entry.
// TODO investigate why it is not possible to overwrite the entry with that method // TODO investigate why it is not possible to overwrite the entry with that method
// The protection entry with the key does not make any difference as also the client himself cannot overwrite any entry // The protection entry with the key does not make any difference as also the client himself cannot overwrite
// any entry
// http://tomp2p.net/doc/P2P-with-TomP2P-1.pdf // http://tomp2p.net/doc/P2P-with-TomP2P-1.pdf
// "add(location_key, value) is translated to put(location_key, hash(value), value)" // "add(location_key, value) is translated to put(location_key, hash(value), value)"

View file

@ -17,13 +17,13 @@
/* /*
* Copyright 2012 Thomas Bocek * Copyright 2012 Thomas Bocek
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not * Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of * use this file except in compliance with the License. You may obtain a copy of
* the License at * the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@ -91,7 +91,8 @@ public class UtilsDHT2 {
} }
public static PeerAddress createAddress(Number160 idSender, String inetSender, int tcpPortSender, public static PeerAddress createAddress(Number160 idSender, String inetSender, int tcpPortSender,
int udpPortSender, boolean firewallUDP, boolean firewallTCP) throws UnknownHostException { int udpPortSender, boolean firewallUDP,
boolean firewallTCP) throws UnknownHostException {
InetAddress inetSend = InetAddress.getByName(inetSender); InetAddress inetSend = InetAddress.getByName(inetSender);
PeerSocketAddress peerSocketAddress = new PeerSocketAddress(inetSend, tcpPortSender, udpPortSender); PeerSocketAddress peerSocketAddress = new PeerSocketAddress(inetSend, tcpPortSender, udpPortSender);
PeerAddress n1 = new PeerAddress(idSender, peerSocketAddress, firewallTCP, firewallUDP, false, PeerAddress n1 = new PeerAddress(idSender, peerSocketAddress, firewallTCP, firewallUDP, false,
@ -100,8 +101,10 @@ public class UtilsDHT2 {
} }
public static Message createDummyMessage(Number160 idSender, String inetSender, int tcpPortSendor, public static Message createDummyMessage(Number160 idSender, String inetSender, int tcpPortSendor,
int udpPortSender, Number160 idRecipien, String inetRecipient, int tcpPortRecipient, int udpPortSender, Number160 idRecipien, String inetRecipient,
int udpPortRecipient, byte command, Type type, boolean firewallUDP, boolean firewallTCP) int tcpPortRecipient,
int udpPortRecipient, byte command, Type type, boolean firewallUDP,
boolean firewallTCP)
throws UnknownHostException { throws UnknownHostException {
Message message = new Message(); Message message = new Message();
PeerAddress n1 = createAddress(idSender, inetSender, tcpPortSendor, udpPortSender, firewallUDP, PeerAddress n1 = createAddress(idSender, inetSender, tcpPortSendor, udpPortSender, firewallUDP,
@ -165,7 +168,8 @@ public class UtilsDHT2 {
PeerMap peerMap = new PeerMap(new PeerMapConfiguration(peerId)); PeerMap peerMap = new PeerMap(new PeerMapConfiguration(peerId));
Peer peer = new PeerBuilder(peerId) Peer peer = new PeerBuilder(peerId)
.masterPeer(master) .masterPeer(master)
.enableMaintenance(maintenance).enableMaintenance(maintenance).peerMap(peerMap).externalBindings(bindings).start().addAutomaticFuture(automaticFuture); .enableMaintenance(maintenance).enableMaintenance(maintenance).peerMap(peerMap)
.externalBindings(bindings).start().addAutomaticFuture(automaticFuture);
peers[i] = new PeerBuilderDHT(peer).start(); peers[i] = new PeerBuilderDHT(peer).start();
} else { } else {
Number160 peerId = new Number160(rnd); Number160 peerId = new Number160(rnd);