From 205259bee9ea6e010956ea27c26e5637a6dc05da Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 19 Jun 2014 23:58:27 +0200 Subject: [PATCH] separate wallet addresses --- pom.xml | 9 +- .../btc/AddressBasedCoinSelector.java | 146 +++++++ .../java/io/bitsquare/btc/AddressInfo.java | 34 +- .../io/bitsquare/btc/BitSquareWallet.java | 9 +- .../java/io/bitsquare/btc/BtcFormatter.java | 6 + src/main/java/io/bitsquare/btc/FeePolicy.java | 55 +++ src/main/java/io/bitsquare/btc/Fees.java | 15 - .../java/io/bitsquare/btc/ScriptUtil.java | 11 +- .../java/io/bitsquare/btc/WalletFacade.java | 394 ++++++++++++------ .../java/io/bitsquare/di/BitSquareModule.java | 3 + .../java/io/bitsquare/gui/MainController.java | 19 +- .../ArbitratorRegistrationController.java | 6 +- .../io/bitsquare/gui/components/HSpacer.java | 3 + .../gui/components/NoFocusScrollPane.java | 4 + .../io/bitsquare/gui/components/VSpacer.java | 3 + .../bitsquare/gui/funds/FundsController.java | 13 +- .../io/bitsquare/gui/funds/FundsView.fxml | 7 +- .../createOffer/CreateOfferController.java | 9 +- .../market/createOffer/CreateOfferView.fxml | 2 - .../market/orderbook/OrderBookController.java | 119 ++++-- .../market/trade/TakerTradeController.java | 54 ++- .../gui/orders/OrdersController.java | 15 +- .../gui/settings/SettingsController.java | 86 ++-- .../bitsquare/gui/util/ConfidenceDisplay.java | 3 +- .../java/io/bitsquare/locale/CountryUtil.java | 5 +- .../java/io/bitsquare/msg/MessageFacade.java | 4 +- .../java/io/bitsquare/msg/TradeMessage.java | 22 +- src/main/java/io/bitsquare/trade/Offer.java | 10 +- src/main/java/io/bitsquare/trade/Trade.java | 4 +- src/main/java/io/bitsquare/trade/Trading.java | 27 +- .../bitsquare/trade/orderbook/OrderBook.java | 4 +- .../offerer/OffererPaymentProtocol.java | 39 +- .../payment/taker/TakerPaymentProtocol.java | 45 +- .../java/io/bitsquare/user/Arbitrator.java | 3 +- 34 files changed, 822 insertions(+), 366 deletions(-) create mode 100644 src/main/java/io/bitsquare/btc/AddressBasedCoinSelector.java create mode 100644 src/main/java/io/bitsquare/btc/FeePolicy.java delete mode 100644 src/main/java/io/bitsquare/btc/Fees.java diff --git a/pom.xml b/pom.xml index 260105f324..dd67ccd546 100644 --- a/pom.xml +++ b/pom.xml @@ -176,7 +176,14 @@ core 1.50.0.0 - + diff --git a/src/main/java/io/bitsquare/btc/AddressBasedCoinSelector.java b/src/main/java/io/bitsquare/btc/AddressBasedCoinSelector.java new file mode 100644 index 0000000000..ccc1d85ee7 --- /dev/null +++ b/src/main/java/io/bitsquare/btc/AddressBasedCoinSelector.java @@ -0,0 +1,146 @@ +package io.bitsquare.btc; + +import com.google.bitcoin.core.*; +import com.google.bitcoin.params.RegTestParams; +import com.google.bitcoin.wallet.CoinSelection; +import com.google.bitcoin.wallet.DefaultCoinSelector; +import com.google.common.annotations.VisibleForTesting; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; +import java.util.*; + +/** + * This class implements a {@link com.google.bitcoin.wallet.CoinSelector} which attempts to get the highest priority + * possible. This means that the transaction is the most likely to get confirmed. Note that this means we may end up + * "spending" more priority than would be required to get the transaction we are creating confirmed. + */ +public class AddressBasedCoinSelector extends DefaultCoinSelector +{ + private static final Logger log = LoggerFactory.getLogger(AddressBasedCoinSelector.class); + private String tradeUID; + private NetworkParameters params; + private AddressInfo addressInfo; + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor + /////////////////////////////////////////////////////////////////////////////////////////// + + public AddressBasedCoinSelector() + { + + } + + public AddressBasedCoinSelector(NetworkParameters params, AddressInfo addressInfo) + { + this.params = params; + this.addressInfo = addressInfo; + } + + public AddressBasedCoinSelector(String tradeUID) + { + + this.tradeUID = tradeUID; + } + + /** + * Sub-classes can override this to just customize whether transactions are usable, but keep age sorting. + */ + protected boolean shouldSelect(Transaction tx) + { + return isSelectable(tx); + } + + protected boolean matchesRequiredAddress(TransactionOutput transactionOutput) + { + if (!ScriptUtil.isOpReturnScript(transactionOutput)) + { + Address addressOutput = transactionOutput.getScriptPubKey().getToAddress(params); + if (addressInfo != null && addressOutput.equals(addressInfo.getAddress())) + { + return true; + } + } + return false; + } + + public CoinSelection select(BigInteger biTarget, LinkedList candidates) + { + long target = biTarget.longValue(); + HashSet selected = new HashSet(); + // Sort the inputs by age*value so we get the highest "coindays" spent. + // TODO: Consider changing the wallets internal format to track just outputs and keep them ordered. + ArrayList sortedOutputs = new ArrayList(candidates); + // When calculating the wallet balance, we may be asked to select all possible coins, if so, avoid sorting + // them in order to improve performance. + if (!biTarget.equals(NetworkParameters.MAX_MONEY)) + { + sortOutputs(sortedOutputs); + } + // Now iterate over the sorted outputs until we have got as close to the target as possible or a little + // bit over (excessive value will be change). + long total = 0; + for (TransactionOutput output : sortedOutputs) + { + if (total >= target) break; + // Only pick chain-included transactions, or transactions that are ours and pending. + // Only select outputs from our defined address(es) + if (!shouldSelect(output.getParentTransaction()) || !matchesRequiredAddress(output)) + continue; + + selected.add(output); + total += output.getValue().longValue(); + } + // Total may be lower than target here, if the given candidates were insufficient to create to requested + // transaction. + return new CoinSelection(BigInteger.valueOf(total), selected); + } + + @VisibleForTesting + static void sortOutputs(ArrayList outputs) + { + Collections.sort(outputs, new Comparator() + { + public int compare(TransactionOutput a, TransactionOutput b) + { + int depth1 = 0; + int depth2 = 0; + TransactionConfidence conf1 = a.getParentTransaction().getConfidence(); + TransactionConfidence conf2 = b.getParentTransaction().getConfidence(); + if (conf1.getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING) + depth1 = conf1.getDepthInBlocks(); + if (conf2.getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING) + depth2 = conf2.getDepthInBlocks(); + BigInteger aValue = a.getValue(); + BigInteger bValue = b.getValue(); + BigInteger aCoinDepth = aValue.multiply(BigInteger.valueOf(depth1)); + BigInteger bCoinDepth = bValue.multiply(BigInteger.valueOf(depth2)); + int c1 = bCoinDepth.compareTo(aCoinDepth); + if (c1 != 0) return c1; + // The "coin*days" destroyed are equal, sort by value alone to get the lowest transaction size. + int c2 = bValue.compareTo(aValue); + if (c2 != 0) return c2; + // They are entirely equivalent (possibly pending) so sort by hash to ensure a total ordering. + BigInteger aHash = a.getParentTransaction().getHash().toBigInteger(); + BigInteger bHash = b.getParentTransaction().getHash().toBigInteger(); + return aHash.compareTo(bHash); + } + }); + } + + + public static boolean isSelectable(Transaction tx) + { + // Only pick chain-included transactions, or transactions that are ours and pending. + TransactionConfidence confidence = tx.getConfidence(); + TransactionConfidence.ConfidenceType type = confidence.getConfidenceType(); + return type.equals(TransactionConfidence.ConfidenceType.BUILDING) || + + type.equals(TransactionConfidence.ConfidenceType.PENDING) && + confidence.getSource().equals(TransactionConfidence.Source.SELF) && + // In regtest mode we expect to have only one peer, so we won't see transactions propagate. + // TODO: The value 1 below dates from a time when transactions we broadcast *to* were counted, set to 0 + (confidence.numBroadcastPeers() > 1 || tx.getParams() == RegTestParams.get()); + } +} diff --git a/src/main/java/io/bitsquare/btc/AddressInfo.java b/src/main/java/io/bitsquare/btc/AddressInfo.java index 1bd0a5e031..774c083843 100644 --- a/src/main/java/io/bitsquare/btc/AddressInfo.java +++ b/src/main/java/io/bitsquare/btc/AddressInfo.java @@ -5,21 +5,33 @@ import com.google.bitcoin.core.ECKey; import com.google.bitcoin.core.NetworkParameters; import com.google.bitcoin.core.Utils; -import java.beans.Transient; import java.io.Serializable; public class AddressInfo implements Serializable { private static final long serialVersionUID = 5501603992599920416L; + public static enum AddressContext + { + REGISTRATION_FEE, + CREATE_OFFER_FEE, + TAKE_OFFER_FEE, + TRADE, + ARBITRATOR_DEPOSIT + } + private ECKey key; private NetworkParameters params; private String label; + private String tradeId = null; - public AddressInfo(ECKey key, NetworkParameters params, String label) + private AddressContext addressContext; + + public AddressInfo(ECKey key, NetworkParameters params, AddressContext addressContext, String label) { this.key = key; this.params = params; + this.addressContext = addressContext; this.label = label; } @@ -28,11 +40,27 @@ public class AddressInfo implements Serializable this.label = label; } + public void setTradeId(String tradeId) + { + this.tradeId = tradeId; + } + + public String getTradeId() + { + return tradeId; + } + + public String getLabel() { return label; } + public AddressContext getAddressContext() + { + return addressContext; + } + public String getAddressString() { return getAddress().toString(); @@ -43,13 +71,11 @@ public class AddressInfo implements Serializable return Utils.bytesToHexString(key.getPubKey()); } - @Transient public ECKey getKey() { return key; } - @Transient public Address getAddress() { return key.toAddress(params); diff --git a/src/main/java/io/bitsquare/btc/BitSquareWallet.java b/src/main/java/io/bitsquare/btc/BitSquareWallet.java index ec37d081d9..8a4633bf19 100644 --- a/src/main/java/io/bitsquare/btc/BitSquareWallet.java +++ b/src/main/java/io/bitsquare/btc/BitSquareWallet.java @@ -3,12 +3,18 @@ package io.bitsquare.btc; import com.google.bitcoin.core.NetworkParameters; import com.google.bitcoin.core.Wallet; import com.google.bitcoin.crypto.KeyCrypter; +import com.google.bitcoin.wallet.CoinSelector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class BitSquareWallet extends Wallet +import java.io.Serializable; + +public class BitSquareWallet extends Wallet implements Serializable { private static final Logger log = LoggerFactory.getLogger(BitSquareWallet.class); + private static final long serialVersionUID = -6231929674475881549L; + + private transient CoinSelector coinSelector = new AddressBasedCoinSelector(); public BitSquareWallet(NetworkParameters params) { @@ -20,4 +26,5 @@ public class BitSquareWallet extends Wallet super(params, keyCrypter); } + } diff --git a/src/main/java/io/bitsquare/btc/BtcFormatter.java b/src/main/java/io/bitsquare/btc/BtcFormatter.java index 92e2318619..d5aefb6307 100644 --- a/src/main/java/io/bitsquare/btc/BtcFormatter.java +++ b/src/main/java/io/bitsquare/btc/BtcFormatter.java @@ -18,6 +18,12 @@ public class BtcFormatter public static BigInteger BTC = new BigInteger("100000000"); public static BigInteger mBTC = new BigInteger("100000"); + + public static String btcToString(BigInteger value) + { + return Utils.bitcoinValueToFriendlyString(value); + } + //TODO public static double satoshiToBTC(BigInteger satoshis) { diff --git a/src/main/java/io/bitsquare/btc/FeePolicy.java b/src/main/java/io/bitsquare/btc/FeePolicy.java new file mode 100644 index 0000000000..94e77d5aae --- /dev/null +++ b/src/main/java/io/bitsquare/btc/FeePolicy.java @@ -0,0 +1,55 @@ +package io.bitsquare.btc; + +import com.google.bitcoin.core.*; +import com.google.inject.Inject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigInteger; + +public class FeePolicy +{ + private static final Logger log = LoggerFactory.getLogger(FeePolicy.class); + + public static BigInteger TX_FEE = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE; + public static BigInteger ACCOUNT_REGISTRATION_FEE = Utils.toNanoCoins("0.01"); + public static BigInteger CREATE_OFFER_FEE = Utils.toNanoCoins("0.001"); + public static BigInteger TAKE_OFFER_FEE = CREATE_OFFER_FEE; + + private static final String registrationFee = "mvkDXt4QmN4Nq9dRUsRigBCaovde9nLkZR"; + private static final String offerFee = "n2upbsaKAe4PD3cc4JfS7UCqPC5oNd7Ckg"; + + private final NetworkParameters params; + + @Inject + public FeePolicy(NetworkParameters params) + { + this.params = params; + } + + //TODO + public Address getAddressForRegistrationFee() + { + try + { + return new Address(params, registrationFee); + } catch (AddressFormatException e) + { + e.printStackTrace(); + return null; + } + } + + //TODO + public Address getAddressForOfferFee() + { + try + { + return new Address(params, offerFee); + } catch (AddressFormatException e) + { + e.printStackTrace(); + return null; + } + } +} diff --git a/src/main/java/io/bitsquare/btc/Fees.java b/src/main/java/io/bitsquare/btc/Fees.java deleted file mode 100644 index ab790ad798..0000000000 --- a/src/main/java/io/bitsquare/btc/Fees.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.bitsquare.btc; - -import com.google.bitcoin.core.Transaction; -import com.google.bitcoin.core.Utils; - -import java.math.BigInteger; - -public class Fees -{ - // min dust value lead to exception at for non standard to address pay scripts, so we use a value >= 7860 instead - public static BigInteger TX_FEE = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE; - public static BigInteger ACCOUNT_REGISTRATION_FEE = Utils.toNanoCoins("0.01"); - public static BigInteger OFFER_CREATION_FEE = Utils.toNanoCoins("0.001"); - public static BigInteger OFFER_TAKER_FEE = OFFER_CREATION_FEE; -} diff --git a/src/main/java/io/bitsquare/btc/ScriptUtil.java b/src/main/java/io/bitsquare/btc/ScriptUtil.java index 68c28b0d05..440e74a62f 100644 --- a/src/main/java/io/bitsquare/btc/ScriptUtil.java +++ b/src/main/java/io/bitsquare/btc/ScriptUtil.java @@ -9,11 +9,14 @@ import static com.google.bitcoin.script.ScriptOpCodes.OP_RETURN; public class ScriptUtil { - public static Script getEmptyOP_RETURNScript() + public static Script getOpReturnScript() { - return new ScriptBuilder() - .op(OP_RETURN) - .build(); + return new ScriptBuilder().op(OP_RETURN).build(); + } + + public static Script getOpReturnScriptWithData(byte[] data) + { + return new ScriptBuilder().op(OP_RETURN).data(data).build(); } public static boolean isOpReturnScript(TransactionOutput transactionOutput) diff --git a/src/main/java/io/bitsquare/btc/WalletFacade.java b/src/main/java/io/bitsquare/btc/WalletFacade.java index 4d5eb39850..5cdea406be 100644 --- a/src/main/java/io/bitsquare/btc/WalletFacade.java +++ b/src/main/java/io/bitsquare/btc/WalletFacade.java @@ -7,7 +7,10 @@ import com.google.bitcoin.params.RegTestParams; import com.google.bitcoin.script.Script; import com.google.bitcoin.script.ScriptBuilder; import com.google.bitcoin.utils.Threading; +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; @@ -22,12 +25,11 @@ import javafx.util.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nullable; import java.math.BigInteger; import java.util.*; import java.util.concurrent.ExecutionException; -import static com.google.bitcoin.script.ScriptOpCodes.OP_RETURN; - public class WalletFacade { public static final String MAIN_NET = "MAIN_NET"; @@ -40,6 +42,7 @@ public class WalletFacade private NetworkParameters params; private BitSquareWalletAppKit walletAppKit; + private FeePolicy feePolicy; private CryptoFacade cryptoFacade; private Storage storage; private BitSquareWallet wallet; @@ -55,10 +58,11 @@ public class WalletFacade /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public WalletFacade(NetworkParameters params, BitSquareWalletAppKit walletAppKit, CryptoFacade cryptoFacade, Storage storage) + public WalletFacade(NetworkParameters params, BitSquareWalletAppKit walletAppKit, FeePolicy feePolicy, CryptoFacade cryptoFacade, Storage storage) { this.params = params; this.walletAppKit = walletAppKit; + this.feePolicy = feePolicy; this.cryptoFacade = cryptoFacade; this.storage = storage; } @@ -123,6 +127,7 @@ public class WalletFacade @Override public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx) { + log.debug("onTransactionConfidenceChanged " + tx.getConfidence()); notifyConfidenceListeners(tx); } @@ -162,8 +167,14 @@ public class WalletFacade } else { - addressInfoList.add(getRegistrationAddressInfo()); - storage.write("addressInfoList", addressInfoList); + ECKey registrationKey = wallet.getKeys().get(0); + AddressInfo registrationAddressInfo = new AddressInfo(registrationKey, params, AddressInfo.AddressContext.REGISTRATION_FEE, "Registration"); + addressInfoList.add(registrationAddressInfo); + saveAddressInfoList(); + + getNewOfferFeeAddressInfo(); + getNewTakerFeeAddressInfo(); + getNewTradeAddressInfo(); } } @@ -180,6 +191,12 @@ public class WalletFacade return wallet; } + private void saveAddressInfoList() + { + // use wallet extension? + storage.write("addressInfoList", addressInfoList); + } + /////////////////////////////////////////////////////////////////////////////////////////// // Listener @@ -250,7 +267,7 @@ public class WalletFacade Address address = transactionOutput.getScriptPubKey().getToAddress(params); if (address.equals(balanceListener.getAddress())) { - balanceListener.onBalanceChanged(getBalance(address)); + balanceListener.onBalanceChanged(getBalanceForAddress(address)); } } } @@ -259,7 +276,7 @@ public class WalletFacade /////////////////////////////////////////////////////////////////////////////////////////// - // Address management + // Get AddressInfo objects /////////////////////////////////////////////////////////////////////////////////////////// public List getAddressInfoList() @@ -269,26 +286,123 @@ public class WalletFacade public AddressInfo getRegistrationAddressInfo() { - ECKey registrationKey = wallet.getKeys().get(0); - return new AddressInfo(registrationKey, params, "Registration"); + return getAddressInfoByAddressContext(AddressInfo.AddressContext.REGISTRATION_FEE); } - public AddressInfo getNewAddressInfo(String label) + public AddressInfo getCreateOfferFeeAddressInfo() { - ECKey key = new ECKey(); - wallet.addKey(key); - AddressInfo addressInfo = new AddressInfo(key, params, label); - addressInfoList.add(addressInfo); - storage.write("addressInfoList", addressInfoList); + return getAddressInfoByAddressContext(AddressInfo.AddressContext.CREATE_OFFER_FEE); + } + + public AddressInfo getTakerFeeAddressInfo() + { + return getAddressInfoByAddressContext(AddressInfo.AddressContext.TAKE_OFFER_FEE); + } + + public AddressInfo getArbitratorDepositAddressInfo() + { + AddressInfo arbitratorDepositAddressInfo = getAddressInfoByAddressContext(AddressInfo.AddressContext.ARBITRATOR_DEPOSIT); + if (arbitratorDepositAddressInfo == null) + arbitratorDepositAddressInfo = getNewArbitratorDepositAddressInfo(); + + return arbitratorDepositAddressInfo; + } + + private AddressInfo getUnusedTradeAddressInfo() + { + if (addressInfoList != null) + { + List filteredList = Lists.newArrayList(Collections2.filter(addressInfoList, new Predicate() + { + @Override + public boolean apply(@Nullable AddressInfo addressInfo) + { + return (addressInfo != null && addressInfo.getAddressContext().equals(AddressInfo.AddressContext.TRADE) && addressInfo.getTradeId() == null); + } + })); + + if (filteredList != null && filteredList.size() > 0) + return filteredList.get(0); + else + return null; + } + return null; + } + + private AddressInfo getAddressInfoByAddressContext(AddressInfo.AddressContext addressContext) + { + if (addressInfoList != null) + { + List filteredList = Lists.newArrayList(Collections2.filter(addressInfoList, new Predicate() + { + @Override + public boolean apply(@Nullable AddressInfo addressInfo) + { + return (addressInfo != null && addressContext != null && addressInfo.getAddressContext() != null && addressInfo.getAddressContext().equals(addressContext)); + } + })); + + if (filteredList != null && filteredList.size() > 0) + return filteredList.get(0); + else + return null; + } + return null; + } + + public AddressInfo getAddressInfoByTradeID(String tradeId) + { + for (AddressInfo addressInfo : addressInfoList) + { + if (addressInfo.getTradeId() != null && addressInfo.getTradeId().equals(tradeId)) + return addressInfo; + } + + AddressInfo addressInfo = getUnusedTradeAddressInfo(); + addressInfo.setTradeId(tradeId); return addressInfo; } - public AddressInfo getNewArbitratorAddressInfo() + /////////////////////////////////////////////////////////////////////////////////////////// + // Create new AddressInfo objects + /////////////////////////////////////////////////////////////////////////////////////////// + + public AddressInfo getNewTradeAddressInfo() { - return getNewAddressInfo("Arbitrator deposit"); + return getNewAddressInfo(AddressInfo.AddressContext.TRADE, "New trade"); } - public TransactionConfidence getConfidence(Address address) + private AddressInfo getNewAddressInfo(AddressInfo.AddressContext addressContext, String label) + { + ECKey key = new ECKey(); + wallet.addKey(key); + AddressInfo addressInfo = new AddressInfo(key, params, addressContext, label); + addressInfoList.add(addressInfo); + saveAddressInfoList(); + return addressInfo; + } + + private AddressInfo getNewOfferFeeAddressInfo() + { + return getNewAddressInfo(AddressInfo.AddressContext.CREATE_OFFER_FEE, "Create offer fee"); + } + + private AddressInfo getNewTakerFeeAddressInfo() + { + return getNewAddressInfo(AddressInfo.AddressContext.TAKE_OFFER_FEE, "Take offer fee"); + } + + private AddressInfo getNewArbitratorDepositAddressInfo() + { + return getNewAddressInfo(AddressInfo.AddressContext.ARBITRATOR_DEPOSIT, "Arbitrator deposit"); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // TransactionConfidence + /////////////////////////////////////////////////////////////////////////////////////////// + + public TransactionConfidence getConfidenceForAddress(Address address) { Set transactions = wallet.getTransactions(true); if (transactions != null) @@ -317,7 +431,12 @@ public class WalletFacade return null; } - public BigInteger getBalance(Address address) + + /////////////////////////////////////////////////////////////////////////////////////////// + // Balance + /////////////////////////////////////////////////////////////////////////////////////////// + + public BigInteger getBalanceForAddress(Address address) { LinkedList all = wallet.calculateAllSpendCandidates(false); BigInteger value = BigInteger.ZERO; @@ -342,103 +461,21 @@ public class WalletFacade public BigInteger getRegistrationBalance() { - return getBalance(getRegistrationAddressInfo().getAddress()); + return getBalanceForAddress(getRegistrationAddressInfo().getAddress()); } - public ECKey getRegistrationKey() + public BigInteger getArbitratorDepositBalance() { - return getRegistrationAddressInfo().getKey(); + return getBalanceForAddress(getArbitratorDepositAddressInfo().getAddress()); } + /////////////////////////////////////////////////////////////////////////////////////////// + // TODO + /////////////////////////////////////////////////////////////////////////////////////////// + + //TODO - public String getTradingAddress() - { - return getTradingKey().toAddress(params).toString(); - } - - //TODO - public String getPubKeyAsHex() - { - return Utils.bytesToHexString(getTradingKey().getPubKey()); - } - - //TODO - public ECKey getTradingKey() - { - return wallet.getKeys().get(1); - } - - - //TODO separate wallets - public BigInteger getCollateralBalance() - { - return wallet.getBalance(Wallet.BalanceType.ESTIMATED); - } - - /////////////////////////////////////////////////////////////////////////////////////////// - // Account registration - /////////////////////////////////////////////////////////////////////////////////////////// - - public void publishRegistrationTxWithExtraData(String stringifiedBankAccounts) throws InsufficientMoneyException - { - log.debug("publishRegistrationTxWithExtraData"); - log.trace("inputs: "); - log.trace("stringifiedBankAccounts " + stringifiedBankAccounts); - byte[] dataToEmbed = cryptoFacade.getEmbeddedAccountRegistrationData(getRegistrationKey(), stringifiedBankAccounts); - Script script = new ScriptBuilder().op(OP_RETURN).data(dataToEmbed).build(); - Transaction tx = new Transaction(params); - TransactionOutput dataOutput = new TransactionOutput(params, tx, Transaction.MIN_NONDUST_OUTPUT, script.getProgram()); - tx.addOutput(dataOutput); - Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx); - - // give fee to miners yet. Later it could be spent to other traders via lottery... - sendRequest.fee = Fees.ACCOUNT_REGISTRATION_FEE.subtract(Transaction.MIN_NONDUST_OUTPUT).subtract(Fees.TX_FEE); - log.trace("sendRequest.fee: " + Utils.bitcoinValueToFriendlyString(sendRequest.fee)); - Wallet.SendResult sendResult = wallet.sendCoins(sendRequest); - log.debug("Registration transaction: " + tx.toString()); - printInputs("publishRegistrationTxWithExtraData", tx); - Futures.addCallback(sendResult.broadcastComplete, new FutureCallback() - { - @Override - public void onSuccess(Transaction result) - { - log.debug("sendResult onSuccess"); - } - - @Override - public void onFailure(Throwable t) - { - log.error("sendResult onFailure:" + t.toString()); - } - }); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Trade process - /////////////////////////////////////////////////////////////////////////////////////////// - - //TODO refactor to similar solution like in PaymentChannelServerState - - public String payOfferFee(BigInteger fee, FutureCallback callback) throws InsufficientMoneyException - { - log.debug("payOfferFee fee=" + Utils.bitcoinValueToFriendlyString(fee)); - Transaction tx = new Transaction(params); - tx.addOutput(Transaction.MIN_NONDUST_OUTPUT, ScriptUtil.getEmptyOP_RETURNScript()); - Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx); - - sendRequest.fee = fee.subtract(Transaction.MIN_NONDUST_OUTPUT).subtract(Fees.TX_FEE); - - Wallet.SendResult sendResult = wallet.sendCoins(sendRequest); - Futures.addCallback(sendResult.broadcastComplete, callback); - - log.debug("Check if wallet is consistent: result=" + wallet.isConsistent()); - printInputs("payOfferFee", tx); - log.debug("tx=" + tx.toString()); - return tx.getHashAsString(); - } - public int getNumOfPeersSeenTx(String txID) { // TODO check from blockchain @@ -447,13 +484,84 @@ public class WalletFacade } + /////////////////////////////////////////////////////////////////////////////////////////// + // Transactions + /////////////////////////////////////////////////////////////////////////////////////////// + + public void payRegistrationFee(String stringifiedBankAccounts, FutureCallback callback) throws InsufficientMoneyException + { + log.debug("payRegistrationFee"); + log.trace("stringifiedBankAccounts " + stringifiedBankAccounts); + + Transaction tx = new Transaction(params); + + byte[] dataToEmbed = cryptoFacade.getEmbeddedAccountRegistrationData(getRegistrationAddressInfo().getKey(), stringifiedBankAccounts); + tx.addOutput(Transaction.MIN_NONDUST_OUTPUT, ScriptUtil.getOpReturnScriptWithData(dataToEmbed)); + + BigInteger fee = FeePolicy.ACCOUNT_REGISTRATION_FEE.subtract(Transaction.MIN_NONDUST_OUTPUT).subtract(FeePolicy.TX_FEE); + log.trace("fee: " + BtcFormatter.btcToString(fee)); + tx.addOutput(fee, feePolicy.getAddressForRegistrationFee()); + + Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx); + sendRequest.coinSelector = new AddressBasedCoinSelector(params, getRegistrationAddressInfo()); + sendRequest.changeAddress = getRegistrationAddressInfo().getAddress(); + Wallet.SendResult sendResult = wallet.sendCoins(sendRequest); + Futures.addCallback(sendResult.broadcastComplete, callback); + + log.debug("Registration transaction: " + tx.toString()); + printInputs("payRegistrationFee", tx); + } + + public String payCreateOfferFee(FutureCallback callback) throws InsufficientMoneyException + { + Transaction tx = new Transaction(params); + BigInteger fee = FeePolicy.CREATE_OFFER_FEE.subtract(FeePolicy.TX_FEE); + log.trace("fee: " + BtcFormatter.btcToString(fee)); + tx.addOutput(fee, feePolicy.getAddressForOfferFee()); + + Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx); + sendRequest.coinSelector = new AddressBasedCoinSelector(params, getCreateOfferFeeAddressInfo()); + sendRequest.changeAddress = getCreateOfferFeeAddressInfo().getAddress(); + Wallet.SendResult sendResult = wallet.sendCoins(sendRequest); + Futures.addCallback(sendResult.broadcastComplete, callback); + + printInputs("payTakeOfferFee", tx); + log.debug("tx=" + tx.toString()); + + return tx.getHashAsString(); + } + + public String payTakeOfferFee(FutureCallback callback) throws InsufficientMoneyException + { + Transaction tx = new Transaction(params); + BigInteger fee = FeePolicy.TAKE_OFFER_FEE.subtract(FeePolicy.TX_FEE); + log.trace("fee: " + BtcFormatter.btcToString(fee)); + tx.addOutput(fee, feePolicy.getAddressForOfferFee()); + + Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx); + sendRequest.coinSelector = new AddressBasedCoinSelector(params, getTakerFeeAddressInfo()); + sendRequest.changeAddress = getTakerFeeAddressInfo().getAddress(); + Wallet.SendResult sendResult = wallet.sendCoins(sendRequest); + Futures.addCallback(sendResult.broadcastComplete, callback); + + printInputs("payTakeOfferFee", tx); + log.debug("tx=" + tx.toString()); + + return tx.getHashAsString(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Trade process + /////////////////////////////////////////////////////////////////////////////////////////// + // 1. step: deposit tx // Offerer creates the 2of3 multiSig deposit tx with his unsigned input and change output - public Transaction offererCreatesMSTxAndAddPayment(BigInteger offererInputAmount, String offererPubKey, String takerPubKey, String arbitratorPubKey) throws InsufficientMoneyException + public Transaction offererCreatesMSTxAndAddPayment(BigInteger offererInputAmount, String offererPubKey, String takerPubKey, String arbitratorPubKey, String tradeId) throws InsufficientMoneyException { log.debug("offererCreatesMSTxAndAddPayment"); log.trace("inputs: "); - log.trace("offererInputAmount=" + Utils.bitcoinValueToFriendlyString(offererInputAmount)); + log.trace("offererInputAmount=" + BtcFormatter.btcToString(offererInputAmount)); log.trace("offererPubKey=" + offererPubKey); log.trace("takerPubKey=" + takerPubKey); log.trace("arbitratorPubKey=" + arbitratorPubKey); @@ -467,7 +575,13 @@ public class WalletFacade Transaction tx = new Transaction(params); Script multiSigOutputScript = getMultiSigScript(offererPubKey, takerPubKey, arbitratorPubKey); tx.addOutput(offererInputAmount, multiSigOutputScript); - wallet.completeTx(Wallet.SendRequest.forTx(tx)); + + Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx); + AddressInfo addressInfo = getAddressInfoByTradeID(tradeId); + addressInfo.setTradeId(tradeId); + sendRequest.coinSelector = new AddressBasedCoinSelector(params, addressInfo); + sendRequest.changeAddress = addressInfo.getAddress(); + wallet.completeTx(sendRequest); // The completeTx() call signs the input, but we don't want to pass over a signed tx so we remove the // signature to make sure the tx is invalid for publishing @@ -497,13 +611,14 @@ public class WalletFacade String offererPubKey, String takerPubKey, String arbitratorPubKey, - String offerersPartialDepositTxAsHex + String offerersPartialDepositTxAsHex, + String tradeId ) throws InsufficientMoneyException, ExecutionException, InterruptedException, AddressFormatException { log.debug("takerAddPaymentAndSignTx"); log.trace("inputs: "); - log.trace("takerInputAmount=" + Utils.bitcoinValueToFriendlyString(takerInputAmount)); - log.trace("msOutputAmount=" + Utils.bitcoinValueToFriendlyString(msOutputAmount)); + log.trace("takerInputAmount=" + BtcFormatter.btcToString(takerInputAmount)); + log.trace("msOutputAmount=" + BtcFormatter.btcToString(msOutputAmount)); log.trace("offererPubKey=" + offererPubKey); log.trace("takerPubKey=" + takerPubKey); log.trace("arbitratorPubKey=" + arbitratorPubKey); @@ -518,7 +633,14 @@ public class WalletFacade Transaction tempTx = new Transaction(params); Script multiSigOutputScript = getMultiSigScript(offererPubKey, takerPubKey, arbitratorPubKey); tempTx.addOutput(takerInputAmount, multiSigOutputScript); - wallet.completeTx(Wallet.SendRequest.forTx(tempTx)); + + Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tempTx); + AddressInfo addressInfo = getAddressInfoByTradeID(tradeId); + addressInfo.setTradeId(tradeId); + sendRequest.coinSelector = new AddressBasedCoinSelector(params, addressInfo); + sendRequest.changeAddress = addressInfo.getAddress(); + wallet.completeTx(sendRequest); + printInputs("tempTx", tempTx); log.trace("tempTx=" + tempTx); // That tx has signed input, but we don't need to remove it as we don't send that tx out, it is just used temporary. @@ -550,7 +672,7 @@ public class WalletFacade tx.addOutput(tempTx.getOutput(1)); // We add the btc tx fee to the msOutputAmount and apply the change to the multiSig output - msOutputAmount = msOutputAmount.add(Fees.TX_FEE); + msOutputAmount = msOutputAmount.add(FeePolicy.TX_FEE); tx.getOutput(0).setValue(msOutputAmount); // Now we sign our input @@ -602,6 +724,8 @@ public class WalletFacade String takersSignedTxAsHex, String takersSignedConnOutAsHex, String takersSignedScriptSigAsHex, + long offererTxOutIndex, + long takerTxOutIndex, FutureCallback callback) throws Exception { log.debug("offererSignAndPublishTx"); @@ -624,9 +748,9 @@ public class WalletFacade // add input Transaction offerersFirstTxConnOut = wallet.getTransaction(offerersFirstTx.getInput(0).getOutpoint().getHash()); // pass that around! - TransactionOutPoint offerersFirstTxOutPoint = new TransactionOutPoint(params, 1, offerersFirstTxConnOut); + TransactionOutPoint offerersFirstTxOutPoint = new TransactionOutPoint(params, offererTxOutIndex, offerersFirstTxConnOut); //TransactionInput offerersFirstTxInput = new TransactionInput(params, tx, offerersFirstTx.getInput(0).getScriptBytes(), offerersFirstTxOutPoint); // pass that around! getScriptBytes = empty bytes aray - TransactionInput offerersFirstTxInput = new TransactionInput(params, tx, new byte[]{}, offerersFirstTxOutPoint); // pass that around! getScriptBytes = empty bytes aray + TransactionInput offerersFirstTxInput = new TransactionInput(params, tx, new byte[]{}, offerersFirstTxOutPoint); // pass that around! getScriptBytes = empty bytes array offerersFirstTxInput.setParent(tx); tx.addInput(offerersFirstTxInput); @@ -638,7 +762,7 @@ public class WalletFacade // add input Transaction takersSignedTxConnOut = new Transaction(params, Utils.parseAsHexOrBase58(takersSignedConnOutAsHex)); - TransactionOutPoint takersSignedTxOutPoint = new TransactionOutPoint(params, 1, takersSignedTxConnOut); + TransactionOutPoint takersSignedTxOutPoint = new TransactionOutPoint(params, takerTxOutIndex, takersSignedTxConnOut); TransactionInput takersSignedTxInput = new TransactionInput(params, tx, Utils.parseAsHexOrBase58(takersSignedScriptSigAsHex), takersSignedTxOutPoint); takersSignedTxInput.setParent(tx); tx.addInput(takersSignedTxInput); @@ -672,13 +796,13 @@ public class WalletFacade else throw new ScriptException("Don't know how to sign for this kind of scriptPubKey: " + scriptPubKey); - log.trace("check if it can be correctly spent for input 0"); input.getScriptSig().correctlySpends(tx, 0, scriptPubKey, false); + log.trace("check if it can be correctly spent for input 0 OK"); - log.trace("check if it can be correctly spent for input 1"); TransactionInput input1 = tx.getInput(1); scriptPubKey = input1.getConnectedOutput().getScriptPubKey(); input1.getScriptSig().correctlySpends(tx, 1, scriptPubKey, false); + log.trace("check if it can be correctly spent for input 1 OK"); /* IN[0] offerer signed 0.1001 @@ -736,13 +860,14 @@ public class WalletFacade public Pair offererCreatesAndSignsPayoutTx(String depositTxID, BigInteger offererPaybackAmount, BigInteger takerPaybackAmount, - String takerAddress) throws InsufficientMoneyException, AddressFormatException + String takerAddress, + String tradeID) throws InsufficientMoneyException, AddressFormatException { log.debug("offererCreatesAndSignsPayoutTx"); log.trace("inputs: "); log.trace("depositTxID=" + depositTxID); - log.trace("offererPaybackAmount=" + Utils.bitcoinValueToFriendlyString(offererPaybackAmount)); - log.trace("takerPaybackAmount=" + Utils.bitcoinValueToFriendlyString(takerPaybackAmount)); + log.trace("offererPaybackAmount=" + BtcFormatter.btcToString(offererPaybackAmount)); + log.trace("takerPaybackAmount=" + BtcFormatter.btcToString(takerPaybackAmount)); log.trace("takerAddress=" + takerAddress); // Offerer has published depositTx earlier, so he has it in his wallet @@ -750,13 +875,13 @@ public class WalletFacade String depositTxAsHex = Utils.bytesToHexString(depositTx.bitcoinSerialize()); // We create the payout tx - Transaction tx = createPayoutTx(depositTxAsHex, offererPaybackAmount, takerPaybackAmount, getTradingAddress(), takerAddress); + Transaction tx = createPayoutTx(depositTxAsHex, offererPaybackAmount, takerPaybackAmount, getAddressInfoByTradeID(tradeID).getAddressString(), takerAddress); // We create the signature for that tx TransactionOutput multiSigOutput = tx.getInput(0).getConnectedOutput(); Script multiSigScript = multiSigOutput.getScriptPubKey(); Sha256Hash sigHash = tx.hashForSignature(0, multiSigScript, Transaction.SigHash.ALL, false); - ECKey.ECDSASignature offererSignature = getTradingKey().sign(sigHash); + ECKey.ECDSASignature offererSignature = getAddressInfoByTradeID(tradeID).getKey().sign(sigHash); TransactionSignature offererTxSig = new TransactionSignature(offererSignature, Transaction.SigHash.ALL, false); Script inputScript = ScriptBuilder.createMultiSigInputScript(ImmutableList.of(offererTxSig)); @@ -773,6 +898,7 @@ public class WalletFacade BigInteger offererPaybackAmount, BigInteger takerPaybackAmount, String offererAddress, + String tradeID, FutureCallback callback) throws InsufficientMoneyException, AddressFormatException { log.debug("takerSignsAndSendsTx"); @@ -780,13 +906,13 @@ public class WalletFacade log.trace("depositTxAsHex=" + depositTxAsHex); log.trace("offererSignatureR=" + offererSignatureR); log.trace("offererSignatureS=" + offererSignatureS); - log.trace("offererPaybackAmount=" + Utils.bitcoinValueToFriendlyString(offererPaybackAmount)); - log.trace("takerPaybackAmount=" + Utils.bitcoinValueToFriendlyString(takerPaybackAmount)); + log.trace("offererPaybackAmount=" + BtcFormatter.btcToString(offererPaybackAmount)); + log.trace("takerPaybackAmount=" + BtcFormatter.btcToString(takerPaybackAmount)); log.trace("offererAddress=" + offererAddress); log.trace("callback=" + callback.toString()); // We create the payout tx - Transaction tx = createPayoutTx(depositTxAsHex, offererPaybackAmount, takerPaybackAmount, offererAddress, getTradingAddress()); + Transaction tx = createPayoutTx(depositTxAsHex, offererPaybackAmount, takerPaybackAmount, offererAddress, getAddressInfoByTradeID(tradeID).getAddressString()); // We sign that tx with our key and apply the signature form the offerer TransactionOutput multiSigOutput = tx.getInput(0).getConnectedOutput(); @@ -794,7 +920,7 @@ public class WalletFacade Sha256Hash sigHash = tx.hashForSignature(0, multiSigScript, Transaction.SigHash.ALL, false); log.trace("sigHash=" + sigHash.toString()); - ECKey.ECDSASignature takerSignature = getTradingKey().sign(sigHash); + ECKey.ECDSASignature takerSignature = getAddressInfoByTradeID(tradeID).getKey().sign(sigHash); TransactionSignature takerTxSig = new TransactionSignature(takerSignature, Transaction.SigHash.ALL, false); ECKey.ECDSASignature offererSignature = new ECKey.ECDSASignature(new BigInteger(offererSignatureR), new BigInteger(offererSignatureS)); @@ -846,8 +972,8 @@ public class WalletFacade log.trace("createPayoutTx"); log.trace("inputs: "); log.trace("depositTxAsHex=" + depositTxAsHex); - log.trace("offererPaybackAmount=" + Utils.bitcoinValueToFriendlyString(offererPaybackAmount)); - log.trace("takerPaybackAmount=" + Utils.bitcoinValueToFriendlyString(takerPaybackAmount)); + log.trace("offererPaybackAmount=" + BtcFormatter.btcToString(offererPaybackAmount)); + log.trace("takerPaybackAmount=" + BtcFormatter.btcToString(takerPaybackAmount)); log.trace("offererAddress=" + offererAddress); log.trace("takerAddress=" + takerAddress); @@ -865,7 +991,7 @@ public class WalletFacade { for (TransactionInput input : tx.getInputs()) if (input.getConnectedOutput() != null) - log.trace(tracePrefix + ": " + Utils.bitcoinValueToFriendlyString(input.getConnectedOutput().getValue())); + log.trace(tracePrefix + ": " + BtcFormatter.btcToString(input.getConnectedOutput().getValue())); else log.trace(tracePrefix + ": " + "Transaction already has inputs but we don't have the connected outputs, so we don't know the value."); } diff --git a/src/main/java/io/bitsquare/di/BitSquareModule.java b/src/main/java/io/bitsquare/di/BitSquareModule.java index e109fcb51e..d89a8fbde7 100644 --- a/src/main/java/io/bitsquare/di/BitSquareModule.java +++ b/src/main/java/io/bitsquare/di/BitSquareModule.java @@ -12,6 +12,7 @@ import com.google.inject.name.Named; import com.google.inject.name.Names; import io.bitsquare.btc.BitSquareWalletAppKit; import io.bitsquare.btc.BlockChainFacade; +import io.bitsquare.btc.FeePolicy; import io.bitsquare.btc.WalletFacade; import io.bitsquare.crypto.CryptoFacade; import io.bitsquare.msg.MessageFacade; @@ -39,6 +40,8 @@ public class BitSquareModule extends AbstractModule bind(CryptoFacade.class).asEagerSingleton(); bind(WalletFacade.class).asEagerSingleton(); + bind(FeePolicy.class).asEagerSingleton(); + bind(BlockChainFacade.class).asEagerSingleton(); bind(MessageFacade.class).asEagerSingleton(); diff --git a/src/main/java/io/bitsquare/gui/MainController.java b/src/main/java/io/bitsquare/gui/MainController.java index fbc47ce6c4..021772d546 100644 --- a/src/main/java/io/bitsquare/gui/MainController.java +++ b/src/main/java/io/bitsquare/gui/MainController.java @@ -1,6 +1,9 @@ package io.bitsquare.gui; -import com.google.bitcoin.core.*; +import com.google.bitcoin.core.ECKey; +import com.google.bitcoin.core.Transaction; +import com.google.bitcoin.core.Wallet; +import com.google.bitcoin.core.WalletEventListener; import com.google.bitcoin.script.Script; import com.google.inject.Inject; import io.bitsquare.bank.BankAccount; @@ -123,8 +126,8 @@ public class MainController implements Initializable, NavigationController //homeButton.fire(); //settingsButton.fire(); - fundsButton.fire(); - // sellButton.fire(); + //fundsButton.fire(); + sellButton.fire(); // ordersButton.fire(); // homeButton.fire(); // msgButton.fire(); @@ -334,31 +337,31 @@ public class MainController implements Initializable, NavigationController vBox.getChildren().setAll(hBox, titleLabel); parent.getChildren().add(vBox); - balanceTextField.setText(Utils.bitcoinValueToFriendlyString(walletFacade.getWalletBalance())); + balanceTextField.setText(BtcFormatter.btcToString(walletFacade.getWalletBalance())); walletFacade.getWallet().addEventListener(new WalletEventListener() { @Override public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) { - balanceTextField.setText(Utils.bitcoinValueToFriendlyString(newBalance)); + balanceTextField.setText(BtcFormatter.btcToString(newBalance)); } @Override public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx) { - balanceTextField.setText(Utils.bitcoinValueToFriendlyString(walletFacade.getWallet().getBalance())); + balanceTextField.setText(BtcFormatter.btcToString(walletFacade.getWallet().getBalance())); } @Override public void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) { - balanceTextField.setText(Utils.bitcoinValueToFriendlyString(newBalance)); + balanceTextField.setText(BtcFormatter.btcToString(newBalance)); } @Override public void onReorganize(Wallet wallet) { - balanceTextField.setText(Utils.bitcoinValueToFriendlyString(walletFacade.getWallet().getBalance())); + balanceTextField.setText(BtcFormatter.btcToString(walletFacade.getWallet().getBalance())); } @Override diff --git a/src/main/java/io/bitsquare/gui/arbitrators/registration/ArbitratorRegistrationController.java b/src/main/java/io/bitsquare/gui/arbitrators/registration/ArbitratorRegistrationController.java index 53672f065e..a71260c47a 100644 --- a/src/main/java/io/bitsquare/gui/arbitrators/registration/ArbitratorRegistrationController.java +++ b/src/main/java/io/bitsquare/gui/arbitrators/registration/ArbitratorRegistrationController.java @@ -371,8 +371,8 @@ public class ArbitratorRegistrationController implements Initializable, ChildCon }); confidenceDisplay = new ConfidenceDisplay(walletFacade.getWallet(), confirmationLabel, balanceTextField, progressIndicator); - paymentDoneButton.setDisable(walletFacade.getCollateralBalance().compareTo(BigInteger.ZERO) == 0); - log.debug("getCollateralBalance " + walletFacade.getCollateralBalance().toString()); + paymentDoneButton.setDisable(walletFacade.getArbitratorDepositBalance().compareTo(BigInteger.ZERO) == 0); + log.debug("getArbitratorDepositBalance " + walletFacade.getArbitratorDepositBalance().toString()); walletFacade.getWallet().addEventListener(new WalletEventListener() { @Override @@ -464,7 +464,7 @@ public class ArbitratorRegistrationController implements Initializable, ChildCon BitSquareValidator.resetTextFields(hasDoubleValueTextFields); BitSquareValidator.textFieldsHasDoubleValue(hasDoubleValueTextFields); - String pubKeyAsHex = walletFacade.getNewArbitratorAddressInfo().getPubKeyAsHexString(); + String pubKeyAsHex = walletFacade.getArbitratorDepositAddressInfo().getPubKeyAsHexString(); String messagePubKeyAsHex = DSAKeyUtil.getHexStringFromPublicKey(messageFacade.getPubKey()); String name = nameTextField.getText(); diff --git a/src/main/java/io/bitsquare/gui/components/HSpacer.java b/src/main/java/io/bitsquare/gui/components/HSpacer.java index 43a93fc542..479e51002e 100644 --- a/src/main/java/io/bitsquare/gui/components/HSpacer.java +++ b/src/main/java/io/bitsquare/gui/components/HSpacer.java @@ -5,6 +5,9 @@ import javafx.scene.layout.Pane; public class HSpacer extends Pane { + public HSpacer() + { + } public HSpacer(double width) { diff --git a/src/main/java/io/bitsquare/gui/components/NoFocusScrollPane.java b/src/main/java/io/bitsquare/gui/components/NoFocusScrollPane.java index b32695d188..59251ae266 100644 --- a/src/main/java/io/bitsquare/gui/components/NoFocusScrollPane.java +++ b/src/main/java/io/bitsquare/gui/components/NoFocusScrollPane.java @@ -4,6 +4,10 @@ import javafx.scene.control.ScrollPane; public class NoFocusScrollPane extends ScrollPane { + public NoFocusScrollPane() + { + } + public void requestFocus() { // prevent focus diff --git a/src/main/java/io/bitsquare/gui/components/VSpacer.java b/src/main/java/io/bitsquare/gui/components/VSpacer.java index b7b2b6624e..d0dc7f339a 100644 --- a/src/main/java/io/bitsquare/gui/components/VSpacer.java +++ b/src/main/java/io/bitsquare/gui/components/VSpacer.java @@ -5,6 +5,9 @@ import javafx.scene.layout.Pane; public class VSpacer extends Pane { + public VSpacer() + { + } public VSpacer(double height) { diff --git a/src/main/java/io/bitsquare/gui/funds/FundsController.java b/src/main/java/io/bitsquare/gui/funds/FundsController.java index 2397a38071..96c45c6cd4 100644 --- a/src/main/java/io/bitsquare/gui/funds/FundsController.java +++ b/src/main/java/io/bitsquare/gui/funds/FundsController.java @@ -1,11 +1,11 @@ package io.bitsquare.gui.funds; import com.google.bitcoin.core.TransactionConfidence; -import com.google.bitcoin.core.Utils; import com.google.inject.Inject; import de.jensd.fx.fontawesome.AwesomeDude; import de.jensd.fx.fontawesome.AwesomeIcon; import io.bitsquare.btc.AddressInfo; +import io.bitsquare.btc.BtcFormatter; import io.bitsquare.btc.WalletFacade; import io.bitsquare.btc.listeners.BalanceListener; import io.bitsquare.btc.listeners.ConfidenceListener; @@ -31,7 +31,6 @@ import java.net.URL; import java.util.List; import java.util.ResourceBundle; - public class FundsController implements Initializable, ChildController { private static final Logger log = LoggerFactory.getLogger(FundsController.class); @@ -105,9 +104,9 @@ public class FundsController implements Initializable, ChildController /////////////////////////////////////////////////////////////////////////////////////////// @FXML - public void onAddNewAddress(ActionEvent actionEvent) + public void onAddNewTradeAddress(ActionEvent actionEvent) { - AddressInfo addressInfo = walletFacade.getNewAddressInfo("New address"); + AddressInfo addressInfo = walletFacade.getNewTradeAddressInfo(); addressList.add(new AddressListItem(addressInfo.getLabel(), addressInfo.getAddress(), false)); } @@ -147,7 +146,7 @@ public class FundsController implements Initializable, ChildController } }); - updateBalance(walletFacade.getBalance(item.getAddress()), balanceLabel); + updateBalance(walletFacade.getBalanceForAddress(item.getAddress()), balanceLabel); setGraphic(balanceLabel); } else @@ -243,7 +242,7 @@ public class FundsController implements Initializable, ChildController } }); - updateConfidence(walletFacade.getConfidence(item.getAddress()), progressIndicator, tooltip); + updateConfidence(walletFacade.getConfidenceForAddress(item.getAddress()), progressIndicator, tooltip); setGraphic(progressIndicator); } else @@ -262,7 +261,7 @@ public class FundsController implements Initializable, ChildController private void updateBalance(BigInteger balance, Label balanceLabel) { if (balance != null) - balanceLabel.setText(Utils.bitcoinValueToFriendlyString(balance)); + balanceLabel.setText(BtcFormatter.btcToString(balance)); } private void updateConfidence(TransactionConfidence confidence, ConfidenceProgressIndicator progressIndicator, Tooltip tooltip) diff --git a/src/main/java/io/bitsquare/gui/funds/FundsView.fxml b/src/main/java/io/bitsquare/gui/funds/FundsView.fxml index 58e5b93368..f1c4d26fcf 100644 --- a/src/main/java/io/bitsquare/gui/funds/FundsView.fxml +++ b/src/main/java/io/bitsquare/gui/funds/FundsView.fxml @@ -4,7 +4,7 @@ - @@ -14,7 +14,7 @@ - + @@ -29,11 +29,10 @@ - -