Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 'use strict';
- var isObject = require('./utils').isObject,
- Parallel = require('paralleljs'),
- defaultOptions = {
- resolved: function() {},
- evalPath: null,
- sha3Path: null,
- workersCount: navigator.hardwareConcurrency || 4,
- workersLifetime: 15, // seconds
- workersOffset: 1
- };
- function POW(options) {
- if (!isObject(options)) {
- options = {};
- }
- this.options = Object.assign({}, defaultOptions, options);
- }
- POW.isSupported = Parallel.isSupported;
- POW.prototype = {
- solve: function(challenge) {
- challenge = Object.entries(challenge);
- this.startedOps = 0;
- this.doneOps = 0;
- this.results = {};
- challenge.forEach(function(ch) {
- var key = ch[0],
- value = ch[1],
- stamp, prefix;
- if (!value.algorithm) {
- return;
- }
- stamp = this.makeStamp(value);
- prefix = this.makePrefix(value);
- this.startedOps++;
- this.results[key] = null;
- this.spawn(key, stamp, prefix);
- }.bind(this));
- },
- spawn: function(key, stamp, prefix) {
- var data = [],
- expiresAt = Date.now() / 1000 + this.options.workersLifetime,
- parallel;
- for (var i = 0; i < this.options.workersCount; i++) {
- data.push({
- key: key,
- stamp: stamp,
- prefix: prefix,
- offset: this.options.workersOffset + i,
- step: this.options.workersCount,
- expiresAt: expiresAt
- });
- }
- parallel = new Parallel(data, {
- evalPath: this.options.evalPath,
- maxWorkers: this.options.workersCount
- });
- parallel.require(this.options.sha3Path).race(workersSolve).then(this.resolved.bind(this));
- },
- resolved: function(results) {
- var result = null,
- resultsPairs = Object.entries(results);
- for (var i = 0; i < resultsPairs.length; i++) {
- if (resultsPairs[i][1] !== null) {
- result = resultsPairs[i][1];
- break;
- }
- }
- this.results[result.key] = result.counter;
- if (++this.doneOps !== this.startedOps) {
- return;
- }
- if (!this.checkResults()) {
- this.options.resolved({
- type: 'pow'
- });
- return;
- }
- this.options.resolved({
- type: 'pow',
- results: this.results,
- key: this.options.challengeKey
- });
- },
- checkResults: function() {
- var results = Object.values(this.results);
- return results.every(Boolean);
- },
- makeStamp: function(challenge) {
- return [
- challenge.algorithm.version,
- challenge.complexity,
- challenge.timestamp,
- challenge.algorithm.resourse,
- challenge.algorithm.extension,
- challenge.random_string // jshint ignore:line
- ].join(':');
- },
- makePrefix: function(challenge) {
- return new Array(challenge.complexity + 1).join('0');
- }
- };
- var workersSolve = function(options) {
- var key = options.key,
- stamp = options.stamp,
- prefix = options.prefix,
- counter = options.offset,
- step = options.step,
- expiresAt = options.expiresAt;
- var checkIsExpired = function() {
- var now = Date.now() / 1000;
- return expiresAt < now;
- };
- var checkPrefix = function(counter) {
- var hash = CryptoJS.SHA3([stamp, counter].join(':'));
- return String(hash, {
- outputLength: 512
- }).indexOf(prefix) === 0;
- };
- while (true) {
- if (counter % 1000 === 0 && checkIsExpired()) {
- return {
- key: key,
- counter: null
- };
- }
- if (checkPrefix(counter)) {
- return {
- key: key,
- counter: counter
- };
- }
- counter += step;
- }
- };
- module.exports = POW;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement