From 9d9ce5918bcc3967651f4a2a7a6595dccede2779 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 2 Feb 2016 02:39:06 +0100 Subject: [PATCH] Fix nullpointer, add check for miningfee --- .../io/bitsquare/btc/TradeWalletService.java | 14 ---- .../java/io/bitsquare/btc/WalletService.java | 70 ++++++++++++------- .../createoffer/CreateOfferDataModel.java | 40 ++++++++++- .../offer/createoffer/CreateOfferView.java | 21 +++++- .../createoffer/CreateOfferViewModel.java | 4 ++ .../io/bitsquare/p2p/peers/PeerManager.java | 2 +- 6 files changed, 106 insertions(+), 45 deletions(-) diff --git a/core/src/main/java/io/bitsquare/btc/TradeWalletService.java b/core/src/main/java/io/bitsquare/btc/TradeWalletService.java index 14899eb955..9744a35206 100644 --- a/core/src/main/java/io/bitsquare/btc/TradeWalletService.java +++ b/core/src/main/java/io/bitsquare/btc/TradeWalletService.java @@ -1040,18 +1040,4 @@ public class TradeWalletService { throw new WalletException(t); } } - - // not used - /* private Coin getBalance(List 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; - }*/ - } diff --git a/core/src/main/java/io/bitsquare/btc/WalletService.java b/core/src/main/java/io/bitsquare/btc/WalletService.java index 2e65ac3555..d9ef32e138 100644 --- a/core/src/main/java/io/bitsquare/btc/WalletService.java +++ b/core/src/main/java/io/bitsquare/btc/WalletService.java @@ -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> 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 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 resultHandler; + private final Set transactionOutPoints; + + public ArbitraryTransactionBloomFilter(Transaction transaction, Consumer 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)); - }*/ - } diff --git a/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferDataModel.java b/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferDataModel.java index 1d38977a35..1ad0783e5f 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferDataModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/offer/createoffer/CreateOfferDataModel.java @@ -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 amountAsCoin = new SimpleObjectProperty<>(); final ObjectProperty 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