use of bisq.core.dao.governance.merit.MeritList in project bisq-core by bisq-network.
the class MyBlindVoteListService method getMerits.
// 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
Set<String> myCompensationProposalTxIs = myProposalListService.getList().stream().filter(proposal -> proposal instanceof CompensationProposal).map(Proposal::getTxId).collect(Collectors.toSet());
return new MeritList(bsqStateService.getIssuanceSet().stream().map(issuance -> {
// We check if it is our proposal
if (!myCompensationProposalTxIs.contains(issuance.getTxId()))
return null;
byte[] signatureAsBytes;
if (blindVoteTxId != null) {
String pubKey = issuance.getPubKey();
if (pubKey == null) {
// Maybe add exception
log.error("We did not have a pubKey in our issuance object. " + "txId={}, issuance={}", issuance.getTxId(), issuance);
return null;
}
DeterministicKey key = bsqWalletService.findKeyFromPubKey(Utilities.decodeFromHex(pubKey));
if (key == null) {
// Maybe add exception
log.error("We did not find the key for our compensation request. txId={}", issuance.getTxId());
return null;
}
// We sign the txId so we be sure that the signature could not be used by anyone else
// In the verification the txId will be checked as well.
// As we use BitcoinJ EC keys we extend our consensus dependency to BitcoinJ.
// Alternative would be to use our own Sig Key but then we need to share the key separately.
// The EC key is in the blockchain already. We prefer here to stick with EC key. If any change
// in BitcoinJ would break our consensus we would need to fall back to the old BitcoinJ EC
// implementation.
ECKey.ECDSASignature signature = key.sign(Sha256Hash.wrap(blindVoteTxId));
signatureAsBytes = signature.toCanonicalised().encodeToDER();
} else {
// In case we use it for requesting the currently available merit we don't apply a signature
signatureAsBytes = new byte[0];
}
return new Merit(issuance, signatureAsBytes);
}).filter(Objects::nonNull).sorted(Comparator.comparing(Merit::getIssuanceTxId)).collect(Collectors.toList()));
}
use of bisq.core.dao.governance.merit.MeritList in project bisq-core by bisq-network.
the class VoteResultService method getDecryptedBallotsWithMeritsSet.
private Set<DecryptedBallotsWithMerits> getDecryptedBallotsWithMeritsSet(int chainHeight) {
// We want all voteRevealTxOutputs which are in current cycle we are processing.
return bsqStateService.getVoteRevealOpReturnTxOutputs().stream().filter(txOutput -> periodService.isTxInCorrectCycle(txOutput.getTxId(), chainHeight)).map(txOutput -> {
// TODO make method
byte[] opReturnData = txOutput.getOpReturnData();
String voteRevealTxId = txOutput.getTxId();
Optional<Tx> optionalVoteRevealTx = bsqStateService.getTx(voteRevealTxId);
if (!optionalVoteRevealTx.isPresent()) {
log.error("optionalVoteRevealTx is not present. voteRevealTxId={}", voteRevealTxId);
// TODO throw exception
return null;
}
Tx voteRevealTx = optionalVoteRevealTx.get();
try {
// TODO maybe verify version in opReturn
byte[] hashOfBlindVoteList = VoteResultConsensus.getHashOfBlindVoteList(opReturnData);
SecretKey secretKey = VoteResultConsensus.getSecretKey(opReturnData);
TxOutput blindVoteStakeOutput = VoteResultConsensus.getConnectedBlindVoteStakeOutput(voteRevealTx, bsqStateService);
long blindVoteStake = blindVoteStakeOutput.getValue();
Tx blindVoteTx = VoteResultConsensus.getBlindVoteTx(blindVoteStakeOutput, bsqStateService, periodService, chainHeight);
String blindVoteTxId = blindVoteTx.getId();
// Here we deal with eventual consistency of the p2p network data!
// TODO make more clear we are in p2p domain now
List<BlindVote> blindVoteList = BlindVoteConsensus.getSortedBlindVoteListOfCycle(blindVoteListService);
Optional<BlindVote> optionalBlindVote = blindVoteList.stream().filter(blindVote -> blindVote.getTxId().equals(blindVoteTxId)).findAny();
if (optionalBlindVote.isPresent()) {
BlindVote blindVote = optionalBlindVote.get();
VoteWithProposalTxIdList voteWithProposalTxIdList = VoteResultConsensus.decryptVotes(blindVote.getEncryptedVotes(), secretKey);
MeritList meritList = MeritConsensus.decryptMeritList(blindVote.getEncryptedMeritList(), secretKey);
// We lookup for the proposals we have in our local list which match the txId from the
// voteWithProposalTxIdList and create a ballot list with the proposal and the vote from
// the voteWithProposalTxIdList
BallotList ballotList = createBallotList(voteWithProposalTxIdList);
return new DecryptedBallotsWithMerits(hashOfBlindVoteList, voteRevealTxId, blindVoteTxId, blindVoteStake, ballotList, meritList);
} else {
// TODO handle recovering
log.warn("We have a blindVoteTx but we do not have the corresponding blindVote in our local list.\n" + "That can happen if the blindVote item was not properly broadcast. We will go on " + "and see if that blindVote was part of the majority data view. If so we should " + "recover the missing blind vote by a request to our peers. blindVoteTxId={}", blindVoteTxId);
return null;
}
} catch (MissingBallotException e) {
// TODO handle case that we are missing proposals
log.error("We are missing proposals to create the vote result: " + e.toString());
return null;
} catch (Throwable e) {
log.error("Could not create DecryptedBallotsWithMerits: " + e.toString());
return null;
}
}).filter(Objects::nonNull).collect(Collectors.toSet());
}
Aggregations