Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
e6f7169
[EV-1080] Add file
akfranco Oct 1, 2018
4b93caf
Update package-lock.json
akfranco Oct 1, 2018
55538af
[EV-1080] Add ProUpRegTxPayload transaction
akfranco Oct 4, 2018
c95958d
[EV-1080] Removed extraneous code
akfranco Oct 7, 2018
516e1c9
Merge branch 'evo' of github.com:dashevo/dashcore-lib into feature/pr…
akfranco Oct 10, 2018
681e435
[EV-1080] Update test suite
akfranco Oct 10, 2018
83e704d
[EV-1080] Consistency changes
akfranco Oct 10, 2018
4f9c003
Merge branch 'evo' of github.com:dashevo/dashcore-lib into feature/pr…
akfranco Oct 13, 2018
8c33ad6
[EV-1080] Add inputsHash
akfranco Oct 15, 2018
4fd367a
Added Node Debug Option
akfranco Oct 20, 2018
5297114
[EV-1080] Typo fix
akfranco Oct 20, 2018
e3cda82
[EV-1080] Update logic
akfranco Oct 20, 2018
8f3ec86
[EV-1080] Update tests
akfranco Oct 20, 2018
5028c11
[EV-1080] Fixes
akfranco Oct 20, 2018
0130979
[EV-1080] Reverse not needed
akfranco Oct 20, 2018
4ac2d79
first commit
Oct 22, 2018
3e6b80c
Merge branch 'evo' into feature/proupregtx
Oct 23, 2018
f0329c6
Merge branch 'evo' of https://github.com/dashevo/dashcore-lib into sp…
Oct 23, 2018
6fcd5d8
Merge pull request #62 from dashevo/feature/proupregtx
Oct 23, 2018
e313e17
Merge branch 'evo' of https://github.com/dashevo/dashcore-lib into sp…
Oct 23, 2018
57c893a
add BLSPubKey const
Oct 23, 2018
cccff25
commitment tx
Oct 23, 2018
ea17f4a
add payload to tx
Oct 24, 2018
d2e1a20
refactor + changes
Oct 24, 2018
de43982
update tests
Oct 24, 2018
03e4915
update copy paste typos
Oct 24, 2018
fd5aeb1
merge evo
Oct 30, 2018
7955c1f
remerge
Oct 30, 2018
2c63b1f
remerge
Oct 30, 2018
7889b88
uppdate BLSPubKey to new spec
Oct 31, 2018
07f772f
BLSSig new spec
Oct 31, 2018
30c5a3f
improve constants naming
Oct 31, 2018
ef16216
improve constants naming
Oct 31, 2018
fc31859
Merge branch 'specialtx/qfcommit' of https://github.com/dashevo/dashc…
Oct 31, 2018
df54d72
typo
Cofresi Oct 31, 2018
c651dec
Merge remote-tracking branch 'remotes/origin/evo' into specialtx/qfco…
Cofresi Oct 31, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 170 additions & 0 deletions lib/transaction/payload/commitmenttxpayload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
var utils = require('../../util/js');
var constants = require('./constants');
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;

/**
* @typedef {Object} CommitmentTxPayloadJSON
* @property {number} version uint16_t 2 Version of the final commitment message
* @property {string} quorumHash uint256 32 The quorum identifier
* @property {number} signersSize compactSize uint 1-9 Bit size of the signers bitvector
* @property {string} signers byte[] (bitSize + 7) / 8 Bitset representing the aggregated signers of this final commitment
* @property {number} validMembersSize compactSize uint 1-9 Bit size of the validMembers bitvector
* @property {string} validMembers byte[] (bitSize + 7) / 8 Bitset of valid members in this commitment
* @property {string} quorumPublicKey BLSPubKey 48 The quorum public key
* @property {string} quorumVvecHash uint256 32 The hash of the quorum verification vector
* @property {string} quorumSig BLSSig 96 Recovered threshold signature
* @property {string} sig BLSSig 96 Aggregated BLS signatures from all included commitments
*/

