UNPKG

parsec-lib

Version:

transaction and block implementation

85 lines (76 loc) 7.44 kB
'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _createClass = function () {function defineProperties(target, props) {for (var i = 0; i < props.length; i++) {var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);}}return function (Constructor, protoProps, staticProps) {if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;};}(); /** * Copyright (c) 2018-present, Parsec Labs (parseclabs.org) * * This source code is licensed under the GNU Affero General Public License, * version 3, found in the LICENSE file in the root directory of this source * tree. */ var _ethereumjsUtil = require('ethereumjs-util'); var _merkleTree = require('./merkleTree');var _merkleTree2 = _interopRequireDefault(_merkleTree);function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}function _classCallCheck(instance, Constructor) {if (!(instance instanceof Constructor)) {throw new TypeError("Cannot call a class as a function");}}var Period = function () { function Period(prevHash, blocks) {var _this = this;_classCallCheck(this, Period); this.prevHash = prevHash; this.blockList = []; this.blockHashList = []; if (blocks) { blocks.forEach(function (block) {return _this.addBlock(block);}); } }_createClass(Period, [{ key: 'addBlock', value: function addBlock( block) { if (this.blockHashList.indexOf(block.hash()) > -1) { throw Error('block already contained'); } this.blockList.push(block); this.blockHashList.push(block.hash()); // invalidate existing tree // todo: optimize not to recalculate the whole tree on every tx added this.merkleTree = null; return this; } }, { key: 'getMerkleTree', value: function getMerkleTree() { if (this.blockList.length === 0) { throw Error('no blocks contained'); } if (!this.merkleTree) { var hashBufs = this.blockList.map(function (block) { if (block.txList.length === 0) { return Buffer.alloc(32, 0); } return block.getMerkleTree().getRoot(); }); this.merkleTree = new _merkleTree2.default(hashBufs); } return this.merkleTree; } }, { key: 'merkleRoot', value: function merkleRoot() { return this.getMerkleTree().getHexRoot(); } }, { key: 'proof', value: function proof( tx) { var blockPos = void 0; var periodPos = -1; for (var i = 0; i < this.blockList.length; i++) { var pos = this.blockList[i].txHashList.indexOf(tx.hash()); if (pos >= 0) { if (periodPos >= 0) { throw Error('tx doublespend'); } blockPos = pos; periodPos = i; } } if (blockPos < 0) { throw Error('tx not in this period'); } // get block proof in period var blockProof = this.getMerkleTree(). getProof(this.blockList[periodPos].getMerkleTree().getRoot()). map(function (buff) {return (0, _ethereumjsUtil.bufferToHex)(buff);}); // get tx proof in block var proof = this.blockList[periodPos].proof(tx, periodPos); // merge and return blockProof.forEach(function (elem) {return proof.push(elem);}); // replace root proof[0] = this.merkleRoot(); return proof; } }]);return Period;}();exports.default = Period;module.exports = exports['default'];