Skip to content

Commit 8bec51b

Browse files
authored
fix: crash is there's no signatory candidate when verifying chainlock (#210)
1 parent bcaa7f4 commit 8bec51b

File tree

4 files changed

+28
-7
lines changed

4 files changed

+28
-7
lines changed

lib/chainlock/chainlock.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,14 @@ class ChainLock {
171171
*/
172172
async verifySignatureWithQuorumOffset(smlStore, requestId, offset) {
173173
const candidateSignatoryQuorum = this.selectSignatoryQuorum(smlStore, requestId, offset);
174+
let result = false;
174175

175-
// Logic taken from dashsync-iOS
176-
// https://github.com/dashevo/dashsync-iOS/blob/master/DashSync/Models/Chain/DSChainLock.m#L148-L185
177-
// first try with default offset
178-
let result = await this.verifySignatureAgainstQuorum(candidateSignatoryQuorum, requestId);
176+
if (candidateSignatoryQuorum != null) {
177+
// Logic taken from dashsync-iOS
178+
// https://github.com/dashevo/dashsync-iOS/blob/master/DashSync/Models/Chain/DSChainLock.m#L148-L185
179+
// first try with default offset
180+
result = await this.verifySignatureAgainstQuorum(candidateSignatoryQuorum, requestId);
181+
}
179182

180183
// second try with 0 offset, else with double offset
181184
if (!result && offset === constants.LLMQ_SIGN_HEIGHT_OFFSET) {
@@ -242,14 +245,18 @@ class ChainLock {
242245
* @param {SimplifiedMNListStore} smlStore - used to reconstruct quorum lists
243246
* @param {Buffer} requestId
244247
* @param {number} offset
245-
* @returns {QuorumEntry} - signatoryQuorum
248+
* @returns {QuorumEntry|null} - signatoryQuorum
246249
*/
247250
selectSignatoryQuorum(smlStore, requestId, offset) {
248251
const chainlockSML = smlStore.getSMLbyHeight(this.height - offset);
249252
const scoredQuorums = chainlockSML.calculateSignatoryQuorumScores(
250253
chainlockSML.getChainlockLLMQType(), requestId,
251254
);
252255

256+
if (scoredQuorums.length === 0) {
257+
return null;
258+
}
259+
253260
scoredQuorums.sort((a, b) => Buffer.compare(a.score, b.score));
254261
return scoredQuorums[0].quorum;
255262
}

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@dashevo/dashcore-lib",
3-
"version": "0.19.14",
3+
"version": "0.19.15",
44
"description": "A pure and powerful JavaScript Dash library.",
55
"author": "Dash Core Group, Inc. <dev@dash.org>",
66
"main": "index.js",

test/chainlock/chainlock.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ const expect = chai.expect;
66

77
const bitcore = require('../../index');
88
const SimplifiedMNListStore = require('../../lib/deterministicmnlist/SimplifiedMNListStore');
9+
const SimplifiedMNList = require('../../lib/deterministicmnlist/SimplifiedMNList');
910
const SMNListFixture = require('../fixtures/mnList');
1011
const ChainLock = bitcore.ChainLock;
1112
const QuorumEntry = bitcore.QuorumEntry;
13+
const Networks = bitcore.Networks;
1214

1315
describe('ChainLock', function () {
1416
let object;
@@ -167,6 +169,18 @@ describe('ChainLock', function () {
167169
const isValid = await chainLock.verify(SMLStore);
168170
expect(isValid).to.equal(true);
169171
});
172+
it("should return false if SML store does not have a signatory candidate", async function () {
173+
const chainLock = new ChainLock(buf4);
174+
const smlDiffArray = SMNListFixture.getChainlockDiffArray();
175+
const SMLStore = new SimplifiedMNListStore(smlDiffArray);
176+
SMLStore.getSMLbyHeight = function () {
177+
var sml = new SimplifiedMNList();
178+
sml.network = Networks.testnet;
179+
return sml;
180+
};
181+
const isValid = await chainLock.verify(SMLStore);
182+
expect(isValid).to.equal(false);
183+
});
170184
});
171185
});
172186

0 commit comments

Comments
 (0)