UI improvements, P2P network WIP

This commit is contained in:
Manfred Karrer 2016-02-14 12:58:30 +01:00
parent 615f5570c3
commit 850b6d209c
54 changed files with 684 additions and 532 deletions

View file

@ -1,7 +1,6 @@
package io.bitsquare.btc.pricefeed;
import com.google.common.util.concurrent.*;
import io.bitsquare.app.Log;
import io.bitsquare.btc.pricefeed.providers.PriceProvider;
import io.bitsquare.common.util.Utilities;
import org.jetbrains.annotations.NotNull;
@ -44,7 +43,7 @@ class GetPriceRequest {
}
private SettableFuture<MarketPrice> requestPrice(String currencyCode, PriceProvider provider, SettableFuture<MarketPrice> resultFuture) {
Log.traceCall(currencyCode);
// Log.traceCall(currencyCode);
ListenableFuture<MarketPrice> future = executorService.submit(() -> {
Thread.currentThread().setName("requestPrice-" + provider.toString());
return provider.getPrice(currencyCode);

View file

@ -4,7 +4,6 @@ import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.SettableFuture;
import com.google.inject.Inject;
import io.bitsquare.app.Log;
import io.bitsquare.btc.pricefeed.providers.BitcoinAveragePriceProvider;
import io.bitsquare.btc.pricefeed.providers.PoloniexPriceProvider;
import io.bitsquare.btc.pricefeed.providers.PriceProvider;
@ -140,7 +139,7 @@ public class MarketPriceFeed {
if (priceConsumer != null && currencyCode != null && type != null) {
if (cache.containsKey(currencyCode)) {
MarketPrice marketPrice = cache.get(currencyCode);
log.debug("applyPrice type=" + type);
//log.debug("applyPrice type=" + type);
priceConsumer.accept(marketPrice.getPrice(type));
} else {
String errorMessage = "We don't have a price for currencyCode " + currencyCode;
@ -151,14 +150,14 @@ public class MarketPriceFeed {
}
private void requestPrice(PriceProvider provider) {
Log.traceCall();
//Log.traceCall();
GetPriceRequest getPriceRequest = new GetPriceRequest();
SettableFuture<MarketPrice> future = getPriceRequest.requestPrice(currencyCode, provider);
Futures.addCallback(future, new FutureCallback<MarketPrice>() {
public void onSuccess(MarketPrice marketPrice) {
UserThread.execute(() -> {
cache.put(marketPrice.currencyCode, marketPrice);
log.debug("marketPrice updated " + marketPrice);
//log.debug("marketPrice updated " + marketPrice);
priceConsumer.accept(marketPrice.getPrice(type));
});
}
@ -170,7 +169,7 @@ public class MarketPriceFeed {
}
private void requestAllPrices(PriceProvider provider, @Nullable Runnable resultHandler) {
Log.traceCall();
// Log.traceCall();
GetPriceRequest getPriceRequest = new GetPriceRequest();
SettableFuture<Map<String, MarketPrice>> future = getPriceRequest.requestAllPrices(provider);
Futures.addCallback(future, new FutureCallback<Map<String, MarketPrice>>() {

View file

@ -4,7 +4,6 @@ import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.internal.LinkedTreeMap;
import io.bitsquare.app.Log;
import io.bitsquare.btc.pricefeed.MarketPrice;
import io.bitsquare.http.HttpClient;
import io.bitsquare.http.HttpException;
@ -45,7 +44,7 @@ public class BitcoinAveragePriceProvider implements PriceProvider {
@Override
public MarketPrice getPrice(String currencyCode) throws IOException, HttpException {
Log.traceCall("currencyCode=" + currencyCode);
//Log.traceCall("currencyCode=" + currencyCode);
JsonObject jsonObject = new JsonParser()
.parse(httpClient.requestWithGET(currencyCode))
.getAsJsonObject();

View file

@ -4,7 +4,6 @@ import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.internal.LinkedTreeMap;
import io.bitsquare.app.Log;
import io.bitsquare.btc.pricefeed.MarketPrice;
import io.bitsquare.http.HttpClient;
import io.bitsquare.http.HttpException;
@ -63,7 +62,7 @@ public class PoloniexPriceProvider implements PriceProvider {
@Override
public MarketPrice getPrice(String currencyCode) throws IOException, HttpException {
Log.traceCall("currencyCode=" + currencyCode);
// Log.traceCall("currencyCode=" + currencyCode);
JsonObject jsonObject = new JsonParser()
.parse(httpClient.requestWithGET(currencyCode))
.getAsJsonObject();

View file

@ -80,6 +80,10 @@ public class CountryUtil {
return new Locale(LanguageUtil.getDefaultLanguage(), countryCode).getDisplayCountry();
}
public static String getNameAndCode(String countryCode) {
return getNameByCode(countryCode) + " (" + countryCode + ")";
}
public static String getCodesString(List<String> countryCodes) {
return countryCodes.stream().collect(Collectors.joining(", "));
}

View file

@ -171,12 +171,6 @@ public class CurrencyUtil {
result.add(new CryptoCurrency("ETH", "Ethereum"));
result.add(new CryptoCurrency("LTC", "Litecoin"));
result.add(new CryptoCurrency("NMC", "Namecoin"));
// Unfortunately we cannot support CryptoNote coins yet as there is no way to proof the transaction. Payment ID helps only locate the tx but the
// arbitrator cannot see if the receiving key matches the receivers address. They might add support for exposing the tx key, but that is not
// implemented yet. To use the view key (also not available in GUI wallets) would reveal the complete wallet history for incoming payments, which is
// not acceptable from privacy point of view.
// result.add(new CryptoCurrency("XMR", "Monero"));
// result.add(new CryptoCurrency("BCN", "Bytecoin"));
result.add(new CryptoCurrency("DASH", "Dash"));
result.add(new CryptoCurrency("NBT", "NuBits"));
result.add(new CryptoCurrency("NSR", "NuShares"));
@ -192,6 +186,13 @@ public class CurrencyUtil {
result.add(new CryptoCurrency("BTS", "BitShares"));
result.add(new CryptoCurrency("XCP", "Counterparty"));
result.add(new CryptoCurrency("XRP", "Ripple"));
// Unfortunately we cannot support CryptoNote coins yet as there is no way to proof the transaction. Payment ID helps only locate the tx but the
// arbitrator cannot see if the receiving key matches the receivers address. They might add support for exposing the tx key, but that is not
// implemented yet. To use the view key (also not available in GUI wallets) would reveal the complete wallet history for incoming payments, which is
// not acceptable from privacy point of view.
// result.add(new CryptoCurrency("XMR", "Monero"));
// result.add(new CryptoCurrency("BCN", "Bytecoin"));
return result;
}
@ -213,8 +214,8 @@ public class CurrencyUtil {
try {
return Currency.getInstance(currencyCode).getDisplayName(Preferences.getDefaultLocale());
} catch (Throwable t) {
// Seems that it is a crypto currency
return getSortedCryptoCurrencies().stream().filter(e -> e.getCode().equals(currencyCode)).findFirst().get().getCodeAndName();
// Seems that it is a cryptocurrency
return getSortedCryptoCurrencies().stream().filter(e -> e.getCode().equals(currencyCode)).findFirst().get().getName();
}
}

View file

@ -58,6 +58,10 @@ public class TradeCurrency implements Serializable {
return symbol;
}
public String getNameAndCode() {
return name + " (" + code + ")";
}
public String getCodeAndName() {
return code + " (" + name + ")";
}

View file

@ -44,6 +44,11 @@ public class AliPayAccountContractData extends PaymentAccountContractData implem
return "AliPay - Account nr.: " + accountNr;
}
@Override
public String getPaymentDetailsForTradePopup() {
return getPaymentDetails();
}
@Override
public String toString() {
return "AliPayAccountContractData{" +

View file

@ -43,9 +43,14 @@ public class BlockChainAccountContractData extends PaymentAccountContractData im
@Override
public String getPaymentDetails() {
return "Address: " + address;
return "Receivers cryptocurrency address: " + address;
}
@Override
public String getPaymentDetailsForTradePopup() {
return getPaymentDetails();
}
public void setPaymentId(String paymentId) {
this.paymentId = paymentId;
}

View file

@ -44,5 +44,8 @@ public class OKPayAccountContractData extends PaymentAccountContractData impleme
return "OKPay - Account nr.: " + accountNr;
}
@Override
public String getPaymentDetailsForTradePopup() {
return getPaymentDetails();
}
}

View file

@ -72,6 +72,8 @@ public abstract class PaymentAccountContractData implements Serializable {
abstract public String getPaymentDetails();
abstract public String getPaymentDetailsForTradePopup();
public int getMaxTradePeriod() {
return maxTradePeriod;
}

View file

@ -44,4 +44,9 @@ public class PerfectMoneyAccountContractData extends PaymentAccountContractData
return "PerfectMoney - Account nr.: " + accountNr;
}
@Override
public String getPaymentDetailsForTradePopup() {
return getPaymentDetails();
}
}

View file

@ -89,4 +89,12 @@ public class SepaAccountContractData extends PaymentAccountContractData implemen
public String getPaymentDetails() {
return "SEPA - Holder name: " + holderName + ", IBAN: " + iban + ", BIC: " + bic + ", country code: " + getCountryCode();
}
@Override
public String getPaymentDetailsForTradePopup() {
return "Holder name: " + holderName + "\n" +
"IBAN: " + iban + "\n" +
"BIC: " + bic + "\n" +
"Country of bank: " + CountryUtil.getNameAndCode(getCountryCode());
}
}

View file

@ -53,4 +53,9 @@ public class SwishAccountContractData extends PaymentAccountContractData impleme
return "Swish - Holder name: " + holderName + ", mobile nr.: " + mobileNr;
}
@Override
public String getPaymentDetailsForTradePopup() {
return "Holder name: " + holderName + "\n" +
"Mobile nr.: " + mobileNr;
}
}

View file

@ -146,7 +146,7 @@ abstract public class Trade implements Tradable, Model, Serializable {
// Mutable
private DecryptedMsgWithPubKey decryptedMsgWithPubKey;
private Date takeOfferDate = new Date(0); // in some error cases the date is not set and cause null pointers, so we set a default
private Date takeOfferDate;
private int takeOfferDateAsBlockHeight;
private Coin tradeAmount;
private NodeAddress tradingPeerNodeAddress;
@ -180,6 +180,7 @@ abstract public class Trade implements Tradable, Model, Serializable {
protected Trade(Offer offer, Storage<? extends TradableList> storage) {
this.offer = offer;
this.storage = storage;
this.takeOfferDate = new Date();
processModel = new ProcessModel();
tradeVolumeProperty = new SimpleObjectProperty<>();
@ -199,6 +200,7 @@ abstract public class Trade implements Tradable, Model, Serializable {
this.tradingPeerNodeAddress = tradingPeerNodeAddress;
tradeAmountProperty.set(tradeAmount);
tradeVolumeProperty.set(getTradeVolume());
this.takeOfferDate = new Date();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
@ -411,9 +413,9 @@ abstract public class Trade implements Tradable, Model, Serializable {
return takeOfferDate;
}
public void setTakeOfferDate(Date takeOfferDate) {
/*public void setTakeOfferDate(Date takeOfferDate) {
this.takeOfferDate = takeOfferDate;
}
}*/
public int getTakeOfferDateAsBlockHeight() {
return takeOfferDateAsBlockHeight;

View file

@ -59,7 +59,6 @@ import org.spongycastle.crypto.params.KeyParameter;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.File;
import java.util.Date;
import java.util.Optional;
import static io.bitsquare.util.Validator.nonEmptyStringOf;
@ -98,7 +97,6 @@ public class TradeManager {
ArbitratorManager arbitratorManager,
P2PService p2PService,
@Named("storage.dir") File storageDir) {
Log.traceCall();
this.user = user;
this.keyRing = keyRing;
this.walletService = walletService;
@ -280,7 +278,7 @@ public class TradeManager {
else
trade = new BuyerAsTakerTrade(offer, amount, model.getPeerNodeAddress(), tradableListStorage);
trade.setTakeOfferDate(new Date());
//trade.setTakeOfferDate(new Date());
trade.setTakeOfferDateAsBlockHeight(tradeWalletService.getBestChainHeight());
trade.setTakerPaymentAccountId(paymentAccountId);
@ -312,8 +310,8 @@ public class TradeManager {
public void onSuccess(@javax.annotation.Nullable Transaction transaction) {
if (transaction != null) {
log.info("onWithdraw onSuccess tx ID:" + transaction.getHashAsString());
trade.setState(Trade.State.WITHDRAW_COMPLETED);
addTradeToClosedTrades(trade);
trade.setState(Trade.State.WITHDRAW_COMPLETED);
resultHandler.handleResult();
}
}

View file

@ -25,6 +25,7 @@ import io.bitsquare.trade.TradableList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.Serializable;
import java.util.Date;
@ -55,6 +56,18 @@ public class OpenOffer implements Tradable, Serializable {
this.storage = storage;
}
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
try {
in.defaultReadObject();
// If we have a reserved state from the local db we reset it
if (state == State.RESERVED)
setState(State.AVAILABLE);
} catch (Throwable t) {
log.error("Cannot be deserialized." + t.getMessage());
}
}
public Date getDate() {
return offer.getDate();
}
@ -98,7 +111,7 @@ public class OpenOffer implements Tradable, Serializable {
stopTimeout();
timeoutTimer = UserThread.runAfter(() -> {
log.info("Timeout reached");
log.info("Timeout for resettin State.RESERVED reached");
if (state == State.RESERVED)
setState(State.AVAILABLE);
}, TIMEOUT_SEC);

View file

@ -47,13 +47,13 @@ public class ProcessFinalizePayoutTxRequest extends TradeTask {
processModel.tradingPeer.setPayoutAddressString(nonEmptyStringOf(message.sellerPayoutAddress));
trade.setLockTimeAsBlockHeight(nonNegativeLongOf(message.lockTimeAsBlockHeight));
trade.setState(Trade.State.FIAT_PAYMENT_RECEIPT_MSG_RECEIVED);
// update to the latest peer address of our peer if the message is correct
trade.setTradingPeerNodeAddress(processModel.getTempTradingPeerNodeAddress());
removeMailboxMessageAfterProcessing();
trade.setState(Trade.State.FIAT_PAYMENT_RECEIPT_MSG_RECEIVED);
complete();
} catch (Throwable t) {
failed(t);

View file

@ -27,8 +27,6 @@ import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
public class SignAndPublishDepositTxAsBuyer extends TradeTask {
private static final Logger log = LoggerFactory.getLogger(SignAndPublishDepositTxAsBuyer.class);
@ -64,7 +62,7 @@ public class SignAndPublishDepositTxAsBuyer extends TradeTask {
log.trace("takerSignAndPublishTx succeeded " + transaction);
trade.setDepositTx(transaction);
trade.setTakeOfferDate(new Date());
//trade.setTakeOfferDate(new Date());
trade.setTakeOfferDateAsBlockHeight(processModel.getTradeWalletService().getBestChainHeight());
trade.setState(Trade.State.DEPOSIT_PUBLISHED);

View file

@ -26,8 +26,6 @@ import org.bitcoinj.core.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static io.bitsquare.util.Validator.checkTradeId;
@ -53,11 +51,10 @@ public class ProcessDepositTxPublishedMessage extends TradeTask {
Transaction transactionFromSerializedTx = processModel.getWalletService().getTransactionFromSerializedTx(message.depositTx);
// update with full tx
trade.setDepositTx(processModel.getTradeWalletService().addTransactionToWallet(transactionFromSerializedTx));
trade.setState(Trade.State.DEPOSIT_PUBLISHED_MSG_RECEIVED);
trade.setTakeOfferDate(new Date());
trade.setTakeOfferDateAsBlockHeight(processModel.getTradeWalletService().getBestChainHeight());
//trade.setTakeOfferDate(new Date());
trade.setTakeOfferDateAsBlockHeight(processModel.getTradeWalletService().getBestChainHeight());
if (trade instanceof OffererTrade)
processModel.getOpenOfferManager().closeOpenOffer(trade.getOffer());
@ -65,6 +62,8 @@ public class ProcessDepositTxPublishedMessage extends TradeTask {
trade.setTradingPeerNodeAddress(processModel.getTempTradingPeerNodeAddress());
removeMailboxMessageAfterProcessing();
trade.setState(Trade.State.DEPOSIT_PUBLISHED_MSG_RECEIVED);
complete();
} catch (Throwable t) {

View file

@ -36,7 +36,6 @@ public class SendPublishDepositTxRequest extends TradeTask {
protected void run() {
try {
runInterceptHook();
trade.setState(Trade.State.DEPOSIT_PUBLISH_REQUESTED);
PublishDepositTxRequest tradeMessage = new PublishDepositTxRequest(
processModel.getId(),
processModel.getPaymentAccountContractData(trade),
@ -69,6 +68,9 @@ public class SendPublishDepositTxRequest extends TradeTask {
}
}
);
//TODO should it be in success handler?
trade.setState(Trade.State.DEPOSIT_PUBLISH_REQUESTED);
} catch (Throwable t) {
failed(t);
}

View file

@ -46,13 +46,13 @@ public class ProcessFiatTransferStartedMessage extends TradeTask {
processModel.tradingPeer.setPayoutAddressString(nonEmptyStringOf(message.buyerPayoutAddress));
trade.setState(Trade.State.FIAT_PAYMENT_STARTED_MSG_RECEIVED);
// update to the latest peer address of our peer if the message is correct
trade.setTradingPeerNodeAddress(processModel.getTempTradingPeerNodeAddress());
removeMailboxMessageAfterProcessing();
trade.setState(Trade.State.FIAT_PAYMENT_STARTED_MSG_RECEIVED);
complete();
} catch (Throwable t) {
failed(t);

View file

@ -46,13 +46,13 @@ public class ProcessPayoutTxFinalizedMessage extends TradeTask {
checkArgument(message.payoutTx != null);
trade.setPayoutTx(processModel.getWalletService().getTransactionFromSerializedTx(message.payoutTx));
trade.setState(Trade.State.PAYOUT_TX_RECEIVED);
// update to the latest peer address of our peer if the message is correct
trade.setTradingPeerNodeAddress(processModel.getTempTradingPeerNodeAddress());
removeMailboxMessageAfterProcessing();
trade.setState(Trade.State.PAYOUT_TX_RECEIVED);
complete();
} catch (Throwable t) {
failed(t);

View file

@ -27,8 +27,6 @@ import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
public class SignAndPublishDepositTxAsSeller extends TradeTask {
private static final Logger log = LoggerFactory.getLogger(SignAndPublishDepositTxAsSeller.class);
@ -62,7 +60,7 @@ public class SignAndPublishDepositTxAsSeller extends TradeTask {
log.trace("takerSignAndPublishTx succeeded " + transaction);
trade.setDepositTx(transaction);
trade.setTakeOfferDate(new Date());
//trade.setTakeOfferDate(new Date());
trade.setTakeOfferDateAsBlockHeight(processModel.getTradeWalletService().getBestChainHeight());
trade.setState(Trade.State.DEPOSIT_PUBLISHED);