From bfb5a39301be322943ab2cd1347121194e871dc2 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 5 Apr 2018 12:51:26 -0500 Subject: [PATCH 01/12] Improvements for blind vote publishing - Move code for broadcasting blind vote to p2p network and applying data to success handler of tx broadcast - Add popups when publishing blind vote --- .../proposal/active/ActiveProposalsView.java | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 268c08d4fe8..cf30c1c16e1 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -39,6 +39,7 @@ import bisq.core.dao.vote.result.BooleanVoteResult; import bisq.core.locale.Res; +import bisq.common.UserThread; import bisq.common.crypto.CryptoException; import bisq.common.util.Tuple2; import bisq.common.util.Tuple3; @@ -47,12 +48,9 @@ import org.bitcoinj.core.Coin; import org.bitcoinj.core.InsufficientMoneyException; -import org.bitcoinj.core.Transaction; import javax.inject.Inject; -import com.google.common.util.concurrent.FutureCallback; - import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.Label; @@ -69,10 +67,7 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; - -import org.jetbrains.annotations.NotNull; - -import javax.annotation.Nullable; +import java.util.concurrent.TimeUnit; import static bisq.desktop.util.FormBuilder.add3ButtonsAfterGroup; import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; @@ -130,19 +125,21 @@ protected void activate() { voteButton.setOnAction(e -> { Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); // TODO verify stake - //TODO show popup + Popup startPublishingPopup = new Popup<>(); + startPublishingPopup.information(Res.get("dao.proposal.blindVote.startPublishing")) + .hideCloseButton() + .show(); try { - blindVoteService.publishBlindVote(stake, new FutureCallback() { - @Override - public void onSuccess(@Nullable Transaction result) { - //TODO - } - - @Override - public void onFailure(@NotNull Throwable t) { - //TODO - } - }); + blindVoteService.publishBlindVote(stake, + () -> { + startPublishingPopup.hide(); + UserThread.runAfter(() -> { + new Popup<>().feedback(Res.get("dao.proposal.blindVote.success")) + .show(); + }, 100, TimeUnit.MILLISECONDS); + }, errorMessage -> { + new Popup<>().error(errorMessage).show(); + }); } catch (CryptoException e1) { //TODO show error popup e1.printStackTrace(); From 2fa19b0685982d7f5d0c2eefa0c35c5d8abd179c Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 5 Apr 2018 17:16:48 -0500 Subject: [PATCH 02/12] Use new TxBroadcaster class for better error handling --- .../main/dao/wallet/send/BsqSendView.java | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java index 21b2d9d7d84..ac1da147c65 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java @@ -34,9 +34,13 @@ import bisq.desktop.util.validation.BsqValidator; import bisq.core.btc.Restrictions; +import bisq.core.btc.wallet.BroadcastException; +import bisq.core.btc.wallet.BroadcastTimeoutException; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; +import bisq.core.btc.wallet.MalleabilityException; +import bisq.core.btc.wallet.TxBroadcaster; import bisq.core.btc.wallet.WalletsManager; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.locale.Res; @@ -50,17 +54,11 @@ import javax.inject.Inject; -import com.google.common.util.concurrent.FutureCallback; - import javafx.scene.control.Button; import javafx.scene.layout.GridPane; import javafx.beans.value.ChangeListener; -import org.jetbrains.annotations.NotNull; - -import javax.annotation.Nullable; - import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; import static bisq.desktop.util.FormBuilder.addLabelInputTextField; import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @@ -159,18 +157,25 @@ public void initialize() { bsqFormatter.formatCoinWithCode(receiverAmount))) .actionButtonText(Res.get("shared.yes")) .onAction(() -> { - walletsManager.publishAndCommitBsqTx(txWithBtcFee, new FutureCallback() { + walletsManager.publishAndCommitBsqTx(txWithBtcFee, new TxBroadcaster.Callback() { + @Override + public void onSuccess() { + log.debug("Successfully sent tx with id " + txWithBtcFee.getHashAsString()); + } + + @Override + public void onTimeout(BroadcastTimeoutException exception) { + new Popup<>().warning(exception.toString()); + } + @Override - public void onSuccess(@Nullable Transaction transaction) { - if (transaction != null) { - log.debug("Successfully sent tx with id " + transaction.getHashAsString()); - } + public void onTxMalleability(MalleabilityException exception) { + new Popup<>().warning(exception.toString()); } @Override - public void onFailure(@NotNull Throwable t) { - log.error(t.toString()); - new Popup<>().warning(t.toString()); + public void onFailure(BroadcastException exception) { + new Popup<>().warning(exception.toString()); } }); From 4d217e682ad63291579d4430944191b480d764da Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 5 Apr 2018 17:49:40 -0500 Subject: [PATCH 03/12] Replace Broadcaster with TxBroadcaster - Add transaction as param to onSuccess handler - Remove Broadcaster - Use onTimeout and onTxMalleability default implementation if not dedicated handling code was there --- .../main/dao/wallet/send/BsqSendView.java | 17 ++++++++++------- .../overlays/windows/ManualPayoutTxWindow.java | 15 ++++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java index ac1da147c65..b7087db1e9e 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java @@ -34,13 +34,13 @@ import bisq.desktop.util.validation.BsqValidator; import bisq.core.btc.Restrictions; -import bisq.core.btc.wallet.BroadcastException; -import bisq.core.btc.wallet.BroadcastTimeoutException; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; -import bisq.core.btc.wallet.MalleabilityException; +import bisq.core.btc.wallet.TxBroadcastException; +import bisq.core.btc.wallet.TxBroadcastTimeoutException; import bisq.core.btc.wallet.TxBroadcaster; +import bisq.core.btc.wallet.TxMalleabilityException; import bisq.core.btc.wallet.WalletsManager; import bisq.core.btc.wallet.WalletsSetup; import bisq.core.locale.Res; @@ -159,22 +159,25 @@ public void initialize() { .onAction(() -> { walletsManager.publishAndCommitBsqTx(txWithBtcFee, new TxBroadcaster.Callback() { @Override - public void onSuccess() { + public void onSuccess(Transaction transaction) { log.debug("Successfully sent tx with id " + txWithBtcFee.getHashAsString()); } @Override - public void onTimeout(BroadcastTimeoutException exception) { + public void onTimeout(TxBroadcastTimeoutException exception) { + //TODO handle new Popup<>().warning(exception.toString()); } @Override - public void onTxMalleability(MalleabilityException exception) { + public void onTxMalleability(TxMalleabilityException exception) { + //TODO handle new Popup<>().warning(exception.toString()); } @Override - public void onFailure(BroadcastException exception) { + public void onFailure(TxBroadcastException exception) { + //TODO handle new Popup<>().warning(exception.toString()); } }); diff --git a/src/main/java/bisq/desktop/main/overlays/windows/ManualPayoutTxWindow.java b/src/main/java/bisq/desktop/main/overlays/windows/ManualPayoutTxWindow.java index 96f9163f555..5b45e9e2e51 100644 --- a/src/main/java/bisq/desktop/main/overlays/windows/ManualPayoutTxWindow.java +++ b/src/main/java/bisq/desktop/main/overlays/windows/ManualPayoutTxWindow.java @@ -25,6 +25,8 @@ import bisq.core.btc.exceptions.TransactionVerificationException; import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.TradeWalletService; +import bisq.core.btc.wallet.TxBroadcastException; +import bisq.core.btc.wallet.TxBroadcaster; import bisq.core.btc.wallet.WalletsSetup; import bisq.network.p2p.P2PService; @@ -37,16 +39,12 @@ import javax.inject.Inject; -import com.google.common.util.concurrent.FutureCallback; - import javafx.scene.Scene; import javafx.scene.input.KeyCode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.jetbrains.annotations.NotNull; - import javax.annotation.Nullable; import static bisq.desktop.util.FormBuilder.addLabelInputTextField; @@ -154,7 +152,7 @@ private void addContent() { actionButtonText("Sign and publish transaction"); - FutureCallback callback = new FutureCallback() { + TxBroadcaster.Callback callback = new TxBroadcaster.Callback() { @Override public void onSuccess(@Nullable Transaction result) { log.error("onSuccess"); @@ -167,10 +165,9 @@ public void onSuccess(@Nullable Transaction result) { } @Override - public void onFailure(@NotNull Throwable t) { - log.error(t.toString()); - log.error("onFailure"); - UserThread.execute(() -> new Popup<>().warning(t.toString()).show()); + public void onFailure(TxBroadcastException exception) { + log.error(exception.toString()); + UserThread.execute(() -> new Popup<>().warning(exception.toString()).show()); } }; onAction(() -> { From 316a305f5335573fc2ff7eb133fa1c5a35454abb Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 6 Apr 2018 17:01:08 -0500 Subject: [PATCH 04/12] Improve UI, logging and error handling - Use ExceptionHandler at publishBlindVote - Add hasEnoughBsqFunds method to BlindVoteService - Show fee and confirmation popup at publish blind vote - Add GUIUtils.showBsqFeeInfoPopup to avoid code duplication - Add busyAnimation to publish blind vote button - Improve logs --- .../main/dao/proposal/BaseProposalView.java | 10 +- .../main/dao/proposal/ProposalListItem.java | 1 - .../proposal/active/ActiveProposalsView.java | 94 ++++++++++--------- .../proposal/closed/ClosedProposalsView.java | 9 +- .../dao/proposal/make/MakeProposalView.java | 35 +++---- .../dao/proposal/myvotes/MyVotesView.java | 10 +- src/main/java/bisq/desktop/util/GUIUtil.java | 18 ++++ 7 files changed, 104 insertions(+), 73 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java index 371fe77ba31..3658f3e8e7f 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/BaseProposalView.java @@ -23,12 +23,14 @@ import bisq.desktop.components.AutoTooltipTableColumn; import bisq.desktop.components.HyperlinkWithIcon; import bisq.desktop.components.TableGroupHeadline; +import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.blockchain.BsqBlockChain; import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.blockchain.vo.BsqBlock; +import bisq.core.dao.param.DaoParamService; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalPayload; @@ -73,8 +75,10 @@ public abstract class BaseProposalView extends ActivatableView i protected final ProposalService proposalService; protected final ReadableBsqBlockChain readableBsqBlockChain; + protected final DaoParamService daoParamService; protected final BsqWalletService bsqWalletService; protected final BsqFormatter bsqFormatter; + protected final BSFormatter btcFormatter; protected final ObservableList proposalListItems = FXCollections.observableArrayList(); protected final SortedList sortedList = new SortedList<>(proposalListItems); @@ -101,13 +105,17 @@ public abstract class BaseProposalView extends ActivatableView i protected BaseProposalView(ProposalService proposalService, BsqWalletService bsqWalletService, ReadableBsqBlockChain readableBsqBlockChain, + DaoParamService daoParamService, PeriodService periodService, - BsqFormatter bsqFormatter) { + BsqFormatter bsqFormatter, + BSFormatter btcFormatter) { this.proposalService = proposalService; this.bsqWalletService = bsqWalletService; this.readableBsqBlockChain = readableBsqBlockChain; + this.daoParamService = daoParamService; this.periodService = periodService; this.bsqFormatter = bsqFormatter; + this.btcFormatter = btcFormatter; } @Override diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 99903701125..8d8bedcf220 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -162,7 +162,6 @@ public void applyState(PeriodService.Phase newValue, VoteResult voteResult) { //TODO } } else { - log.error("actionButtonIconView.setVisible(false);"); actionButtonIconView.setVisible(false); } } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index cf30c1c16e1..49b0a0c1cb1 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -18,36 +18,37 @@ package bisq.desktop.main.dao.proposal.active; import bisq.desktop.common.view.FxmlView; +import bisq.desktop.components.BusyAnimation; import bisq.desktop.components.InputTextField; import bisq.desktop.components.TitledGroupBg; import bisq.desktop.main.dao.proposal.BaseProposalView; import bisq.desktop.main.dao.proposal.ProposalListItem; import bisq.desktop.main.overlays.popups.Popup; +import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; +import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; import bisq.core.btc.exceptions.TransactionVerificationException; import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.btc.wallet.InsufficientBsqException; import bisq.core.dao.blockchain.ReadableBsqBlockChain; +import bisq.core.dao.param.DaoParamService; import bisq.core.dao.vote.PeriodService; +import bisq.core.dao.vote.blindvote.BlindVoteConsensus; import bisq.core.dao.vote.blindvote.BlindVoteService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; import bisq.core.dao.vote.result.BooleanVoteResult; import bisq.core.locale.Res; -import bisq.common.UserThread; -import bisq.common.crypto.CryptoException; import bisq.common.util.Tuple2; import bisq.common.util.Tuple3; -import com.google.protobuf.InvalidProtocolBufferException; - import org.bitcoinj.core.Coin; import org.bitcoinj.core.InsufficientMoneyException; +import org.bitcoinj.core.Transaction; import javax.inject.Inject; @@ -62,17 +63,11 @@ import javafx.util.Callback; -import java.io.IOException; - import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import java.util.concurrent.TimeUnit; -import static bisq.desktop.util.FormBuilder.add3ButtonsAfterGroup; -import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; -import static bisq.desktop.util.FormBuilder.addLabelInputTextField; -import static bisq.desktop.util.FormBuilder.addTitledGroupBg; +import static bisq.desktop.util.FormBuilder.*; @FxmlView public class ActiveProposalsView extends BaseProposalView implements BsqBalanceListener { @@ -82,6 +77,8 @@ public class ActiveProposalsView extends BaseProposalView implements BsqBalanceL private Button removeButton, acceptButton, rejectButton, cancelVoteButton, voteButton; private InputTextField stakeInputTextField; private List voteViewItems = new ArrayList<>(); + private BusyAnimation voteButtonBusyAnimation; + private Label voteButtonInfoLabel; /////////////////////////////////////////////////////////////////////////////////////////// @@ -94,9 +91,11 @@ private ActiveProposalsView(ProposalService voteRequestManger, BlindVoteService blindVoteService, BsqWalletService bsqWalletService, ReadableBsqBlockChain readableBsqBlockChain, - BsqFormatter bsqFormatter) { - super(voteRequestManger, bsqWalletService, readableBsqBlockChain, periodService, - bsqFormatter); + DaoParamService daoParamService, + BsqFormatter bsqFormatter, + BSFormatter btcFormatter) { + super(voteRequestManger, bsqWalletService, readableBsqBlockChain, daoParamService, periodService, bsqFormatter, + btcFormatter); this.blindVoteService = blindVoteService; } @@ -123,43 +122,43 @@ protected void activate() { if (voteButton != null) { voteButton.setOnAction(e -> { - Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); // TODO verify stake - Popup startPublishingPopup = new Popup<>(); - startPublishingPopup.information(Res.get("dao.proposal.blindVote.startPublishing")) - .hideCloseButton() - .show(); + Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText()); + final Coin fee = BlindVoteConsensus.getFee(daoParamService, readableBsqBlockChain.getChainHeadHeight()); + Transaction dummyTx = null; try { - blindVoteService.publishBlindVote(stake, - () -> { - startPublishingPopup.hide(); - UserThread.runAfter(() -> { - new Popup<>().feedback(Res.get("dao.proposal.blindVote.success")) - .show(); - }, 100, TimeUnit.MILLISECONDS); - }, errorMessage -> { - new Popup<>().error(errorMessage).show(); - }); - } catch (CryptoException e1) { - //TODO show error popup - e1.printStackTrace(); - } catch (InsufficientBsqException e1) { - e1.printStackTrace(); - } catch (WalletException e1) { - e1.printStackTrace(); - } catch (TransactionVerificationException e1) { - e1.printStackTrace(); - } catch (InsufficientMoneyException e1) { - e1.printStackTrace(); - } catch (InvalidProtocolBufferException e1) { - e1.printStackTrace(); - } catch (IOException e1) { - e1.printStackTrace(); + // We create a tx with dummy opreturn data to get the mining fee for confirmation popup + dummyTx = blindVoteService.getBlindVoteTx(stake, fee, new byte[22]); + } catch (InsufficientMoneyException | WalletException | TransactionVerificationException exception) { + new Popup<>().warning(exception.toString()).show(); + } + + if (dummyTx != null) { + Coin miningFee = dummyTx.getFee(); + int txSize = dummyTx.bitcoinSerialize().length; + GUIUtil.showBsqFeeInfoPopup(fee, miningFee, txSize, bsqFormatter, btcFormatter, + Res.get("dao.blindVote"), () -> publishBlindVote(stake)); } }); } } + private void publishBlindVote(Coin stake) { + voteButtonBusyAnimation.play(); + voteButtonInfoLabel.setText(Res.get("dao.blindVote.startPublishing")); + blindVoteService.publishBlindVote(stake, + () -> { + voteButtonBusyAnimation.stop(); + voteButtonInfoLabel.setText(""); + new Popup().feedback(Res.get("dao.blindVote.success")) + .show(); + }, exception -> { + voteButtonBusyAnimation.stop(); + voteButtonInfoLabel.setText(""); + new Popup<>().warning(exception.toString()).show(); + }); + } + @Override protected void deactivate() { super.deactivate(); @@ -180,7 +179,10 @@ private void createVoteView() { Res.getWithCol("dao.proposal.myVote.stake"), Layout .FIRST_ROW_AND_GROUP_DISTANCE - 20); stakeInputTextField = tuple2.second; - voteButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.proposal.myVote.button")); + Tuple3 tuple = addButtonBusyAnimationLabelAfterGroup(root, ++gridRow, Res.get("dao.proposal.myVote.button")); + voteButton = tuple.first; + voteButtonBusyAnimation = tuple.second; + voteButtonInfoLabel = tuple.third; voteViewItems.add(titledGroupBg); voteViewItems.add(tuple2.first); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java index 66ed8481b4f..8acd1359f61 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/closed/ClosedProposalsView.java @@ -19,10 +19,12 @@ import bisq.desktop.common.view.FxmlView; import bisq.desktop.main.dao.proposal.BaseProposalView; +import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.blockchain.ReadableBsqBlockChain; +import bisq.core.dao.param.DaoParamService; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.ProposalService; @@ -40,8 +42,11 @@ private ClosedProposalsView(ProposalService proposalService, PeriodService periodService, BsqWalletService bsqWalletService, ReadableBsqBlockChain readableBsqBlockChain, - BsqFormatter bsqFormatter) { - super(proposalService, bsqWalletService, readableBsqBlockChain, periodService, bsqFormatter); + DaoParamService daoParamService, + BsqFormatter bsqFormatter, + BSFormatter bsFormatter) { + super(proposalService, bsqWalletService, readableBsqBlockChain, daoParamService, periodService, + bsqFormatter, bsFormatter); } @Override diff --git a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java index 6185f7dcdb6..57ae79d3b63 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/make/MakeProposalView.java @@ -44,7 +44,6 @@ import bisq.core.dao.vote.proposal.generic.GenericProposalService; import bisq.core.locale.Res; import bisq.core.provider.fee.FeeService; -import bisq.core.util.CoinUtil; import bisq.network.p2p.P2PService; @@ -175,25 +174,11 @@ private void publishProposal(ProposalType type) { Coin miningFee = Objects.requireNonNull(tx).getFee(); int txSize = tx.bitcoinSerialize().length; - final Coin fee = ProposalConsensus.getFee(daoParamService, readableBsqBlockChain); - new Popup<>().headLine(Res.get("dao.proposal.create.confirm")) - .confirmation(Res.get("dao.proposal.create.confirm.info", - bsqFormatter.formatCoinWithCode(fee), - btcFormatter.formatCoinWithCode(miningFee), - CoinUtil.getFeePerByte(miningFee, txSize), - txSize / 1000d)) - .actionButtonText(Res.get("shared.yes")) - .onAction(() -> { - proposalService.publishProposal(proposal, - () -> { - proposalDisplay.clearForm(); - proposalTypeComboBox.getSelectionModel().clearSelection(); - new Popup<>().confirmation(Res.get("dao.tx.published.success")).show(); - }, - errorMessage -> new Popup<>().warning(errorMessage).show()); - }) - .closeButtonText(Res.get("shared.cancel")) - .show(); + final Coin fee = ProposalConsensus.getFee(daoParamService, readableBsqBlockChain.getChainHeadHeight()); + + GUIUtil.showBsqFeeInfoPopup(fee, miningFee, txSize, bsqFormatter, btcFormatter, + Res.get("dao.proposal"), () -> publishProposal(proposal)); + } catch (InsufficientMoneyException e) { BSFormatter formatter = e instanceof InsufficientBsqException ? bsqFormatter : btcFormatter; new Popup<>().warning(Res.get("dao.proposal.create.missingFunds", @@ -214,6 +199,16 @@ private void publishProposal(ProposalType type) { } } + private void publishProposal(Proposal proposal) { + proposalService.publishProposal(proposal, + () -> { + proposalDisplay.clearForm(); + proposalTypeComboBox.getSelectionModel().clearSelection(); + new Popup<>().confirmation(Res.get("dao.tx.published.success")).show(); + }, + errorMessage -> new Popup<>().warning(errorMessage).show()); + } + private Proposal createProposal(ProposalType type) throws InsufficientMoneyException, TransactionVerificationException, ValidationException, WalletException, IOException { diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index d319b68dd52..d744bbdb815 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -24,12 +24,14 @@ import bisq.desktop.components.TableGroupHeadline; import bisq.desktop.main.dao.proposal.BaseProposalView; import bisq.desktop.main.dao.proposal.ProposalListItem; +import bisq.desktop.util.BSFormatter; import bisq.desktop.util.BsqFormatter; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.Layout; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.blockchain.ReadableBsqBlockChain; +import bisq.core.dao.param.DaoParamService; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.myvote.MyVoteService; import bisq.core.dao.vote.proposal.ProposalList; @@ -92,10 +94,12 @@ private MyVotesView(ProposalService voteRequestManger, MyVoteService myVoteService, BsqWalletService bsqWalletService, ReadableBsqBlockChain readableBsqBlockChain, + DaoParamService daoParamService, Preferences preferences, - BsqFormatter bsqFormatter) { - super(voteRequestManger, bsqWalletService, readableBsqBlockChain, periodService, - bsqFormatter); + BsqFormatter bsqFormatter, + BSFormatter btcFormatter) { + super(voteRequestManger, bsqWalletService, readableBsqBlockChain, daoParamService, periodService, bsqFormatter, + btcFormatter); this.myVoteService = myVoteService; this.readableBsqBlockChain = readableBsqBlockChain; this.preferences = preferences; diff --git a/src/main/java/bisq/desktop/util/GUIUtil.java b/src/main/java/bisq/desktop/util/GUIUtil.java index 0c8271c01fc..1824148c1a4 100644 --- a/src/main/java/bisq/desktop/util/GUIUtil.java +++ b/src/main/java/bisq/desktop/util/GUIUtil.java @@ -33,6 +33,7 @@ import bisq.core.user.DontShowAgainLookup; import bisq.core.user.Preferences; import bisq.core.user.User; +import bisq.core.util.CoinUtil; import bisq.network.p2p.P2PService; @@ -543,4 +544,21 @@ public static void removeChildrenFromGridPaneRows(GridPane gridPane, int start, childByRowMap.get(i).forEach(child -> gridPane.getChildren().remove(child)); } } + + public static void showBsqFeeInfoPopup(Coin fee, Coin miningFee, int txSize, BsqFormatter bsqFormatter, + BSFormatter btcFormatter, String type, + Runnable actionHandler) { + new Popup<>().headLine(Res.get("dao.feeTx.confirm", type)) + .confirmation(Res.get("dao.feeTx.confirm.details", + type, + bsqFormatter.formatCoinWithCode(fee), + btcFormatter.formatCoinWithCode(miningFee), + CoinUtil.getFeePerByte(miningFee, txSize), + txSize / 1000d, + type)) + .actionButtonText(Res.get("shared.yes")) + .onAction(actionHandler::run) + .closeButtonText(Res.get("shared.cancel")) + .show(); + } } From 3003964bf3e94aa08ba2e81a003dccf87012b566 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Apr 2018 12:08:33 -0500 Subject: [PATCH 05/12] Extract reusable code to baseService. Add more validation --- .../java/bisq/desktop/main/dao/proposal/ProposalListItem.java | 2 +- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 8d8bedcf220..3d038016c1c 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -131,7 +131,7 @@ public void applyState(PeriodService.Phase newValue, VoteResult voteResult) { case UNDEFINED: break; case PROPOSAL: - if (proposalService.isMine(proposal)) { + if (proposalService.isMine(proposal.getProposalPayload())) { actionButton.setVisible(!isTxInPastCycle); actionButtonIconView.setVisible(actionButton.isVisible()); actionButton.setText(Res.get("shared.remove")); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 49b0a0c1cb1..01406800042 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -266,7 +266,7 @@ protected void onPhaseChanged(PeriodService.Phase phase) { final Proposal proposal = selectedProposalListItem.getProposal(); switch (phase) { case PROPOSAL: - if (proposalService.isMine(proposal)) { + if (proposalService.isMine(proposal.getProposalPayload())) { if (removeButton == null) { removeButton = addButtonAfterGroup(detailsGridPane, proposalDisplay.incrementAndGetGridRow(), Res.get("dao.proposal.active.remove")); removeButton.setOnAction(event -> onRemove()); From 7c03980bc22c9dc09662e31cfda3f1167d9c6bdd Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Apr 2018 15:12:55 -0500 Subject: [PATCH 06/12] Use BaseService for BlindVoteService. Fix checks with current cycle --- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 01406800042..cf8b3e3fd66 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -325,7 +325,7 @@ protected void onPhaseChanged(PeriodService.Phase phase) { @Override protected void updateProposalList() { - doUpdateProposalList(proposalService.getActiveProposals()); + doUpdateProposalList(proposalService.getValidOrMyUnconfirmedProposals()); } private void updateStateAfterVote() { From 2e5d5d2191c049df5eccec5560ba8d5eba3b4eaf Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Apr 2018 19:29:09 -0500 Subject: [PATCH 07/12] Pass chainHeight to period service. --- .../java/bisq/desktop/main/dao/proposal/ProposalListItem.java | 3 ++- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 3d038016c1c..ac65e11efec 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -126,7 +126,8 @@ public void applyState(PeriodService.Phase newValue, VoteResult voteResult) { actionButton.setText(""); actionButton.setVisible(false); actionButton.setOnAction(null); - final boolean isTxInPastCycle = periodService.isTxInPastCycle(proposal.getTxId()); + final boolean isTxInPastCycle = periodService.isTxInPastCycle(proposal.getTxId(), + readableBsqBlockChain.getChainHeadHeight()); switch (newValue) { case UNDEFINED: break; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index cf8b3e3fd66..c12ad4bba9e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -262,7 +262,8 @@ protected void onPhaseChanged(PeriodService.Phase phase) { } if (selectedProposalListItem != null && proposalDisplay != null && - !periodService.isTxInPastCycle(selectedProposalListItem.getProposal().getTxId())) { + !periodService.isTxInPastCycle(selectedProposalListItem.getProposal().getTxId(), + readableBsqBlockChain.getChainHeadHeight())) { final Proposal proposal = selectedProposalListItem.getProposal(); switch (phase) { case PROPOSAL: From 819f8e472f610426ca84237e2587a322bea328f8 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Apr 2018 20:13:47 -0500 Subject: [PATCH 08/12] Add isTxInCorrectCycle checks with correct chainHeight --- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index c12ad4bba9e..e17f03c5d2e 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -326,7 +326,7 @@ protected void onPhaseChanged(PeriodService.Phase phase) { @Override protected void updateProposalList() { - doUpdateProposalList(proposalService.getValidOrMyUnconfirmedProposals()); + doUpdateProposalList(proposalService.getActiveOrMyUnconfirmedProposals()); } private void updateStateAfterVote() { From 585478fef9cd945ea912777c143a438491a0240f Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Apr 2018 21:11:07 -0500 Subject: [PATCH 09/12] Rename package result to voteresult --- .../java/bisq/desktop/main/dao/proposal/ProposalListItem.java | 4 ++-- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 2 +- .../bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index ac65e11efec..b4ded74d6de 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -30,8 +30,8 @@ import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.result.BooleanVoteResult; -import bisq.core.dao.vote.result.VoteResult; +import bisq.core.dao.vote.voteresult.BooleanVoteResult; +import bisq.core.dao.vote.voteresult.VoteResult; import bisq.core.locale.Res; import org.bitcoinj.core.Transaction; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index e17f03c5d2e..4527e4ad5d6 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -40,7 +40,7 @@ import bisq.core.dao.vote.blindvote.BlindVoteService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.result.BooleanVoteResult; +import bisq.core.dao.vote.voteresult.BooleanVoteResult; import bisq.core.locale.Res; import bisq.common.util.Tuple2; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index d744bbdb815..46b9a5ad78a 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -36,8 +36,8 @@ import bisq.core.dao.vote.myvote.MyVoteService; import bisq.core.dao.vote.proposal.ProposalList; import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.result.BooleanVoteResult; -import bisq.core.dao.vote.result.VoteResult; +import bisq.core.dao.vote.voteresult.BooleanVoteResult; +import bisq.core.dao.vote.voteresult.VoteResult; import bisq.core.locale.Res; import bisq.core.user.Preferences; From d06b067aa5c214e043d7c17c75456fc3fcfd1d90 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Apr 2018 21:22:47 -0500 Subject: [PATCH 10/12] Renaming - VoteResult to Vote - LongVoteResult to LongVote - BooleanVoteResult to BooleanVote --- .../main/dao/proposal/ProposalListItem.java | 16 ++++++++-------- .../dao/proposal/active/ActiveProposalsView.java | 8 ++++---- .../main/dao/proposal/myvotes/MyVotesView.java | 10 +++++----- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index b4ded74d6de..9daffa03fcd 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -30,8 +30,8 @@ import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.voteresult.BooleanVoteResult; -import bisq.core.dao.vote.voteresult.VoteResult; +import bisq.core.dao.vote.voteresult.BooleanVote; +import bisq.core.dao.vote.voteresult.Vote; import bisq.core.locale.Res; import org.bitcoinj.core.Transaction; @@ -63,7 +63,7 @@ public class ProposalListItem implements BsqBlockChain.Listener { private final ReadableBsqBlockChain readableBsqBlockChain; private final BsqFormatter bsqFormatter; private final ChangeListener chainHeightListener; - private final ChangeListener voteResultChangeListener; + private final ChangeListener voteResultChangeListener; @Getter private TxConfidenceIndicator txConfidenceIndicator; @Getter @@ -111,7 +111,7 @@ public class ProposalListItem implements BsqBlockChain.Listener { readableBsqBlockChain.addListener(this); phaseChangeListener = (observable, oldValue, newValue) -> { - applyState(newValue, proposal.getVoteResult()); + applyState(newValue, proposal.getVote()); }; voteResultChangeListener = (observable, oldValue, newValue) -> { @@ -122,7 +122,7 @@ public class ProposalListItem implements BsqBlockChain.Listener { proposal.getVoteResultProperty().addListener(voteResultChangeListener); } - public void applyState(PeriodService.Phase newValue, VoteResult voteResult) { + public void applyState(PeriodService.Phase newValue, Vote vote) { actionButton.setText(""); actionButton.setVisible(false); actionButton.setOnAction(null); @@ -151,10 +151,10 @@ public void applyState(PeriodService.Phase newValue, VoteResult voteResult) { if (!isTxInPastCycle) { actionNode = actionButtonIconView; actionButton.setVisible(false); - if (proposal.getVoteResult() != null) { + if (proposal.getVote() != null) { actionButtonIconView.setVisible(true); - if (voteResult instanceof BooleanVoteResult) { - if (((BooleanVoteResult) voteResult).isAccepted()) { + if (vote instanceof BooleanVote) { + if (((BooleanVote) vote).isAccepted()) { actionButtonIconView.setId("accepted"); } else { actionButtonIconView.setId("rejected"); diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 4527e4ad5d6..22f7e6f5a50 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -40,7 +40,7 @@ import bisq.core.dao.vote.blindvote.BlindVoteService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.voteresult.BooleanVoteResult; +import bisq.core.dao.vote.voteresult.BooleanVote; import bisq.core.locale.Res; import bisq.common.util.Tuple2; @@ -235,17 +235,17 @@ protected void onSelectProposal(ProposalListItem item) { } private void onAccept() { - selectedProposalListItem.getProposal().setVoteResult(new BooleanVoteResult(true)); + selectedProposalListItem.getProposal().setVote(new BooleanVote(true)); updateStateAfterVote(); } private void onReject() { - selectedProposalListItem.getProposal().setVoteResult(new BooleanVoteResult(false)); + selectedProposalListItem.getProposal().setVote(new BooleanVote(false)); updateStateAfterVote(); } private void onCancelVote() { - selectedProposalListItem.getProposal().setVoteResult(null); + selectedProposalListItem.getProposal().setVote(null); updateStateAfterVote(); } diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index 46b9a5ad78a..d43bfac60d6 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -36,8 +36,8 @@ import bisq.core.dao.vote.myvote.MyVoteService; import bisq.core.dao.vote.proposal.ProposalList; import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.voteresult.BooleanVoteResult; -import bisq.core.dao.vote.voteresult.VoteResult; +import bisq.core.dao.vote.voteresult.BooleanVote; +import bisq.core.dao.vote.voteresult.Vote; import bisq.core.locale.Res; import bisq.core.user.Preferences; @@ -375,9 +375,9 @@ public void updateItem(final ProposalListItem item, boolean empty) { if (item != null && !empty) { actionButtonIconView = new ImageView(); - VoteResult voteResult = item.getProposal().getVoteResult(); - if (voteResult instanceof BooleanVoteResult) { - if (((BooleanVoteResult) voteResult).isAccepted()) { + Vote vote = item.getProposal().getVote(); + if (vote instanceof BooleanVote) { + if (((BooleanVote) vote).isAccepted()) { actionButtonIconView.setId("accepted"); } else { actionButtonIconView.setId("rejected"); From 1a08030ba3f188990d540348c891c50144e88628 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Apr 2018 21:23:43 -0500 Subject: [PATCH 11/12] Move vote classes one level down --- .../java/bisq/desktop/main/dao/proposal/ProposalListItem.java | 4 ++-- .../desktop/main/dao/proposal/active/ActiveProposalsView.java | 2 +- .../bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java index 9daffa03fcd..330dbd98407 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/ProposalListItem.java @@ -27,11 +27,11 @@ import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.blockchain.vo.BsqBlock; import bisq.core.dao.blockchain.vo.Tx; +import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; +import bisq.core.dao.vote.Vote; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.voteresult.BooleanVote; -import bisq.core.dao.vote.voteresult.Vote; import bisq.core.locale.Res; import org.bitcoinj.core.Transaction; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java index 22f7e6f5a50..5b8f40d5052 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/active/ActiveProposalsView.java @@ -35,12 +35,12 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.param.DaoParamService; +import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; import bisq.core.dao.vote.blindvote.BlindVoteConsensus; import bisq.core.dao.vote.blindvote.BlindVoteService; import bisq.core.dao.vote.proposal.Proposal; import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.voteresult.BooleanVote; import bisq.core.locale.Res; import bisq.common.util.Tuple2; diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java index d43bfac60d6..02bb9b869e3 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/MyVotesView.java @@ -32,12 +32,12 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.blockchain.ReadableBsqBlockChain; import bisq.core.dao.param.DaoParamService; +import bisq.core.dao.vote.BooleanVote; import bisq.core.dao.vote.PeriodService; +import bisq.core.dao.vote.Vote; import bisq.core.dao.vote.myvote.MyVoteService; import bisq.core.dao.vote.proposal.ProposalList; import bisq.core.dao.vote.proposal.ProposalService; -import bisq.core.dao.vote.voteresult.BooleanVote; -import bisq.core.dao.vote.voteresult.Vote; import bisq.core.locale.Res; import bisq.core.user.Preferences; From 80221720cb88a8c7c0d5e049beb5bb0d3dae8dc7 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 7 Apr 2018 23:38:46 -0500 Subject: [PATCH 12/12] Refactor and improve Issuance domain. Add issued amount to UI - Add VoteResultService for all proposals - Use stake instead of nr. of votes for majority data view calculation - Use IssuanceService fro compensation requests - Add more checks at issuance - Use secondary sort by hex of hash for getMajorityHash - Add issued amount to dashboard view --- .../dao/proposal/myvotes/VoteListItem.java | 2 +- .../wallet/dashboard/BsqDashboardView.java | 23 ++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java index 62e441cda2d..6ddcfbf5e08 100644 --- a/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java +++ b/src/main/java/bisq/desktop/main/dao/proposal/myvotes/VoteListItem.java @@ -149,7 +149,7 @@ public void onTransactionConfidenceChanged(TransactionConfidence confidence) { private void calculateStake() { if (stake == 0) { String txId = myVote.getTxId(); - stake = readableBsqBlockChain.getBlindVoteStakeTxOutputs().stream() + stake = readableBsqBlockChain.getUnspentBlindVoteStakeTxOutputs().stream() .filter(txOutput -> txOutput.getTxId().equals(txId)) .filter(txOutput -> txOutput.getIndex() == 0) .mapToLong(TxOutput::getValue) diff --git a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index a1dac3b057e..3d78201af99 100644 --- a/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -66,8 +66,8 @@ public class BsqDashboardView extends ActivatableView implements private final BsqFormatter bsqFormatter; private int gridRow = 0; - private TextField issuedAmountTextField, availableAmountTextField, burntAmountTextField, allTxTextField, - burntTxTextField, spentTxTextField, + private TextField genesisIssueAmountTextField, compRequestIssueAmountTextField, availableAmountTextField, burntAmountTextField, allTxTextField, + burntTxTextField/*, spentTxTextField*/, utxoTextField, priceTextField, marketCapTextField; private ChangeListener priceChangeListener; private HyperlinkWithIcon hyperlinkWithIcon; @@ -94,7 +94,7 @@ private BsqDashboardView(BsqBalanceUtil bsqBalanceUtil, public void initialize() { gridRow = bsqBalanceUtil.addGroup(root, gridRow); - addTitledGroupBg(root, ++gridRow, 12, Res.get("dao.wallet.dashboard.statistics"), Layout.GROUP_DISTANCE); + addTitledGroupBg(root, ++gridRow, 11, Res.get("dao.wallet.dashboard.statistics"), Layout.GROUP_DISTANCE); addLabelTextField(root, gridRow, Res.get("dao.wallet.dashboard.genesisBlockHeight"), String.valueOf(readableBsqBlockChain.getGenesisBlockHeight()), Layout.FIRST_ROW_AND_GROUP_DISTANCE); @@ -109,13 +109,14 @@ public void initialize() { GridPane.setMargin(hyperlinkWithIcon, new Insets(0, 0, 0, -4)); root.getChildren().add(hyperlinkWithIcon); - issuedAmountTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.issuedAmount")).second; + genesisIssueAmountTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.genesisIssueAmount")).second; + compRequestIssueAmountTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.compRequestIssueAmount")).second; availableAmountTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.availableAmount")).second; burntAmountTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.burntAmount")).second; allTxTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.allTx")).second; utxoTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.utxo")).second; - spentTxTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.spentTxo")).second; + // spentTxTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.spentTxo")).second; burntTxTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.burntTx")).second; priceTextField = addLabelTextField(root, ++gridRow, Res.get("dao.wallet.dashboard.price")).second; @@ -157,14 +158,20 @@ public void onBlockAdded(BsqBlock bsqBlock) { private void updateWithBsqBlockChainData() { - issuedAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(readableBsqBlockChain.getIssuedAmountAtGenesis())); + final Coin issuedAmountFromGenesis = readableBsqBlockChain.getIssuedAmountAtGenesis(); + genesisIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromGenesis)); + + final Coin issuedAmountFromCompRequests = readableBsqBlockChain.getIssuedAmountFromCompRequests(); + compRequestIssueAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromCompRequests)); + final Coin burntFee = readableBsqBlockChain.getTotalBurntFee(); - final Coin availableAmount = readableBsqBlockChain.getIssuedAmountAtGenesis().subtract(burntFee); + final Coin availableAmount = issuedAmountFromGenesis.add(issuedAmountFromCompRequests).subtract(burntFee); + availableAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(availableAmount)); burntAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(burntFee)); allTxTextField.setText(String.valueOf(readableBsqBlockChain.getTransactions().size())); utxoTextField.setText(String.valueOf(readableBsqBlockChain.getUnspentTxOutputs().size())); - spentTxTextField.setText(String.valueOf(readableBsqBlockChain.getSpentTxOutputs().size())); + //spentTxTextField.setText(String.valueOf(readableBsqBlockChain.getSpentTxOutputs().size())); burntTxTextField.setText(String.valueOf(readableBsqBlockChain.getFeeTransactions().size())); }