mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-04-19 15:26:03 -04:00
Fix nullpointer, add check for miningfee
This commit is contained in:
parent
4232a10f47
commit
9d9ce5918b
@ -1040,18 +1040,4 @@ public class TradeWalletService {
|
||||
throw new WalletException(t);
|
||||
}
|
||||
}
|
||||
|
||||
// not used
|
||||
/* private Coin getBalance(List<TransactionOutput> transactionOutputs, Address address) {
|
||||
Coin balance = Coin.ZERO;
|
||||
for (TransactionOutput transactionOutput : transactionOutputs) {
|
||||
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isPayToScriptHash()) {
|
||||
Address addressOutput = transactionOutput.getScriptPubKey().getToAddress(params);
|
||||
if (addressOutput.equals(address))
|
||||
balance = balance.add(transactionOutput.getValue());
|
||||
}
|
||||
}
|
||||
return balance;
|
||||
}*/
|
||||
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ import java.util.*;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -86,6 +87,7 @@ public class WalletService {
|
||||
private final IntegerProperty numPeers = new SimpleIntegerProperty(0);
|
||||
private final ObjectProperty<List<Peer>> connectedPeers = new SimpleObjectProperty<>();
|
||||
public final BooleanProperty shutDownDone = new SimpleBooleanProperty();
|
||||
private ArbitraryTransactionBloomFilter arbitraryTransactionBloomFilter;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -129,7 +131,11 @@ public class WalletService {
|
||||
walletAppKit.wallet().allowSpendingUnconfirmedTransactions();
|
||||
if (params != RegTestParams.get())
|
||||
walletAppKit.peerGroup().setMaxConnections(11);
|
||||
|
||||
// https://groups.google.com/forum/#!msg/bitcoinj/Ys13qkTwcNg/9qxnhwnkeoIJ
|
||||
// DEFAULT_BLOOM_FILTER_FP_RATE = 0.00001
|
||||
walletAppKit.peerGroup().setBloomFilterFalsePositiveRate(0.00001);
|
||||
|
||||
wallet = walletAppKit.wallet();
|
||||
wallet.addEventListener(walletEventListener);
|
||||
|
||||
@ -613,18 +619,36 @@ public class WalletService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* // TODO
|
||||
private class BloomFilterForForeignTx extends AbstractPeerEventListener implements PeerFilterProvider {
|
||||
private final String txId;
|
||||
|
||||
public BloomFilterForForeignTx(String txId) {
|
||||
this.txId = txId;
|
||||
public void requestTransactionFromBlockChain(Transaction transaction, Consumer<Coin> resultHandler) {
|
||||
arbitraryTransactionBloomFilter = new ArbitraryTransactionBloomFilter(transaction, resultHandler);
|
||||
PeerGroup peerGroup = walletAppKit.peerGroup();
|
||||
peerGroup.addEventListener(arbitraryTransactionBloomFilter);
|
||||
peerGroup.addPeerFilterProvider(arbitraryTransactionBloomFilter);
|
||||
}
|
||||
|
||||
private class ArbitraryTransactionBloomFilter extends AbstractPeerEventListener implements PeerFilterProvider {
|
||||
private final Transaction transaction;
|
||||
private final Consumer<Coin> resultHandler;
|
||||
private final Set<TransactionOutPoint> transactionOutPoints;
|
||||
|
||||
public ArbitraryTransactionBloomFilter(Transaction transaction, Consumer<Coin> resultHandler) {
|
||||
this.transaction = transaction;
|
||||
this.resultHandler = resultHandler;
|
||||
|
||||
transactionOutPoints = transaction.getInputs().stream()
|
||||
.map(e -> e.getOutpoint() != null ? e.getOutpoint() : null)
|
||||
.filter(e -> e != null)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
log.debug("transaction=" + transaction);
|
||||
log.debug("transaction.fee=" + transaction.getFee());
|
||||
log.debug("outpoints=" + transactionOutPoints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEarliestKeyCreationTime() {
|
||||
return Utils.currentTimeSeconds();
|
||||
return System.currentTimeMillis() / 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -633,16 +657,15 @@ public class WalletService {
|
||||
|
||||
@Override
|
||||
public int getBloomFilterElementCount() {
|
||||
return 1;
|
||||
return transactionOutPoints.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BloomFilter getBloomFilter(int size, double falsePositiveRate, long nTweak) {
|
||||
BloomFilter filter = new BloomFilter(size, falsePositiveRate, nTweak);
|
||||
*//* for (TransactionOutPoint pledge : allPledges.keySet()) {
|
||||
filter.insert(pledge.bitcoinSerialize());
|
||||
}*//*
|
||||
// how to add txid ???
|
||||
for (TransactionOutPoint transactionOutPoint : transactionOutPoints) {
|
||||
filter.insert(transactionOutPoint.bitcoinSerialize());
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
@ -656,20 +679,15 @@ public class WalletService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransaction(Peer peer, Transaction t) {
|
||||
// executor.checkOnThread();
|
||||
// TODO: Gate this logic on t being announced by multiple peers.
|
||||
// checkForRevocation(t);
|
||||
// TODO: Watch out for the confirmation. If no confirmation of the revocation occurs within N hours, alert the user.
|
||||
public void onTransaction(Peer peer, Transaction tx) {
|
||||
if (transactionOutPoints.contains(tx))
|
||||
transactionOutPoints.remove(tx);
|
||||
|
||||
if (transactionOutPoints.isEmpty())
|
||||
resultHandler.accept(transaction.getFee());
|
||||
|
||||
log.debug("onTransaction: transaction=" + tx);
|
||||
log.debug("onTransaction: transaction.fee=" + tx.getFee());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
public void findTxInBlockChain(String txId) {
|
||||
// https://groups.google.com/forum/?hl=de#!topic/bitcoinj/kinFP7lLsRE
|
||||
// https://groups.google.com/forum/?hl=de#!topic/bitcoinj/f7m87kCWdb8
|
||||
// https://groups.google.com/forum/?hl=de#!topic/bitcoinj/jNE5ohLExVM
|
||||
walletAppKit.peerGroup().addPeerFilterProvider(new BloomFilterForForeignTx(txId));
|
||||
}*/
|
||||
|
||||
}
|
||||
|
@ -42,7 +42,8 @@ import javafx.beans.property.*;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.SetChangeListener;
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.*;
|
||||
import org.bitcoinj.script.Script;
|
||||
import org.bitcoinj.utils.ExchangeRate;
|
||||
import org.bitcoinj.utils.Fiat;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -84,6 +85,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||
|
||||
final BooleanProperty isWalletFunded = new SimpleBooleanProperty();
|
||||
final BooleanProperty useMBTC = new SimpleBooleanProperty();
|
||||
final BooleanProperty insufficientFee = new SimpleBooleanProperty();
|
||||
|
||||
final ObjectProperty<Coin> amountAsCoin = new SimpleObjectProperty<>();
|
||||
final ObjectProperty<Coin> minAmountAsCoin = new SimpleObjectProperty<>();
|
||||
@ -160,9 +162,43 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||
|
||||
private void addListeners() {
|
||||
walletService.addBalanceListener(balanceListener);
|
||||
walletService.getWallet().addEventListener(new WalletEventListener() {
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
walletService.requestTransactionFromBlockChain(tx, fee -> {
|
||||
if (fee == null || fee.compareTo(FeePolicy.getFeePerKb()) < 0)
|
||||
insufficientFee.set(true);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReorganize(Wallet wallet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWalletChanged(Wallet wallet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScriptsChanged(Wallet wallet, List<Script> scripts, boolean isAddingScripts) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeysAdded(List<ECKey> keys) {
|
||||
}
|
||||
});
|
||||
user.getPaymentAccountsAsObservable().addListener(paymentAccountsChangeListener);
|
||||
}
|
||||
|
||||
|
||||
private void removeListeners() {
|
||||
walletService.removeBalanceListener(balanceListener);
|
||||
user.getPaymentAccountsAsObservable().removeListener(paymentAccountsChangeListener);
|
||||
@ -323,7 +359,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
||||
if (direction == Offer.Direction.BUY)
|
||||
totalToPayAsCoin.set(offerFeeAsCoin.add(networkFeeAsCoin).add(securityDepositAsCoin));
|
||||
else
|
||||
totalToPayAsCoin.set(offerFeeAsCoin.add(networkFeeAsCoin).add(securityDepositAsCoin).add(amountAsCoin.get()));
|
||||
totalToPayAsCoin.set(offerFeeAsCoin.add(networkFeeAsCoin).add(securityDepositAsCoin).add(amountAsCoin.get() == null ? Coin.ZERO : amountAsCoin.get()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ package io.bitsquare.gui.main.offer.createoffer;
|
||||
import de.jensd.fx.fontawesome.AwesomeDude;
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
import io.bitsquare.app.BitsquareApp;
|
||||
import io.bitsquare.btc.FeePolicy;
|
||||
import io.bitsquare.common.util.Tuple2;
|
||||
import io.bitsquare.common.util.Tuple3;
|
||||
import io.bitsquare.gui.Navigation;
|
||||
@ -100,9 +101,10 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
private ChangeListener<String> errorMessageListener;
|
||||
private ChangeListener<Boolean> isPlaceOfferSpinnerVisibleListener;
|
||||
private ChangeListener<Boolean> showTransactionPublishedScreen;
|
||||
private ChangeListener<Boolean> insufficientFeeListener;
|
||||
private EventHandler<ActionEvent> paymentAccountsComboBoxSelectionHandler;
|
||||
private EventHandler<ActionEvent> currencyComboBoxSelectionHandler;
|
||||
|
||||
private EventHandler<ActionEvent> currencyComboBoxSelectionHandler;
|
||||
private int gridRow = 0;
|
||||
|
||||
|
||||
@ -186,7 +188,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
public void onClose() {
|
||||
// we use model.requestPlaceOfferSuccess to not react on close caused by placeOffer
|
||||
if (model.dataModel.isWalletFunded.get() && !model.requestPlaceOfferSuccess.get())
|
||||
new Popup().warning("You have already funds paid in.\nIn the <Funds/Open for withdrawal> section you can withdraw those funds.").show();
|
||||
new Popup().warning("You have already funds paid in.\nIn the \"Funds/Open for withdrawal\" section you can withdraw those funds.").show();
|
||||
}
|
||||
|
||||
public void setCloseHandler(OfferView.CloseHandler closeHandler) {
|
||||
@ -421,6 +423,19 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
placeOfferSpinner.setVisible(newValue);
|
||||
};
|
||||
|
||||
insufficientFeeListener = (observable, oldValue, newValue) -> {
|
||||
if (newValue) {
|
||||
new Popup().warning("You need to use at least a mining fee of " +
|
||||
model.formatCoin(FeePolicy.getFeePerKb()) +
|
||||
".\n\nThe trade transactions might take too much time to be included in " +
|
||||
"a block if the fee is too low.\n" +
|
||||
"Please withdraw the amount you have funded back to your wallet and " +
|
||||
"do a funding again with the correct fee.")
|
||||
.onClose(() -> close())
|
||||
.show();
|
||||
}
|
||||
};
|
||||
|
||||
paymentAccountsComboBoxSelectionHandler = e -> onPaymentAccountsComboBoxSelected();
|
||||
currencyComboBoxSelectionHandler = e -> onCurrencyComboBoxSelected();
|
||||
|
||||
@ -464,6 +479,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
model.showWarningAdjustedVolume.addListener(showWarningAdjustedVolumeListener);
|
||||
model.errorMessage.addListener(errorMessageListener);
|
||||
model.isPlaceOfferSpinnerVisible.addListener(isPlaceOfferSpinnerVisibleListener);
|
||||
model.dataModel.insufficientFee.addListener(insufficientFeeListener);
|
||||
|
||||
model.requestPlaceOfferSuccess.addListener(showTransactionPublishedScreen);
|
||||
|
||||
@ -485,6 +501,7 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||
model.showWarningAdjustedVolume.removeListener(showWarningAdjustedVolumeListener);
|
||||
model.errorMessage.removeListener(errorMessageListener);
|
||||
model.isPlaceOfferSpinnerVisible.removeListener(isPlaceOfferSpinnerVisibleListener);
|
||||
model.dataModel.insufficientFee.removeListener(insufficientFeeListener);
|
||||
|
||||
model.requestPlaceOfferSuccess.removeListener(showTransactionPublishedScreen);
|
||||
|
||||
|
@ -476,6 +476,10 @@ class CreateOfferViewModel extends ActivatableWithDataModel<CreateOfferDataModel
|
||||
return paymentLabel;
|
||||
}
|
||||
|
||||
public String formatCoin(Coin coin) {
|
||||
return formatter.formatCoin(coin);
|
||||
}
|
||||
|
||||
public Offer createAndGetOffer() {
|
||||
offer = dataModel.createAndGetOffer();
|
||||
return offer;
|
||||
|
@ -347,7 +347,7 @@ public class PeerManager implements ConnectionListener, MessageListener {
|
||||
"Reported peers:");
|
||||
reportedPeers.stream().forEach(e -> result.append("\n").append(e));
|
||||
result.append("\n------------------------------------------------------------\n");
|
||||
log.trace(result.toString());
|
||||
//log.trace(result.toString());
|
||||
log.info("Number of reported peers: {}", reportedPeers.size());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user