From cad826ffc697a119a1882e72510da48cfb6440c0 Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Mon, 15 Jul 2019 21:19:18 +0300 Subject: [PATCH] Fix for signers size of quorum commitment transaction (#132) * Fix commitment tx payload signers size serialization and adjusted tests * Bump the version --- .../payload/commitmenttxpayload.js | 17 ++--- package-lock.json | 2 +- package.json | 2 +- .../payload/commitmenttxpayload.js | 72 ++++++++++++------- 4 files changed, 56 insertions(+), 37 deletions(-) diff --git a/lib/transaction/payload/commitmenttxpayload.js b/lib/transaction/payload/commitmenttxpayload.js index 0131edb75..47575b77e 100644 --- a/lib/transaction/payload/commitmenttxpayload.js +++ b/lib/transaction/payload/commitmenttxpayload.js @@ -7,7 +7,6 @@ var Preconditions = require('../../util/preconditions'); var BufferWriter = require('../../encoding/bufferwriter'); var BufferReader = require('../../encoding/bufferreader'); var AbstractPayload = require('./abstractpayload'); -var Script = require('../../script'); var CURRENT_PAYLOAD_VERSION = 1; @@ -83,10 +82,12 @@ CommitmentTxPayload.fromBuffer = function fromBuffer(rawPayload) { payload.quorumHash = payloadBufferReader.read(constants.SHA256_HASH_SIZE).toString('hex'); payload.signersSize = payloadBufferReader.readVarintNum(); - payload.signers = payloadBufferReader.read(Math.floor((payload.signersSize + 7) / 8)).toString('hex'); + var signersBytesToRead = Math.floor((payload.signersSize + 7) / 8) || 1; + payload.signers = payloadBufferReader.read(signersBytesToRead).toString('hex'); payload.validMembersSize = payloadBufferReader.readVarintNum(); - payload.validMembers = payloadBufferReader.read(Math.floor((payload.validMembersSize + 7) / 8)).toString('hex'); + var validMembersBytesToRead = Math.floor((payload.validMembersSize + 7) / 8) || 1; + payload.validMembers = payloadBufferReader.read(validMembersBytesToRead).toString('hex'); payload.quorumPublicKey = payloadBufferReader.read(constants.BLS_PUBLIC_KEY_SIZE).toString('hex'); payload.quorumVvecHash = payloadBufferReader.read(constants.SHA256_HASH_SIZE).toString('hex'); @@ -144,7 +145,7 @@ CommitmentTxPayload.prototype.toJSON = function toJSON(options) { qfcVersion: this.qfcVersion, llmqtype: this.llmqtype, quorumHash: this.quorumHash, - signerSize: this.signerSize, + signersSize: this.signersSize, signers: this.signers, validMembersSize: this.validMembersSize, validMembers: this.validMembers, @@ -188,7 +189,7 @@ CommitmentTxPayload.prototype.toBuffer = function toBuffer(options) { validMemberSizeLength = 10; break; default: - throw new Error(`Invalid llmq type ${this.llmqtype}`); + throw new Error('Invalid llmq type ' + this.llmqtype); } var payloadBufferWriter = new BufferWriter(); @@ -198,14 +199,14 @@ CommitmentTxPayload.prototype.toBuffer = function toBuffer(options) { .writeUInt16LE(this.qfcVersion) .writeUInt8(this.llmqtype) .write(Buffer.from(this.quorumHash, 'hex')) - .writeVarintNum(signerSizeLength) + .writeVarintNum(this.signersSize) .write(Buffer.from(this.signers, 'hex')) - .writeVarintNum(validMemberSizeLength) + .writeVarintNum(this.validMembersSize) .write(Buffer.from(this.validMembers, 'hex')) .write(Buffer.from(this.quorumPublicKey, 'hex')) .write(Buffer.from(this.quorumVvecHash, 'hex')) .write(Buffer.from(this.quorumSig, 'hex')) - .write(Buffer.from(this.sig, 'hex')) + .write(Buffer.from(this.sig, 'hex')); return payloadBufferWriter.toBuffer(); }; diff --git a/package-lock.json b/package-lock.json index ff7545295..1c3822a7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@dashevo/dashcore-lib", - "version": "0.17.6", + "version": "0.17.7", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 97f6d9d0a..d263a15c8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@dashevo/dashcore-lib", - "version": "0.17.6", + "version": "0.17.7", "description": "A pure and powerful JavaScript Dash library.", "author": "Dash Core Group, Inc. ", "main": "index.js", diff --git a/test/transaction/payload/commitmenttxpayload.js b/test/transaction/payload/commitmenttxpayload.js index f8da3ae4f..60451cf19 100644 --- a/test/transaction/payload/commitmenttxpayload.js +++ b/test/transaction/payload/commitmenttxpayload.js @@ -6,27 +6,32 @@ var sinon = require('sinon'); var DashcoreLib = require('../../../index'); -var Script = DashcoreLib.Script; +var Transaction = DashcoreLib.Transaction; var CommitmentTxPayload = DashcoreLib.Transaction.Payload.CommitmentTxPayload; var validCommitmentTxPayloadJSON = { version: 1, - height: 279326, + height: 137051, qfcVersion: 1, llmqtype: 1, - quorumHash: '4cb9568141dded955ed90345b393fc62634be7d260ca328b89afdd0500000000', + quorumHash: "f015624411254dd5a806e16310e7b9989e8224796f57e42bfb01420200000000", signersSize: 50, - signers: '00000000000000', + signers: "ffffffffffff03", validMembersSize: 50, - validMembers: '00000000000000', - quorumPublicKey: '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', - quorumVvecHash: '0000000000000000000000000000000000000000000000000000000000000000', - quorumSig: '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', - sig: '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + validMembers: "ffffffffffff03", + quorumPublicKey: "0ea4465cc4b2e6890e5bd37987822cabf1b79ec8dece016a3be75802482480af29f7961281405d2cb3d6e38157bda824", + quorumVvecHash: "e3107d64e8d2bec7dff1f6d7fd1a9d31a181c82acaf052f8d27b71507fe2db12", + quorumSig: "0f0a203004f025076c7c0d989464013b31a0104155946968317e6abcfafbe70a53c2b57811f0ebe888cef36eacf649401497c569a9f617c3eeaa7eacbc45969389fa229355097abe277f2452792a5f2e84e804bf2eac0843f01690fb6bd10df1", + sig: "195f7a49aed846bcf475a4a3500b15a626c514c9223b46ce6fef505f19af8f8e1cec554cb63a04125c2d19bf0211ea4c15f289f1413b8618abdf7295e44fb196e326a803d9d7c7c69a12314cf88e463653fde5fecb1f8c3d6791180cdc382392" }; -var validCommitmentTxPayloadHexString = '01001e430400010001f2a1f356b9e086220d38754b1de1e4dcbd8b080c3fa0a62c2bd0961400000000320000000000000032000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'; -var payload = CommitmentTxPayload.fromBuffer(Buffer.from(validCommitmentTxPayloadHexString, 'hex')); +var testNetPayloadHex = '01005b170200010001f015624411254dd5a806e16310e7b9989e8224796f57e42bfb0142020000000032ffffffffffff0332ffffffffffff030ea4465cc4b2e6890e5bd37987822cabf1b79ec8dece016a3be75802482480af29f7961281405d2cb3d6e38157bda824e3107d64e8d2bec7dff1f6d7fd1a9d31a181c82acaf052f8d27b71507fe2db120f0a203004f025076c7c0d989464013b31a0104155946968317e6abcfafbe70a53c2b57811f0ebe888cef36eacf649401497c569a9f617c3eeaa7eacbc45969389fa229355097abe277f2452792a5f2e84e804bf2eac0843f01690fb6bd10df1195f7a49aed846bcf475a4a3500b15a626c514c9223b46ce6fef505f19af8f8e1cec554cb63a04125c2d19bf0211ea4c15f289f1413b8618abdf7295e44fb196e326a803d9d7c7c69a12314cf88e463653fde5fecb1f8c3d6791180cdc382392'; +var testNetCommitmentTxHex = '03000600000000000000fd490101005b170200010001f015624411254dd5a806e16310e7b9989e8224796f57e42bfb0142020000000032ffffffffffff0332ffffffffffff030ea4465cc4b2e6890e5bd37987822cabf1b79ec8dece016a3be75802482480af29f7961281405d2cb3d6e38157bda824e3107d64e8d2bec7dff1f6d7fd1a9d31a181c82acaf052f8d27b71507fe2db120f0a203004f025076c7c0d989464013b31a0104155946968317e6abcfafbe70a53c2b57811f0ebe888cef36eacf649401497c569a9f617c3eeaa7eacbc45969389fa229355097abe277f2452792a5f2e84e804bf2eac0843f01690fb6bd10df1195f7a49aed846bcf475a4a3500b15a626c514c9223b46ce6fef505f19af8f8e1cec554cb63a04125c2d19bf0211ea4c15f289f1413b8618abdf7295e44fb196e326a803d9d7c7c69a12314cf88e463653fde5fecb1f8c3d6791180cdc382392'; +var testNetCommitmentTxHash = 'cf4b01ce796a4f37e6af6dd62671b608160d4a39acf3bfe95f9a59d1854b63f3'; + +function getPayloadBuffer() { + return Buffer.from(testNetPayloadHex, 'hex'); +} function checkValidJSON(payload) { expect(payload.version).to.be.equal(validCommitmentTxPayloadJSON.version); @@ -45,9 +50,6 @@ function checkValidJSON(payload) { describe('CommitmentTxPayload', function () { - var payload = null; - var payloadBuffer = null; - describe('.fromJSON', function () { beforeEach(function () { @@ -59,7 +61,7 @@ describe('CommitmentTxPayload', function () { }); it('Should return instance of CommitmentTxPayload and call #validate on it', function () { - payload = CommitmentTxPayload.fromJSON(validCommitmentTxPayloadJSON); + var payload = CommitmentTxPayload.fromJSON(validCommitmentTxPayloadJSON); checkValidJSON(payload); }); }); @@ -69,18 +71,18 @@ describe('CommitmentTxPayload', function () { sinon.spy(CommitmentTxPayload.prototype, 'validate'); }); - it('Should return payload buffer of specific length', function () { + after(function () { + CommitmentTxPayload.prototype.validate.restore(); + }); + it('Should return payload buffer of specific length', function () { + var payload = CommitmentTxPayload.fromBuffer(getPayloadBuffer()); //Manually calculated from validCommitmentTxPayloadJSON - var expectedBufferLength = 329; + var expectedBufferLength = getPayloadBuffer().length; - payloadBuffer = payload.toBuffer(); + var payloadBuffer = payload.toBuffer(); expect(payloadBuffer.length).to.be.equal(expectedBufferLength); }); - - after(function () { - CommitmentTxPayload.prototype.validate.restore(); - }) }); describe('.fromBuffer', function () { @@ -88,14 +90,14 @@ describe('CommitmentTxPayload', function () { sinon.spy(CommitmentTxPayload.prototype, 'validate'); }); + after(function () { + CommitmentTxPayload.prototype.validate.restore(); + }); + it('Should return payload from buffer', function () { - var payloadFromBuffer = CommitmentTxPayload.fromBuffer(payloadBuffer); + var payloadFromBuffer = CommitmentTxPayload.fromBuffer(getPayloadBuffer()); checkValidJSON(payloadFromBuffer); }); - - after(function () { - CommitmentTxPayload.prototype.validate.restore(); - }) }); describe('#toJSON', function () { @@ -108,8 +110,24 @@ describe('CommitmentTxPayload', function () { }); it('Should be able to serialize payload JSON', function () { + var payload = CommitmentTxPayload.fromBuffer(getPayloadBuffer()); var payloadJSON = payload.toJSON(); checkValidJSON(payloadJSON); }); }); + + describe('#toString', function () { + it('Should serizlize to the same hex string', function () { + var expectedCommitementHex = '03000600000000000000fd3d01010009020000010064b5fc275d292adda4e5c454e93f4bc47d2c77975fb0d06bb07bd6bada068bdf0c050005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'; + var parsed = new Transaction(expectedCommitementHex); + console.log(parsed.hash); + var actualCommitementHex = parsed.toString(); + expect(actualCommitementHex).to.be.equal(expectedCommitementHex); + + var testnetParsedTransaction = new Transaction(testNetCommitmentTxHex); + var ped = testnetParsedTransaction.extraPayload.toJSON(); + expect(testnetParsedTransaction.toString()).to.be.equal(testNetCommitmentTxHex); + expect(testnetParsedTransaction.hash).to.be.equal(testNetCommitmentTxHash); + }); + }); });