Add popups

This commit is contained in:
Manfred Karrer 2015-11-16 15:20:50 +01:00
parent 8bf207b656
commit cb8761b74e
32 changed files with 178 additions and 117 deletions

View File

@ -21,7 +21,9 @@ public class PopupId {
// We don't use an enum because it would break updates if we add a new item in a new version // We don't use an enum because it would break updates if we add a new item in a new version
public static String SEC_DEPOSIT = "SEC_DEPOSIT"; public static String TRADE_WALLET = "tradeWallet";
public static String TRADE_WALLET = "TRADE_WALLET"; public static String SEND_PAYMENT_INFO = "sendPaymentInfo";
public static String PAYMENT_SENT = "paymentSent";
public static String PAYMENT_RECEIVED = "paymentReceived";
} }

View File

@ -143,8 +143,10 @@ public class Preferences implements Serializable {
showTakeOfferConfirmation = true; showTakeOfferConfirmation = true;
showAgainMap = new HashMap<>(); showAgainMap = new HashMap<>();
showAgainMap.put(PopupId.SEC_DEPOSIT, true);
showAgainMap.put(PopupId.TRADE_WALLET, true); showAgainMap.put(PopupId.TRADE_WALLET, true);
showAgainMap.put(PopupId.SEND_PAYMENT_INFO, true);
showAgainMap.put(PopupId.PAYMENT_SENT, true);
showAgainMap.put(PopupId.PAYMENT_RECEIVED, true);
storage.queueUpForSave(); storage.queueUpForSave();
} }
@ -345,6 +347,10 @@ public class Preferences implements Serializable {
return showAgainMap; return showAgainMap;
} }
public boolean showAgain(String key) {
return getShowAgainMap().containsKey(key) && getShowAgainMap().get(key);
}
public boolean getTacAccepted() { public boolean getTacAccepted() {
return tacAccepted; return tacAccepted;
} }

View File

@ -269,7 +269,11 @@ public class User implements Serializable {
}*/ }*/
public Arbitrator getAcceptedArbitratorByAddress(Address address) { public Arbitrator getAcceptedArbitratorByAddress(Address address) {
return acceptedArbitrators.stream().filter(e -> e.getArbitratorAddress().equals(address)).findFirst().get(); Optional<Arbitrator> arbitratorOptional = acceptedArbitrators.stream().filter(e -> e.getArbitratorAddress().equals(address)).findFirst();
if (arbitratorOptional.isPresent())
return arbitratorOptional.get();
else
return null;
} }

View File

