Merge pull request #1722 from ManfredKarrer/fix-parser

Fix bugs with voting
This commit is contained in:
Manfred Karrer 2018-09-25 09:49:06 -05:00 committed by GitHub
commit d4c622237b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 63 additions and 30 deletions

View file

@ -22,6 +22,7 @@ import bisq.core.dao.DaoSetupService;
import bisq.core.dao.governance.ballot.vote.Vote;
import bisq.core.dao.governance.proposal.ProposalService;
import bisq.core.dao.governance.proposal.storage.appendonly.ProposalPayload;
import bisq.core.dao.state.period.PeriodService;
import bisq.common.proto.persistable.PersistedDataHost;
import bisq.common.storage.Storage;
@ -32,6 +33,7 @@ import javafx.collections.ListChangeListener;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
@ -49,14 +51,16 @@ public class BallotListService implements PersistedDataHost, DaoSetupService {
}
private final ProposalService proposalService;
private final PeriodService periodService;
private final Storage<BallotList> storage;
private final BallotList ballotList = new BallotList();
private final List<BallotListChangeListener> listeners = new CopyOnWriteArrayList<>();
@Inject
public BallotListService(ProposalService proposalService, Storage<BallotList> storage) {
public BallotListService(ProposalService proposalService, PeriodService periodService, Storage<BallotList> storage) {
this.proposalService = proposalService;
this.periodService = periodService;
this.storage = storage;
}
@ -125,6 +129,12 @@ public class BallotListService implements PersistedDataHost, DaoSetupService {
return ballotList;
}
public List<Ballot> getBallotsOfCycle() {
return ballotList.stream()
.filter(ballot -> periodService.isTxInCorrectCycle(ballot.getTxId(), periodService.getChainHeight()))
.collect(Collectors.toList());
}
///////////////////////////////////////////////////////////////////////////////////////////
// Private

View file

@ -56,7 +56,7 @@ public class BlindVoteConsensus {
}
public static BallotList getSortedBallotList(BallotListService ballotListService) {
List<Ballot> ballotList = ballotListService.getBallotList().stream()
List<Ballot> ballotList = ballotListService.getBallotsOfCycle().stream()
.sorted(Comparator.comparing(Ballot::getTxId))
.collect(Collectors.toList());
log.info("Sorted ballotList: " + ballotList);

View file

@ -89,6 +89,11 @@ public class BlindVoteValidator {
public boolean isTxInPhaseAndCycle(BlindVote blindVote) {
String txId = blindVote.getTxId();
Optional<Tx> optionalTx = bsqStateService.getTx(txId);
if (!optionalTx.isPresent()) {
log.warn("Tx is not in bsqStateService. blindVoteTxId={}", txId);
return false;
}
int txHeight = optionalTx.get().getBlockHeight();
if (!periodService.isTxInCorrectCycle(txHeight, bsqStateService.getChainHeight())) {
log.debug("Tx is not in current cycle. blindVote={}", blindVote);

View file

@ -271,10 +271,11 @@ public class MyBlindVoteListService implements PersistedDataHost, BsqStateListen
// blindVoteTxId is null if we use the method from the getCurrentlyAvailableMerit call.
public MeritList getMerits(@Nullable String blindVoteTxId) {
// Create a lookup set for txIds of own comp. requests
// Create a lookup set for txIds of own comp. requests from past cycles (we ignore request form that cycle)
Set<String> myCompensationProposalTxIs = myProposalListService.getList().stream()
.filter(proposal -> proposal instanceof CompensationProposal)
.map(Proposal::getTxId)
.filter(txId -> periodService.isTxInPastCycle(txId, periodService.getChainHeight()))
.collect(Collectors.toSet());
return new MeritList(bsqStateService.getIssuanceSet().stream()

View file

@ -22,6 +22,7 @@ import bisq.core.dao.state.governance.Issuance;
import bisq.common.proto.network.NetworkPayload;
import bisq.common.proto.persistable.PersistablePayload;
import bisq.common.util.Utilities;
import io.bisq.generated.protobuffer.PB;
@ -63,4 +64,12 @@ public class Merit implements PersistablePayload, NetworkPayload, ConsensusCriti
public String getIssuanceTxId() {
return issuance.getTxId();
}
@Override
public String toString() {
return "Merit{" +
"\n issuance=" + issuance +
",\n signature=" + Utilities.bytesAsHexString(signature) +
"\n}";
}
}

View file

@ -84,7 +84,7 @@ public class MeritConsensus {
// We verify if signature of hash of blindVoteTxId is correct. EC key from first input for blind vote tx is
// used for signature.
if (pubKeyAsHex == null) {
log.error("Error at getMeritStake: pubKeyAsHex is null");
log.error("Error at isSignatureValid: pubKeyAsHex is null");
return false;
}
@ -110,16 +110,15 @@ public class MeritConsensus {
public static long getWeightedMeritAmount(long amount, int issuanceHeight, int blockHeight, int blocksPerYear) {
if (issuanceHeight > blockHeight)
throw new IllegalArgumentException("issuanceHeight must not be larger than blockHeight");
throw new IllegalArgumentException("issuanceHeight must not be larger than blockHeight. issuanceHeight=" + issuanceHeight + "; blockHeight=" + blockHeight);
if (blockHeight < 0)
throw new IllegalArgumentException("blockHeight must not be negative");
throw new IllegalArgumentException("blockHeight must not be negative. blockHeight=" + blockHeight);
if (amount < 0)
throw new IllegalArgumentException("amount must not be negative");
throw new IllegalArgumentException("amount must not be negative. amount" + amount);
if (blocksPerYear < 0)
throw new IllegalArgumentException("blocksPerYear must not be negative");
throw new IllegalArgumentException("blocksPerYear must not be negative. blocksPerYear=" + blocksPerYear);
if (issuanceHeight < 0)
throw new IllegalArgumentException("issuanceHeight must not be negative");
throw new IllegalArgumentException("issuanceHeight must not be negative. issuanceHeight=" + issuanceHeight);
// We use a linear function to apply a factor for the issuance amount of 1 if the issuance was recent and 0
// if the issuance was 2 years old or older.

View file

@ -131,7 +131,6 @@ public abstract class Proposal implements PersistablePayload, NetworkPayload, Co
public abstract Param getThresholdParam();
@Override
public String toString() {
return "Proposal{" +

View file

@ -28,7 +28,7 @@ public class EvaluatedProposal {
private final long requiredQuorum;
private final long requiredThreshold;
public EvaluatedProposal(boolean isAccepted, ProposalVoteResult proposalVoteResult, long requiredQuorum, long requiredThreshold) {
EvaluatedProposal(boolean isAccepted, ProposalVoteResult proposalVoteResult, long requiredQuorum, long requiredThreshold) {
this.isAccepted = isAccepted;
this.proposalVoteResult = proposalVoteResult;
this.requiredQuorum = requiredQuorum;

View file

@ -264,10 +264,10 @@ public class TxParser {
/**
* Whether the BSQ fee and phase is valid for a transaction.
*
* @param blockHeight The height of the block that the transaction is in.
* @param bsqFee The fee in BSQ, in satoshi.
* @param phase The current phase of the DAO, e.g {@code DaoPhase.Phase.PROPOSAL}.
* @param param The parameter for the fee, e.g {@code Param.PROPOSAL_FEE}.
* @param blockHeight The height of the block that the transaction is in.
* @param bsqFee The fee in BSQ, in satoshi.
* @param phase The current phase of the DAO, e.g {@code DaoPhase.Phase.PROPOSAL}.
* @param param The parameter for the fee, e.g {@code Param.PROPOSAL_FEE}.
* @return True if the fee and phase was valid, false otherwise.
*/
private boolean isFeeAndPhaseValid(int blockHeight, long bsqFee, DaoPhase.Phase phase, Param param) {
@ -296,10 +296,10 @@ public class TxParser {
/**
* Retrieve the type of the transaction, assuming it is relevant to bisq.
*
* @param tx The temporary transaction.
* @param hasOpReturnCandidate True if we have a candidate for an OP_RETURN.
* @param remainingInputValue The remaining value of inputs not yet accounted for, in satoshi.
* @param optionalOpReturnType If present, the OP_RETURN type of the transaction.
* @param tx The temporary transaction.
* @param hasOpReturnCandidate True if we have a candidate for an OP_RETURN.
* @param remainingInputValue The remaining value of inputs not yet accounted for, in satoshi.
* @param optionalOpReturnType If present, the OP_RETURN type of the transaction.
* @return The type of the transaction, if it is relevant to bisq.
*/
@VisibleForTesting
@ -399,10 +399,10 @@ public class TxParser {
/**
* Parse and return the genesis transaction for bisq, if applicable.
*
* @param genesisTxId The transaction id of the bisq genesis transaction.
* @param genesisBlockHeight The block height of the bisq genesis transaction.
* @param genesisTotalSupply The total supply of the genesis issuance for bisq.
* @param rawTx The candidate transaction.
* @param genesisTxId The transaction id of the bisq genesis transaction.
* @param genesisBlockHeight The block height of the bisq genesis transaction.
* @param genesisTotalSupply The total supply of the genesis issuance for bisq.
* @param rawTx The candidate transaction.
* @return The genesis transaction if applicable, or Optional.empty() otherwise.
*/
public static Optional<TempTx> findGenesisTx(String genesisTxId, int genesisBlockHeight, Coin genesisTotalSupply,

View file

@ -132,10 +132,10 @@ public class BsqState implements PersistableEnvelope {
@Override
public Message toProtoMessage() {
return PB.PersistableEnvelope.newBuilder().setBsqState(getStateBuilder()).build();
return PB.PersistableEnvelope.newBuilder().setBsqState(getBsqStateBuilder()).build();
}
private PB.BsqState.Builder getStateBuilder() {
private PB.BsqState.Builder getBsqStateBuilder() {
final PB.BsqState.Builder builder = PB.BsqState.newBuilder();
builder.setChainHeight(chainHeight)
.addAllBlocks(blocks.stream().map(Block::toProtoMessage).collect(Collectors.toList()))
@ -193,10 +193,10 @@ public class BsqState implements PersistableEnvelope {
}
BsqState getClone() {
return (BsqState) BsqState.fromProto(getStateBuilder().build());
return (BsqState) BsqState.fromProto(getBsqStateBuilder().build());
}
BsqState getClone(BsqState snapshotCandidate) {
return (BsqState) BsqState.fromProto(snapshotCandidate.getStateBuilder().build());
return (BsqState) BsqState.fromProto(snapshotCandidate.getBsqStateBuilder().build());
}
}

View file

@ -75,4 +75,14 @@ public class Issuance implements PersistablePayload, NetworkPayload {
proto.getAmount(),
proto.getPubKey().isEmpty() ? null : proto.getPubKey());
}
@Override
public String toString() {
return "Issuance{" +
"\n txId='" + txId + '\'' +
",\n chainHeight=" + chainHeight +
",\n amount=" + amount +
",\n pubKey='" + pubKey + '\'' +
"\n}";
}
}

View file

@ -74,9 +74,9 @@ public enum Param {
PHASE_BREAK1(1), // 10 blocks
PHASE_BLIND_VOTE(2), // 4 days
PHASE_BREAK2(1), // 10 blocks
PHASE_VOTE_REVEAL(1), // 2 days
PHASE_VOTE_REVEAL(2), // 2 days
PHASE_BREAK3(1), // 10 blocks
PHASE_RESULT(1), // 1 block
PHASE_RESULT(2), // 1 block
PHASE_BREAK4(1); // 10 blocks
/*PHASE_UNDEFINED(0),