Skip to content

Commit

Permalink
feat: add method to restore sml store from json (#213)
Browse files Browse the repository at this point in the history
  • Loading branch information
antouhou authored Dec 28, 2020
1 parent 942368c commit 38efe81
Show file tree
Hide file tree
Showing 10 changed files with 16,940 additions and 11 deletions.
27 changes: 27 additions & 0 deletions lib/deterministicmnlist/SimplifiedMNList.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ const BufferWriter = require('../encoding/bufferwriter');
const Hash = require('../crypto/hash');
const { getMerkleTree, getMerkleRoot } = require('../util/merkletree');
const SimplifiedMNListDiff = require('./SimplifiedMNListDiff');
const QuorumEntry = require('./QuorumEntry');
const SimplifiedMNListEntry = require('./SimplifiedMNListEntry');
const PartialMerkleTree = require('../block/PartialMerkleTree');
const constants = require('../constants');
const Networks = require('../networks');
const Transaction = require('../transaction');
Expand Down Expand Up @@ -449,6 +452,30 @@ SimplifiedMNList.prototype.toSimplifiedMNListDiff = function toSimplifiedMNListD
}, network);
};

/**
* Recreates SML from json
* @param {Object} smlJson
*/
SimplifiedMNList.fromJSON = function fromJSON(smlJson) {
const sml = new SimplifiedMNList();
sml.baseBlockHash = smlJson.baseBlockHash;
sml.blockHash = smlJson.blockHash;
sml.merkleRootMNList = smlJson.merkleRootMNList;
sml.lastDiffMerkleRootMNList = smlJson.lastDiffMerkleRootMNList;
sml.lastDiffMerkleRootQuorums = smlJson.lastDiffMerkleRootQuorums;
sml.quorumsActive = smlJson.quorumsActive;
sml.cbTx = new Transaction(smlJson.cbTx);
sml.cbTxMerkleTree = new PartialMerkleTree();
sml.cbTxMerkleTree.totalTransactions = smlJson.cbTxMerkleTree.totalTransactions;
sml.cbTxMerkleTree.merkleHashes = smlJson.cbTxMerkleTree.merkleHashes;
sml.cbTxMerkleTree.merkleFlags = smlJson.cbTxMerkleTree.merkleFlags;
sml.mnList = smlJson.mnList.map(mnRecord => new SimplifiedMNListEntry(mnRecord));
sml.quorumList = smlJson.quorumList.map(quorumEntry => new QuorumEntry(quorumEntry));
sml.validMNs = smlJson.validMNs.map(mnRecord => new SimplifiedMNListEntry(mnRecord));

return sml;
};

/**
* Deterministically selects all members of the quorum which
* has started it's DKG session with the block of this MNList
Expand Down
21 changes: 20 additions & 1 deletion lib/deterministicmnlist/SimplifiedMNListDiff.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,9 @@ SimplifiedMNListDiff.fromObject = function fromObject(obj, network) {
simplifiedMNListDiff.cbTx = new Transaction(obj.cbTx);
// Copy array of strings
simplifiedMNListDiff.deletedMNs = obj.deletedMNs.slice();
simplifiedMNListDiff.mnList = obj.mnList.map(SMLEntry => new SimplifiedMNListEntry(SMLEntry, validNetwork));
simplifiedMNListDiff.mnList = obj.mnList.map(
SMLEntry => new SimplifiedMNListEntry(SMLEntry, validNetwork),
);
simplifiedMNListDiff.deletedQuorums = obj.deletedQuorums.slice();
simplifiedMNListDiff.newQuorums = obj.newQuorums.map(quorumEntry => new QuorumEntry(quorumEntry));
simplifiedMNListDiff.merkleRootMNList = obj.merkleRootMNList;
Expand All @@ -185,6 +187,23 @@ SimplifiedMNListDiff.fromObject = function fromObject(obj, network) {
return simplifiedMNListDiff;
};

/**
* This method constructs the diff from the JSON produced by JSON.sringify.
* PLEASE DON'T PASS RESULT OF .toObject() to this method!
* @param {Object} diffJSON
* @return {SimplifiedMNListDiff}
*/
SimplifiedMNListDiff.fromJSON = function fromJSON(diffJSON) {
const cbTxMerkleTree = new PartialMerkleTree();
cbTxMerkleTree.totalTransactions = diffJSON.cbTxMerkleTree.totalTransactions;
cbTxMerkleTree.merkleHashes = diffJSON.cbTxMerkleTree.merkleHashes;
cbTxMerkleTree.merkleFlags = diffJSON.cbTxMerkleTree.merkleFlags;

return SimplifiedMNListDiff.fromObject({
...diffJSON, cbTxMerkleTree,
}, Networks.get(diffJSON.network.name));
};

