Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@dashevo/dashcore-lib

Package Overview
Dependencies
Maintainers
8
Versions
117
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@dashevo/dashcore-lib - npm Package Compare versions

Comparing version 0.19.5 to 0.19.6

lib/instantlock/instantlock.js

1

index.js

@@ -76,2 +76,3 @@ /* eslint-disable */

bitcore.ChainLock = require('./lib/chainlock/chainlock');
bitcore.InstantLock = require('./lib/instantlock/instantlock');

@@ -78,0 +79,0 @@ // dependencies, subject to change

533

lib/chainlock/chainlock.js

@@ -25,308 +25,319 @@ const { isObject, isString } = require('lodash');

*/
function ChainLock(arg) {
if (arg instanceof ChainLock) {
return arg.copy();
}
const info = ChainLock._from(arg);
class ChainLock {
constructor(arg) {
if (arg instanceof ChainLock) {
return arg.copy();
}
const info = ChainLock._from(arg);
this.height = info.height;
this.blockHash = info.blockHash;
this.signature = info.signature;
this.height = info.height;
this.blockHash = info.blockHash;
this.signature = info.signature;
return this;
}
/**
* @param {Buffer|Object|string} arg - A Buffer, JSON string or Object
* @returns {Object} - An object representing chainlock data
* @throws {TypeError} - If the argument was not recognized
* @private
*/
ChainLock._from = function _from(arg) {
let info = {};
if (BufferUtil.isBuffer(arg)) {
info = ChainLock._fromBufferReader(BufferReader(arg));
} else if (isObject(arg)) {
info = ChainLock._fromObject(arg);
} else if (isHexaString(arg)) {
info = ChainLock.fromHex(arg);
} else {
throw new TypeError('Unrecognized argument for ChainLock');
return this;
}
return info;
};
ChainLock._fromObject = function _fromObject(data) {
$.checkArgument(data, 'data is required');
let blockHash = data.blockHash || data.blockhash;
let { signature } = data;
if (isString(blockHash)) {
blockHash = BufferUtil.reverse(Buffer.from(blockHash, 'hex'));
static get CLSIG_REQUESTID_PREFIX() {
return 'clsig';
}
if (isString(data.signature)) {
signature = Buffer.from(data.signature, 'hex');
/**
* @param {Buffer|Object|string} arg - A Buffer, JSON string or Object
* @returns {Object} - An object representing chainlock data
* @throws {TypeError} - If the argument was not recognized
* @private
*/
static _from(arg) {
let info = {};
if (BufferUtil.isBuffer(arg)) {
info = ChainLock._fromBufferReader(BufferReader(arg));
} else if (isObject(arg)) {
info = ChainLock._fromObject(arg);
} else if (isHexaString(arg)) {
info = ChainLock.fromHex(arg);
} else {
throw new TypeError('Unrecognized argument for ChainLock');
}
return info;
}
const info = {
height: data.height,
blockHash,
signature,
};
return info;
};
/**
* @param {BufferReader} br - Chainlock data
* @returns {Object} - An object representing the chainlock data
* @private
*/
ChainLock._fromBufferReader = function _fromBufferReader(br) {
const info = {};
info.height = br.readInt32LE();
info.blockHash = br.read(SHA256_HASH_SIZE);
info.signature = br.read(BLS_SIGNATURE_SIZE);
return info;
};
static _fromObject(data) {
$.checkArgument(data, 'data is required');
let blockHash = data.blockHash || data.blockhash;
let { signature } = data;
if (isString(blockHash)) {
blockHash = BufferUtil.reverse(Buffer.from(blockHash, 'hex'));
}
/**
* @param {BufferReader} br A buffer reader of the block
* @returns {ChainLock} - An instance of ChainLock
*/
ChainLock.fromBufferReader = function fromBufferReader(br) {
$.checkArgument(br, 'br is required');
const data = ChainLock._fromBufferReader(br);
return new ChainLock(data);
};
if (isString(data.signature)) {
signature = Buffer.from(data.signature, 'hex');
}
return {
height: data.height,
blockHash,
signature,
};
}
/**
* Creates ChainLock from a hex string.
* @param {String} string - A hex string representation of the chainLock
* @return {ChainLock} - An instance of ChainLock
*/
ChainLock.fromString = function fromString(string) {
return ChainLock.fromBuffer(Buffer.from(string, 'hex'));
};
/**
* @param {BufferReader} br - Chainlock data
* @returns {Object} - An object representing the chainlock data
* @private
*/
static _fromBufferReader(br) {
const info = {};
info.height = br.readInt32LE();
info.blockHash = br.read(SHA256_HASH_SIZE);
info.signature = br.read(BLS_SIGNATURE_SIZE);
return info;
}
ChainLock.fromHex = ChainLock.fromString;
/**
* @param {BufferReader} br A buffer reader of the block
* @returns {ChainLock} - An instance of ChainLock
*/
static fromBufferReader(br) {
$.checkArgument(br, 'br is required');
const data = ChainLock._fromBufferReader(br);
return new ChainLock(data);
}
/**
* Creates ChainLock from a Buffer.
* @param {Buffer} buffer - A buffer of the chainLock
* @return {ChainLock} - An instance of ChainLock
*/
ChainLock.fromBuffer = function fromBuffer(buffer) {
return ChainLock.fromBufferReader(new BufferReader(buffer));
};
/**
* Creates ChainLock from a hex string.
* @param {String} string - A hex string representation of the chainLock
* @return {ChainLock} - An instance of ChainLock
*/
static fromString(string) {
return ChainLock.fromBuffer(Buffer.from(string, 'hex'));
}
/**
* Create ChainLock from an object
* @param {Object} obj - an object with all properties of chainlock
* @return {ChainLock}
*/
ChainLock.fromObject = function fromObject(obj) {
const data = ChainLock._fromObject(obj);
return new ChainLock(data);
};
/**
* Creates ChainLock from a hex string.
* @param {String} string - A hex string representation of the chainLock
* @return {ChainLock} - An instance of ChainLock
*/
static fromHex(string) {
return ChainLock.fromBuffer(Buffer.from(string, 'hex'));
}
/**
* Verify that the signature is valid against the Quorum using quorumPublicKey
* @private
* @param {QuorumEntry} quorumEntry - quorum entry to test signature against
* @returns {Promise<Boolean>} - returns the result of the signature verification
*/
async function verifySignatureAgainstQuorum(quorumEntry) {
const { signature } = this;
const { quorumPublicKey } = quorumEntry;
const signHash = this.getSignHashForQuorumEntry(quorumEntry);
/**
* Creates ChainLock from a Buffer.
* @param {Buffer} buffer - A buffer of the chainLock
* @return {ChainLock} - An instance of ChainLock
*/
static fromBuffer(buffer) {
return ChainLock.fromBufferReader(new BufferReader(buffer));
}
const blsInstance = await bls.getInstance();
/**
* Create ChainLock from an object
* @param {Object} obj - an object with all properties of chainlock
* @return {ChainLock}
*/
static fromObject(obj) {
const data = ChainLock._fromObject(obj);
return new ChainLock(data);
}
const quorumPubKey = blsInstance.PublicKey.fromBytes(Buffer.from(quorumPublicKey, 'hex'));
/**
* Verify that the signature is valid against the Quorum using quorumPublicKey
* @private
* @param {QuorumEntry} quorumEntry - quorum entry to test signature against
* @param {Buffer} requestId
* @returns {Promise<Boolean>} - returns the result of the signature verification
*/
async verifySignatureAgainstQuorum(quorumEntry, requestId) {
const { signature } = this;
const { quorumPublicKey } = quorumEntry;
const signHash = this.getSignHashForQuorumEntry(quorumEntry, requestId);
const aggregationInfo = blsInstance.AggregationInfo.fromMsgHash(quorumPubKey, signHash);
const thresholdSignature = blsInstance.Signature.fromBytes(Buffer.from(signature, 'hex'));
const blsInstance = await bls.getInstance();
thresholdSignature.setAggregationInfo(aggregationInfo);
const quorumPubKey = blsInstance.PublicKey.fromBytes(Buffer.from(quorumPublicKey, 'hex'));
return thresholdSignature.verify();
}
const aggregationInfo = blsInstance.AggregationInfo.fromMsgHash(quorumPubKey, signHash);
const thresholdSignature = blsInstance.Signature.fromBytes(Buffer.from(signature, 'hex'));
ChainLock.prototype.verifySignatureAgainstQuorum = verifySignatureAgainstQuorum;
thresholdSignature.setAggregationInfo(aggregationInfo);
/**
* @private
* @param {SimplifiedMNListStore} smlStore - used to reconstruct quorum lists
* @param {number} offset - starting height offset to identify the signatory
* @returns {Promise<Boolean>}
*/
async function verifySignatureWithQuorumOffset(smlStore, offset) {
const requestId = this.getRequestId();
const candidateSignatoryQuorum = this.selectSignatoryQuorum(smlStore, requestId, offset);
// Logic taken from dashsync-iOS
// https://github.com/dashevo/dashsync-iOS/blob/master/DashSync/Models/Chain/DSChainLock.m#L148-L185
// first try with default offset
let result = await this.verifySignatureAgainstQuorum(candidateSignatoryQuorum);
// second try with 0 offset, else with double offset
if (!result && offset === constants.LLMQ_SIGN_HEIGHT_OFFSET) {
result = await this.verifySignatureWithQuorumOffset(smlStore, 0);
} else if (!result && offset === 0) {
result = await this.verifySignatureWithQuorumOffset(
smlStore, constants.LLMQ_SIGN_HEIGHT_OFFSET * 2,
);
return thresholdSignature.verify();
}
return result;
}
/**
* @private
* @param {SimplifiedMNListStore} smlStore - used to reconstruct quorum lists
* @param {Buffer} requestId
* @param {number} offset - starting height offset to identify the signatory
* @returns {Promise<Boolean>}
*/
async verifySignatureWithQuorumOffset(smlStore, requestId, offset) {
const candidateSignatoryQuorum = this.selectSignatoryQuorum(smlStore, requestId, offset);
ChainLock.prototype.verifySignatureWithQuorumOffset = verifySignatureWithQuorumOffset;
// Logic taken from dashsync-iOS
// https://github.com/dashevo/dashsync-iOS/blob/master/DashSync/Models/Chain/DSChainLock.m#L148-L185
// first try with default offset
let result = await this.verifySignatureAgainstQuorum(candidateSignatoryQuorum, requestId);
/**
* Verifies that the signature is valid
* @param {SimplifiedMNListStore} smlStore - used to reconstruct quorum lists
* @returns {Promise<Boolean>} - returns the result of the verification
*/
async function verify(smlStore) {
return this.verifySignatureWithQuorumOffset(smlStore, constants.LLMQ_SIGN_HEIGHT_OFFSET);
}
// second try with 0 offset, else with double offset
if (!result && offset === constants.LLMQ_SIGN_HEIGHT_OFFSET) {
result = await this.verifySignatureWithQuorumOffset(smlStore, requestId, 0);
} else if (!result && offset === 0) {
result = await this.verifySignatureWithQuorumOffset(
smlStore, requestId, constants.LLMQ_SIGN_HEIGHT_OFFSET * 2,
);
}
ChainLock.prototype.verify = verify;
return result;
}
/**
* Validate Chainlock structure
*/
ChainLock.prototype.validate = function validate() {
$.checkArgument(isUnsignedInteger(this.height), 'Expect height to be an unsigned integer');
$.checkArgument(isHexStringOfSize(this.blockHash.toString('hex'), SHA256_HASH_SIZE * 2), `Expected blockhash to be a hex string of size ${SHA256_HASH_SIZE}`);
$.checkArgument(isHexStringOfSize(this.signature.toString('hex'), BLS_SIGNATURE_SIZE * 2), 'Expected signature to be a bls signature');
};
/**
* Verifies that the signature is valid
* @param {SimplifiedMNListStore} smlStore - used to reconstruct quorum lists
* @returns {Promise<Boolean>} - returns the result of the verification
*/
async verify(smlStore) {
const requestId = this.getRequestId();
return this.verifySignatureWithQuorumOffset(
smlStore, requestId, constants.LLMQ_SIGN_HEIGHT_OFFSET,
);
}
/**
* Returns chainLock hash
* @returns {Buffer}
*/
ChainLock.prototype.getHash = function getHash() {
return doubleSha256(this.toBuffer()).reverse();
};
/**
* Validate Chainlock structure
*/
validate() {
$.checkArgument(isUnsignedInteger(this.height), 'Expect height to be an unsigned integer');
$.checkArgument(isHexStringOfSize(this.blockHash.toString('hex'), SHA256_HASH_SIZE * 2), `Expected blockhash to be a hex string of size ${SHA256_HASH_SIZE}`);
$.checkArgument(isHexStringOfSize(this.signature.toString('hex'), BLS_SIGNATURE_SIZE * 2), 'Expected signature to be a bls signature');
}
/**
* Computes the request ID for this ChainLock
* @returns {Buffer} - Request id for this chainlock
*/
ChainLock.prototype.getRequestId = function getRequestId() {
const bufferWriter = new BufferWriter();
/**
* Returns chainLock hash
* @returns {Buffer}
*/
getHash() {
return doubleSha256(this.toBuffer()).reverse();
}
const prefix = ChainLock.CLSIG_REQUESTID_PREFIX;
const prefixLength = prefix.length;
/**
* Computes the request ID for this ChainLock
* @returns {Buffer} - Request id for this chainlock
*/
getRequestId() {
const bufferWriter = new BufferWriter();
bufferWriter.writeVarintNum(prefixLength);
bufferWriter.write(Buffer.from(ChainLock.CLSIG_REQUESTID_PREFIX, 'utf-8'));
bufferWriter.writeUInt32LE(this.height);
const prefix = ChainLock.CLSIG_REQUESTID_PREFIX;
const prefixLength = prefix.length;
// Double-sha is used to protect from extension attacks.
return doubleSha256(bufferWriter.toBuffer()).reverse();
};
bufferWriter.writeVarintNum(prefixLength);
bufferWriter.write(Buffer.from(prefix, 'utf-8'));
bufferWriter.writeUInt32LE(this.height);
/**
* Selects the correct quorum that signed this ChainLock
* msgHash
* @param {SimplifiedMNListStore} smlStore - used to reconstruct quorum lists
* @param {Buffer} requestId
* @returns {QuorumEntry} - signatoryQuorum
*/
ChainLock.prototype.selectSignatoryQuorum = function selectSignatoryQuorum(smlStore, requestId, offset) {
const chainlockSML = smlStore.getSMLbyHeight(this.height - offset);
const scoredQuorums = chainlockSML.calculateSignatoryQuorumScores(
chainlockSML.getChainlockLLMQType(), requestId,
);
// Double-sha is used to protect from extension attacks.
return doubleSha256(bufferWriter.toBuffer()).reverse();
}
scoredQuorums.sort((a, b) => Buffer.compare(a.score, b.score));
return scoredQuorums[0].quorum;
};
/**
* Selects the correct quorum that signed this ChainLock
* msgHash
* @param {SimplifiedMNListStore} smlStore - used to reconstruct quorum lists
* @param {Buffer} requestId
* @param {number} offset
* @returns {QuorumEntry} - signatoryQuorum
*/
selectSignatoryQuorum(smlStore, requestId, offset) {
const chainlockSML = smlStore.getSMLbyHeight(this.height - offset);
const scoredQuorums = chainlockSML.calculateSignatoryQuorumScores(
chainlockSML.getChainlockLLMQType(), requestId,
);
/**
* Computes signature id for a quorum entry
* @param {QuorumEntry} quorumEntry
* @returns {Buffer} - Signature id for this requestId and quorum.
*/
ChainLock.prototype.getSignHashForQuorumEntry = function getSignatureIDForQuorumEntry(quorumEntry) {
const { llmqType, quorumHash } = quorumEntry;
const requestID = this.getRequestId();
const { blockHash } = this;
scoredQuorums.sort((a, b) => Buffer.compare(a.score, b.score));
return scoredQuorums[0].quorum;
}
const bufferWriter = new BufferWriter();
bufferWriter.writeUInt8(llmqType);
bufferWriter.writeReverse(Buffer.from(quorumHash, 'hex'));
bufferWriter.writeReverse(requestID);
bufferWriter.write(blockHash);
return doubleSha256(bufferWriter.toBuffer());
};
/**
* Computes signature id for a quorum entry
* @param {QuorumEntry} quorumEntry
* @param {Buffer} requestId
* @returns {Buffer} - Signature id for this requestId and quorum.
*/
getSignHashForQuorumEntry(quorumEntry, requestId) {
const { llmqType, quorumHash } = quorumEntry;
const { blockHash } = this;
/**
* Serializes chainlock to JSON
* @returns {Object} A plain object with the chainlock information
*/
ChainLock.prototype.toObject = function toJSON() {
return {
height: this.height,
blockHash: BufferUtil.reverse(this.blockHash).toString('hex'),
signature: this.signature.toString('hex'),
};
};
const bufferWriter = new BufferWriter();
bufferWriter.writeUInt8(llmqType);
bufferWriter.writeReverse(Buffer.from(quorumHash, 'hex'));
bufferWriter.writeReverse(requestId);
bufferWriter.write(blockHash);
return doubleSha256(bufferWriter.toBuffer());
}
/**
* Serializes chainlock to Object
* @returns {Object} A plain object with the chainlock information
*/
ChainLock.prototype.toJSON = ChainLock.prototype.toObject;
/**
* Serializes chainlock to JSON
* @returns {Object} A plain object with the chainlock information
*/
toObject() {
return {
height: this.height,
blockHash: BufferUtil.reverse(this.blockHash).toString('hex'),
signature: this.signature.toString('hex'),
};
}
/**
* Serialize ChainLock
* @returns {string} - A hex encoded string of the chainlock
*/
ChainLock.prototype.toString = function toString() {
return this.toBuffer().toString('hex');
};
/**
* Serializes chainlock to JSON
* @returns {Object} A plain object with the chainlock information
*/
toJSON() {
return this.toObject();
}
/**
* Serialize ChainLock to buffer
* @return {Buffer}
*/
ChainLock.prototype.toBuffer = function toBuffer() {
return this.toBufferWriter().toBuffer();
};
/**
* Serialize ChainLock
* @returns {string} - A hex encoded string of the chainlock
*/
toString() {
return this.toBuffer().toString('hex');
}
/**
* @param {BufferWriter} bw - An existing instance BufferWriter
* @returns {BufferWriter} - An instance of BufferWriter representation of the ChainLock
*/
ChainLock.prototype.toBufferWriter = function toBufferWriter(bw) {
const bufferWriter = bw || new BufferWriter();
bufferWriter.writeInt32LE(this.height);
bufferWriter.write(this.blockHash);
bufferWriter.write(this.signature);
return bufferWriter;
};
/**
* Creates a copy of ChainLock
* @return {ChainLock} - a new copy instance of ChainLock
*/
ChainLock.prototype.copy = function copy() {
return ChainLock.fromBuffer(this.toBuffer());
};
/**
* Serialize ChainLock to buffer
* @return {Buffer}
*/
toBuffer() {
return this.toBufferWriter().toBuffer();
}
/**
* Will return a string formatted for the console
*
* @returns {string} ChainLock block hash and height
*/
ChainLock.prototype.inspect = function inspect() {
const reversedBlockHash = BufferUtil.reverse(this.blockHash).toString('hex');
return `<ChainLock: ${reversedBlockHash}, height: ${this.height}>`;
};
/**
* @param {BufferWriter} bw - An existing instance BufferWriter
* @returns {BufferWriter} - An instance of BufferWriter representation of the ChainLock
*/
toBufferWriter(bw) {
const bufferWriter = bw || new BufferWriter();
bufferWriter.writeInt32LE(this.height);
bufferWriter.write(this.blockHash);
bufferWriter.write(this.signature);
return bufferWriter;
}
/**
* Creates a copy of ChainLock
* @return {ChainLock} - a new copy instance of ChainLock
*/
copy() {
return ChainLock.fromBuffer(this.toBuffer());
}
ChainLock.CLSIG_REQUESTID_PREFIX = 'clsig';
/**
* Will return a string formatted for the console
*
* @returns {string} ChainLock block hash and height
*/
inspect() {
const reversedBlockHash = BufferUtil.reverse(this.blockHash).toString('hex');
return `<ChainLock: ${reversedBlockHash}, height: ${this.height}>`;
}
}
module.exports = ChainLock;
{
"name": "@dashevo/dashcore-lib",
"version": "0.19.5",
"version": "0.19.6",
"description": "A pure and powerful JavaScript Dash library.",

@@ -5,0 +5,0 @@ "author": "Dash Core Group, Inc. <dev@dash.org>",

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc