mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-04-19 23:36:00 -04:00
Require password at startup, heck for open offers at emptying wallet, add check for isBootstrapped,
This commit is contained in:
parent
5af70848a7
commit
0ebf3f6b36
@ -145,8 +145,12 @@ public class ArbitratorManager {
|
||||
ArbitratorManager.this.onBootstrapComplete();
|
||||
}
|
||||
};
|
||||
p2PService.addP2PServiceListener(bootstrapListener);
|
||||
|
||||
if (p2PService.isBootstrapped())
|
||||
onBootstrapComplete();
|
||||
else
|
||||
p2PService.addP2PServiceListener(bootstrapListener);
|
||||
|
||||
} else {
|
||||
republishArbitrator();
|
||||
}
|
||||
|
@ -125,7 +125,10 @@ public class DisputeManager {
|
||||
applyMessages();
|
||||
}
|
||||
};
|
||||
p2PService.addP2PServiceListener(bootstrapListener);
|
||||
if (p2PService.isBootstrapped())
|
||||
applyMessages();
|
||||
else
|
||||
p2PService.addP2PServiceListener(bootstrapListener);
|
||||
}
|
||||
|
||||
private void applyMessages() {
|
||||
@ -146,7 +149,8 @@ public class DisputeManager {
|
||||
});
|
||||
decryptedMailboxMessageWithPubKeys.clear();
|
||||
|
||||
p2PService.removeP2PServiceListener(bootstrapListener);
|
||||
if (bootstrapListener != null)
|
||||
p2PService.removeP2PServiceListener(bootstrapListener);
|
||||
}
|
||||
|
||||
|
||||
|
@ -151,13 +151,15 @@ public class TradeManager {
|
||||
bootstrapListener = new BootstrapListener() {
|
||||
@Override
|
||||
public void onBootstrapComplete() {
|
||||
Log.traceCall("onNetworkReady");
|
||||
// Get called after onMailboxMessageAdded from initial data request
|
||||
// The mailbox message will be removed inside the tasks after they are processed successfully
|
||||
initPendingTrades();
|
||||
}
|
||||
};
|
||||
p2PService.addP2PServiceListener(bootstrapListener);
|
||||
if (p2PService.isBootstrapped())
|
||||
initPendingTrades();
|
||||
else
|
||||
p2PService.addP2PServiceListener(bootstrapListener);
|
||||
}
|
||||
|
||||
|
||||
@ -167,7 +169,8 @@ public class TradeManager {
|
||||
|
||||
private void initPendingTrades() {
|
||||
Log.traceCall();
|
||||
p2PService.removeP2PServiceListener(bootstrapListener);
|
||||
if (bootstrapListener != null)
|
||||
p2PService.removeP2PServiceListener(bootstrapListener);
|
||||
|
||||
//List<Trade> failedTrades = new ArrayList<>();
|
||||
for (Trade trade : trades) {
|
||||
|
@ -53,6 +53,7 @@ import javax.annotation.Nullable;
|
||||
import javax.inject.Named;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -121,6 +122,11 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||
};
|
||||
p2PService.addP2PServiceListener(bootstrapListener);
|
||||
p2PService.addDecryptedDirectMessageListener(this);
|
||||
|
||||
if (p2PService.isBootstrapped())
|
||||
onBootstrapComplete();
|
||||
else
|
||||
p2PService.addP2PServiceListener(bootstrapListener);
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@ -151,6 +157,15 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||
UserThread.runAfter(completeHandler::run, openOffers.size() * 100 + 200, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public void removeAllOpenOffers(@Nullable Runnable completeHandler) {
|
||||
List<OpenOffer> openOffersList = new ArrayList<>(openOffers);
|
||||
openOffersList.forEach(openOffer -> removeOpenOffer(openOffer, () -> {
|
||||
}, errorMessage -> {
|
||||
}));
|
||||
if (completeHandler != null)
|
||||
UserThread.runAfter(completeHandler::run, openOffers.size() * 100 + 200, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// DecryptedDirectMessageListener implementation
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -172,7 +187,8 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void onBootstrapComplete() {
|
||||
p2PService.removeP2PServiceListener(bootstrapListener);
|
||||
if (bootstrapListener != null)
|
||||
p2PService.removeP2PServiceListener(bootstrapListener);
|
||||
|
||||
stopped = false;
|
||||
|
||||
|
@ -409,13 +409,10 @@ public class MainViewModel implements ViewModel {
|
||||
}
|
||||
|
||||
private void onAllServicesInitialized() {
|
||||
// We need to request the password in case we have an encrypted wallet as we need to set the aesKey to our trading wallet.
|
||||
// In case we have any offers open or a pending trade we need to unlock our trading wallet so a trade can be executed automatically
|
||||
// Otherwise we delay the password request to create offer, or take offer.
|
||||
// When the password is set it will be stored to the tradeWalletService as well, so its only needed after a restart.
|
||||
if (walletService.getWallet().isEncrypted() &&
|
||||
(openOfferManager.getOpenOffers().size() > 0
|
||||
|| tradeManager.getTrades().size() > 0
|
||||
|| disputeManager.getDisputesAsObservableList().size() > 0)) {
|
||||
if (walletService.getWallet().isEncrypted()) {
|
||||
walletPasswordWindow
|
||||
.onAesKey(aesKey -> {
|
||||
tradeWalletService.setAesKey(aesKey);
|
||||
|
@ -145,9 +145,7 @@ public class PasswordView extends ActivatableView<GridPane, Void> {
|
||||
addMultilineLabel(root, gridRow,
|
||||
"With password protection you need to enter your password when" +
|
||||
" withdrawing bitcoin out of your wallet or " +
|
||||
"if you want to view or restore a wallet from seed words.\n" +
|
||||
"For the transactions used in the trade process we don't support password protection as that would make automatic offer " +
|
||||
"execution impossible, but you need to provide the password at application startup if you have open offer, trades or disputes.",
|
||||
"if you want to view or restore a wallet from seed words as well as at application startup.",
|
||||
Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,6 @@ import io.bitsquare.gui.main.overlays.windows.DisputeSummaryWindow;
|
||||
import io.bitsquare.gui.main.overlays.windows.TradeDetailsWindow;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.gui.util.GUIUtil;
|
||||
import io.bitsquare.p2p.BootstrapListener;
|
||||
import io.bitsquare.p2p.P2PService;
|
||||
import io.bitsquare.p2p.network.Connection;
|
||||
import io.bitsquare.trade.Trade;
|
||||
@ -110,7 +109,6 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
private TableGroupHeadline tableGroupHeadline;
|
||||
private ObservableList<DisputeCommunicationMessage> disputeCommunicationMessages;
|
||||
private Button sendButton;
|
||||
private boolean isBootstrapped;
|
||||
private Subscription inputTextAreaTextSubscription;
|
||||
|
||||
|
||||
@ -175,17 +173,6 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
};
|
||||
|
||||
disputeDirectMessageListListener = c -> scrollToBottom();
|
||||
|
||||
if (!p2PService.isBootstrapped()) {
|
||||
p2PService.addP2PServiceListener(new BootstrapListener() {
|
||||
@Override
|
||||
public void onBootstrapComplete() {
|
||||
isBootstrapped = true;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
isBootstrapped = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -425,7 +412,7 @@ public class TraderDisputeView extends ActivatableView<VBox, Void> {
|
||||
sendButton = new Button("Send");
|
||||
sendButton.setDefaultButton(true);
|
||||
sendButton.setOnAction(e -> {
|
||||
if (isBootstrapped) {
|
||||
if (p2PService.isBootstrapped()) {
|
||||
String text = inputTextArea.getText();
|
||||
if (!text.isEmpty())
|
||||
onSendMessage(text, selectedDispute);
|
||||
|
@ -25,6 +25,7 @@ import io.bitsquare.btc.AddressEntryException;
|
||||
import io.bitsquare.btc.Restrictions;
|
||||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.util.Utilities;
|
||||
import io.bitsquare.gui.common.view.ActivatableView;
|
||||
import io.bitsquare.gui.common.view.FxmlView;
|
||||
@ -58,6 +59,7 @@ import org.spongycastle.crypto.params.KeyParameter;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@FxmlView
|
||||
@ -281,7 +283,9 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
||||
|
||||
private void doWithdraw(Coin amount, FutureCallback<Transaction> callback) {
|
||||
if (walletService.getWallet().isEncrypted()) {
|
||||
walletPasswordWindow.onAesKey(aesKey -> sendFunds(amount, aesKey, callback)).show();
|
||||
UserThread.runAfter(() -> walletPasswordWindow.onAesKey(aesKey ->
|
||||
sendFunds(amount, aesKey, callback))
|
||||
.show(), 300, TimeUnit.MILLISECONDS);
|
||||
} else {
|
||||
sendFunds(amount, null, callback);
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ import io.bitsquare.common.crypto.KeyRing;
|
||||
import io.bitsquare.gui.Navigation;
|
||||
import io.bitsquare.gui.common.model.ActivatableDataModel;
|
||||
import io.bitsquare.gui.main.overlays.notifications.Notification;
|
||||
import io.bitsquare.gui.main.overlays.windows.WalletPasswordWindow;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.locale.TradeCurrency;
|
||||
import io.bitsquare.p2p.P2PService;
|
||||
@ -63,14 +62,13 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
class CreateOfferDataModel extends ActivatableDataModel {
|
||||
private final OpenOfferManager openOfferManager;
|
||||
final WalletService walletService;
|
||||
private final TradeWalletService tradeWalletService;
|
||||
final TradeWalletService tradeWalletService;
|
||||
private final Preferences preferences;
|
||||
private final User user;
|
||||
private final KeyRing keyRing;
|
||||
private final P2PService p2PService;
|
||||
private final PriceFeed priceFeed;
|
||||
private Navigation navigation;
|
||||
private final WalletPasswordWindow walletPasswordWindow;
|
||||
private final BlockchainService blockchainService;
|
||||
private final BSFormatter formatter;
|
||||
private final String offerId;
|
||||
@ -117,8 +115,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||
@Inject
|
||||
CreateOfferDataModel(OpenOfferManager openOfferManager, WalletService walletService, TradeWalletService tradeWalletService,
|
||||
Preferences preferences, User user, KeyRing keyRing, P2PService p2PService, PriceFeed priceFeed,
|
||||
Navigation navigation,
|
||||
WalletPasswordWindow walletPasswordWindow, BlockchainService blockchainService, BSFormatter formatter) {
|
||||
Navigation navigation, BlockchainService blockchainService, BSFormatter formatter) {
|
||||
this.openOfferManager = openOfferManager;
|
||||
this.walletService = walletService;
|
||||
this.tradeWalletService = tradeWalletService;
|
||||
@ -128,7 +125,6 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||
this.p2PService = p2PService;
|
||||
this.priceFeed = priceFeed;
|
||||
this.navigation = navigation;
|
||||
this.walletPasswordWindow = walletPasswordWindow;
|
||||
this.blockchainService = blockchainService;
|
||||
this.formatter = formatter;
|
||||
|
||||
@ -286,17 +282,6 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||
}
|
||||
|
||||
void onPlaceOffer(Offer offer, TransactionResultHandler resultHandler) {
|
||||
if (walletService.getWallet().isEncrypted() && tradeWalletService.getAesKey() == null) {
|
||||
walletPasswordWindow.onAesKey(aesKey -> {
|
||||
tradeWalletService.setAesKey(aesKey);
|
||||
doPlaceOffer(offer, resultHandler);
|
||||
}).show();
|
||||
} else {
|
||||
doPlaceOffer(offer, resultHandler);
|
||||
}
|
||||
}
|
||||
|
||||
private void doPlaceOffer(Offer offer, TransactionResultHandler resultHandler) {
|
||||
openOfferManager.placeOffer(offer, totalToPayAsCoin.get().subtract(offerFeeAsCoin), useSavingsWallet, resultHandler);
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,6 @@ import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.pricefeed.PriceFeed;
|
||||
import io.bitsquare.gui.common.model.ActivatableDataModel;
|
||||
import io.bitsquare.gui.main.overlays.notifications.Notification;
|
||||
import io.bitsquare.gui.main.overlays.windows.WalletPasswordWindow;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.locale.CurrencyUtil;
|
||||
import io.bitsquare.locale.TradeCurrency;
|
||||
@ -61,10 +60,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
*/
|
||||
class TakeOfferDataModel extends ActivatableDataModel {
|
||||
private final TradeManager tradeManager;
|
||||
private final TradeWalletService tradeWalletService;
|
||||
private final WalletService walletService;
|
||||
final TradeWalletService tradeWalletService;
|
||||
final WalletService walletService;
|
||||
private final User user;
|
||||
private final WalletPasswordWindow walletPasswordWindow;
|
||||
private final Preferences preferences;
|
||||
private final PriceFeed priceFeed;
|
||||
private final BlockchainService blockchainService;
|
||||
@ -103,14 +101,13 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
||||
|
||||
@Inject
|
||||
TakeOfferDataModel(TradeManager tradeManager, TradeWalletService tradeWalletService,
|
||||
WalletService walletService, User user, WalletPasswordWindow walletPasswordWindow,
|
||||
WalletService walletService, User user,
|
||||
Preferences preferences, PriceFeed priceFeed, BlockchainService blockchainService,
|
||||
BSFormatter formatter) {
|
||||
this.tradeManager = tradeManager;
|
||||
this.tradeWalletService = tradeWalletService;
|
||||
this.walletService = walletService;
|
||||
this.user = user;
|
||||
this.walletPasswordWindow = walletPasswordWindow;
|
||||
this.preferences = preferences;
|
||||
this.priceFeed = priceFeed;
|
||||
this.blockchainService = blockchainService;
|
||||
@ -227,17 +224,6 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
||||
// errorMessageHandler is used only in the check availability phase. As soon we have a trade we write the error msg in the trade object as we want to
|
||||
// have it persisted as well.
|
||||
void onTakeOffer(TradeResultHandler tradeResultHandler) {
|
||||
if (walletService.getWallet().isEncrypted() && tradeWalletService.getAesKey() == null) {
|
||||
walletPasswordWindow.onAesKey(aesKey -> {
|
||||
tradeWalletService.setAesKey(aesKey);
|
||||
doTakeOffer(tradeResultHandler);
|
||||
}).show();
|
||||
} else {
|
||||
doTakeOffer(tradeResultHandler);
|
||||
}
|
||||
}
|
||||
|
||||
private void doTakeOffer(TradeResultHandler tradeResultHandler) {
|
||||
tradeManager.onTakeOffer(amountAsCoin.get(),
|
||||
totalToPayAsCoin.get().subtract(takerFeeAsCoin),
|
||||
offer,
|
||||
|
@ -62,7 +62,8 @@ public class EmptyWalletWindow extends Overlay<EmptyWalletWindow> {
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public EmptyWalletWindow(WalletService walletService, WalletPasswordWindow walletPasswordWindow, OpenOfferManager openOfferManager, BSFormatter formatter) {
|
||||
public EmptyWalletWindow(WalletService walletService, WalletPasswordWindow walletPasswordWindow,
|
||||
OpenOfferManager openOfferManager, BSFormatter formatter) {
|
||||
this.walletService = walletService;
|
||||
this.walletPasswordWindow = walletPasswordWindow;
|
||||
this.openOfferManager = openOfferManager;
|
||||
@ -140,8 +141,23 @@ public class EmptyWalletWindow extends Overlay<EmptyWalletWindow> {
|
||||
}
|
||||
|
||||
private void doEmptyWallet(KeyParameter aesKey) {
|
||||
if (!openOfferManager.getOpenOffers().isEmpty()) {
|
||||
UserThread.runAfter(() ->
|
||||
new Popup().warning("You have open offers which will be removed if you empty the wallet.\n" +
|
||||
"Are you sure that you want to empty your wallet?")
|
||||
.actionButtonText("Yes, I am sure")
|
||||
.onAction(() -> {
|
||||
doEmptyWallet2(aesKey);
|
||||
})
|
||||
.show(), 300, TimeUnit.MILLISECONDS);
|
||||
} else {
|
||||
doEmptyWallet2(aesKey);
|
||||
}
|
||||
}
|
||||
|
||||
private void doEmptyWallet2(KeyParameter aesKey) {
|
||||
emptyWalletButton.setDisable(true);
|
||||
openOfferManager.closeAllOpenOffers(() -> {
|
||||
openOfferManager.removeAllOpenOffers(() -> {
|
||||
try {
|
||||
walletService.emptyWallet(addressInputTextField.getText(),
|
||||
aesKey,
|
||||
|
@ -23,6 +23,7 @@ import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.AddressEntryException;
|
||||
import io.bitsquare.btc.Restrictions;
|
||||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.handlers.FaultHandler;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
import io.bitsquare.common.util.Tuple2;
|
||||
@ -47,6 +48,8 @@ import org.bitcoinj.core.AddressFormatException;
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.spongycastle.crypto.params.KeyParameter;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static io.bitsquare.gui.util.FormBuilder.*;
|
||||
|
||||
public class BuyerStep5View extends TradeStepView {
|
||||
@ -223,8 +226,6 @@ public class BuyerStep5View extends TradeStepView {
|
||||
}
|
||||
|
||||
private void doWithdrawal(Coin receiverAmount) {
|
||||
useSavingsWalletButton.setDisable(true);
|
||||
withdrawToExternalWalletButton.setDisable(true);
|
||||
String toAddress = withdrawAddressTextField.getText();
|
||||
ResultHandler resultHandler = this::handleTradeCompleted;
|
||||
FaultHandler faultHandler = (errorMessage, throwable) -> {
|
||||
@ -236,17 +237,16 @@ public class BuyerStep5View extends TradeStepView {
|
||||
new Popup().error(errorMessage).show();
|
||||
};
|
||||
if (model.dataModel.walletService.getWallet().isEncrypted()) {
|
||||
model.dataModel.walletPasswordWindow.onAesKey(aesKey -> doWithdrawRequest(toAddress, receiverAmount, aesKey, resultHandler, faultHandler))
|
||||
.onClose(() -> {
|
||||
useSavingsWalletButton.setDisable(false);
|
||||
withdrawToExternalWalletButton.setDisable(false);
|
||||
})
|
||||
.show();
|
||||
UserThread.runAfter(() -> model.dataModel.walletPasswordWindow.onAesKey(aesKey ->
|
||||
doWithdrawRequest(toAddress, receiverAmount, aesKey, resultHandler, faultHandler))
|
||||
.show(), 300, TimeUnit.MILLISECONDS);
|
||||
} else
|
||||
doWithdrawRequest(toAddress, receiverAmount, null, resultHandler, faultHandler);
|
||||
}
|
||||
|
||||
private void doWithdrawRequest(String toAddress, Coin receiverAmount, KeyParameter aesKey, ResultHandler resultHandler, FaultHandler faultHandler) {
|
||||
useSavingsWalletButton.setDisable(true);
|
||||
withdrawToExternalWalletButton.setDisable(true);
|
||||
model.dataModel.onWithdrawRequest(toAddress,
|
||||
receiverAmount,
|
||||
aesKey,
|
||||
|
Loading…
x
Reference in New Issue
Block a user