SimplifiedMNListDiff.prototype.toObject = function toObject() {
const obj = {};
obj.baseBlockHash = this.baseBlockHash;
Expand Down
25 changes: 24 additions & 1 deletion lib/deterministicmnlist/SimplifiedMNListStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,12 @@ SimplifiedMNListStore.prototype.addDiff = function addDiff(diff) {
}

if (this.diffStore.length >= this.maxDiffs - 1) {
let oldestCoinbase = this.diffStore[0].diff.cbTx;
this.baseSimplifiedMNList.applyDiff(this.diffStore[0].diff);
if (typeof oldestCoinbase === 'string') {
oldestCoinbase = new Transaction(oldestCoinbase);
}
this.baseHeight = oldestCoinbase.extraPayload.height;
this.diffStore.shift();
}

Expand Down Expand Up @@ -127,7 +132,7 @@ SimplifiedMNListStore.prototype.getSMLbyHeight = function getSMLbyHeight(height)
const diffs = this.getSMLDiffbyHeightRange(this.baseHeight, height);

if (diffs.length === 0) {
throw new Error('unable to construct SML at this height');
throw new Error(`Unable to reconstruct SML at height ${height}`);
}
return this.createListFromBaseAndDiffs(diffs);
};
Expand Down Expand Up @@ -156,4 +161,22 @@ SimplifiedMNListStore.prototype.createListFromBaseAndDiffs = function createList
return createdList;
};

/**
* Restores store that was recreated from JSON.stringify
* @param smlStoreJSON
* @return {SimplifiedMNListStore}
*/
SimplifiedMNListStore.fromJSON = function fromJSON(smlStoreJSON) {
const baseDiff = SimplifiedMNList
.fromJSON(smlStoreJSON.baseSimplifiedMNList).toSimplifiedMNListDiff();
// Getting jsons of all other diffs
const diffsFromFile = smlStoreJSON.diffStore
.map(diff => SimplifiedMNListDiff.fromJSON(diff.diff));
// Concatenating all diffs into an array
const totalDiffsFromFile = [baseDiff, ...diffsFromFile];
const smlStore = new SimplifiedMNListStore(totalDiffsFromFile, smlStoreJSON.options);

return smlStore;
};

module.exports = SimplifiedMNListStore;
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.19.17",
"version": "0.19.18",
"description": "A pure and powerful JavaScript Dash library.",
"author": "Dash Core Group, Inc. <dev@dash.org>",
"main": "index.js",
Expand Down
37 changes: 34 additions & 3 deletions test/deterministicmnlist/SimplifiedMNListStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ const constants = require('../../lib/constants');
const SimplifiedMNListStore = require('../../lib/deterministicmnlist/SimplifiedMNListStore');
const SMNListFixture = require('../fixtures/mnList');
const Transaction = require('../../lib/transaction');
const getSMLStoreJSONFixture = require('../fixtures/getSMLStoreJSON');
const sml4848Json = require('../fixtures/smlstore4848_4864.json');

let smlDiffArray;


let sml4848;

describe('SimplifiedMNListStore', function () {
this.timeout(5000);

beforeEach(()=>{
smlDiffArray = SMNListFixture.getChainlockDiffArray();
sml4848 = SimplifiedMNListStore.fromJSON(sml4848Json);
});

describe('constructor', function () {
Expand Down Expand Up @@ -101,7 +103,36 @@ describe('SimplifiedMNListStore', function () {
const height = 11111;
expect(function () {
smlStore.getSMLbyHeight(height);
}).to.throw('unable to construct SML at this height');
}).to.throw('Unable to reconstruct SML at height 11111');
});
});
describe('.fromJSON', function () {
it('should restore an SML store from JSON', function () {
const smlStoreJSON = getSMLStoreJSONFixture();
const smlStore = SimplifiedMNListStore.fromJSON(getSMLStoreJSONFixture());
const restoredSmlStoreJson = JSON.parse(JSON.stringify(smlStore));

expect(restoredSmlStoreJson).to.be.deep.equal(smlStoreJSON);
});
});
describe('.addDiff', function () {
it('should update baseHeight if the base diff was updated', function () {
const smlStore = SimplifiedMNListStore.fromJSON(getSMLStoreJSONFixture());

expect(smlStore.baseHeight).to.be.equal(4838);

const diffAtHeight4854 = sml4848.diffStore[4].diff;
const diffAtHeight4855 = sml4848.diffStore[5].diff;

smlStore.addDiff(diffAtHeight4854);

expect(smlStore.baseHeight).to.be.equal(4839);
expect(smlStore.tipHeight).to.be.equal(smlStore.baseHeight + 15);

smlStore.addDiff(diffAtHeight4855);

expect(smlStore.baseHeight).to.be.equal(4840);
expect(smlStore.tipHeight).to.be.equal(smlStore.baseHeight + 15);
});
});
});
5 changes: 5 additions & 0 deletions test/fixtures/getSMLStoreJSON.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const json = require('./smlstore4765_4853.json');

module.exports = function () {
return JSON.parse(JSON.stringify(json));
}
Loading

0 comments on commit 38efe81

Please sign in to comment.