Skip to content

Commit

Permalink
Persist EvaluatedProposalList
Browse files Browse the repository at this point in the history
  • Loading branch information
ManfredKarrer committed Oct 9, 2018
1 parent d279dae commit 4cc17fe
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 23 deletions.
21 changes: 21 additions & 0 deletions common/src/main/proto/pb.proto
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,7 @@ message PersistableEnvelope {
MeritList merit_list = 23;
BondedRoleList bonded_role_list = 24;
RemovedAssetList removed_asset_list = 25;
EvaluatedProposalList evaluated_proposal_list = 26;
}
}

Expand Down Expand Up @@ -1625,6 +1626,26 @@ message MeritList {
repeated Merit merit = 1;
}

message ProposalVoteResult {
Proposal proposal = 1;
int64 stake_of_Accepted_votes = 2;
int64 stake_of_Rejected_votes = 3;
int32 num_accepted_votes = 4;
int32 num_rejected_votes = 5;
int32 num_ignored_votes = 6;
}

message EvaluatedProposal {
bool is_accepted = 1;
ProposalVoteResult proposal_vote_result = 2;
int64 required_quorum = 3;
int64 required_threshold = 4;
}

message EvaluatedProposalList {
repeated EvaluatedProposal evaluated_proposal = 1;
}