/**
* @class CommitmentTxPayload
* @property {number} version
* @property {number} quorumHash
* @property {number} signersSize
* @property {number} signers
* @property {number} validMembersSize
* @property {number} validMembers
* @property {number} quorumPublicKey
* @property {number} quorumVvecHash
* @property {number} quorumSig
* @property {number} sig
*/

function CommitmentTxPayload(options) {
AbstractPayload.call(this);
this.version = CURRENT_PAYLOAD_VERSION;

if (options) {
this.quorumHash = options.quorumHash;
this.signers = options.signers;
this.validMembers = options.validMembers;
this.quorumPublicKey = options.quorumPublicKey;
this.quorumVvecHash = options.quorumVvecHash;
this.quorumSig = options.quorumSig;
this.sig = options.sig;
}
}

CommitmentTxPayload.prototype = Object.create(AbstractPayload.prototype);
CommitmentTxPayload.prototype.constructor = AbstractPayload;

/* Static methods */

/**
* Parse raw payload
* @param {Buffer} rawPayload
* @return {CommitmentTxPayload}
*/
CommitmentTxPayload.fromBuffer = function fromBuffer(rawPayload) {
var payloadBufferReader = new BufferReader(rawPayload);
var payload = new CommitmentTxPayload();
payload.version = payloadBufferReader.readUInt16LE();
payload.quorumHash = payloadBufferReader.read(constants.SHA256_HASH_SIZE).toString('hex');

payload.signersSize = payloadBufferReader.readVarintNum();
payload.signers = payloadBufferReader.read((payload.signersSize + 7) / 8).toString('hex');

payload.validMembersSize = payloadBufferReader.readVarintNum();
payload.validMembers = payloadBufferReader.read((payload.validMembersSize + 7) / 8).toString('hex');

payload.quorumPublicKey = payloadBufferReader.read(constants.BLS_PUBLIC_KEY_SIZE).toString('hex');
payload.quorumVvecHash = payloadBufferReader.read(constants.SHA256_HASH_SIZE).toString('hex');
payload.quorumSig = payloadBufferReader.read(constants.BLS_SIGNATURE_SIZE).toString('hex');
payload.sig = payloadBufferReader.read(constants.BLS_SIGNATURE_SIZE).toString('hex');

if (!payloadBufferReader.finished()) {
throw new Error('Failed to parse payload: raw payload is bigger than expected.');
}

return payload;
};

/**
* Create new instance of payload from JSON
* @param {string|CommitmentTxPayloadJSON} payloadJson
* @return {CommitmentTxPayload}
*/
CommitmentTxPayload.fromJSON = function fromJSON(payloadJson) {
var payload = new CommitmentTxPayload(payloadJson);
payload.validate();
return payload;
};

/* Instance methods */

/**
* Validate payload
* @return {boolean}
*/
CommitmentTxPayload.prototype.validate = function () {
Preconditions.checkArgument(utils.isUnsignedInteger(this.version), 'Expect version to be an unsigned integer');
Preconditions.checkArgument(utils.isHexaString(this.quorumHash), 'Expect quorumHash to be a hex string');
Preconditions.checkArgument(utils.isHexaString(this.signers), 'Expect signers to be a hex string');
Preconditions.checkArgument(utils.isHexaString(this.validMembers), 'Expect validMembers to be a hex string');
Preconditions.checkArgument(utils.isHexaString(this.quorumPublicKey), 'Expect quorumPublicKey to be a hex string');
Preconditions.checkArgument(utils.isHexaString(this.quorumVvecHash), 'Expect quorumVvecHash to be a hex string');
Preconditions.checkArgument(utils.isHexaString(this.quorumSig), 'Expect quorumSig to be a hex string');
Preconditions.checkArgument(utils.isHexaString(this.sig), 'Expect sig to be a hex string');
};

/**
* Serializes payload to JSON
* @param [options]
* @return {CommitmentTxPayload}
*/
CommitmentTxPayload.prototype.toJSON = function toJSON(options) {
this.validate();
var payloadJSON = {
version: this.version,
quorumHash: this.quorumHash,
signerSize: this.signerSize,
signers: this.signers,
validMembersSize: this.validMembersSize,
validMembers: this.validMembers,
quorumPublicKey: this.quorumPublicKey,
quorumVvecHash: this.quorumVvecHash,
quorumSig: this.quorumSig,
sig: this.sig,
};

return payloadJSON;
};

