Skip to content

Commit

Permalink
fix: inconsistencies between DashCore RPC quorum output (#161)
Browse files Browse the repository at this point in the history
  • Loading branch information
Cofresi authored Jun 25, 2020
1 parent 0ac0344 commit c0fdf57
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 22 deletions.
43 changes: 30 additions & 13 deletions lib/deterministicmnlist/QuorumEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ var Hash = require('../crypto/hash');
var constants = require('../constants');
var utils = require('../util/js');

var isSha256 = utils.isSha256HexString;
var isHexStringOfSize = utils.isHexStringOfSize;
var isHexString = utils.isHexaString;
var isHexStringOfSize = utils.isHexStringOfSize;
var isUnsignedInteger = utils.isUnsignedInteger;
var isSha256 = utils.isSha256HexString;

var SHA256_HASH_SIZE = constants.SHA256_HASH_SIZE;
var BLS_PUBLIC_KEY_SIZE = constants.BLS_PUBLIC_KEY_SIZE;
Expand Down Expand Up @@ -76,6 +77,18 @@ function QuorumEntry(arg) {
QuorumEntry.fromBuffer = function fromBuffer(buffer) {
var bufferReader = new BufferReader(buffer);
var SMLQuorumEntry = new QuorumEntry();
if (buffer.length < 100) {
SMLQuorumEntry.isOutdatedRPC = true;
SMLQuorumEntry.version = bufferReader.readUInt16LE();
SMLQuorumEntry.llmqType = bufferReader.readUInt8();
SMLQuorumEntry.quorumHash = bufferReader.read(constants.SHA256_HASH_SIZE).reverse().toString('hex');
SMLQuorumEntry.signersCount = bufferReader.readVarintNum();
SMLQuorumEntry.validMembersCount = bufferReader.readVarintNum();
SMLQuorumEntry.quorumPublicKey = bufferReader.read(BLS_PUBLIC_KEY_SIZE).toString('hex');

return SMLQuorumEntry;
}
SMLQuorumEntry.isOutdatedRPC = false;
SMLQuorumEntry.version = bufferReader.readUInt16LE();
SMLQuorumEntry.llmqType = bufferReader.readUInt8();
SMLQuorumEntry.quorumHash = bufferReader.read(constants.SHA256_HASH_SIZE).reverse().toString('hex');
Expand Down Expand Up @@ -113,6 +126,13 @@ QuorumEntry.prototype.toBuffer = function toBuffer() {
bufferWriter.writeUInt8(this.llmqType);
bufferWriter.write(Buffer.from(this.quorumHash, 'hex').reverse());
bufferWriter.writeVarintNum(this.signersCount);
if (this.isOutdatedRPC) {
bufferWriter.writeVarintNum(this.validMembersCount);
bufferWriter.write(Buffer.from(this.quorumPublicKey, 'hex'));

return bufferWriter.toBuffer();
}

bufferWriter.write(Buffer.from(this.signers, 'hex'));
bufferWriter.writeVarintNum(this.validMembersCount);
bufferWriter.write(Buffer.from(this.validMembers, 'hex'));
Expand Down Expand Up @@ -171,6 +191,7 @@ QuorumEntry.prototype.getCommitmentHash = function getCommitmentBuffer() {
*/
QuorumEntry.fromObject = function fromObject(obj) {
var SMLQuorumEntry = new QuorumEntry();
SMLQuorumEntry.isOutdatedRPC = false;
SMLQuorumEntry.version = obj.version;
SMLQuorumEntry.llmqType = obj.llmqType;
SMLQuorumEntry.quorumHash = obj.quorumHash;
Expand All @@ -182,7 +203,9 @@ QuorumEntry.fromObject = function fromObject(obj) {
SMLQuorumEntry.quorumVvecHash = obj.quorumVvecHash;
SMLQuorumEntry.quorumSig = obj.quorumSig;
SMLQuorumEntry.membersSig = obj.membersSig;

if (SMLQuorumEntry.signers === undefined) {
SMLQuorumEntry.isOutdatedRPC = true;
}
SMLQuorumEntry.validate();
return SMLQuorumEntry;
};
Expand All @@ -191,20 +214,14 @@ QuorumEntry.prototype.validate = function validate() {
$.checkArgument(utils.isUnsignedInteger(this.version), 'Expect version to be an unsigned integer');
$.checkArgument(utils.isUnsignedInteger(this.llmqType), 'Expect llmqType to be an unsigned integer');
$.checkArgument(isSha256(this.quorumHash), 'Expected quorumHash to be a sha256 hex string');
if (this.signers) {
$.checkArgument(isUnsignedInteger(this.signersCount), 'Expect signersCount to be an unsigned integer');
$.checkArgument(isUnsignedInteger(this.validMembersCount), 'Expect validMembersCount to be an unsigned integer');
$.checkArgument(isHexStringOfSize(this.quorumPublicKey, BLS_PUBLIC_KEY_SIZE * 2), 'Expected quorumPublicKey to be a bls pubkey');
if (!this.isOutdatedRPC) {
$.checkArgument(utils.isHexaString(this.signers), 'Expect signers to be a hex string');
}
if (this.validMembers) {
$.checkArgument(utils.isHexaString(this.validMembers), 'Expect validMembers to be a hex string');
}
$.checkArgument(isHexStringOfSize(this.quorumPublicKey, BLS_PUBLIC_KEY_SIZE * 2), 'Expected quorumPublicKey to be a bls pubkey');
if (this.quorumVvecHash) {
$.checkArgument(isHexStringOfSize(this.quorumVvecHash, SHA256_HASH_SIZE * 2), `Expected quorumVvecHash to be a hex string of size ${SHA256_HASH_SIZE}`);
}
if (this.quorumSig) {
$.checkArgument(isHexStringOfSize(this.quorumSig, BLS_SIGNATURE_SIZE * 2), 'Expected quorumSig to be a bls signature');
}
if (this.membersSig) {
$.checkArgument(isHexStringOfSize(this.membersSig, BLS_SIGNATURE_SIZE * 2), 'Expected membersSig to be a bls signature');
}
};
Expand Down
18 changes: 11 additions & 7 deletions lib/deterministicmnlist/SimplifiedMNList.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,23 +74,27 @@ SimplifiedMNList.prototype.applyDiff = function applyDiff(simplifiedMNListDiff)

this.cbTx = new Transaction(diff.cbTx);
this.cbTxMerkleTree = diff.cbTxMerkleTree.copy();

this.validMNs = this.mnList.filter(function (smlEntry) {
return smlEntry.isValid;
});
this.quorumsActive = this.cbTx.version >= 2;

if (this.quorumsActive) {
this.deleteQuorums(diff.deletedQuorums);
this.addAndMaybeRemoveQuorums(diff.newQuorums);
this.lastDiffMerkleRootQuorums = diff.merkleRootQuorums || constants.NULL_HASH;
this.merkleRootQuorums = this.calculateMerkleRootQuorums();

// we cannot verify the quorum merkle root for DashCore vers. < 0.16
if (this.quorumList[0].isOutdatedRPC) {
this.merkleRootQuorums = diff.merkleRootQuorums;
return
}

this.merkleRootQuorums = this.calculateMerkleRootQuorums();
if (this.lastDiffMerkleRootQuorums !== this.merkleRootQuorums) {
throw new Error("Quorum merkle root from the diff doesn't match calculated merkle root after diff is applied");
}
}

this.validMNs = this.mnList.filter(function (smlEntry) {
return smlEntry.isValid;
});
};

/**
Expand Down Expand Up @@ -121,7 +125,7 @@ SimplifiedMNList.prototype.addOrUpdateMNs = function addMNs(mnListEntries) {
* if list has reached maximum entries for llmqType
* @param {QuorumEntry[]} quorumEntries
*/
SimplifiedMNList.prototype.addAndMaybeRemoveQuorums = function addOrUpdateQuorums(quorumEntries) {
SimplifiedMNList.prototype.addAndMaybeRemoveQuorums = function addAndMaybeRemoveQuorums(quorumEntries) {

var llmqTypeArray = [...this.getLLMQTypes()];

Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dashevo/dashcore-lib",
"version": "0.18.7",
"version": "0.18.8",
"description": "A pure and powerful JavaScript Dash library.",
"author": "Dash Core Group, Inc. <dev@dash.org>",
"main": "index.js",
Expand Down

0 comments on commit c0fdf57

Please sign in to comment.