diff --git a/core/src/main/java/io/bisq/core/offer/placeoffer/tasks/CreateMakerFeeTx.java b/core/src/main/java/io/bisq/core/offer/placeoffer/tasks/CreateMakerFeeTx.java index 5540982edc..051677623d 100644 --- a/core/src/main/java/io/bisq/core/offer/placeoffer/tasks/CreateMakerFeeTx.java +++ b/core/src/main/java/io/bisq/core/offer/placeoffer/tasks/CreateMakerFeeTx.java @@ -52,19 +52,21 @@ public class CreateMakerFeeTx extends Task { @Override protected void run() { Offer offer = model.getOffer(); + try { runInterceptHook(); + String id = offer.getId(); + BtcWalletService walletService = model.getWalletService(); + NodeAddress selectedArbitratorNodeAddress = ArbitratorSelectionRule.select(model.getUser().getAcceptedArbitratorAddresses(), model.getOffer()); log.debug("selectedArbitratorAddress " + selectedArbitratorNodeAddress); Arbitrator selectedArbitrator = model.getUser().getAcceptedArbitratorByAddress(selectedArbitratorNodeAddress); checkNotNull(selectedArbitrator, "selectedArbitrator must not be null at CreateOfferFeeTx"); - BtcWalletService walletService = model.getWalletService(); - String id = offer.getId(); + Address fundingAddress = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.OFFER_FUNDING).getAddress(); - Address reservedForTradeAddress = walletService.getOrCreateAddressEntry(id, - AddressEntry.Context.RESERVED_FOR_TRADE).getAddress(); + Address reservedForTradeAddress = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE).getAddress(); Address changeAddress = walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress(); final TradeWalletService tradeWalletService = model.getTradeWalletService(); @@ -84,6 +86,7 @@ public class CreateMakerFeeTx extends Task { // tx malleability offer.setOfferFeePaymentTxId(btcTransaction.getHashAsString()); model.setTransaction(btcTransaction); + walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.OFFER_FUNDING); complete(); } else { @@ -110,7 +113,8 @@ public class CreateMakerFeeTx extends Task { checkArgument(transaction.equals(signedTx)); offer.setOfferFeePaymentTxId(transaction.getHashAsString()); model.setTransaction(transaction); - + walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.OFFER_FUNDING); + complete(); log.debug("Successfully sent tx with id " + transaction.getHashAsString()); } diff --git a/core/src/main/java/io/bisq/core/trade/TradeManager.java b/core/src/main/java/io/bisq/core/trade/TradeManager.java index ee8a99fdf1..6b695b5c57 100644 --- a/core/src/main/java/io/bisq/core/trade/TradeManager.java +++ b/core/src/main/java/io/bisq/core/trade/TradeManager.java @@ -533,8 +533,7 @@ public class TradeManager implements PersistedDataHost { Stream available = Stream.concat(availableOrPayout, btcWalletService.getAddressEntries(AddressEntry.Context.ARBITRATOR).stream()); available = Stream.concat(available, btcWalletService.getAddressEntries(AddressEntry.Context.OFFER_FUNDING).stream()); - return available - .filter(addressEntry -> btcWalletService.getBalanceForAddress(addressEntry.getAddress()).isPositive()); + return available.filter(addressEntry -> btcWalletService.getBalanceForAddress(addressEntry.getAddress()).isPositive()); } public Stream getLockedTradeStream() { diff --git a/core/src/main/java/io/bisq/core/trade/protocol/TradeProtocol.java b/core/src/main/java/io/bisq/core/trade/protocol/TradeProtocol.java index 8ec2e249c0..11a1c075c7 100644 --- a/core/src/main/java/io/bisq/core/trade/protocol/TradeProtocol.java +++ b/core/src/main/java/io/bisq/core/trade/protocol/TradeProtocol.java @@ -136,7 +136,7 @@ public abstract class TradeProtocol { private void cleanupTradableOnFault() { final Trade.State state = trade.getState(); - log.debug("cleanupTradable tradeState=" + state); + log.warn("cleanupTradableOnFault tradeState=" + state); TradeManager tradeManager = processModel.getTradeManager(); if (trade.isInPreparation()) { // no funds left. we just clean up the trade list diff --git a/core/src/main/java/io/bisq/core/trade/protocol/tasks/buyer/BuyerProcessPayoutTxPublishedMessage.java b/core/src/main/java/io/bisq/core/trade/protocol/tasks/buyer/BuyerProcessPayoutTxPublishedMessage.java index 13f09ae37d..8744a942a7 100644 --- a/core/src/main/java/io/bisq/core/trade/protocol/tasks/buyer/BuyerProcessPayoutTxPublishedMessage.java +++ b/core/src/main/java/io/bisq/core/trade/protocol/tasks/buyer/BuyerProcessPayoutTxPublishedMessage.java @@ -18,6 +18,7 @@ package io.bisq.core.trade.protocol.tasks.buyer; import io.bisq.common.taskrunner.TaskRunner; +import io.bisq.core.btc.AddressEntry; import io.bisq.core.btc.wallet.BtcWalletService; import io.bisq.core.trade.Trade; import io.bisq.core.trade.messages.PayoutTxPublishedMessage; @@ -55,6 +56,7 @@ public class BuyerProcessPayoutTxPublishedMessage extends TradeTask { processModel.removeMailboxMessageAfterProcessing(trade); trade.setState(Trade.State.BUYER_RECEIVED_PAYOUT_TX_PUBLISHED_MSG); + processModel.getBtcWalletService().swapTradeEntryToAvailableEntry(trade.getId(), AddressEntry.Context.MULTI_SIG); complete(); } catch (Throwable t) { diff --git a/core/src/main/java/io/bisq/core/trade/protocol/tasks/buyer/BuyerSetupPayoutTxListener.java b/core/src/main/java/io/bisq/core/trade/protocol/tasks/buyer/BuyerSetupPayoutTxListener.java index 1b38f4eddf..15f4859731 100644 --- a/core/src/main/java/io/bisq/core/trade/protocol/tasks/buyer/BuyerSetupPayoutTxListener.java +++ b/core/src/main/java/io/bisq/core/trade/protocol/tasks/buyer/BuyerSetupPayoutTxListener.java @@ -43,21 +43,24 @@ public class BuyerSetupPayoutTxListener extends TradeTask { @Override protected void run() { + try { runInterceptHook(); if (!trade.isPayoutPublished()) { BtcWalletService walletService = processModel.getBtcWalletService(); - Address address = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), - AddressEntry.Context.TRADE_PAYOUT).getAddress(); - + final String id = processModel.getOffer().getId(); + Address address = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.TRADE_PAYOUT).getAddress(); if (isInNetwork(walletService.getConfidenceForAddress(address))) { trade.setState(Trade.State.BUYER_SAW_PAYOUT_TX_IN_NETWORK); + swapMultiSigEntry(); } else { listener = new AddressConfidenceListener(address) { @Override public void onTransactionConfidenceChanged(TransactionConfidence confidence) { - if (isInNetwork(confidence)) + if (isInNetwork(confidence)) { trade.setState(Trade.State.BUYER_SAW_PAYOUT_TX_IN_NETWORK); + swapMultiSigEntry(); + } } }; walletService.addAddressConfidenceListener(listener); @@ -66,6 +69,7 @@ public class BuyerSetupPayoutTxListener extends TradeTask { log.debug("BuyerSetupListenerForPayoutTx tradeStateSubscription tradeState=" + newValue); if (trade.isPayoutPublished()) { walletService.removeAddressConfidenceListener(listener); + swapMultiSigEntry(); // hack to remove tradeStateSubscription at callback UserThread.execute(this::unSubscribe); } @@ -80,6 +84,10 @@ public class BuyerSetupPayoutTxListener extends TradeTask { } } + private void swapMultiSigEntry() { + processModel.getBtcWalletService().swapTradeEntryToAvailableEntry(trade.getId(), AddressEntry.Context.MULTI_SIG); + } + private boolean isInNetwork(TransactionConfidence confidence) { log.debug("onTransactionConfidenceChanged " + confidence); return confidence != null && diff --git a/core/src/main/java/io/bisq/core/trade/protocol/tasks/buyer_as_maker/BuyerAsMakerSignPayoutTx.java b/core/src/main/java/io/bisq/core/trade/protocol/tasks/buyer_as_maker/BuyerAsMakerSignPayoutTx.java index 2ee138a300..1e3df3ef5e 100644 --- a/core/src/main/java/io/bisq/core/trade/protocol/tasks/buyer_as_maker/BuyerAsMakerSignPayoutTx.java +++ b/core/src/main/java/io/bisq/core/trade/protocol/tasks/buyer_as_maker/BuyerAsMakerSignPayoutTx.java @@ -74,14 +74,6 @@ public class BuyerAsMakerSignPayoutTx extends TradeTask { buyerMultiSigPubKey, sellerMultiSigPubKey, trade.getArbitratorBtcPubKey()); - - /* - DeterministicKey multiSigKeyPair, - byte[] buyerPubKey, - byte[] sellerPubKey, - byte[] arbitratorPubKey - */ - processModel.setPayoutTxSignature(payoutTxSignature); complete(); diff --git a/core/src/main/java/io/bisq/core/trade/protocol/tasks/buyer_as_taker/BuyerAsTakerSignAndPublishDepositTx.java b/core/src/main/java/io/bisq/core/trade/protocol/tasks/buyer_as_taker/BuyerAsTakerSignAndPublishDepositTx.java index beb7b1a3da..68ff4a5783 100644 --- a/core/src/main/java/io/bisq/core/trade/protocol/tasks/buyer_as_taker/BuyerAsTakerSignAndPublishDepositTx.java +++ b/core/src/main/java/io/bisq/core/trade/protocol/tasks/buyer_as_taker/BuyerAsTakerSignAndPublishDepositTx.java @@ -82,6 +82,8 @@ public class BuyerAsTakerSignAndPublishDepositTx extends TradeTask { Timer timeoutTimer = UserThread.runAfter(() -> { log.warn("Broadcast not completed after 5 sec. We go on with the trade protocol."); trade.setState(Trade.State.TAKER_PUBLISHED_DEPOSIT_TX); + walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE); + complete(); }, 5); @@ -102,6 +104,8 @@ public class BuyerAsTakerSignAndPublishDepositTx extends TradeTask { log.trace("takerSignAndPublishTx succeeded " + transaction); trade.setDepositTx(transaction); trade.setState(Trade.State.TAKER_PUBLISHED_DEPOSIT_TX); + walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE); + complete(); } else { log.warn("We got the callback called after the timeout has been triggered a complete()."); diff --git a/core/src/main/java/io/bisq/core/trade/protocol/tasks/maker/MakerProcessDepositTxPublishedMessage.java b/core/src/main/java/io/bisq/core/trade/protocol/tasks/maker/MakerProcessDepositTxPublishedMessage.java index 470ea271b9..b9f6dd3e07 100644 --- a/core/src/main/java/io/bisq/core/trade/protocol/tasks/maker/MakerProcessDepositTxPublishedMessage.java +++ b/core/src/main/java/io/bisq/core/trade/protocol/tasks/maker/MakerProcessDepositTxPublishedMessage.java @@ -18,6 +18,7 @@ package io.bisq.core.trade.protocol.tasks.maker; import io.bisq.common.taskrunner.TaskRunner; +import io.bisq.core.btc.AddressEntry; import io.bisq.core.btc.wallet.BtcWalletService; import io.bisq.core.trade.Trade; import io.bisq.core.trade.messages.DepositTxPublishedMessage; @@ -59,6 +60,7 @@ public class MakerProcessDepositTxPublishedMessage extends TradeTask { processModel.removeMailboxMessageAfterProcessing(trade); trade.setState(Trade.State.MAKER_RECEIVED_DEPOSIT_TX_PUBLISHED_MSG); + processModel.getBtcWalletService().swapTradeEntryToAvailableEntry(trade.getId(), AddressEntry.Context.RESERVED_FOR_TRADE); complete(); } catch (Throwable t) { diff --git a/core/src/main/java/io/bisq/core/trade/protocol/tasks/maker/MakerSetupDepositTxListener.java b/core/src/main/java/io/bisq/core/trade/protocol/tasks/maker/MakerSetupDepositTxListener.java index 12ee95339a..cecacbcf17 100644 --- a/core/src/main/java/io/bisq/core/trade/protocol/tasks/maker/MakerSetupDepositTxListener.java +++ b/core/src/main/java/io/bisq/core/trade/protocol/tasks/maker/MakerSetupDepositTxListener.java @@ -48,18 +48,20 @@ public class MakerSetupDepositTxListener extends TradeTask { runInterceptHook(); if (trade.getState().getPhase() == Trade.Phase.TAKER_FEE_PUBLISHED) { BtcWalletService walletService = processModel.getBtcWalletService(); - Address address = walletService.getOrCreateAddressEntry(trade.getId(), - AddressEntry.Context.RESERVED_FOR_TRADE).getAddress(); + final String id = trade.getId(); + Address address = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE).getAddress(); if (walletService.getBalanceForAddress(address).isZero()) { trade.setState(Trade.State.MAKER_SAW_DEPOSIT_TX_IN_NETWORK); + swapReservedForTradeEntry(); } else { listener = new BalanceListener(address) { @Override public void onBalanceChanged(Coin balance, Transaction tx) { - // dont store trade.getState().getPhase() as variable as we need it volatile! - if (balance.isZero() && trade.getState().getPhase() == Trade.Phase.TAKER_FEE_PUBLISHED) + if (balance.isZero() && trade.getState().getPhase() == Trade.Phase.TAKER_FEE_PUBLISHED) { trade.setState(Trade.State.MAKER_SAW_DEPOSIT_TX_IN_NETWORK); + swapReservedForTradeEntry(); + } } }; walletService.addBalanceListener(listener); @@ -68,6 +70,7 @@ public class MakerSetupDepositTxListener extends TradeTask { log.error("MakerSetupDepositTxListener tradeStateSubscription tradeState=" + newValue); if (newValue.getPhase() != Trade.Phase.TAKER_FEE_PUBLISHED) { walletService.removeBalanceListener(listener); + swapReservedForTradeEntry(); // hack to remove tradeStateSubscription at callback UserThread.execute(this::unSubscribe); } @@ -83,6 +86,10 @@ public class MakerSetupDepositTxListener extends TradeTask { } } + private void swapReservedForTradeEntry() { + processModel.getBtcWalletService().swapTradeEntryToAvailableEntry(trade.getId(), AddressEntry.Context.RESERVED_FOR_TRADE); + } + private void unSubscribe() { if (tradeStateSubscription != null) tradeStateSubscription.unsubscribe(); diff --git a/core/src/main/java/io/bisq/core/trade/protocol/tasks/seller/SellerSignAndFinalizePayoutTx.java b/core/src/main/java/io/bisq/core/trade/protocol/tasks/seller/SellerSignAndFinalizePayoutTx.java index b2be3b8c19..0d33cf7e40 100644 --- a/core/src/main/java/io/bisq/core/trade/protocol/tasks/seller/SellerSignAndFinalizePayoutTx.java +++ b/core/src/main/java/io/bisq/core/trade/protocol/tasks/seller/SellerSignAndFinalizePayoutTx.java @@ -30,6 +30,7 @@ import org.bitcoinj.core.Transaction; import org.bitcoinj.crypto.DeterministicKey; import java.util.Arrays; +import java.util.Optional; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; @@ -66,8 +67,9 @@ public class SellerSignAndFinalizePayoutTx extends TradeTask { final byte[] buyerMultiSigPubKey = tradingPeer.getMultiSigPubKey(); byte[] sellerMultiSigPubKey = processModel.getMyMultiSigPubKey(); - checkArgument(Arrays.equals(sellerMultiSigPubKey, - walletService.getOrCreateAddressEntry(id, AddressEntry.Context.MULTI_SIG).getPubKey()), + Optional MultiSigAddressEntryOptional = walletService.getAddressEntry(id, AddressEntry.Context.MULTI_SIG); + checkArgument(MultiSigAddressEntryOptional.isPresent() && Arrays.equals(sellerMultiSigPubKey, + MultiSigAddressEntryOptional.get().getPubKey()), "sellerMultiSigPubKey from AddressEntry must match the one from the trade data. trade id =" + id); DeterministicKey multiSigKeyPair = walletService.getMultiSigKeyPair(id, sellerMultiSigPubKey); @@ -86,6 +88,7 @@ public class SellerSignAndFinalizePayoutTx extends TradeTask { ); trade.setPayoutTx(transaction); + walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.MULTI_SIG); complete(); } catch (Throwable t) { diff --git a/core/src/main/java/io/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerCreatesAndSignsDepositTx.java b/core/src/main/java/io/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerCreatesAndSignsDepositTx.java index 8706954a51..15e2d86a32 100644 --- a/core/src/main/java/io/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerCreatesAndSignsDepositTx.java +++ b/core/src/main/java/io/bisq/core/trade/protocol/tasks/seller_as_maker/SellerAsMakerCreatesAndSignsDepositTx.java @@ -79,18 +79,11 @@ public class SellerAsMakerCreatesAndSignsDepositTx extends TradeTask { .add(offer.getBuyerSecurityDeposit()); final List takerRawTransactionInputs = tradingPeer.getRawTransactionInputs(); - final long takerChangeOutputValue = tradingPeer.getChangeOutputValue(); - final String takerChangeAddressString = tradingPeer.getChangeOutputAddress(); - - final Address makerAddress = walletService.getOrCreateAddressEntry(id, - AddressEntry.Context.RESERVED_FOR_TRADE).getAddress(); - + final Address makerAddress = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE).getAddress(); final Address makerChangeAddress = walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress(); - final byte[] buyerPubKey = tradingPeer.getMultiSigPubKey(); - final byte[] sellerPubKey = processModel.getMyMultiSigPubKey(); checkArgument(Arrays.equals(sellerPubKey, makerMultiSigAddressEntry.getPubKey()), diff --git a/core/src/main/java/io/bisq/core/trade/protocol/tasks/seller_as_taker/SellerAsTakerSignAndPublishDepositTx.java b/core/src/main/java/io/bisq/core/trade/protocol/tasks/seller_as_taker/SellerAsTakerSignAndPublishDepositTx.java index dff9b158ed..aa2504de5b 100644 --- a/core/src/main/java/io/bisq/core/trade/protocol/tasks/seller_as_taker/SellerAsTakerSignAndPublishDepositTx.java +++ b/core/src/main/java/io/bisq/core/trade/protocol/tasks/seller_as_taker/SellerAsTakerSignAndPublishDepositTx.java @@ -81,6 +81,8 @@ public class SellerAsTakerSignAndPublishDepositTx extends TradeTask { Timer timeoutTimer = UserThread.runAfter(() -> { log.warn("Broadcast not completed after 5 sec. We go on with the trade protocol."); trade.setState(Trade.State.TAKER_PUBLISHED_DEPOSIT_TX); + walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE); + complete(); }, 5); @@ -101,7 +103,8 @@ public class SellerAsTakerSignAndPublishDepositTx extends TradeTask { log.trace("takerSignAndPublishTx succeeded " + transaction); trade.setDepositTx(transaction); trade.setState(Trade.State.TAKER_PUBLISHED_DEPOSIT_TX); - + walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE); + complete(); } else { log.warn("We got the callback called after the timeout has been triggered a complete()."); diff --git a/core/src/main/java/io/bisq/core/trade/protocol/tasks/taker/CreateTakerFeeTx.java b/core/src/main/java/io/bisq/core/trade/protocol/tasks/taker/CreateTakerFeeTx.java index 1849437cf4..9cf0ae7813 100644 --- a/core/src/main/java/io/bisq/core/trade/protocol/tasks/taker/CreateTakerFeeTx.java +++ b/core/src/main/java/io/bisq/core/trade/protocol/tasks/taker/CreateTakerFeeTx.java @@ -60,11 +60,11 @@ public class CreateTakerFeeTx extends TradeTask { log.debug("selectedArbitratorAddress " + selectedArbitratorNodeAddress); Arbitrator selectedArbitrator = user.getAcceptedArbitratorByAddress(selectedArbitratorNodeAddress); checkNotNull(selectedArbitrator, "selectedArbitrator must not be null at CreateTakeOfferFeeTx"); + BtcWalletService walletService = processModel.getBtcWalletService(); String id = processModel.getOffer().getId(); AddressEntry addressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.OFFER_FUNDING); - AddressEntry reservedForTradeAddressEntry = walletService.getOrCreateAddressEntry(id, - AddressEntry.Context.RESERVED_FOR_TRADE); + AddressEntry reservedForTradeAddressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE); AddressEntry changeAddressEntry = walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE); Address fundingAddress = addressEntry.getAddress(); Address reservedForTradeAddress = reservedForTradeAddressEntry.getAddress(); @@ -84,6 +84,7 @@ public class CreateTakerFeeTx extends TradeTask { //TODO use handler for broadcastTx success processModel.setTakeOfferFeeTx(createTakeOfferFeeTx); trade.setTakerFeeTxId(createTakeOfferFeeTx.getHashAsString()); + walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.OFFER_FUNDING); complete(); } else { @@ -109,6 +110,8 @@ public class CreateTakerFeeTx extends TradeTask { log.warn("Broadcast not completed after 5 sec. We go on with the trade protocol."); trade.setTakerFeeTxId(signedTx.getHashAsString()); processModel.setTakeOfferFeeTx(signedTx); + walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.OFFER_FUNDING); + complete(); }, 5); @@ -118,12 +121,13 @@ public class CreateTakerFeeTx extends TradeTask { if (!completed) { timeoutTimer.stop(); if (transaction != null) { + log.debug("Successfully sent tx with id " + transaction.getHashAsString()); checkArgument(transaction.equals(signedTx)); trade.setTakerFeeTxId(transaction.getHashAsString()); processModel.setTakeOfferFeeTx(transaction); + walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.OFFER_FUNDING); complete(); - log.debug("Successfully sent tx with id " + transaction.getHashAsString()); } } else { log.warn("We got the callback called after the timeout has been triggered a complete()."); diff --git a/core/src/main/java/io/bisq/core/trade/protocol/tasks/taker/TakerVerifyAndSignContract.java b/core/src/main/java/io/bisq/core/trade/protocol/tasks/taker/TakerVerifyAndSignContract.java index 41f7e497a6..4c06da8043 100644 --- a/core/src/main/java/io/bisq/core/trade/protocol/tasks/taker/TakerVerifyAndSignContract.java +++ b/core/src/main/java/io/bisq/core/trade/protocol/tasks/taker/TakerVerifyAndSignContract.java @@ -110,11 +110,11 @@ public class TakerVerifyAndSignContract extends TradeTask { Sig.verify(maker.getPubKeyRing().getSignaturePubKey(), contractAsJson, maker.getContractSignature()); + + complete(); } catch (Throwable t) { failed("Signature verification failed. " + t.getMessage()); } - - complete(); } catch (Throwable t) { failed(t); } diff --git a/gui/src/main/java/io/bisq/gui/main/MainViewModel.java b/gui/src/main/java/io/bisq/gui/main/MainViewModel.java index efeccbd45e..054af8fb4d 100644 --- a/gui/src/main/java/io/bisq/gui/main/MainViewModel.java +++ b/gui/src/main/java/io/bisq/gui/main/MainViewModel.java @@ -1044,9 +1044,15 @@ public class MainViewModel implements ViewModel { private void updateReservedBalance() { Coin sum = Coin.valueOf(openOfferManager.getObservableList().stream() .map(openOffer -> { - Address address = btcWalletService.getOrCreateAddressEntry(openOffer.getId(), AddressEntry.Context.RESERVED_FOR_TRADE).getAddress(); - return btcWalletService.getBalanceForAddress(address); + final Optional addressEntryOptional = btcWalletService.getAddressEntry(openOffer.getId(), AddressEntry.Context.RESERVED_FOR_TRADE); + if (addressEntryOptional.isPresent()) { + Address address = addressEntryOptional.get().getAddress(); + return btcWalletService.getBalanceForAddress(address); + } else { + return null; + } }) + .filter(e -> e != null) .mapToLong(Coin::getValue) .sum()); @@ -1056,8 +1062,11 @@ public class MainViewModel implements ViewModel { private void updateLockedBalance() { Coin sum = Coin.valueOf(tradeManager.getLockedTradeStream() .mapToLong(trade -> { - Coin lockedTradeAmount = btcWalletService.getOrCreateAddressEntry(trade.getId(), AddressEntry.Context.MULTI_SIG).getCoinLockedInMultiSig(); - return lockedTradeAmount.getValue(); + final Optional addressEntryOptional = btcWalletService.getAddressEntry(trade.getId(), AddressEntry.Context.MULTI_SIG); + if (addressEntryOptional.isPresent()) + return addressEntryOptional.get().getCoinLockedInMultiSig().getValue(); + else + return 0; }) .sum()); lockedBalance.set(formatter.formatCoinWithCode(sum)); diff --git a/gui/src/main/java/io/bisq/gui/main/funds/locked/LockedView.java b/gui/src/main/java/io/bisq/gui/main/funds/locked/LockedView.java index 4a07514f27..5c9254b47d 100644 --- a/gui/src/main/java/io/bisq/gui/main/funds/locked/LockedView.java +++ b/gui/src/main/java/io/bisq/gui/main/funds/locked/LockedView.java @@ -58,7 +58,7 @@ public class LockedView extends ActivatableView { @FXML TableColumn dateColumn, detailsColumn, addressColumn, balanceColumn; - private final BtcWalletService walletService; + private final BtcWalletService btcWalletService; private final TradeManager tradeManager; private final OpenOfferManager openOfferManager; private final Preferences preferences; @@ -77,9 +77,9 @@ public class LockedView extends ActivatableView { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private LockedView(BtcWalletService walletService, TradeManager tradeManager, OpenOfferManager openOfferManager, Preferences preferences, + private LockedView(BtcWalletService btcWalletService, TradeManager tradeManager, OpenOfferManager openOfferManager, Preferences preferences, BSFormatter formatter, OfferDetailsWindow offerDetailsWindow, TradeDetailsWindow tradeDetailsWindow) { - this.walletService = walletService; + this.btcWalletService = btcWalletService; this.tradeManager = tradeManager; this.openOfferManager = openOfferManager; this.preferences = preferences; @@ -133,7 +133,7 @@ public class LockedView extends ActivatableView { tableView.setItems(sortedList); updateList(); - walletService.addBalanceListener(balanceListener); + btcWalletService.addBalanceListener(balanceListener); } @Override @@ -142,7 +142,7 @@ public class LockedView extends ActivatableView { tradeManager.getTradableList().removeListener(tradeListChangeListener); sortedList.comparatorProperty().unbind(); observableList.forEach(LockedListItem::cleanup); - walletService.removeBalanceListener(balanceListener); + btcWalletService.removeBalanceListener(balanceListener); } @@ -153,10 +153,18 @@ public class LockedView extends ActivatableView { private void updateList() { observableList.forEach(LockedListItem::cleanup); observableList.setAll(tradeManager.getLockedTradeStream() - .map(trade -> new LockedListItem(trade, - walletService.getOrCreateAddressEntry(trade.getId(), AddressEntry.Context.MULTI_SIG), - walletService, - formatter)) + .map(trade -> { + final Optional addressEntryOptional = btcWalletService.getAddressEntry(trade.getId(), AddressEntry.Context.MULTI_SIG); + if (addressEntryOptional.isPresent()) { + return new LockedListItem(trade, + addressEntryOptional.get(), + btcWalletService, + formatter); + } else { + return null; + } + }) + .filter(e -> e != null) .collect(Collectors.toList())); } diff --git a/gui/src/main/java/io/bisq/gui/main/funds/reserved/ReservedListItem.java b/gui/src/main/java/io/bisq/gui/main/funds/reserved/ReservedListItem.java index 7a4b0bc9d7..fbefa1ed24 100644 --- a/gui/src/main/java/io/bisq/gui/main/funds/reserved/ReservedListItem.java +++ b/gui/src/main/java/io/bisq/gui/main/funds/reserved/ReservedListItem.java @@ -28,20 +28,22 @@ import org.bitcoinj.core.Address; import org.bitcoinj.core.Coin; import org.bitcoinj.core.Transaction; +import java.util.Optional; + class ReservedListItem { private final BalanceListener balanceListener; private final Label balanceLabel; private final OpenOffer openOffer; private final AddressEntry addressEntry; - private final BtcWalletService walletService; + private final BtcWalletService btcWalletService; private final BSFormatter formatter; private final String addressString; private Coin balance; - public ReservedListItem(OpenOffer openOffer, AddressEntry addressEntry, BtcWalletService walletService, BSFormatter formatter) { + public ReservedListItem(OpenOffer openOffer, AddressEntry addressEntry, BtcWalletService btcWalletService, BSFormatter formatter) { this.openOffer = openOffer; this.addressEntry = addressEntry; - this.walletService = walletService; + this.btcWalletService = btcWalletService; this.formatter = formatter; addressString = addressEntry.getAddressString(); @@ -53,19 +55,21 @@ class ReservedListItem { updateBalance(); } }; - walletService.addBalanceListener(balanceListener); + btcWalletService.addBalanceListener(balanceListener); updateBalance(); } public void cleanup() { - walletService.removeBalanceListener(balanceListener); + btcWalletService.removeBalanceListener(balanceListener); } private void updateBalance() { - Address address = walletService.getOrCreateAddressEntry(openOffer.getId(), AddressEntry.Context.RESERVED_FOR_TRADE).getAddress(); - balance = walletService.getBalanceForAddress(address); - if (balance != null) - balanceLabel.setText(formatter.formatCoin(this.balance)); + final Optional addressEntryOptional = btcWalletService.getAddressEntry(openOffer.getId(), AddressEntry.Context.RESERVED_FOR_TRADE); + addressEntryOptional.ifPresent(addressEntry -> { + balance = btcWalletService.getBalanceForAddress(addressEntry.getAddress()); + if (balance != null) + balanceLabel.setText(formatter.formatCoin(balance)); + }); } private Address getAddress() { diff --git a/gui/src/main/java/io/bisq/gui/main/funds/reserved/ReservedView.java b/gui/src/main/java/io/bisq/gui/main/funds/reserved/ReservedView.java index 1443f6d038..59c8f770e5 100644 --- a/gui/src/main/java/io/bisq/gui/main/funds/reserved/ReservedView.java +++ b/gui/src/main/java/io/bisq/gui/main/funds/reserved/ReservedView.java @@ -58,7 +58,7 @@ public class ReservedView extends ActivatableView { @FXML TableColumn dateColumn, detailsColumn, addressColumn, balanceColumn; - private final BtcWalletService walletService; + private final BtcWalletService btcWalletService; private final TradeManager tradeManager; private final OpenOfferManager openOfferManager; private final Preferences preferences; @@ -77,9 +77,9 @@ public class ReservedView extends ActivatableView { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private ReservedView(BtcWalletService walletService, TradeManager tradeManager, OpenOfferManager openOfferManager, Preferences preferences, + private ReservedView(BtcWalletService btcWalletService, TradeManager tradeManager, OpenOfferManager openOfferManager, Preferences preferences, BSFormatter formatter, OfferDetailsWindow offerDetailsWindow, TradeDetailsWindow tradeDetailsWindow) { - this.walletService = walletService; + this.btcWalletService = btcWalletService; this.tradeManager = tradeManager; this.openOfferManager = openOfferManager; this.preferences = preferences; @@ -133,7 +133,7 @@ public class ReservedView extends ActivatableView { tableView.setItems(sortedList); updateList(); - walletService.addBalanceListener(balanceListener); + btcWalletService.addBalanceListener(balanceListener); } @Override @@ -142,7 +142,7 @@ public class ReservedView extends ActivatableView { tradeManager.getTradableList().removeListener(tradeListChangeListener); sortedList.comparatorProperty().unbind(); observableList.forEach(ReservedListItem::cleanup); - walletService.removeBalanceListener(balanceListener); + btcWalletService.removeBalanceListener(balanceListener); } @@ -153,10 +153,18 @@ public class ReservedView extends ActivatableView { private void updateList() { observableList.forEach(ReservedListItem::cleanup); observableList.setAll(openOfferManager.getObservableList().stream() - .map(openOffer -> new ReservedListItem(openOffer, - walletService.getOrCreateAddressEntry(openOffer.getId(), AddressEntry.Context.RESERVED_FOR_TRADE), - walletService, - formatter)) + .map(openOffer -> { + Optional addressEntryOptional = btcWalletService.getAddressEntry(openOffer.getId(), AddressEntry.Context.RESERVED_FOR_TRADE); + if (addressEntryOptional.isPresent()) { + return new ReservedListItem(openOffer, + addressEntryOptional.get(), + btcWalletService, + formatter); + } else { + return null; + } + }) + .filter(e -> e != null) .collect(Collectors.toList())); } diff --git a/gui/src/main/java/io/bisq/gui/main/funds/withdrawal/WithdrawalView.java b/gui/src/main/java/io/bisq/gui/main/funds/withdrawal/WithdrawalView.java index f604461ea1..9350111906 100644 --- a/gui/src/main/java/io/bisq/gui/main/funds/withdrawal/WithdrawalView.java +++ b/gui/src/main/java/io/bisq/gui/main/funds/withdrawal/WithdrawalView.java @@ -212,8 +212,11 @@ public class WithdrawalView extends ActivatableView { trades.stream() .filter(Trade::isPayoutPublished) .forEach(trade -> { - if (walletService.getBalanceForAddress(walletService.getOrCreateAddressEntry(trade.getId(), AddressEntry.Context.TRADE_PAYOUT).getAddress()).isZero()) - tradeManager.addTradeToClosedTrades(trade); + walletService.getAddressEntry(trade.getId(), AddressEntry.Context.TRADE_PAYOUT) + .ifPresent(addressEntry -> { + if (walletService.getBalanceForAddress(addressEntry.getAddress()).isZero()) + tradeManager.addTradeToClosedTrades(trade); + }); }); }