Calculate POW target
This commit is contained in:
parent
8c2f180037
commit
a7eb439706
|
@ -5,6 +5,8 @@
|
|||
"use strict";
|
||||
|
||||
var hash = require("hash.js");
|
||||
var BN = require("bn.js");
|
||||
var assert = require("./util").assert;
|
||||
|
||||
exports.sha512 = function(buf) {
|
||||
return new Buffer(hash.sha512().update(buf).digest());
|
||||
|
@ -23,3 +25,19 @@ exports.randomBytes = function(size) {
|
|||
window.crypto.getRandomValues(arr);
|
||||
return new Buffer(arr);
|
||||
};
|
||||
|
||||
var B64 = new BN("18446744073709551616");
|
||||
|
||||
exports.getTarget = function(opts) {
|
||||
var length = new BN(opts.payloadLength);
|
||||
length.iaddn(8);
|
||||
length.iaddn(opts.payloadLengthExtraBytes);
|
||||
var denominator = new BN(opts.ttl);
|
||||
denominator.imul(length);
|
||||
denominator.idivn(65536);
|
||||
denominator.iadd(length);
|
||||
denominator.imul(new BN(opts.nonceTrialsPerByte));
|
||||
var target = parseInt(B64.div(denominator).toString(16), 16);
|
||||
assert(target <= 9007199254740991, "Unsafe target");
|
||||
return target;
|
||||
};
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
"use strict";
|
||||
|
||||
var crypto = require("crypto");
|
||||
var bignum = require("bignum");
|
||||
var assert = require("./util").assert;
|
||||
|
||||
var createHash = crypto.createHash;
|
||||
|
||||
exports.sha512 = function(buf) {
|
||||
|
@ -20,3 +23,25 @@ exports.ripemd160 = function(buf) {
|
|||
};
|
||||
|
||||
exports.randomBytes = crypto.randomBytes;
|
||||
|
||||
// 2^64.
|
||||
var B64 = bignum("18446744073709551616");
|
||||
|
||||
// NOTE(Kagami): We can't calculate entire target in JavaScript but the
|
||||
// result can be represented in native number type without losing
|
||||
// precision (targets mainly much less than 2^53).
|
||||
exports.getTarget = function(opts) {
|
||||
// Calculate it bottom-up, right-to-left.
|
||||
var length = bignum(opts.payloadLength)
|
||||
// To account for the nonce which we will append later.
|
||||
.add(8)
|
||||
.add(opts.payloadLengthExtraBytes);
|
||||
var denominator = bignum(opts.ttl)
|
||||
.mul(length)
|
||||
.div(65536)
|
||||
.add(length)
|
||||
.mul(opts.nonceTrialsPerByte);
|
||||
var target = B64.div(denominator).toNumber();
|
||||
assert(target <= 9007199254740991, "Unsafe target");
|
||||
return target;
|
||||
};
|
||||
|
|
31
lib/pow.js
31
lib/pow.js
|
@ -3,3 +3,34 @@
|
|||
* @see {@link https://bitmessage.org/wiki/Proof_of_work}
|
||||
* @module bitmessage/pow
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var platform = require("./platform");
|
||||
|
||||
var DEFAULT_TRIALS_PER_BYTE = 1000;
|
||||
var DEFAULT_EXTRA_BYTES = 1000;
|
||||
|
||||
/**
|
||||
* Calculate target
|
||||
* @param {{ttl: number, payloadLength: number}} opts - Target options
|
||||
* @return {number} Target.
|
||||
*/
|
||||
// Just a wrapper around platform-specific implementation.
|
||||
exports.getTarget = function(opts) {
|
||||
var nonceTrialsPerByte = opts.nonceTrialsPerByte;
|
||||
// Automatically raise lower values per spec.
|
||||
if (!nonceTrialsPerByte || nonceTrialsPerByte < DEFAULT_TRIALS_PER_BYTE) {
|
||||
nonceTrialsPerByte = DEFAULT_TRIALS_PER_BYTE;
|
||||
}
|
||||
var payloadLengthExtraBytes = opts.payloadLengthExtraBytes;
|
||||
if (!payloadLengthExtraBytes || payloadLengthExtraBytes < DEFAULT_EXTRA_BYTES) {
|
||||
payloadLengthExtraBytes = DEFAULT_EXTRA_BYTES;
|
||||
}
|
||||
return platform.getTarget({
|
||||
ttl: opts.ttl,
|
||||
payloadLength: opts.payloadLength,
|
||||
nonceTrialsPerByte: nonceTrialsPerByte,
|
||||
payloadLengthExtraBytes: payloadLengthExtraBytes,
|
||||
});
|
||||
};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"./lib/platform.js": "./lib/platform.browser.js"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "ALL_TESTS=1 mocha && xvfb-run -a karma start && jshint .",
|
||||
"test": "ALL_TESTS=1 mocha && ALL_TESTS=1 xvfb-run -a karma start && jshint .",
|
||||
"m": "mocha",
|
||||
"k": "xvfb-run -a karma start",
|
||||
"kc": "xvfb-run -a karma start --browsers Chromium",
|
||||
|
@ -46,10 +46,13 @@
|
|||
"mocha": "*"
|
||||
},
|
||||
"dependencies": {
|
||||
"bignum": "^0.9.0",
|
||||
"bn.js": "^1.0.0",
|
||||
"bs58": "^2.0.0",
|
||||
"buffer-equal": "~0.0.1",
|
||||
"eccrypto": "^0.1.2",
|
||||
"hash.js": "^1.0.2",
|
||||
"object-assign": "^2.0.0"
|
||||
"object-assign": "^2.0.0",
|
||||
"sha.js": "^2.3.0"
|
||||
}
|
||||
}
|
||||
|
|
12
test.js
12
test.js
|
@ -15,6 +15,7 @@ var messageEncodings = structs.messageEncodings;
|
|||
var serviceFeatures = structs.serviceFeatures;
|
||||
var pubkeyFeatures = structs.pubkeyFeatures;
|
||||
var WIF = bitmessage.WIF;
|
||||
var POW = bitmessage.POW;
|
||||
var Address = bitmessage.Address;
|
||||
|
||||
describe("Crypto", function() {
|
||||
|
@ -263,6 +264,13 @@ describe("WIF", function() {
|
|||
});
|
||||
});
|
||||
|
||||
describe("POW", function() {
|
||||
it("should calculate target", function() {
|
||||
expect(POW.getTarget({ttl: 2418984, payloadLength: 628, nonceTrialsPerByte: 1000, payloadLengthExtraBytes: 1000})).to.equal(297422593171);
|
||||
expect(POW.getTarget({ttl: 86400, payloadLength: 628})).to.equal(4864647698763);
|
||||
});
|
||||
});
|
||||
|
||||
describe("High-level classes", function() {
|
||||
// FIXME(Kagami): Add more fail tests.
|
||||
describe("Address", function() {
|
||||
|
@ -296,7 +304,9 @@ describe("High-level classes", function() {
|
|||
expect(addr2.ripe[0]).to.equal(0);
|
||||
});
|
||||
|
||||
if (allTests) {
|
||||
// FIXME(Kagami): Don't run it in browser currently because it's
|
||||
// very slow. This need to be fixed.
|
||||
if (allTests && typeof window === "undefined") {
|
||||
it("should allow to generate shorter address", function() {
|
||||
this.timeout(60000);
|
||||
var addr = Address.fromRandom({ripelen: 18});
|
||||
|
|
Loading…
Reference in New Issue
Block a user