mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 01:41:11 +01:00
Merge pull request #7092 from stejbac/speed-up-vote-result-view-load
Speed up Vote Result display, cycle list item selection & JSON export
This commit is contained in:
commit
0b85e0615d
@ -48,7 +48,6 @@ import org.bitcoinj.core.InsufficientMoneyException;
|
||||
import org.bitcoinj.core.NetworkParameters;
|
||||
import org.bitcoinj.core.Sha256Hash;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
import org.bitcoinj.core.TransactionConfidence;
|
||||
import org.bitcoinj.core.TransactionInput;
|
||||
import org.bitcoinj.core.TransactionOutPoint;
|
||||
import org.bitcoinj.core.TransactionOutput;
|
||||
@ -60,14 +59,12 @@ import org.bitcoinj.wallet.SendRequest;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@ -95,6 +92,7 @@ public class BsqWalletService extends WalletService implements DaoStateListener
|
||||
private final DaoStateService daoStateService;
|
||||
private final UnconfirmedBsqChangeOutputListService unconfirmedBsqChangeOutputListService;
|
||||
private final List<Transaction> walletTransactions = new ArrayList<>();
|
||||
private Map<String, Transaction> walletTransactionsById;
|
||||
private final CopyOnWriteArraySet<BsqBalanceListener> bsqBalanceListeners = new CopyOnWriteArraySet<>();
|
||||
private final List<WalletTransactionsChangeListener> walletTransactionsChangeListeners = new ArrayList<>();
|
||||
private boolean updateBsqWalletTransactionsPending;
|
||||
@ -233,7 +231,7 @@ public class BsqWalletService extends WalletService implements DaoStateListener
|
||||
private void updateBsqBalance() {
|
||||
long ts = System.currentTimeMillis();
|
||||
unverifiedBalance = Coin.valueOf(
|
||||
getTransactions(false).stream()
|
||||
walletTransactions.stream()
|
||||
.filter(tx -> tx.getConfidence().getConfidenceType() == PENDING)
|
||||
.mapToLong(tx -> {
|
||||
// Sum up outputs into BSQ wallet and subtract the inputs using lockup or unlocking
|
||||
@ -270,7 +268,7 @@ public class BsqWalletService extends WalletService implements DaoStateListener
|
||||
.sum()
|
||||
);
|
||||
|
||||
Set<String> confirmedTxIdSet = getTransactions(false).stream()
|
||||
Set<String> confirmedTxIdSet = walletTransactions.stream()
|
||||
.filter(tx -> tx.getConfidence().getConfidenceType() == BUILDING)
|
||||
.map(Transaction::getTxId)
|
||||
.map(Sha256Hash::toString)
|
||||
@ -343,13 +341,15 @@ public class BsqWalletService extends WalletService implements DaoStateListener
|
||||
// BSQ TransactionOutputs and Transactions
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// not thread safe - call only from user thread
|
||||
public List<Transaction> getClonedWalletTransactions() {
|
||||
return new ArrayList<>(walletTransactions);
|
||||
}
|
||||
|
||||
// not thread safe - call only from user thread
|
||||
public Stream<Transaction> getPendingWalletTransactionsStream() {
|
||||
return walletTransactions.stream()
|
||||
.filter(transaction -> transaction.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.PENDING);
|
||||
.filter(transaction -> transaction.getConfidence().getConfidenceType() == PENDING);
|
||||
}
|
||||
|
||||
private void updateBsqWalletTransactions() {
|
||||
@ -363,6 +363,7 @@ public class BsqWalletService extends WalletService implements DaoStateListener
|
||||
UserThread.runAfter(() -> {
|
||||
walletTransactions.clear();
|
||||
walletTransactions.addAll(getTransactions(false));
|
||||
walletTransactionsById = null;
|
||||
walletTransactionsChangeListeners.forEach(WalletTransactionsChangeListener::onWalletTransactionsChange);
|
||||
updateBsqBalance();
|
||||
updateBsqWalletTransactionsPending = false;
|
||||
@ -371,37 +372,6 @@ public class BsqWalletService extends WalletService implements DaoStateListener
|
||||
}
|
||||
}
|
||||
|
||||
private Set<Transaction> getBsqWalletTransactions() {
|
||||
return getTransactions(false).stream()
|
||||
.filter(transaction -> transaction.getConfidence().getConfidenceType() == PENDING ||
|
||||
daoStateService.containsTx(transaction.getTxId().toString()))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public Set<Transaction> getUnverifiedBsqTransactions() {
|
||||
Set<Transaction> bsqWalletTransactions = getBsqWalletTransactions();
|
||||
Set<Transaction> walletTxs = new HashSet<>(getTransactions(false));
|
||||
checkArgument(walletTxs.size() >= bsqWalletTransactions.size(),
|
||||
"We cannot have more txsWithOutputsFoundInBsqTxo than walletTxs");
|
||||
if (walletTxs.size() == bsqWalletTransactions.size()) {
|
||||
// As expected
|
||||
return new HashSet<>();
|
||||
} else {
|
||||
Map<String, Transaction> map = walletTxs.stream()
|
||||
.collect(Collectors.toMap(t -> t.getTxId().toString(), Function.identity()));
|
||||
|
||||
Set<String> walletTxIds = walletTxs.stream()
|
||||
.map(Transaction::getTxId).map(Sha256Hash::toString).collect(Collectors.toSet());
|
||||
Set<String> bsqTxIds = bsqWalletTransactions.stream()
|
||||
.map(Transaction::getTxId).map(Sha256Hash::toString).collect(Collectors.toSet());
|
||||
|
||||
walletTxIds.stream()
|
||||
.filter(bsqTxIds::contains)
|
||||
.forEach(map::remove);
|
||||
return new HashSet<>(map.values());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Coin getValueSentFromMeForTransaction(Transaction transaction) throws ScriptException {
|
||||
Coin result = Coin.ZERO;
|
||||
@ -414,7 +384,7 @@ public class BsqWalletService extends WalletService implements DaoStateListener
|
||||
// We grab the parent tx of the connected output
|
||||
final Transaction parentTransaction = connectedOutput.getParentTransaction();
|
||||
final boolean isConfirmed = parentTransaction != null &&
|
||||
parentTransaction.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING;
|
||||
parentTransaction.getConfidence().getConfidenceType() == BUILDING;
|
||||
if (connectedOutput.isMineOrWatched(wallet)) {
|
||||
if (isConfirmed) {
|
||||
// We lookup if we have a BSQ tx matching the parent tx
|
||||
@ -455,7 +425,7 @@ public class BsqWalletService extends WalletService implements DaoStateListener
|
||||
for (int i = 0; i < transaction.getOutputs().size(); i++) {
|
||||
TransactionOutput output = transaction.getOutputs().get(i);
|
||||
final boolean isConfirmed = output.getParentTransaction() != null &&
|
||||
output.getParentTransaction().getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING;
|
||||
output.getParentTransaction().getConfidence().getConfidenceType() == BUILDING;
|
||||
if (output.isMineOrWatched(wallet)) {
|
||||
if (isConfirmed) {
|
||||
if (txOptional.isPresent()) {
|
||||
@ -484,8 +454,13 @@ public class BsqWalletService extends WalletService implements DaoStateListener
|
||||
return result;
|
||||
}
|
||||
|
||||
// not thread safe - call only from user thread
|
||||
public Optional<Transaction> isWalletTransaction(String txId) {
|
||||
return walletTransactions.stream().filter(e -> e.getTxId().toString().equals(txId)).findAny();
|
||||
if (walletTransactionsById == null) {
|
||||
walletTransactionsById = walletTransactions.stream()
|
||||
.collect(Collectors.toMap(tx -> tx.getTxId().toString(), tx -> tx));
|
||||
}
|
||||
return Optional.ofNullable(walletTransactionsById.get(txId));
|
||||
}
|
||||
|
||||
|
||||
|
@ -72,7 +72,6 @@ import org.bitcoinj.wallet.listeners.WalletReorganizeEventListener;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultiset;
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
import com.google.common.collect.Multiset;
|
||||
@ -88,7 +87,6 @@ import org.bouncycastle.crypto.params.KeyParameter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
@ -107,6 +105,9 @@ import javax.annotation.Nullable;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static org.bitcoinj.core.TransactionConfidence.ConfidenceType.BUILDING;
|
||||
import static org.bitcoinj.core.TransactionConfidence.ConfidenceType.DEAD;
|
||||
import static org.bitcoinj.core.TransactionConfidence.ConfidenceType.PENDING;
|
||||
|
||||
/**
|
||||
* Abstract base class for BTC and BSQ wallet. Provides all non-trade specific functionality.
|
||||
@ -124,7 +125,6 @@ public abstract class WalletService {
|
||||
private final WalletChangeEventListener cacheInvalidationListener;
|
||||
private final AtomicReference<Multiset<Address>> txOutputAddressCache = new AtomicReference<>();
|
||||
private final AtomicReference<SetMultimap<Address, Transaction>> addressToMatchingTxSetCache = new AtomicReference<>();
|
||||
private final AtomicReference<Map<Sha256Hash, Transaction>> txByIdCache = new AtomicReference<>();
|
||||
@Getter
|
||||
protected Wallet wallet;
|
||||
@Getter
|
||||
@ -150,7 +150,6 @@ public abstract class WalletService {
|
||||
cacheInvalidationListener = wallet -> {
|
||||
txOutputAddressCache.set(null);
|
||||
addressToMatchingTxSetCache.set(null);
|
||||
txByIdCache.set(null);
|
||||
};
|
||||
}
|
||||
|
||||
@ -337,8 +336,9 @@ public abstract class WalletService {
|
||||
txIn = partialTx.getInput(index);
|
||||
if (txIn.getConnectedOutput() != null) {
|
||||
// If we don't have a sig we don't do the check to avoid error reports of failed sig checks
|
||||
final List<ScriptChunk> chunks = txIn.getConnectedOutput().getScriptPubKey().getChunks();
|
||||
if (!chunks.isEmpty() && chunks.get(0).data != null && chunks.get(0).data.length > 0) {
|
||||
List<ScriptChunk> chunks = txIn.getConnectedOutput().getScriptPubKey().getChunks();
|
||||
byte[] pushData;
|
||||
if (!chunks.isEmpty() && (pushData = chunks.get(0).data) != null && pushData.length > 0) {
|
||||
try {
|
||||
// We assume if it's already signed, it's hopefully got a SIGHASH type that will not invalidate when
|
||||
// we sign missing pieces (to check this would require either assuming any signatures are signing
|
||||
@ -460,9 +460,8 @@ public abstract class WalletService {
|
||||
transactionConfidenceList.addAll(transactions.stream()
|
||||
.map(tx -> getTransactionConfidence(tx, address))
|
||||
.filter(Objects::nonNull)
|
||||
.filter(con -> con.getConfidenceType() == TransactionConfidence.ConfidenceType.PENDING ||
|
||||
(con.getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING &&
|
||||
con.getAppearedAtChainHeight() > targetHeight))
|
||||
.filter(con -> con.getConfidenceType() == PENDING ||
|
||||
(con.getConfidenceType() == BUILDING && con.getAppearedAtChainHeight() > targetHeight))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
return getMostRecentConfidence(transactionConfidenceList);
|
||||
@ -486,23 +485,16 @@ public abstract class WalletService {
|
||||
@Nullable
|
||||
public TransactionConfidence getConfidenceForTxId(@Nullable String txId) {
|
||||
if (wallet != null && txId != null && !txId.isEmpty()) {
|
||||
Transaction tx = getTxByIdMap().get(Sha256Hash.wrap(txId));
|
||||
if (tx != null) {
|
||||
return tx.getConfidence();
|
||||
Sha256Hash hash = Sha256Hash.wrap(txId);
|
||||
Transaction tx = getTransaction(hash);
|
||||
TransactionConfidence confidence;
|
||||
if (tx != null && (confidence = tx.getConfidence()).getConfidenceType() != DEAD) {
|
||||
return confidence;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Map<Sha256Hash, Transaction> getTxByIdMap() {
|
||||
return txByIdCache.updateAndGet(map -> map != null ? map : computeTxByIdMap());
|
||||
}
|
||||
|
||||
private Map<Sha256Hash, Transaction> computeTxByIdMap() {
|
||||
return wallet.getTransactions(false).stream()
|
||||
.collect(ImmutableMap.toImmutableMap(Transaction::getTxId, tx -> tx));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TransactionConfidence getTransactionConfidence(Transaction tx, Address address) {
|
||||
List<TransactionConfidence> transactionConfidenceList = getOutputsWithConnectedOutputs(tx).stream()
|
||||
@ -538,11 +530,9 @@ public abstract class WalletService {
|
||||
TransactionConfidence transactionConfidence = null;
|
||||
for (TransactionConfidence confidence : transactionConfidenceList) {
|
||||
if (confidence != null) {
|
||||
if (transactionConfidence == null ||
|
||||
confidence.getConfidenceType().equals(TransactionConfidence.ConfidenceType.PENDING) ||
|
||||
(confidence.getConfidenceType().equals(TransactionConfidence.ConfidenceType.BUILDING) &&
|
||||
transactionConfidence.getConfidenceType().equals(
|
||||
TransactionConfidence.ConfidenceType.BUILDING) &&
|
||||
if (transactionConfidence == null || confidence.getConfidenceType() == PENDING ||
|
||||
(confidence.getConfidenceType() == BUILDING &&
|
||||
transactionConfidence.getConfidenceType() == BUILDING &&
|
||||
confidence.getDepthInBlocks() < transactionConfidence.getDepthInBlocks())) {
|
||||
transactionConfidence = confidence;
|
||||
}
|
||||
@ -632,7 +622,7 @@ public abstract class WalletService {
|
||||
for (TransactionOutput transactionOutput : proposedTransaction.getOutputs()) {
|
||||
if (transactionOutput.getValue().isLessThan(Restrictions.getMinNonDustOutput())) {
|
||||
dust = dust.add(transactionOutput.getValue());
|
||||
log.info("Dust TXO = {}", transactionOutput.toString());
|
||||
log.info("Dust TXO = {}", transactionOutput);
|
||||
}
|
||||
}
|
||||
return dust;
|
||||
@ -662,13 +652,13 @@ public abstract class WalletService {
|
||||
Futures.addCallback(sendResult.broadcastComplete, new FutureCallback<>() {
|
||||
@Override
|
||||
public void onSuccess(Transaction result) {
|
||||
log.info("emptyBtcWallet onSuccess Transaction=" + result);
|
||||
log.info("emptyBtcWallet onSuccess Transaction={}", result);
|
||||
resultHandler.handleResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NotNull Throwable t) {
|
||||
log.error("emptyBtcWallet onFailure " + t.toString());
|
||||
log.error("emptyBtcWallet onFailure " + t);
|
||||
errorMessageHandler.handleErrorMessage(t.getMessage());
|
||||
}
|
||||
}, MoreExecutors.directExecutor());
|
||||
@ -688,7 +678,7 @@ public abstract class WalletService {
|
||||
}
|
||||
|
||||
public int getBestChainHeight() {
|
||||
final BlockChain chain = walletsSetup.getChain();
|
||||
BlockChain chain = walletsSetup.getChain();
|
||||
return isWalletReady() && chain != null ? chain.getBestChainHeight() : 0;
|
||||
}
|
||||
|
||||
@ -714,13 +704,13 @@ public abstract class WalletService {
|
||||
}
|
||||
|
||||
public void addNewBestBlockListener(NewBestBlockListener listener) {
|
||||
final BlockChain chain = walletsSetup.getChain();
|
||||
BlockChain chain = walletsSetup.getChain();
|
||||
if (isWalletReady() && chain != null)
|
||||
chain.addNewBestBlockListener(listener);
|
||||
}
|
||||
|
||||
public void removeNewBestBlockListener(NewBestBlockListener listener) {
|
||||
final BlockChain chain = walletsSetup.getChain();
|
||||
BlockChain chain = walletsSetup.getChain();
|
||||
if (isWalletReady() && chain != null)
|
||||
chain.removeNewBestBlockListener(listener);
|
||||
}
|
||||
@ -865,7 +855,7 @@ public abstract class WalletService {
|
||||
/**
|
||||
* @param serializedTransaction The serialized transaction to be added to the wallet
|
||||
* @return The transaction we added to the wallet, which is different as the one we passed as argument!
|
||||
* @throws VerificationException
|
||||
* @throws VerificationException if the transaction could not be parsed or fails sanity checks
|
||||
*/
|
||||
public static Transaction maybeAddTxToWallet(byte[] serializedTransaction,
|
||||
Wallet wallet,
|
||||
|
@ -40,7 +40,6 @@ import org.bitcoinj.core.Coin;
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TableRow;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.StackPane;
|
||||
|
||||
@ -51,18 +50,14 @@ import lombok.Getter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ProposalListItem {
|
||||
|
||||
@Getter
|
||||
private EvaluatedProposal evaluatedProposal;
|
||||
private final EvaluatedProposal evaluatedProposal;
|
||||
@Getter
|
||||
private final Proposal proposal;
|
||||
private final Vote vote;
|
||||
private final boolean isMyBallotIncluded;
|
||||
private final BsqFormatter bsqFormatter;
|
||||
|
||||
private TableRow tableRow;
|
||||
|
||||
|
||||
ProposalListItem(EvaluatedProposal evaluatedProposal, Ballot ballot, boolean isMyBallotIncluded,
|
||||
BsqFormatter bsqFormatter) {
|
||||
this.evaluatedProposal = evaluatedProposal;
|
||||
@ -104,17 +99,6 @@ public class ProposalListItem {
|
||||
return myVoteIcon;
|
||||
}
|
||||
|
||||
public void setTableRow(TableRow tableRow) {
|
||||
this.tableRow = tableRow;
|
||||
}
|
||||
|
||||
public void resetTableRow() {
|
||||
if (tableRow != null) {
|
||||
tableRow.setStyle(null);
|
||||
tableRow.requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
public String getProposalOwnerName() {
|
||||
return evaluatedProposal.getProposal().getName();
|
||||
}
|
||||
|
@ -148,6 +148,7 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||
private ProposalListItem selectedProposalListItem;
|
||||
private boolean isVoteIncludedInResult;
|
||||
private final Set<Cycle> cyclesAdded = new HashSet<>();
|
||||
private Map<String, Ballot> ballotByProposalTxIdMap;
|
||||
private boolean hasCalculatedResult = false;
|
||||
|
||||
|
||||
@ -205,7 +206,7 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||
|
||||
if (daoStateService.isParseBlockChainComplete()) {
|
||||
checkForResultPhase(daoStateService.getChainHeight());
|
||||
fillCycleList();
|
||||
fillCycleListAndBallotMap();
|
||||
}
|
||||
|
||||
exportButton.setOnAction(event -> {
|
||||
@ -243,7 +244,7 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||
@Override
|
||||
public void onParseBlockCompleteAfterBatchProcessing(Block block) {
|
||||
checkForResultPhase(daoStateService.getChainHeight());
|
||||
fillCycleList();
|
||||
fillCycleListAndBallotMap();
|
||||
}
|
||||
|
||||
private void checkForResultPhase(int chainHeight) {
|
||||
@ -283,16 +284,9 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||
resultsOfCycle = item.getResultsOfCycle();
|
||||
|
||||
// Check if my vote is included in result
|
||||
isVoteIncludedInResult = false;
|
||||
resultsOfCycle.getEvaluatedProposals().forEach(evProposal -> resultsOfCycle.getDecryptedVotesForCycle()
|
||||
.forEach(decryptedBallotsWithMerits -> {
|
||||
// Iterate through all included votes to see if any of those are ours
|
||||
if (!isVoteIncludedInResult) {
|
||||
isVoteIncludedInResult = bsqWalletService.isWalletTransaction(decryptedBallotsWithMerits
|
||||
.getVoteRevealTxId()).isPresent();
|
||||
}
|
||||
}));
|
||||
|
||||
isVoteIncludedInResult = resultsOfCycle.getDecryptedVotesForCycle().stream()
|
||||
.anyMatch(decryptedBallotsWithMerits -> bsqWalletService.isWalletTransaction(decryptedBallotsWithMerits
|
||||
.getVoteRevealTxId()).isPresent());
|
||||
|
||||
maybeShowVoteResultErrors(item.getResultsOfCycle().getCycle());
|
||||
createProposalsTable();
|
||||
@ -359,11 +353,8 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||
|
||||
if (selectedProposalListItem != null) {
|
||||
EvaluatedProposal evaluatedProposal = selectedProposalListItem.getEvaluatedProposal();
|
||||
Optional<Ballot> optionalBallot = daoFacade.getAllValidBallots().stream()
|
||||
.filter(ballot -> ballot.getTxId().equals(evaluatedProposal.getProposalTxId()))
|
||||
.findAny();
|
||||
Ballot ballot = ballotByProposalTxIdMap.get(evaluatedProposal.getProposalTxId());
|
||||
|
||||
Ballot ballot = optionalBallot.orElse(null);
|
||||
voteListItemList.clear();
|
||||
resultsOfCycle.getEvaluatedProposals().stream()
|
||||
.filter(evProposal -> evProposal.getProposal().equals(selectedProposalListItem.getEvaluatedProposal().getProposal()))
|
||||
@ -389,16 +380,19 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||
// Fill lists: Cycle
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void fillCycleList() {
|
||||
private void fillCycleListAndBallotMap() {
|
||||
// At data creation we delay a bit so that the UI has a chance to display the placeholder.
|
||||
if (cyclesAdded.isEmpty()) {
|
||||
UserThread.runAfter(this::doFillCycleList, 50, TimeUnit.MILLISECONDS);
|
||||
UserThread.runAfter(this::doFillCycleListAndBallotMap, 50, TimeUnit.MILLISECONDS);
|
||||
} else {
|
||||
doFillCycleList();
|
||||
doFillCycleListAndBallotMap();
|
||||
}
|
||||
}
|
||||
|
||||
private void doFillCycleList() {
|
||||
private void doFillCycleListAndBallotMap() {
|
||||
ballotByProposalTxIdMap = daoFacade.getAllValidBallots().stream()
|
||||
.collect(Collectors.toMap(Ballot::getTxId, ballot -> ballot));
|
||||
|
||||
// Creating our data structure is a bit expensive so we ensure to only create the CycleListItems once.
|
||||
daoStateService.getCycles().stream()
|
||||
.filter(cycle -> !cyclesAdded.contains(cycle))
|
||||
@ -412,7 +406,7 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||
.collect(Collectors.toList());
|
||||
|
||||
AtomicLong stakeAndMerit = new AtomicLong();
|
||||
List<DecryptedBallotsWithMerits> decryptedVotesForCycle = daoStateService.getDecryptedBallotsWithMeritsList().stream()
|
||||
List<DecryptedBallotsWithMerits> decryptedVotesForCycle = daoStateService.getDecryptedBallotsWithMeritsList().parallelStream()
|
||||
.filter(decryptedBallotsWithMerits -> cycleService.isTxInCycle(cycle, decryptedBallotsWithMerits.getBlindVoteTxId()))
|
||||
.filter(decryptedBallotsWithMerits -> cycleService.isTxInCycle(cycle, decryptedBallotsWithMerits.getVoteRevealTxId()))
|
||||
.peek(decryptedBallotsWithMerits -> stakeAndMerit.getAndAdd(decryptedBallotsWithMerits.getStake() + decryptedBallotsWithMerits.getMerit(daoStateService)))
|
||||
@ -464,8 +458,6 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||
|
||||
cyclesTableView.setItems(sortedCycleListItemList);
|
||||
sortedCycleListItemList.comparatorProperty().bind(cyclesTableView.comparatorProperty());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -495,11 +487,8 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||
proposalsTableView.setItems(sortedProposalList);
|
||||
sortedProposalList.comparatorProperty().bind(proposalsTableView.comparatorProperty());
|
||||
|
||||
proposalList.forEach(ProposalListItem::resetTableRow);
|
||||
proposalList.clear();
|
||||
|
||||
Map<String, Ballot> ballotByProposalTxIdMap = daoFacade.getAllValidBallots().stream()
|
||||
.collect(Collectors.toMap(Ballot::getTxId, ballot -> ballot));
|
||||
proposalList.setAll(resultsOfCycle.getEvaluatedProposals().stream()
|
||||
.filter(evaluatedProposal -> {
|
||||
boolean containsKey = ballotByProposalTxIdMap.containsKey(evaluatedProposal.getProposalTxId());
|
||||
@ -893,6 +882,12 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||
cycleJson.addProperty("totalAcceptedVotes", cycleListItem.getResultsOfCycle().getNumAcceptedVotes());
|
||||
cycleJson.addProperty("totalRejectedVotes", cycleListItem.getResultsOfCycle().getNumRejectedVotes());
|
||||
|
||||
List<DecryptedBallotsWithMerits> decryptedVotesForCycle = cycleListItem.getResultsOfCycle().getDecryptedVotesForCycle();
|
||||
// Make sure the votes are sorted so we can easier compare json files from different users
|
||||
decryptedVotesForCycle.sort(Comparator.comparing(DecryptedBallotsWithMerits::getBlindVoteTxId));
|
||||
Map<String, Long> meritStakeMap = decryptedVotesForCycle.stream()
|
||||
.collect(Collectors.toMap(DecryptedBallotsWithMerits::getBlindVoteTxId, d -> d.getMerit(daoStateService)));
|
||||
|
||||
JsonArray proposalsArray = new JsonArray();
|
||||
List<EvaluatedProposal> evaluatedProposals = cycleListItem.getResultsOfCycle().getEvaluatedProposals();
|
||||
evaluatedProposals.sort(Comparator.comparingLong(o -> o.getProposal().getCreationDate()));
|
||||
@ -984,18 +979,15 @@ public class VoteResultView extends ActivatableView<GridPane, Void> implements D
|
||||
evaluatedProposals.stream()
|
||||
.filter(evaluatedProposal -> evaluatedProposal.getProposal().equals(proposal))
|
||||
.forEach(evaluatedProposal -> {
|
||||
List<DecryptedBallotsWithMerits> decryptedVotesForCycle = cycleListItem.getResultsOfCycle().getDecryptedVotesForCycle();
|
||||
// Make sure the votes are sorted so we can easier compare json files from different users
|
||||
decryptedVotesForCycle.sort(Comparator.comparing(DecryptedBallotsWithMerits::getBlindVoteTxId));
|
||||
decryptedVotesForCycle.forEach(decryptedBallotsWithMerits -> {
|
||||
JsonObject voteJson = new JsonObject();
|
||||
// Domain data of decryptedBallotsWithMerits
|
||||
voteJson.addProperty("hashOfBlindVoteList", Utilities.bytesAsHexString(decryptedBallotsWithMerits.getHashOfBlindVoteList()));
|
||||
voteJson.addProperty("blindVoteTxId", decryptedBallotsWithMerits.getBlindVoteTxId());
|
||||
voteJson.addProperty("voteRevealTxId", decryptedBallotsWithMerits.getVoteRevealTxId());
|
||||
voteJson.addProperty("stake", decryptedBallotsWithMerits.getStake());
|
||||
|
||||
voteJson.addProperty("voteWeight", decryptedBallotsWithMerits.getMerit(daoStateService));
|
||||
long stake = decryptedBallotsWithMerits.getStake();
|
||||
voteJson.addProperty("stake", stake);
|
||||
voteJson.addProperty("voteWeight", stake + meritStakeMap.get(decryptedBallotsWithMerits.getBlindVoteTxId()));
|
||||
String voteResult = decryptedBallotsWithMerits.getVote(evaluatedProp.getProposalTxId())
|
||||
.map(vote -> vote.isAccepted() ? "Accepted" : "Rejected")
|
||||
.orElse("Ignored");
|
||||
|
Loading…
Reference in New Issue
Block a user