@ -73,7 +73,7 @@ import static io.bitsquare.app.BitsquareEnvironment.APP_NAME_KEY;
public class BitsquareApp extends Application { public class BitsquareApp extends Application {
private static final Logger log = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(BitsquareApp.class); private static final Logger log = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(BitsquareApp.class);
public static final boolean DEV_MODE = true; public static final boolean DEV_MODE = false;
private static Environment env; private static Environment env;

View File

@ -31,6 +31,7 @@ import javafx.geometry.Insets;
import javafx.geometry.VPos; import javafx.geometry.VPos;
import javafx.scene.control.CheckBox; import javafx.scene.control.CheckBox;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.FlowPane; import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -94,6 +95,7 @@ public class OKPayForm extends PaymentMethodForm {
checkBox.setSelected(okPayAccount.getTradeCurrencies().contains(e)); checkBox.setSelected(okPayAccount.getTradeCurrencies().contains(e));
checkBox.setMinWidth(60); checkBox.setMinWidth(60);
checkBox.setMaxWidth(checkBox.getMinWidth()); checkBox.setMaxWidth(checkBox.getMinWidth());
checkBox.setTooltip(new Tooltip(e.getName()));
checkBox.setOnAction(event -> { checkBox.setOnAction(event -> {
if (checkBox.isSelected()) if (checkBox.isSelected())
okPayAccount.addCurrency(e); okPayAccount.addCurrency(e);

View File

@ -34,6 +34,7 @@ import javafx.geometry.VPos;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.layout.FlowPane; import javafx.scene.layout.FlowPane;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import javafx.scene.text.TextAlignment;
import javafx.util.StringConverter; import javafx.util.StringConverter;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -98,9 +99,9 @@ public class SepaForm extends PaymentMethodForm {
}); });
Tuple2<Label, ComboBox> tuple2 = addLabelComboBox(gridPane, ++gridRow, "Country of Bank:"); Tuple2<Label, ComboBox> tuple2 = addLabelComboBox(gridPane, ++gridRow, "Country of your Bank:");
ComboBox<Country> countryComboBox = tuple2.second; ComboBox<Country> countryComboBox = tuple2.second;
countryComboBox.setPromptText("Select country of Bank"); countryComboBox.setPromptText("Select country of your Bank");
countryComboBox.setConverter(new StringConverter<Country>() { countryComboBox.setConverter(new StringConverter<Country>() {
@Override @Override
public String toString(Country country) { public String toString(Country country) {
@ -141,15 +142,18 @@ public class SepaForm extends PaymentMethodForm {
} }
private void addEuroCountriesGrid(boolean isEditable) { private void addEuroCountriesGrid(boolean isEditable) {
addCountriesGrid(isEditable, "Accept taker countries (Euro):", euroCountryCheckBoxes, CountryUtil.getAllSepaEuroCountries()); addCountriesGrid(isEditable, "Accept trades from those Euro countries:", euroCountryCheckBoxes, CountryUtil.getAllSepaEuroCountries());
} }
private void addNonEuroCountriesGrid(boolean isEditable) { private void addNonEuroCountriesGrid(boolean isEditable) {
addCountriesGrid(isEditable, "Accepted taker countries (non-Euro):", nonEuroCountryCheckBoxes, CountryUtil.getAllSepaNonEuroCountries()); addCountriesGrid(isEditable, "Accept trades from those non-Euro countries:", nonEuroCountryCheckBoxes, CountryUtil.getAllSepaNonEuroCountries());
} }
private void addCountriesGrid(boolean isEditable, String title, List<CheckBox> checkBoxList, List<Country> dataProvider) { private void addCountriesGrid(boolean isEditable, String title, List<CheckBox> checkBoxList, List<Country> dataProvider) {
Label label = addLabel(gridPane, ++gridRow, title, 0); Label label = addLabel(gridPane, ++gridRow, title, 0);
label.setWrapText(true);
label.setPrefWidth(200);
label.setTextAlignment(TextAlignment.RIGHT);
GridPane.setValignment(label, VPos.TOP); GridPane.setValignment(label, VPos.TOP);
FlowPane flowPane = new FlowPane(); FlowPane flowPane = new FlowPane();
flowPane.setPadding(new Insets(10, 10, 10, 10)); flowPane.setPadding(new Insets(10, 10, 10, 10));
@ -169,7 +173,6 @@ public class SepaForm extends PaymentMethodForm {
checkBoxList.add(checkBox); checkBoxList.add(checkBox);
checkBox.setMouseTransparent(!isEditable); checkBox.setMouseTransparent(!isEditable);
checkBox.setMinWidth(45); checkBox.setMinWidth(45);
checkBox.setMaxWidth(checkBox.getMinWidth());
checkBox.setTooltip(new Tooltip(country.name)); checkBox.setTooltip(new Tooltip(country.name));
checkBox.setOnAction(event -> { checkBox.setOnAction(event -> {
if (checkBox.isSelected()) if (checkBox.isSelected())

View File

@ -338,7 +338,7 @@ class MainViewModel implements ViewModel {
// tac // tac
if (!preferences.getTacAccepted() && !BitsquareApp.DEV_MODE) if (!preferences.getTacAccepted() && !BitsquareApp.DEV_MODE)
new TacPopup().url(WebViewPopup.getLocalUrl("tac.html")).onAgree(() -> preferences.setTacAccepted(true)).show(); new TacPopup().url(WebViewPopup.getLocalUrl("tac")).onAgree(() -> preferences.setTacAccepted(true)).show();
// update nr of peers in footer // update nr of peers in footer

View File

@ -196,8 +196,8 @@ public class ArbitratorRegistrationView extends ActivatableViewAndModel<VBox, Ar
addTitledGroupBg(gridPane, ++gridRow, 2, "Information", Layout.GROUP_DISTANCE); addTitledGroupBg(gridPane, ++gridRow, 2, "Information", Layout.GROUP_DISTANCE);
Label infoLabel = addMultilineLabel(gridPane, gridRow); Label infoLabel = addMultilineLabel(gridPane, gridRow);
GridPane.setMargin(infoLabel, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, 0, 0, 0)); GridPane.setMargin(infoLabel, new Insets(Layout.FIRST_ROW_AND_GROUP_DISTANCE, 0, 0, 0));
infoLabel.setText("Please not that you need to stay available for 15 days after revoking as there might be trades which are using you as " + infoLabel.setText("Please note that you need to stay available for 15 days after revoking as there might be trades which are using you as " +
"arbitrator. The max. allowed trader period is 8 days and the dispute process might take up to 7 days."); "arbitrator. The max. allowed trade period is 8 days and the dispute process might take up to 7 days.");
} }
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////

View File

@ -28,7 +28,6 @@ import io.bitsquare.gui.util.Layout;
import io.bitsquare.locale.LanguageUtil; import io.bitsquare.locale.LanguageUtil;
import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;
import javafx.geometry.HPos;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.VPos; import javafx.geometry.VPos;
import javafx.scene.control.*; import javafx.scene.control.*;
@ -192,12 +191,6 @@ public class ArbitratorSelectionView extends ActivatableViewAndModel<GridPane, A
GridPane.setMargin(autoSelectAllMatchingCheckBox, new Insets(0, -10, 0, -10)); GridPane.setMargin(autoSelectAllMatchingCheckBox, new Insets(0, -10, 0, -10));
autoSelectAllMatchingCheckBox.setOnAction(event -> model.setAutoSelectArbitrators(autoSelectAllMatchingCheckBox.isSelected())); autoSelectAllMatchingCheckBox.setOnAction(event -> model.setAutoSelectArbitrators(autoSelectAllMatchingCheckBox.isSelected()));
Button reloadButton = addButton(root, gridRow, "Reload");
GridPane.setColumnIndex(reloadButton, 1);
GridPane.setHalignment(reloadButton, HPos.RIGHT);
GridPane.setMargin(reloadButton, new Insets(0, -10, 0, -10));
reloadButton.setOnAction(event -> model.reload());
TableColumn<ArbitratorListItem, String> dateColumn = new TableColumn("Registration date"); TableColumn<ArbitratorListItem, String> dateColumn = new TableColumn("Registration date");
dateColumn.setCellValueFactory(param -> new ReadOnlyObjectWrapper(param.getValue().getRegistrationDate())); dateColumn.setCellValueFactory(param -> new ReadOnlyObjectWrapper(param.getValue().getRegistrationDate()));
dateColumn.setMinWidth(130); dateColumn.setMinWidth(130);

View File

@ -130,10 +130,6 @@ class ArbitratorSelectionViewModel extends ActivatableDataModel {
return user.isMyOwnRegisteredArbitrator(arbitrator); return user.isMyOwnRegisteredArbitrator(arbitrator);
} }
public void reload() {
arbitratorManager.applyArbitrators();
}
private void updateAutoSelectArbitrators() { private void updateAutoSelectArbitrators() {
if (preferences.getAutoSelectArbitrators()) { if (preferences.getAutoSelectArbitrators()) {
arbitratorListItems.stream().forEach(item -> { arbitratorListItems.stream().forEach(item -> {

View File

@ -25,7 +25,7 @@ import io.bitsquare.gui.main.MainView;
import io.bitsquare.gui.main.funds.reserved.ReservedView; import io.bitsquare.gui.main.funds.reserved.ReservedView;
import io.bitsquare.gui.main.funds.transactions.TransactionsView; import io.bitsquare.gui.main.funds.transactions.TransactionsView;
import io.bitsquare.gui.main.funds.withdrawal.WithdrawalView; import io.bitsquare.gui.main.funds.withdrawal.WithdrawalView;
import io.bitsquare.gui.popups.FirstTimePopup; import io.bitsquare.gui.popups.FirstTimeWebViewPopup;
import io.bitsquare.gui.popups.WebViewPopup; import io.bitsquare.gui.popups.WebViewPopup;
import io.bitsquare.user.PopupId; import io.bitsquare.user.PopupId;
import io.bitsquare.user.Preferences; import io.bitsquare.user.Preferences;
@ -85,8 +85,9 @@ public class FundsView extends ActivatableViewAndModel<TabPane, Activatable> {
else if (root.getSelectionModel().getSelectedItem() == transactionsTab) else if (root.getSelectionModel().getSelectedItem() == transactionsTab)
navigation.navigateTo(MainView.class, FundsView.class, TransactionsView.class); navigation.navigateTo(MainView.class, FundsView.class, TransactionsView.class);
if (preferences.getShowAgainMap().get(PopupId.TRADE_WALLET) && !BitsquareApp.DEV_MODE) String key = PopupId.TRADE_WALLET;
new FirstTimePopup(preferences).url(WebViewPopup.getLocalUrl("tradeWallet.html")).show(); if (preferences.showAgain(key) && !BitsquareApp.DEV_MODE)
new FirstTimeWebViewPopup(preferences).id(key).url(WebViewPopup.getLocalUrl(key)).show();
} }
@Override @Override

View File

@ -21,19 +21,14 @@ import io.bitsquare.btc.WalletService;
import io.bitsquare.btc.listeners.AddressConfidenceListener; import io.bitsquare.btc.listeners.AddressConfidenceListener;
import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator; import io.bitsquare.gui.components.confidence.ConfidenceProgressIndicator;
import io.bitsquare.gui.util.BSFormatter; import io.bitsquare.gui.util.BSFormatter;
import org.bitcoinj.core.Address;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionConfidence;
import org.bitcoinj.core.TransactionOutput;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import javafx.scene.control.*; import javafx.scene.control.Tooltip;
import org.bitcoinj.core.*;
public class TransactionsListItem { public class TransactionsListItem {
private final StringProperty date = new SimpleStringProperty(); private final StringProperty date = new SimpleStringProperty();
private final StringProperty amount = new SimpleStringProperty(); private final StringProperty amount = new SimpleStringProperty();
private final StringProperty type = new SimpleStringProperty(); private final StringProperty type = new SimpleStringProperty();
@ -44,6 +39,7 @@ public class TransactionsListItem {
private final Tooltip tooltip; private final Tooltip tooltip;
private String addressString; private String addressString;
private boolean notAnAddress;
private AddressConfidenceListener confidenceListener; private AddressConfidenceListener confidenceListener;
public TransactionsListItem(Transaction transaction, WalletService walletService, BSFormatter formatter) { public TransactionsListItem(Transaction transaction, WalletService walletService, BSFormatter formatter) {
@ -64,14 +60,13 @@ public class TransactionsListItem {
address = address =
transactionOutput.getScriptPubKey().getToAddress(walletService.getWallet().getParams()); transactionOutput.getScriptPubKey().getToAddress(walletService.getWallet().getParams());
addressString = address.toString(); addressString = address.toString();
} } else {
else {
addressString = "No sent to address script used."; addressString = "No sent to address script used.";
notAnAddress = true;
} }
} }
} }
} } else if (valueSentFromMe.isZero()) {
else if (valueSentFromMe.isZero()) {
amount.set(formatter.formatCoin(valueSentToMe)); amount.set(formatter.formatCoin(valueSentToMe));
type.set("Received with"); type.set("Received with");
@ -82,14 +77,13 @@ public class TransactionsListItem {
address = address =
transactionOutput.getScriptPubKey().getToAddress(walletService.getWallet().getParams()); transactionOutput.getScriptPubKey().getToAddress(walletService.getWallet().getParams());
addressString = address.toString(); addressString = address.toString();
} } else {
else {
addressString = "No sent to address script used."; addressString = "No sent to address script used.";
notAnAddress = true;
} }
} }
} }
} } else {
else {
amount.set(formatter.formatCoin(valueSentToMe.subtract(valueSentFromMe))); amount.set(formatter.formatCoin(valueSentToMe.subtract(valueSentFromMe)));
boolean outgoing = false; boolean outgoing = false;
for (TransactionOutput transactionOutput : transaction.getOutputs()) { for (TransactionOutput transactionOutput : transaction.getOutputs()) {
@ -100,19 +94,19 @@ public class TransactionsListItem {
address = transactionOutput.getScriptPubKey().getToAddress(walletService.getWallet().getParams address = transactionOutput.getScriptPubKey().getToAddress(walletService.getWallet().getParams
()); ());
addressString = address.toString(); addressString = address.toString();
} } else {
else {
addressString = "No sent to address script used."; addressString = "No sent to address script used.";
notAnAddress = true;
} }
} }
} }
if (outgoing) { if (outgoing) {
type.set("Sent to"); type.set("Sent to");
} } else {
else {
type.set("Internal (TX Fee)"); type.set("Internal (TX Fee)");
addressString = "Internal swap between addresses."; addressString = "Internal swap between addresses.";
notAnAddress = true;
} }
} }
@ -194,5 +188,9 @@ public class TransactionsListItem {
public String getAddressString() { public String getAddressString() {
return addressString; return addressString;
} }
public boolean isNotAnAddress() {
return notAnAddress;
}
} }

View File

@ -40,8 +40,10 @@ import java.util.stream.Collectors;
@FxmlView @FxmlView
public class TransactionsView extends ActivatableView<VBox, Void> { public class TransactionsView extends ActivatableView<VBox, Void> {
@FXML TableView<TransactionsListItem> table; @FXML
@FXML TableColumn<TransactionsListItem, TransactionsListItem> dateColumn, addressColumn, amountColumn, typeColumn, TableView<TransactionsListItem> table;
@FXML
TableColumn<TransactionsListItem, TransactionsListItem> dateColumn, addressColumn, amountColumn, typeColumn,
confidenceColumn; confidenceColumn;
private ObservableList<TransactionsListItem> transactionsListItems; private ObservableList<TransactionsListItem> transactionsListItems;
@ -85,12 +87,14 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
// TODO Open popup with details view // TODO Open popup with details view
log.debug("openTxDetails " + item); log.debug("openTxDetails " + item);
try { if (!item.isNotAnAddress()) {
Utilities.openWebPage(preferences.getBlockChainExplorer().addressUrl + item.getAddressString()); try {
} catch (Exception e) { Utilities.openWebPage(preferences.getBlockChainExplorer().addressUrl + item.getAddressString());
log.error(e.getMessage()); } catch (Exception e) {
new Popup().warning("Opening browser failed. Please check your internet " + log.error(e.getMessage());
"connection.").show(); new Popup().warning("Opening browser failed. Please check your internet " +
"connection.").show();
}
} }
} }
@ -114,8 +118,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
hyperlink = new Hyperlink(item.getAddressString()); hyperlink = new Hyperlink(item.getAddressString());
hyperlink.setOnAction(event -> openTxDetails(item)); hyperlink.setOnAction(event -> openTxDetails(item));
setGraphic(hyperlink); setGraphic(hyperlink);
} } else {
else {
setGraphic(null); setGraphic(null);
setId(null); setId(null);
} }
@ -143,8 +146,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
if (item != null && !empty) { if (item != null && !empty) {
setGraphic(item.getProgressIndicator()); setGraphic(item.getProgressIndicator());
} } else {
else {
setGraphic(null); setGraphic(null);
} }
} }

View File

@ -203,7 +203,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
formatter.formatCoinWithCode(FeePolicy.TX_FEE) + "\n" + formatter.formatCoinWithCode(FeePolicy.TX_FEE) + "\n" +
"Receivers amount: " + "Receivers amount: " +
formatter.formatCoinWithCode(amount.subtract(FeePolicy.TX_FEE)) + " BTC\n\n" + formatter.formatCoinWithCode(amount.subtract(FeePolicy.TX_FEE)) + " BTC\n\n" +
"Are you sure you withdraw that amount?") "Are you sure you want to withdraw that amount?")
.onAction(() -> { .onAction(() -> {
doWithdraw(amount, callback); doWithdraw(amount, callback);
}) })

View File

@ -56,8 +56,8 @@ public class BuyerSubView extends TradeSubView {
@Override @Override
protected void addWizards() { protected void addWizards() {
waitTxInBlockchain = new TradeWizardItem(WaitTxInBlockchainView.class, "Wait for blockchain confirmation"); waitTxInBlockchain = new TradeWizardItem(WaitTxInBlockchainView.class, "Wait for blockchain confirmation");
startPayment = new TradeWizardItem(StartPaymentView.class, "Start EUR payment"); startPayment = new TradeWizardItem(StartPaymentView.class, "Start payment");
waitPaymentReceived = new TradeWizardItem(WaitPaymentReceivedView.class, "Wait until EUR payment arrived"); waitPaymentReceived = new TradeWizardItem(WaitPaymentReceivedView.class, "Wait until payment arrived");
waitPayoutUnlock = new TradeWizardItem(WaitPayoutLockTimeView.class, "Wait for payout unlock"); waitPayoutUnlock = new TradeWizardItem(WaitPayoutLockTimeView.class, "Wait for payout unlock");
completed = new TradeWizardItem(CompletedView.class, "Completed"); completed = new TradeWizardItem(CompletedView.class, "Completed");

View File

@ -36,6 +36,7 @@ import io.bitsquare.gui.popups.WalletPasswordPopup;
import io.bitsquare.payment.PaymentAccountContractData; import io.bitsquare.payment.PaymentAccountContractData;
import io.bitsquare.trade.*; import io.bitsquare.trade.*;
import io.bitsquare.trade.offer.Offer; import io.bitsquare.trade.offer.Offer;
import io.bitsquare.user.Preferences;
import io.bitsquare.user.User; import io.bitsquare.user.User;
import javafx.beans.property.*; import javafx.beans.property.*;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
@ -69,6 +70,7 @@ public class PendingTradesDataModel extends ActivatableDataModel {
private final ObjectProperty<Trade> tradeProperty = new SimpleObjectProperty<>(); private final ObjectProperty<Trade> tradeProperty = new SimpleObjectProperty<>();
private final StringProperty txId = new SimpleStringProperty(); private final StringProperty txId = new SimpleStringProperty();
private Trade trade; private Trade trade;
private Preferences preferences;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -77,7 +79,7 @@ public class PendingTradesDataModel extends ActivatableDataModel {
@Inject @Inject
public PendingTradesDataModel(TradeManager tradeManager, WalletService walletService, TradeWalletService tradeWalletService, public PendingTradesDataModel(TradeManager tradeManager, WalletService walletService, TradeWalletService tradeWalletService,
User user, KeyRing keyRing, DisputeManager disputeManager, User user, KeyRing keyRing, DisputeManager disputeManager, Preferences preferences,
Navigation navigation, WalletPasswordPopup walletPasswordPopup) { Navigation navigation, WalletPasswordPopup walletPasswordPopup) {
this.tradeManager = tradeManager; this.tradeManager = tradeManager;
this.walletService = walletService; this.walletService = walletService;
@ -85,6 +87,7 @@ public class PendingTradesDataModel extends ActivatableDataModel {
this.user = user; this.user = user;
this.keyRing = keyRing; this.keyRing = keyRing;
this.disputeManager = disputeManager; this.disputeManager = disputeManager;
this.preferences = preferences;
this.navigation = navigation; this.navigation = navigation;
this.walletPasswordPopup = walletPasswordPopup; this.walletPasswordPopup = walletPasswordPopup;
@ -323,6 +326,10 @@ public class PendingTradesDataModel extends ActivatableDataModel {
return disputeManager; return disputeManager;
} }
public Preferences getPreferences() {
return preferences;
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Utils // Utils

View File

@ -56,8 +56,8 @@ public class SellerSubView extends TradeSubView {
@Override @Override
protected void addWizards() { protected void addWizards() {
waitTxInBlockchain = new TradeWizardItem(WaitTxInBlockchainView.class, "Wait for blockchain confirmation"); waitTxInBlockchain = new TradeWizardItem(WaitTxInBlockchainView.class, "Wait for blockchain confirmation");
waitPaymentStarted = new TradeWizardItem(WaitPaymentStartedView.class, "Wait until EUR payment has started"); waitPaymentStarted = new TradeWizardItem(WaitPaymentStartedView.class, "Wait until payment has started");
confirmPaymentReceived = new TradeWizardItem(ConfirmPaymentReceivedView.class, "Confirm EUR payment received"); confirmPaymentReceived = new TradeWizardItem(ConfirmPaymentReceivedView.class, "Confirm payment received");
waitPayoutUnlock = new TradeWizardItem(WaitPayoutLockTimeView.class, "Wait for payout unlock"); waitPayoutUnlock = new TradeWizardItem(WaitPayoutLockTimeView.class, "Wait for payout unlock");
completed = new TradeWizardItem(CompletedView.class, "Completed"); completed = new TradeWizardItem(CompletedView.class, "Completed");
@ -110,11 +110,11 @@ public class SellerSubView extends TradeSubView {
showItem(confirmPaymentReceived); showItem(confirmPaymentReceived);
if (model.isBlockChainMethod()) { if (model.isBlockChainMethod()) {
((ConfirmPaymentReceivedView) tradeStepDetailsView).setInfoLabelText(BSResources.get("The Bitcoin buyer has started the {0} payment." + ((ConfirmPaymentReceivedView) tradeStepDetailsView).setInfoLabelText(BSResources.get("The Bitcoin buyer has started the {0} payment. " +
"Check your Altcoin wallet or Block explorer and confirm when you have received the payment.", "Check your Altcoin wallet or Block explorer and confirm when you have received the payment.",
model.getCurrencyCode())); model.getCurrencyCode()));
} else { } else {
((ConfirmPaymentReceivedView) tradeStepDetailsView).setInfoLabelText(BSResources.get("The Bitcoin buyer has started the {0} payment." + ((ConfirmPaymentReceivedView) tradeStepDetailsView).setInfoLabelText(BSResources.get("The Bitcoin buyer has started the {0} payment. " +
"Check your payment account and confirm when you have received the payment.", "Check your payment account and confirm when you have received the payment.",
model.getCurrencyCode())); model.getCurrencyCode()));
} }

View File

@ -17,10 +17,13 @@
package io.bitsquare.gui.main.portfolio.pendingtrades.steps; package io.bitsquare.gui.main.portfolio.pendingtrades.steps;
import io.bitsquare.app.BitsquareApp;
import io.bitsquare.gui.components.TxIdTextField; import io.bitsquare.gui.components.TxIdTextField;
import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel; import io.bitsquare.gui.main.portfolio.pendingtrades.PendingTradesViewModel;
import io.bitsquare.gui.popups.Popup; import io.bitsquare.gui.popups.Popup;
import io.bitsquare.gui.util.Layout; import io.bitsquare.gui.util.Layout;
import io.bitsquare.user.PopupId;
import io.bitsquare.user.Preferences;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.geometry.HPos; import javafx.geometry.HPos;
@ -105,13 +108,23 @@ public class ConfirmPaymentReceivedView extends TradeStepDetailsView {
private void onPaymentReceived(ActionEvent actionEvent) { private void onPaymentReceived(ActionEvent actionEvent) {
log.debug("onPaymentReceived"); log.debug("onPaymentReceived");
if (model.isAuthenticated()) { if (model.isAuthenticated()) {
confirmFiatReceivedButton.setDisable(true); Preferences preferences = model.dataModel.getPreferences();
String key = PopupId.PAYMENT_RECEIVED;
if (preferences.showAgain(key) && !BitsquareApp.DEV_MODE) {
new Popup().information("Please note that as soon you have confirmed that you have received the " +
"payment the locked Bitcoin will be released.\n" +
"There is no way to reverse a Bitcoin payment. Confirm only if you are sure.")
.onClose(() -> preferences.dontShowAgain(key))
.show();
} else {
confirmFiatReceivedButton.setDisable(true);
statusProgressIndicator.setVisible(true); statusProgressIndicator.setVisible(true);
statusProgressIndicator.setProgress(-1); statusProgressIndicator.setProgress(-1);
statusLabel.setText("Sending message to trading partner..."); statusLabel.setText("Sending message to trading partner...");
model.fiatPaymentReceived(); model.fiatPaymentReceived();
}
} else { } else {
new Popup().warning("You need to wait until your client is authenticated in the network.\n" + new Popup().warning("You need to wait until your client is authenticated in the network.\n" +
"That might take up to about 2 minutes at startup.").show(); "That might take up to about 2 minutes at startup.").show();

View File

@ -17,6 +17,7 @@
package io.bitsquare.gui.main.portfolio.pendingtrades.steps; package io.bitsquare.gui.main.portfolio.pendingtrades.steps;
import io.bitsquare.app.BitsquareApp;
import io.bitsquare.common.util.Tuple3; import io.bitsquare.common.util.Tuple3;
import io.bitsquare.gui.components.TitledGroupBg; import io.bitsquare.gui.components.TitledGroupBg;
import io.bitsquare.gui.components.TxIdTextField; import io.bitsquare.gui.components.TxIdTextField;
@ -26,6 +27,8 @@ import io.bitsquare.gui.popups.Popup;
import io.bitsquare.gui.util.Layout; import io.bitsquare.gui.util.Layout;
import io.bitsquare.payment.PaymentAccountContractData; import io.bitsquare.payment.PaymentAccountContractData;
import io.bitsquare.payment.PaymentMethod; import io.bitsquare.payment.PaymentMethod;
import io.bitsquare.user.PopupId;
import io.bitsquare.user.Preferences;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.geometry.Insets; import javafx.geometry.Insets;
@ -37,6 +40,7 @@ import javafx.scene.layout.GridPane;
import static io.bitsquare.gui.util.FormBuilder.*; import static io.bitsquare.gui.util.FormBuilder.*;
public class StartPaymentView extends TradeStepDetailsView { public class StartPaymentView extends TradeStepDetailsView {
private final Preferences preferences;
private TxIdTextField txIdTextField; private TxIdTextField txIdTextField;
private Button paymentStartedButton; private Button paymentStartedButton;
@ -55,6 +59,7 @@ public class StartPaymentView extends TradeStepDetailsView {
public StartPaymentView(PendingTradesViewModel model) { public StartPaymentView(PendingTradesViewModel model) {
super(model); super(model);
txIdChangeListener = (ov, oldValue, newValue) -> txIdTextField.setup(newValue); txIdChangeListener = (ov, oldValue, newValue) -> txIdTextField.setup(newValue);
preferences = model.dataModel.getPreferences();
} }
@Override @Override
@ -63,6 +68,16 @@ public class StartPaymentView extends TradeStepDetailsView {
model.getTxId().addListener(txIdChangeListener); model.getTxId().addListener(txIdChangeListener);
txIdTextField.setup(model.getTxId().get()); txIdTextField.setup(model.getTxId().get());
String key = PopupId.SEND_PAYMENT_INFO;
if (preferences.showAgain(key) && !BitsquareApp.DEV_MODE) {
new Popup().information("You need to transfer now the agreed amount to your trading partner.\n" +
"Please take care that you use the exact data presented here, including the reference text\n" +
"Please do not click the \"Payment started\" button if you have before you have completed the transfer.\n" +
"Take care that you make the transfer soon to not miss the exceed trading period.")
.onClose(() -> preferences.dontShowAgain(key))
.show();
}
} }
@Override @Override
@ -126,13 +141,21 @@ public class StartPaymentView extends TradeStepDetailsView {
private void onPaymentStarted(ActionEvent actionEvent) { private void onPaymentStarted(ActionEvent actionEvent) {
log.debug("onPaymentStarted"); log.debug("onPaymentStarted");
if (model.isAuthenticated()) { if (model.isAuthenticated()) {
paymentStartedButton.setDisable(true); String key = PopupId.PAYMENT_SENT;
if (preferences.showAgain(key) && !BitsquareApp.DEV_MODE) {
new Popup().information("You are confirming that you have transferred the payment to your trading partner.\n" +
"Please click the \"Payment started\" button only if you have completed the transfer.")
.onClose(() -> preferences.dontShowAgain(key))
.show();
} else {
paymentStartedButton.setDisable(true);
statusProgressIndicator.setVisible(true); statusProgressIndicator.setVisible(true);
statusProgressIndicator.setProgress(-1); statusProgressIndicator.setProgress(-1);
statusLabel.setText("Sending message to trading partner..."); statusLabel.setText("Sending message to trading partner...");
model.fiatPaymentStarted(); model.fiatPaymentStarted();
}
} else { } else {
new Popup().warning("You need to wait until your client is authenticated in the network.\n" + new Popup().warning("You need to wait until your client is authenticated in the network.\n" +
"That might take up to about 2 minutes at startup.").show(); "That might take up to about 2 minutes at startup.").show();

View File

@ -29,8 +29,8 @@ import java.util.Optional;
import static io.bitsquare.gui.util.FormBuilder.addCheckBox; import static io.bitsquare.gui.util.FormBuilder.addCheckBox;
public class FirstTimePopup extends WebViewPopup { public class FirstTimeWebViewPopup extends WebViewPopup {
private static final Logger log = LoggerFactory.getLogger(FirstTimePopup.class); private static final Logger log = LoggerFactory.getLogger(FirstTimeWebViewPopup.class);
private Preferences preferences; private Preferences preferences;
private String id; private String id;
@ -39,22 +39,22 @@ public class FirstTimePopup extends WebViewPopup {
// Public API // Public API
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
public FirstTimePopup(Preferences preferences) { public FirstTimeWebViewPopup(Preferences preferences) {
this.preferences = preferences; this.preferences = preferences;
} }
@Override @Override
public FirstTimePopup url(String url) { public FirstTimeWebViewPopup url(String url) {
super.url(url); super.url(url);
return this; return this;
} }
public FirstTimePopup onClose(Runnable closeHandler) { public FirstTimeWebViewPopup onClose(Runnable closeHandler) {
this.closeHandlerOptional = Optional.of(closeHandler); this.closeHandlerOptional = Optional.of(closeHandler);
return this; return this;
} }
public FirstTimePopup id(String id) { public FirstTimeWebViewPopup id(String id) {
this.id = id; this.id = id;
return this; return this;
} }

View File

@ -110,7 +110,7 @@ public class OfferDetailsPopup extends Popup {
} }
private void addContent() { private void addContent() {
int rows = 9; int rows = 11;
if (offer.getPaymentMethodCountryCode() != null) if (offer.getPaymentMethodCountryCode() != null)
rows++; rows++;
if (offer.getOfferFeePaymentTxID() != null) if (offer.getOfferFeePaymentTxID() != null)
@ -124,7 +124,8 @@ public class OfferDetailsPopup extends Popup {
addLabelTextField(gridPane, rowIndex, "Offer ID:", offer.getId(), Layout.FIRST_ROW_DISTANCE); addLabelTextField(gridPane, rowIndex, "Offer ID:", offer.getId(), Layout.FIRST_ROW_DISTANCE);
addLabelTextField(gridPane, ++rowIndex, "Creation date:", formatter.formatDateTime(offer.getDate())); addLabelTextField(gridPane, ++rowIndex, "Creation date:", formatter.formatDateTime(offer.getDate()));
addLabelTextField(gridPane, ++rowIndex, "Offer direction:", Offer.Direction.BUY.name()); addLabelTextField(gridPane, ++rowIndex, "Offer direction:", Offer.Direction.BUY.name());
addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(offer.getPrice()) + " " + offer.getCurrencyCode()); addLabelTextField(gridPane, ++rowIndex, "Currency:", offer.getCurrencyCode());
addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(offer.getPrice()) + " " + offer.getCurrencyCode() + "/" + "BTC");
addLabelTextField(gridPane, ++rowIndex, "Amount:", formatter.formatCoinWithCode(offer.getAmount())); addLabelTextField(gridPane, ++rowIndex, "Amount:", formatter.formatCoinWithCode(offer.getAmount()));
addLabelTextField(gridPane, ++rowIndex, "Min. amount:", formatter.formatCoinWithCode(offer.getMinAmount())); addLabelTextField(gridPane, ++rowIndex, "Min. amount:", formatter.formatCoinWithCode(offer.getMinAmount()));
addLabelTextField(gridPane, ++rowIndex, "Payment method:", BSResources.get(offer.getPaymentMethod().getId())); addLabelTextField(gridPane, ++rowIndex, "Payment method:", BSResources.get(offer.getPaymentMethod().getId()));
@ -192,6 +193,7 @@ public class OfferDetailsPopup extends Popup {
}); });
CheckBox checkBox = addCheckBox(gridPane, ++rowIndex, "Don't show again", 5); CheckBox checkBox = addCheckBox(gridPane, ++rowIndex, "Don't show again", 5);
checkBox.setPadding(new Insets(10, 0, 15, 0));
checkBox.setSelected(!preferences.getShowTakeOfferConfirmation()); checkBox.setSelected(!preferences.getShowTakeOfferConfirmation());
checkBox.setOnAction(e -> preferences.setShowTakeOfferConfirmation(!checkBox.isSelected())); checkBox.setOnAction(e -> preferences.setShowTakeOfferConfirmation(!checkBox.isSelected()));
} else { } else {

View File

@ -30,6 +30,7 @@ import javafx.geometry.Insets;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.TextArea; import javafx.scene.control.TextArea;
import javafx.scene.control.TextField; import javafx.scene.control.TextField;
import javafx.scene.control.Tooltip;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -126,15 +127,19 @@ public class TradeDetailsPopup extends Popup {
addLabelTextField(gridPane, ++rowIndex, "Offer direction:", direction); addLabelTextField(gridPane, ++rowIndex, "Offer direction:", direction);
addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(offer.getPrice()) + " " + offer.getCurrencyCode()); addLabelTextField(gridPane, ++rowIndex, "Price:", formatter.formatFiat(offer.getPrice()) + " " + offer.getCurrencyCode());
addLabelTextField(gridPane, ++rowIndex, "Trade amount:", formatter.formatCoinWithCode(trade.getTradeAmount())); addLabelTextField(gridPane, ++rowIndex, "Trade amount:", formatter.formatCoinWithCode(trade.getTradeAmount()));
addLabelTextField(gridPane, ++rowIndex, "Selected arbitrator:", formatter.arbitratorAddressToShortAddress(trade.getArbitratorAddress())); addLabelTextField(gridPane, ++rowIndex, "Selected arbitrator:", trade.getArbitratorAddress().getFullAddress());
if (contract != null) { if (contract != null) {
if (buyerPaymentAccountContractData != null) if (buyerPaymentAccountContractData != null) {
addLabelTextField(gridPane, ++rowIndex, "Buyer payment details:", BSResources.get(buyerPaymentAccountContractData.getPaymentDetails())); TextField tf = addLabelTextField(gridPane, ++rowIndex, "Buyer payment details:", BSResources.get(buyerPaymentAccountContractData.getPaymentDetails())).second;
tf.setTooltip(new Tooltip(tf.getText()));
if (sellerPaymentAccountContractData != null) tf.setMouseTransparent(false);
addLabelTextField(gridPane, ++rowIndex, "Seller payment details:", BSResources.get(sellerPaymentAccountContractData.getPaymentDetails())); }
if (sellerPaymentAccountContractData != null) {
TextField tf = addLabelTextField(gridPane, ++rowIndex, "Seller payment details:", BSResources.get(sellerPaymentAccountContractData.getPaymentDetails())).second;
tf.setTooltip(new Tooltip(tf.getText()));
tf.setMouseTransparent(false);
}
if (buyerPaymentAccountContractData == null && sellerPaymentAccountContractData == null) if (buyerPaymentAccountContractData == null && sellerPaymentAccountContractData == null)
addLabelTextField(gridPane, ++rowIndex, "Payment method:", BSResources.get(contract.getPaymentMethodName())); addLabelTextField(gridPane, ++rowIndex, "Payment method:", BSResources.get(contract.getPaymentMethodName()));
} }

View File

@ -33,7 +33,7 @@ public class WebViewPopup extends Popup {
protected String url; protected String url;
public static String getLocalUrl(String htmlFile) { public static String getLocalUrl(String htmlFile) {
return WebViewPopup.class.getResource("/html/" + htmlFile).toExternalForm(); return WebViewPopup.class.getResource("/html/" + htmlFile + ".html").toExternalForm();
} }
public WebViewPopup() { public WebViewPopup() {

View File

@ -308,14 +308,9 @@ public class BSFormatter {
public String arbitratorAddressesToString(List<Address> addresses) { public String arbitratorAddressesToString(List<Address> addresses) {
//return addresses.stream().map(e -> e.getFullAddress().substring(0, 8)).collect(Collectors.joining(", "));
return addresses.stream().map(e -> e.getFullAddress()).collect(Collectors.joining(", ")); return addresses.stream().map(e -> e.getFullAddress()).collect(Collectors.joining(", "));
} }
public String arbitratorAddressToShortAddress(Address address) {
return address.getFullAddress().substring(0, 8);
}
public String languageCodesToString(List<String> languageLocales) { public String languageCodesToString(List<String> languageLocales) {
return languageLocales.stream().map(LanguageUtil::getDisplayName).collect(Collectors.joining(", ")); return languageLocales.stream().map(LanguageUtil::getDisplayName).collect(Collectors.joining(", "));
} }

View File

@ -18,7 +18,8 @@
body { body {
font-family: sans-serif; font-family: sans-serif;
color: #333; color: #333;
font-size: 13px; font-size: 14px;
line-height: 2;
} }
a { a {

View File

@ -75,7 +75,7 @@ createOffer.advancedBox.currency=Currency:
createOffer.advancedBox.county=Payments account country: createOffer.advancedBox.county=Payments account country:
createOffer.advancedBox.info=Your trading partners must fulfill your offer restrictions. You can edit the accepted countries, languages and arbitrators in the settings. The payments account details are used from your current selected payments account (if you have multiple payments accounts). createOffer.advancedBox.info=Your trading partners must fulfill your offer restrictions. You can edit the accepted countries, languages and arbitrators in the settings. The payments account details are used from your current selected payments account (if you have multiple payments accounts).
createOffer.success.headline=Your offer has been successfully published to the distributed offerbook. createOffer.success.headline=Your offer has been published to the offerbook.
createOffer.success.info=In the portfolio screen you can manage your open offers. createOffer.success.info=In the portfolio screen you can manage your open offers.
createOffer.error.message=An error occurred when placing the offer.\n\n{0} createOffer.error.message=An error occurred when placing the offer.\n\n{0}

View File

@ -80,7 +80,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
private MonadicBinding<Boolean> readyForAuthentication; private MonadicBinding<Boolean> readyForAuthentication;
private final Storage<Address> dbStorage; private final Storage<Address> dbStorage;
private Address myOnionAddress; private Address myOnionAddress;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Constructor // Constructor
@ -186,7 +186,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
// We set connectionType to that connection to avoid that is get closed when // We set connectionType to that connection to avoid that is get closed when
// we get too many connection attempts. // we get too many connection attempts.
// That is used as protection against eclipse attacks. // That is used as protection against eclipse attacks.
connection.setConnectionType(ConnectionType.DIRECT_MSG); connection.setConnectionType(ConnectionMode.DIRECT_MSG);
log.info("Received SealedAndSignedMessage and decrypted it: " + decryptedMsgWithPubKey); log.info("Received SealedAndSignedMessage and decrypted it: " + decryptedMsgWithPubKey);
decryptedMailListeners.stream().forEach( decryptedMailListeners.stream().forEach(
@ -305,7 +305,8 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
Log.traceCall(); Log.traceCall();
checkArgument(networkNode.getAddress() != null, "Address must be set when we have the hidden service ready"); checkArgument(networkNode.getAddress() != null, "Address must be set when we have the hidden service ready");
if (myOnionAddress != null) if (myOnionAddress != null)
checkArgument(networkNode.getAddress() == myOnionAddress, "networkNode.getAddress() must be same as myOnionAddress"); checkArgument(networkNode.getAddress().equals(myOnionAddress),
"networkNode.getAddress() must be same as myOnionAddress.");
myOnionAddress = networkNode.getAddress(); myOnionAddress = networkNode.getAddress();
dbStorage.queueUpForSave(myOnionAddress); dbStorage.queueUpForSave(myOnionAddress);
@ -709,7 +710,7 @@ public class P2PService implements SetupListener, MessageListener, ConnectionLis
return blurredAddressHash != null && return blurredAddressHash != null &&
Arrays.equals(blurredAddressHash, sealedAndSignedMessage.addressPrefixHash); Arrays.equals(blurredAddressHash, sealedAndSignedMessage.addressPrefixHash);
} else { } else {
log.warn("myOnionAddress must not be null at verifyAddressPrefixHash"); log.debug("myOnionAddress is null at verifyAddressPrefixHash. That is expected at startup.");
return false; return false;
} }
} }

View File

@ -31,7 +31,7 @@ public class Connection implements MessageListener {
private static final Logger log = LoggerFactory.getLogger(Connection.class); private static final Logger log = LoggerFactory.getLogger(Connection.class);
private static final int MAX_MSG_SIZE = 5 * 1024 * 1024; // 5 MB of compressed data private static final int MAX_MSG_SIZE = 5 * 1024 * 1024; // 5 MB of compressed data
private static final int SOCKET_TIMEOUT = 30 * 60 * 1000; // 30 min. private static final int SOCKET_TIMEOUT = 30 * 60 * 1000; // 30 min.
private ConnectionType connectionType; private ConnectionMode connectionType;
public static int getMaxMsgSize() { public static int getMaxMsgSize() {
return MAX_MSG_SIZE; return MAX_MSG_SIZE;
@ -123,7 +123,7 @@ public class Connection implements MessageListener {
connectionListener.onPeerAddressAuthenticated(peerAddress, connection); connectionListener.onPeerAddressAuthenticated(peerAddress, connection);
} }
public void setConnectionType(ConnectionType connectionType) { public void setConnectionType(ConnectionMode connectionType) {
this.connectionType = connectionType; this.connectionType = connectionType;
} }
@ -210,7 +210,7 @@ public class Connection implements MessageListener {
return stopped; return stopped;
} }
public ConnectionType getConnectionType() { public ConnectionMode getConnectionType() {
return connectionType; return connectionType;
} }

View File

@ -0,0 +1,8 @@
package io.bitsquare.p2p.network;
public enum ConnectionMode {
PASSIVE, // for connections initiated by other peer
ACTIVE, // for connections initiated by us
DIRECT_MSG, // for connections used for direct messaging
AUTH_REQUEST // for connections used for starting the authentication
}

View File

@ -8,7 +8,7 @@ import io.bitsquare.common.UserThread;
import io.bitsquare.p2p.Address; import io.bitsquare.p2p.Address;
import io.bitsquare.p2p.Message; import io.bitsquare.p2p.Message;
import io.bitsquare.p2p.network.Connection; import io.bitsquare.p2p.network.Connection;
import io.bitsquare.p2p.network.ConnectionType; import io.bitsquare.p2p.network.ConnectionMode;
import io.bitsquare.p2p.network.MessageListener; import io.bitsquare.p2p.network.MessageListener;
import io.bitsquare.p2p.network.NetworkNode; import io.bitsquare.p2p.network.NetworkNode;
import io.bitsquare.p2p.peers.messages.auth.*; import io.bitsquare.p2p.peers.messages.auth.*;
@ -72,7 +72,7 @@ public class AuthenticationHandshake implements MessageListener {
// We use the active connectionType if we started the authentication request to another peer // We use the active connectionType if we started the authentication request to another peer
// That is used for protecting eclipse attacks // That is used for protecting eclipse attacks
connection.setConnectionType(ConnectionType.ACTIVE); connection.setConnectionType(ConnectionMode.ACTIVE);
AuthenticationResponse authenticationResponse = (AuthenticationResponse) message; AuthenticationResponse authenticationResponse = (AuthenticationResponse) message;
Address peerAddress = authenticationResponse.address; Address peerAddress = authenticationResponse.address;
@ -180,7 +180,7 @@ public class AuthenticationHandshake implements MessageListener {
log.trace("send AuthenticationRequest to " + peerAddress + " succeeded."); log.trace("send AuthenticationRequest to " + peerAddress + " succeeded.");
connection.setPeerAddress(peerAddress); connection.setPeerAddress(peerAddress);
// We protect that connection from getting closed by maintenance cleanup... // We protect that connection from getting closed by maintenance cleanup...
connection.setConnectionType(ConnectionType.AUTH_REQUEST); connection.setConnectionType(ConnectionMode.AUTH_REQUEST);
} }
@Override @Override
@ -228,7 +228,7 @@ public class AuthenticationHandshake implements MessageListener {
connection.setPeerAddress(peerAddress); connection.setPeerAddress(peerAddress);
// We use passive connectionType for connections created from received authentication requests from other peers // We use passive connectionType for connections created from received authentication requests from other peers
// That is used for protecting eclipse attacks // That is used for protecting eclipse attacks
connection.setConnectionType(ConnectionType.PASSIVE); connection.setConnectionType(ConnectionMode.PASSIVE);
} }
@Override @Override

View File

@ -168,7 +168,7 @@ public class PeerGroup implements MessageListener, ConnectionListener {
Address peerAddress = message.address; Address peerAddress = message.address;
if (!authenticationHandshakes.containsKey(peerAddress)) { if (!authenticationHandshakes.containsKey(peerAddress)) {
// We protect that connection from getting closed by maintenance cleanup... // We protect that connection from getting closed by maintenance cleanup...
connection.setConnectionType(ConnectionType.AUTH_REQUEST); connection.setConnectionType(ConnectionMode.AUTH_REQUEST);
AuthenticationHandshake authenticationHandshake = new AuthenticationHandshake(networkNode, PeerGroup.this, getMyAddress()); AuthenticationHandshake authenticationHandshake = new AuthenticationHandshake(networkNode, PeerGroup.this, getMyAddress());
authenticationHandshakes.put(peerAddress, authenticationHandshake); authenticationHandshakes.put(peerAddress, authenticationHandshake);
SettableFuture<Connection> future = authenticationHandshake.respondToAuthenticationRequest(message, connection); SettableFuture<Connection> future = authenticationHandshake.respondToAuthenticationRequest(message, connection);
@ -186,8 +186,7 @@ public class PeerGroup implements MessageListener, ConnectionListener {
@Override @Override
public void onFailure(@NotNull Throwable throwable) { public void onFailure(@NotNull Throwable throwable) {
log.error("AuthenticationHandshake failed. " + throwable.getMessage()); log.info("AuthenticationHandshake failed. That is expected if peer went offline. " + throwable.getMessage());
throwable.printStackTrace();
removePeer(connection.getPeerAddress()); removePeer(connection.getPeerAddress());
} }
}); });
@ -468,7 +467,7 @@ public class PeerGroup implements MessageListener, ConnectionListener {
List<Connection> authenticatedConnections = allConnections.stream() List<Connection> authenticatedConnections = allConnections.stream()
.filter(e -> e.isAuthenticated()) .filter(e -> e.isAuthenticated())
.filter(e -> e.getConnectionType() == ConnectionType.PASSIVE) .filter(e -> e.getConnectionType() == ConnectionMode.PASSIVE)
.collect(Collectors.toList()); .collect(Collectors.toList());
if (authenticatedConnections.size() == 0) { if (authenticatedConnections.size() == 0) {
@ -477,7 +476,7 @@ public class PeerGroup implements MessageListener, ConnectionListener {
if (size > MAX_CONNECTIONS_NORMAL_PRIO) { if (size > MAX_CONNECTIONS_NORMAL_PRIO) {
authenticatedConnections = allConnections.stream() authenticatedConnections = allConnections.stream()
.filter(e -> e.isAuthenticated()) .filter(e -> e.isAuthenticated())
.filter(e -> e.getConnectionType() == ConnectionType.PASSIVE || e.getConnectionType() == ConnectionType.ACTIVE) .filter(e -> e.getConnectionType() == ConnectionMode.PASSIVE || e.getConnectionType() == ConnectionMode.ACTIVE)
.collect(Collectors.toList()); .collect(Collectors.toList());
if (authenticatedConnections.size() == 0) { if (authenticatedConnections.size() == 0) {

View File

@ -285,7 +285,7 @@ public class ProtectedExpirableDataStorage implements MessageListener {
Log.traceCall(); Log.traceCall();
int newSequenceNumber = data.sequenceNumber; int newSequenceNumber = data.sequenceNumber;
Integer storedSequenceNumber = sequenceNumberMap.get(hashOfData); Integer storedSequenceNumber = sequenceNumberMap.get(hashOfData);
if (sequenceNumberMap.containsKey(hashOfData) && newSequenceNumber <= storedSequenceNumber) { if (sequenceNumberMap.containsKey(hashOfData) && newSequenceNumber < storedSequenceNumber) {
log.trace("Sequence number is invalid. newSequenceNumber=" log.trace("Sequence number is invalid. newSequenceNumber="
+ newSequenceNumber + " / storedSequenceNumber=" + storedSequenceNumber); + newSequenceNumber + " / storedSequenceNumber=" + storedSequenceNumber);
return false; return false;