///////////////////////////////////////////////////////////////////////////////////////////
// Misc
///////////////////////////////////////////////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import bisq.core.dao.governance.blindvote.MyBlindVoteListService;
import bisq.core.dao.governance.myvote.MyVoteListService;
import bisq.core.dao.governance.role.BondedRolesService;
import bisq.core.dao.governance.voteresult.VoteResultService;
import bisq.core.filter.FilterManager;
import bisq.core.payment.AccountAgeWitnessService;
import bisq.core.trade.statistics.TradeStatisticsManager;
Expand Down Expand Up @@ -52,7 +53,8 @@ public AppSetupWithP2PAndDAO(EncryptionService encryptionService,
BallotListService ballotListService,
MyBlindVoteListService myBlindVoteListService,
BondedRolesService bondedRolesService,
AssetService assetService) {
AssetService assetService,
VoteResultService voteResultService) {
super(encryptionService,
keyRing,
p2PService,
Expand All @@ -67,6 +69,7 @@ public AppSetupWithP2PAndDAO(EncryptionService encryptionService,
persistedDataHosts.add(myBlindVoteListService);
persistedDataHosts.add(bondedRolesService);
persistedDataHosts.add(assetService);
persistedDataHosts.add(voteResultService);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@

import bisq.core.dao.governance.proposal.Proposal;

import bisq.common.proto.persistable.PersistablePayload;

import io.bisq.generated.protobuffer.PB;

import lombok.Value;

@Value
public class EvaluatedProposal {
public class EvaluatedProposal implements PersistablePayload {
private final boolean isAccepted;
private final ProposalVoteResult proposalVoteResult;
private final long requiredQuorum;
Expand All @@ -35,6 +39,33 @@ public class EvaluatedProposal {
this.requiredThreshold = requiredThreshold;
}


///////////////////////////////////////////////////////////////////////////////////////////
// PROTO BUFFER
///////////////////////////////////////////////////////////////////////////////////////////

@Override
public PB.EvaluatedProposal toProtoMessage() {
PB.EvaluatedProposal.Builder builder = PB.EvaluatedProposal.newBuilder()
.setIsAccepted(isAccepted)
.setProposalVoteResult(proposalVoteResult.toProtoMessage())
.setRequiredQuorum(requiredQuorum)
.setRequiredThreshold(requiredThreshold);
return builder.build();
}

public static EvaluatedProposal fromProto(PB.EvaluatedProposal evaluatedProposal) {
return new EvaluatedProposal(evaluatedProposal.getIsAccepted(),
ProposalVoteResult.fromProto(evaluatedProposal.getProposalVoteResult()),
evaluatedProposal.getRequiredQuorum(),
evaluatedProposal.getRequiredThreshold());
}


///////////////////////////////////////////////////////////////////////////////////////////
// API
///////////////////////////////////////////////////////////////////////////////////////////

public Proposal getProposal() {
return proposalVoteResult.getProposal();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/

package bisq.core.dao.governance.voteresult;

import bisq.core.dao.governance.ConsensusCritical;

import bisq.common.proto.persistable.PersistableList;

import io.bisq.generated.protobuffer.PB;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import lombok.EqualsAndHashCode;

/**
* PersistableEnvelope wrapper for list of evaluatedProposals.
*/
@EqualsAndHashCode(callSuper = true)
public class EvaluatedProposalList extends PersistableList<EvaluatedProposal> implements ConsensusCritical {

public EvaluatedProposalList(List<EvaluatedProposal> list) {
super(list);
}

public EvaluatedProposalList() {
super();
}


///////////////////////////////////////////////////////////////////////////////////////////
// PROTO BUFFER
///////////////////////////////////////////////////////////////////////////////////////////

@Override
public PB.PersistableEnvelope toProtoMessage() {
return PB.PersistableEnvelope.newBuilder().setEvaluatedProposalList(getBuilder()).build();
}

public PB.EvaluatedProposalList.Builder getBuilder() {
return PB.EvaluatedProposalList.newBuilder()
.addAllEvaluatedProposal(getList().stream()
.map(EvaluatedProposal::toProtoMessage)
.collect(Collectors.toList()));
}

public static EvaluatedProposalList fromProto(PB.EvaluatedProposalList proto) {
return new EvaluatedProposalList(new ArrayList<>(proto.getEvaluatedProposalList().stream()
.map(EvaluatedProposal::fromProto)
.collect(Collectors.toList())));
}

@Override
public String toString() {
return "List of proposalTxId's in EvaluatedProposalList: " + getList().stream()
.map(EvaluatedProposal::getProposalTxId)
.collect(Collectors.toList());
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,18 @@

import bisq.core.dao.governance.proposal.Proposal;

import bisq.common.proto.persistable.PersistablePayload;

import io.bisq.generated.protobuffer.PB;

import lombok.Value;
import lombok.extern.slf4j.Slf4j;

import static com.google.common.base.Preconditions.checkArgument;

@Value
@Slf4j
public class ProposalVoteResult {
public class ProposalVoteResult implements PersistablePayload {
private final Proposal proposal;
private final long stakeOfAcceptedVotes;
private final long stakeOfRejectedVotes;
Expand All @@ -44,6 +48,36 @@ public class ProposalVoteResult {
this.numIgnoredVotes = numIgnoredVotes;
}


///////////////////////////////////////////////////////////////////////////////////////////
// PROTO BUFFER
///////////////////////////////////////////////////////////////////////////////////////////

@Override
public PB.ProposalVoteResult toProtoMessage() {
PB.ProposalVoteResult.Builder builder = PB.ProposalVoteResult.newBuilder()
.setProposal(proposal.toProtoMessage())
.setStakeOfAcceptedVotes(stakeOfAcceptedVotes)
.setStakeOfRejectedVotes(stakeOfRejectedVotes)
.setNumAcceptedVotes(numAcceptedVotes)
.setNumRejectedVotes(numRejectedVotes)
.setNumIgnoredVotes(numIgnoredVotes);
return builder.build();
}

public static ProposalVoteResult fromProto(PB.ProposalVoteResult proposalVoteResult) {
return new ProposalVoteResult(Proposal.fromProto(proposalVoteResult.getProposal()),
proposalVoteResult.getStakeOfAcceptedVotes(),
proposalVoteResult.getStakeOfRejectedVotes(),
proposalVoteResult.getNumAcceptedVotes(),
proposalVoteResult.getNumRejectedVotes(),
proposalVoteResult.getNumIgnoredVotes());
}

///////////////////////////////////////////////////////////////////////////////////////////
// API
///////////////////////////////////////////////////////////////////////////////////////////

public int getNumActiveVotes() {
return numAcceptedVotes + numRejectedVotes;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package bisq.core.dao.governance.voteresult;

import bisq.core.app.BisqEnvironment;
import bisq.core.dao.DaoSetupService;
import bisq.core.dao.governance.asset.AssetService;
import bisq.core.dao.governance.ballot.Ballot;
Expand Down Expand Up @@ -55,6 +56,8 @@

import bisq.network.p2p.storage.P2PDataStorage;

import bisq.common.proto.persistable.PersistedDataHost;
import bisq.common.storage.Storage;
import bisq.common.util.Utilities;

import javax.inject.Inject;
Expand Down Expand Up @@ -92,7 +95,7 @@
* the missing blindVotes from the network.
*/
@Slf4j
public class VoteResultService implements BsqStateListener, DaoSetupService {
public class VoteResultService implements BsqStateListener, DaoSetupService, PersistedDataHost {
private final VoteRevealService voteRevealService;
private final ProposalListPresentation proposalListPresentation;
private final BsqStateService bsqStateService;
Expand All @@ -102,13 +105,14 @@ public class VoteResultService implements BsqStateListener, DaoSetupService {
private final BondedRolesService bondedRolesService;
private final IssuanceService issuanceService;
private final AssetService assetService;
private final Storage<EvaluatedProposalList> storage;
@Getter
private final ObservableList<VoteResultException> voteResultExceptions = FXCollections.observableArrayList();
// Use a list to have order by cycle

// TODO persist, PB
@Getter
private final Set<EvaluatedProposal> allEvaluatedProposals = new HashSet<>();
private final EvaluatedProposalList evaluatedProposalList = new EvaluatedProposalList();

@Getter
private final Set<DecryptedBallotsWithMerits> allDecryptedBallotsWithMerits = new HashSet<>();

Expand All @@ -126,7 +130,8 @@ public VoteResultService(VoteRevealService voteRevealService,
BlindVoteListService blindVoteListService,
BondedRolesService bondedRolesService,
IssuanceService issuanceService,
AssetService assetService) {
AssetService assetService,
Storage<EvaluatedProposalList> storage) {
this.voteRevealService = voteRevealService;
this.proposalListPresentation = proposalListPresentation;
this.bsqStateService = bsqStateService;
Expand All @@ -136,34 +141,38 @@ public VoteResultService(VoteRevealService voteRevealService,
this.bondedRolesService = bondedRolesService;
this.issuanceService = issuanceService;
this.assetService = assetService;
this.storage = storage;
}


///////////////////////////////////////////////////////////////////////////////////////////
// DaoSetupService
// PersistedDataHost
///////////////////////////////////////////////////////////////////////////////////////////

@Override
public void addListeners() {
bsqStateService.addBsqStateListener(this);
}

@Override
public void start() {
maybeCalculateVoteResult(bsqStateService.getChainHeight());
public void readPersisted() {
if (BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq()) {
EvaluatedProposalList persisted = storage.initAndGetPersisted(evaluatedProposalList, 100);
if (persisted != null) {
evaluatedProposalList.clear();
evaluatedProposalList.addAll(persisted.getList());
}
}
}


///////////////////////////////////////////////////////////////////////////////////////////
// API
// DaoSetupService
///////////////////////////////////////////////////////////////////////////////////////////

public Set<EvaluatedProposal> getAllAcceptedEvaluatedProposals() {
return getAcceptedEvaluatedProposals(allEvaluatedProposals);
@Override
public void addListeners() {
bsqStateService.addBsqStateListener(this);
}

public Set<EvaluatedProposal> getAllRejectedEvaluatedProposals() {
return getRejectedEvaluatedProposals(allEvaluatedProposals);
@Override
public void start() {
maybeCalculateVoteResult(bsqStateService.getChainHeight());
}


Expand Down Expand Up @@ -221,7 +230,10 @@ private void maybeCalculateVoteResult(int chainHeight) {
Set<EvaluatedProposal> acceptedEvaluatedProposals = getAcceptedEvaluatedProposals(evaluatedProposals);
applyAcceptedProposals(acceptedEvaluatedProposals, chainHeight);

allEvaluatedProposals.addAll(evaluatedProposals);
evaluatedProposals.stream()
.filter(e -> !evaluatedProposalList.getList().contains(e))
.forEach(evaluatedProposalList::add);
persist();
log.info("processAllVoteResults completed");
} else {
log.warn("Our list of received blind votes do not match the list from the majority of voters.");
Expand Down Expand Up @@ -689,6 +701,10 @@ private boolean isInVoteResultPhase(int chainHeight) {
return periodService.getFirstBlockOfPhase(chainHeight, DaoPhase.Phase.RESULT) == chainHeight;
}

private void persist() {
storage.queueUpForSave(20);
}


///////////////////////////////////////////////////////////////////////////////////////////
// Inner classes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import bisq.core.dao.governance.proposal.storage.appendonly.ProposalStore;
import bisq.core.dao.governance.proposal.storage.temp.TempProposalStore;
import bisq.core.dao.governance.role.BondedRoleList;
import bisq.core.dao.governance.voteresult.EvaluatedProposalList;
import bisq.core.dao.state.BsqState;
import bisq.core.payment.AccountAgeWitnessStore;
import bisq.core.payment.PaymentAccountList;
Expand Down Expand Up @@ -135,6 +136,8 @@ public PersistableEnvelope fromProto(PB.PersistableEnvelope proto) {
return BondedRoleList.fromProto(proto.getBondedRoleList());
case REMOVED_ASSET_LIST:
return RemovedAssetsList.fromProto(proto.getRemovedAssetList());
case EVALUATED_PROPOSAL_LIST:
return EvaluatedProposalList.fromProto(proto.getEvaluatedProposalList());
default:
throw new ProtobufferRuntimeException("Unknown proto message case(PB.PersistableEnvelope). " +
"messageCase=" + proto.getMessageCase() + "; proto raw data=" + proto.toString());
Expand Down
Loading

0 comments on commit 4cc17fe

Please sign in to comment.