mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-23 15:00:30 +01:00
Merge pull request #1722 from ManfredKarrer/fix-parser
Fix bugs with voting
This commit is contained in:
commit
d4c622237b
12 changed files with 63 additions and 30 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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}";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -131,7 +131,6 @@ public abstract class Proposal implements PersistablePayload, NetworkPayload, Co
|
|||
|
||||
public abstract Param getThresholdParam();
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Proposal{" +
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Add table
Reference in a new issue