/**
* Serialize payload to buffer
* @param [options]
* @return {Buffer}
*/
CommitmentTxPayload.prototype.toBuffer = function toBuffer(options) {
this.validate();

// var signerSizeLength = Buffer.from(this.signersSize).length;
// var validMemberSizeLength = Buffer.from(this.validMembersSize).length;

var payloadBufferWriter = new BufferWriter();
payloadBufferWriter
.writeUInt16LE(this.version)
.write(Buffer.from(this.quorumHash, 'hex'))
.writeVarintNum(Buffer.from(this.signers, 'hex').length * 8 - 7)
.write(Buffer.from(this.signers, 'hex'))
.writeVarintNum(Buffer.from(this.validMembers, 'hex').length * 8 - 7)
.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'))

return payloadBufferWriter.toBuffer();
};

CommitmentTxPayload.prototype.copy = function copy() {
return CommitmentTxPayload.fromBuffer(this.toBuffer());
};

module.exports = CommitmentTxPayload;
26 changes: 15 additions & 11 deletions lib/transaction/payload/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,22 @@ module.exports = {
COMPACT_SIGNATURE_SIZE: 65,
// SHA256 hash size in bytes
SHA256_HASH_SIZE: 32,
// Quorum BLS Public Key size in bytes
BLS_PUBLIC_KEY_SIZE: 48,
//BLS Signature size in bytes
BLS_SIGNATURE_SIZE: 96,
registeredTransactionTypes: {
TRANSACTION_NORMAL : 0,
TRANSACTION_PROVIDER_REGISTER : 1,
TRANSACTION_PROVIDER_UPDATE_SERVICE : 2,
TRANSACTION_PROVIDER_UPDATE_REGISTRAR : 3,
TRANSACTION_PROVIDER_UPDATE_REVOKE : 4,
TRANSACTION_COINBASE : 5,
TRANSACTION_SUBTX_REGISTER : 8,
TRANSACTION_SUBTX_TOPUP : 9,
TRANSACTION_SUBTX_RESETKEY : 10,
TRANSACTION_SUBTX_CLOSEACCOUNT : 11,
TRANSACTION_SUBTX_TRANSITION : 12
TRANSACTION_NORMAL: 0,
TRANSACTION_PROVIDER_REGISTER: 1,
TRANSACTION_PROVIDER_UPDATE_SERVICE: 2,
TRANSACTION_PROVIDER_UPDATE_REGISTRAR: 3,
TRANSACTION_PROVIDER_UPDATE_REVOKE: 4,
TRANSACTION_COINBASE: 5,
TRANSACTION_SUBTX_REGISTER: 8,
TRANSACTION_SUBTX_TOPUP: 9,
TRANSACTION_SUBTX_RESETKEY: 10,
TRANSACTION_SUBTX_CLOSEACCOUNT: 11,
TRANSACTION_SUBTX_TRANSITION: 12
},
EMPTY_SIGNATURE_SIZE: 0,
IP_ADDRESS_SIZE: 16,
Expand Down
1 change: 1 addition & 0 deletions lib/transaction/payload/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Payload.SubTxTransitionPayload = require('./subtxtransitionpayload');
Payload.CoinbasePayload = require('./coinbasepayload');
Payload.ProRegTxPayload = require('./proregtxpayload');
Payload.ProTxUpServPayload = require('./proupservtxpayload');
Payload.CommitmentTxPayload = require('./commitmenttxpayload')

Payload.constants = require('./constants');

Expand Down
109 changes: 109 additions & 0 deletions test/transaction/payload/commitmenttxpayload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
var expect = require('chai').expect;
var sinon = require('sinon');

var DashcoreLib = require('../../../index');

var Script = DashcoreLib.Script;
var CommitmentTxPayload = DashcoreLib.Transaction.Payload.CommitmentTxPayload;

var merkleRootMNList = 'e83c76065797d4542f1cd02e00d02093bea6fb53f5ad6aaa160fd3ccb30001b9';
console.log(merkleRootMNList);

var validCommitmentTxPayloadJSON = {
version: 1,
quorumHash: '723d90a45fd882f0df01a56ee1e83f45d03522f390aae5b7f1273745bf2446fd',
signersSize: 9,
signers: 'f01a',
validMembersSize: 9,
validMembers: 'f991',
quorumPublicKey: 'ae5b7f1273724463d90a01a56e45f3d90a01a56e45fd8fd45d03522f390aae5b7f12737244682f0df72e1e83f45bffd5',
quorumVvecHash: '45fd882f0df723d90a01a56ee1e83f45bf2446fd45d03522f390aae5b7f12737',
quorumSig: '3d90a01a56e45fd882f0df72e1e83f45bffd45d03522f390aae5b7f12737241a56e45fd882f0df01a56e45fd882f0df72e1e83f45bffd45d03522f390aae5b7f1273724461a56e45fd882f0df1a56e45fd882f0df1a56e45fd881a56e452f0df',
sig: 'd45d03522f45fd82446f390aae5b7f1273782f0df723d90a01a56ee1e83f45bfd45d03522f45fd82446f390aae5b7f1273782f0df723d90a01a56ee1e83f45bfd45d03522f45fd82446f390aae5b7f1273782f0df723d90a01a56ee1e83f45bf',
};

// Todo after commitement tx implemnetation done in core
// var validCommitmentTxPayloadHexString = ''
// var payload = CommitmentTxPayload.fromBuffer(Buffer.from(validCommitmentTxPayloadHexString, 'hex'));

function checkValidJSON(payload) {
expect(payload.version).to.be.equal(validCommitmentTxPayloadJSON.version);
expect(payload.quorumHash).to.be.equal(validCommitmentTxPayloadJSON.quorumHash);
expect(payload.signers).to.be.equal(validCommitmentTxPayloadJSON.signers);
expect(payload.validMembers).to.be.equal(validCommitmentTxPayloadJSON.validMembers);
expect(payload.quorumPublicKey).to.be.equal(validCommitmentTxPayloadJSON.quorumPublicKey);
expect(payload.quorumVvecHash).to.be.equal(validCommitmentTxPayloadJSON.quorumVvecHash);
expect(payload.quorumSig).to.be.equal(validCommitmentTxPayloadJSON.quorumSig);
expect(payload.sig).to.be.equal(validCommitmentTxPayloadJSON.sig);
}

describe('CommitmentTxPayload', function () {

var payload = null;
var payloadBuffer = null;

describe('.fromJSON', function () {

beforeEach(function () {
sinon.spy(CommitmentTxPayload.prototype, 'validate');
});

afterEach(function () {
CommitmentTxPayload.prototype.validate.restore();
});

it('Should return instance of CommitmentTxPayload and call #validate on it', function () {
payload = CommitmentTxPayload.fromJSON(validCommitmentTxPayloadJSON);
checkValidJSON(payload);
});
});

describe('.toBuffer', function () {
before(function () {
sinon.spy(CommitmentTxPayload.prototype, 'validate');
});

it('Should return payload buffer of specific length', function () {

//Manually calculated from validCommitmentTxPayloadJSON
var expectedBufferLength = 312;

payloadBuffer = payload.toBuffer();
expect(payloadBuffer.length).to.be.equal(expectedBufferLength);
});

after(function () {
CommitmentTxPayload.prototype.validate.restore();
})
});

describe('.fromBuffer', function () {
before(function () {
sinon.spy(CommitmentTxPayload.prototype, 'validate');
});

it('Should return payload from buffer', function () {
var payloadFromBuffer = CommitmentTxPayload.fromBuffer(payloadBuffer);
checkValidJSON(payloadFromBuffer);
});

after(function () {
CommitmentTxPayload.prototype.validate.restore();
})
});

describe('#toJSON', function () {
beforeEach(function () {
sinon.spy(CommitmentTxPayload.prototype, 'validate');
});

afterEach(function () {
CommitmentTxPayload.prototype.validate.restore();
});

it('Should be able to serialize payload JSON', function () {
var payloadJSON = payload.toJSON();
checkValidJSON(payloadJSON);
});
});
});