mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-05-13 03:52:16 -04:00
Wrap lines at 120 chars
This commit is contained in:
parent
23b2cabf19
commit
1ad1d318e8
85 changed files with 742 additions and 369 deletions
2
.idea/codeStyleSettings.xml
generated
2
.idea/codeStyleSettings.xml
generated
|
@ -4,10 +4,12 @@
|
||||||
<option name="PER_PROJECT_SETTINGS">
|
<option name="PER_PROJECT_SETTINGS">
|
||||||
<value>
|
<value>
|
||||||
<option name="LINE_SEPARATOR" value=" " />
|
<option name="LINE_SEPARATOR" value=" " />
|
||||||
|
<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>
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
});
|
});
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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");
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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.");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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<>();
|
||||||
|
|
|
@ -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()));
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
+ "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)"
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue