spruce things up for the browser.
This commit is contained in:
parent
10efd549ce
commit
f71aa44acc
12
Makefile
12
Makefile
@ -1,12 +1,14 @@
|
||||
all:
|
||||
@browserify lib/bcoin.js -o bcoin.browser.js
|
||||
@uglifyjs --comments '/\*[^\0]+?Copyright[^\0]+?\*/' -o bcoin.min.js bcoin.browser.js
|
||||
@./node_modules/.bin/browserify lib/bcoin.js -o browser/bcoin.js
|
||||
|
||||
ugly:
|
||||
@uglifyjs --comments '/\*[^\0]+?Copyright[^\0]+?\*/' -o browser/bcoin.min.js browser/bcoin.js
|
||||
|
||||
clean:
|
||||
@rm bcoin.browser.js
|
||||
@rm bcoin.min.js
|
||||
@rm browser/bcoin.js
|
||||
@rm browser/bcoin.min.js
|
||||
|
||||
test:
|
||||
@npm test
|
||||
|
||||
.PHONY: all clean test
|
||||
.PHONY: all ugly clean test
|
||||
|
||||
@ -575,7 +575,6 @@ Block.prototype.inspect = function inspect() {
|
||||
ts: this.ts,
|
||||
bits: this.bits,
|
||||
nonce: this.nonce,
|
||||
totalTX: this.totalTX,
|
||||
txs: this.txs
|
||||
};
|
||||
};
|
||||
|
||||
@ -409,7 +409,7 @@ ChainEntry.prototype.toRaw = function toRaw(writer) {
|
||||
p.writeU32(this.bits);
|
||||
p.writeU32(this.nonce);
|
||||
p.writeU32(this.height);
|
||||
p.writeBytes(this.chainwork.toBuffer('le', 32));
|
||||
p.writeBytes(this.chainwork.toArrayLike(Buffer, 'le', 32));
|
||||
|
||||
if (!writer)
|
||||
p = p.render();
|
||||
|
||||
@ -61,7 +61,7 @@ ec.generatePrivateKey = function generatePrivateKey() {
|
||||
} while (!secp256k1.privateKeyVerify(priv));
|
||||
} else {
|
||||
key = ec.elliptic.genKeyPair();
|
||||
priv = key.getPrivate().toBuffer('be', 32);
|
||||
priv = key.getPrivate().toArrayLike(Buffer, 'be', 32);
|
||||
}
|
||||
|
||||
return priv;
|
||||
@ -93,7 +93,7 @@ ec.publicKeyCreate = function publicKeyCreate(priv, compressed) {
|
||||
ec.random = function random(size) {
|
||||
if (crypto)
|
||||
return crypto.randomBytes(size);
|
||||
return new Buffer(ec.elliptic.rand(size));
|
||||
return new Buffer(elliptic.rand(size));
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -189,6 +189,9 @@ function Environment(options) {
|
||||
this.useWorkers = null;
|
||||
this.maxWorkers = null;
|
||||
this.workerTimeout = null;
|
||||
this.proxyServer = null;
|
||||
this.workerUri = null;
|
||||
this.logger = null;
|
||||
|
||||
this.time = new this.timedata();
|
||||
|
||||
@ -257,9 +260,17 @@ Environment.prototype.set = function set(options) {
|
||||
this.useWorkers = !!options.useWorkers;
|
||||
this.maxWorkers = options.maxWorkers;
|
||||
this.workerTimeout = options.workerTimeout;
|
||||
this.workerUri = options.workerUri || '/bcoin-worker.js';
|
||||
this.proxyServer = options.proxyServer || 'http://localhost:8080';
|
||||
this.logger = options.logger;
|
||||
|
||||
this.network.set(this.networkType);
|
||||
|
||||
if (this.isBrowser && this.useWorkers) {
|
||||
this.useWorkers = typeof utils.global.Worker === 'function'
|
||||
|| typeof utils.global.postMessage === 'function';
|
||||
}
|
||||
|
||||
if (this.useWorkers) {
|
||||
this.workers = require('./workers');
|
||||
this.workerPool = new this.workers({
|
||||
@ -307,12 +318,15 @@ Environment.prototype.debug = function debug() {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var msg;
|
||||
|
||||
if (this.logger)
|
||||
this.logger.debug(args);
|
||||
|
||||
if (this.isBrowser) {
|
||||
if (this.debugLogs) {
|
||||
msg = typeof args[0] !== 'object'
|
||||
? utils.format(args, false)
|
||||
: args[0];
|
||||
console.error(msg);
|
||||
console.log(msg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -342,6 +356,9 @@ Environment.prototype.error = function error(err) {
|
||||
if (typeof err === 'string')
|
||||
err = new Error(err);
|
||||
|
||||
if (this.logger)
|
||||
this.logger.error(err);
|
||||
|
||||
if (this.isBrowser) {
|
||||
if (this.debugLogs)
|
||||
console.error(err);
|
||||
|
||||
@ -106,14 +106,16 @@ Fullnode.prototype._init = function _init() {
|
||||
});
|
||||
|
||||
// HTTP needs access to the node.
|
||||
this.http = new bcoin.http.server({
|
||||
network: this.network,
|
||||
node: this,
|
||||
key: this.options.sslKey,
|
||||
cert: this.options.sslCert,
|
||||
port: this.options.httpPort || this.network.rpcPort,
|
||||
host: this.options.httpHost || '0.0.0.0'
|
||||
});
|
||||
if (!utils.isBrowser) {
|
||||
this.http = new bcoin.http.server({
|
||||
network: this.network,
|
||||
node: this,
|
||||
key: this.options.sslKey,
|
||||
cert: this.options.sslCert,
|
||||
port: this.options.httpPort || this.network.rpcPort,
|
||||
host: this.options.httpHost || '0.0.0.0'
|
||||
});
|
||||
}
|
||||
|
||||
// Bind to errors
|
||||
this.mempool.on('error', function(err) {
|
||||
@ -132,14 +134,16 @@ Fullnode.prototype._init = function _init() {
|
||||
self.emit('error', err);
|
||||
});
|
||||
|
||||
this.http.on('error', function(err) {
|
||||
self.emit('error', err);
|
||||
});
|
||||
|
||||
this.walletdb.on('error', function(err) {
|
||||
self.emit('error', err);
|
||||
});
|
||||
|
||||
if (this.http) {
|
||||
this.http.on('error', function(err) {
|
||||
self.emit('error', err);
|
||||
});
|
||||
}
|
||||
|
||||
this.on('tx', function(tx) {
|
||||
self.walletdb.addTX(tx, function(err) {
|
||||
if (err)
|
||||
@ -235,7 +239,11 @@ Fullnode.prototype._init = function _init() {
|
||||
next();
|
||||
});
|
||||
},
|
||||
this.http.open.bind(this.http)
|
||||
function(next) {
|
||||
if (!self.http)
|
||||
return next();
|
||||
self.http.open(next);
|
||||
}
|
||||
], load);
|
||||
};
|
||||
|
||||
@ -341,9 +349,16 @@ Fullnode.prototype.open = function open(callback) {
|
||||
|
||||
Fullnode.prototype.close =
|
||||
Fullnode.prototype.destroy = function destroy(callback) {
|
||||
var self = this;
|
||||
|
||||
this.wallet.destroy();
|
||||
|
||||
utils.serial([
|
||||
this.http.close.bind(this.http),
|
||||
function(next) {
|
||||
if (!self.http)
|
||||
return next();
|
||||
self.http.close(next);
|
||||
},
|
||||
this.walletdb.close.bind(this.walletdb),
|
||||
this.pool.close.bind(this.pool),
|
||||
this.miner.close.bind(this.miner),
|
||||
|
||||
@ -566,7 +566,7 @@ HDPrivateKey.prototype.derive = function derive(index, hardened) {
|
||||
privateKey = left
|
||||
.add(new bn(this.privateKey))
|
||||
.mod(ec.elliptic.curve.n)
|
||||
.toBuffer('be', 32);
|
||||
.toArrayLike(Buffer, 'be', 32);
|
||||
|
||||
if (!this.fingerPrint)
|
||||
this.fingerPrint = utils.ripesha(this.publicKey).slice(0, 4);
|
||||
|
||||
@ -71,6 +71,9 @@ HTTPBase.prototype._initIO = function _initIO() {
|
||||
var self = this;
|
||||
var IOServer;
|
||||
|
||||
if (!this.options.sockets)
|
||||
return;
|
||||
|
||||
try {
|
||||
IOServer = require('socket.io');
|
||||
} catch (e) {
|
||||
@ -93,8 +96,8 @@ HTTPBase.prototype._initRouter = function _initRouter() {
|
||||
var self = this;
|
||||
|
||||
this.server.on('request', function(req, res) {
|
||||
function _send(code, msg) {
|
||||
send(res, code, msg);
|
||||
function _send(code, msg, type) {
|
||||
send(res, code, msg, type);
|
||||
}
|
||||
|
||||
function done(err) {
|
||||
@ -347,17 +350,36 @@ HTTPBase.prototype.close = function close(callback) {
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function send(res, code, msg) {
|
||||
function send(res, code, msg, type) {
|
||||
var len;
|
||||
|
||||
if (!msg)
|
||||
msg = { error: 'No message.' };
|
||||
|
||||
try {
|
||||
res.statusCode = code;
|
||||
if (typeof msg === 'object') {
|
||||
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
||||
|
||||
if (msg && typeof msg === 'object' && !Buffer.isBuffer(msg)) {
|
||||
msg = JSON.stringify(msg, null, 2) + '\n';
|
||||
type = 'json';
|
||||
}
|
||||
res.setHeader('Content-Length', Buffer.byteLength(msg) + '');
|
||||
|
||||
if (type === 'html')
|
||||
res.setHeader('Content-Type', 'text/html; charset=utf-8');
|
||||
else if (type === 'text')
|
||||
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
|
||||
else if (type === 'json')
|
||||
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
||||
else if (type === 'js')
|
||||
res.setHeader('Content-Type', 'application/javascript; charset=utf-8');
|
||||
else if (type === 'binary')
|
||||
res.setHeader('Content-Type', 'application/octet-stream; charset=utf-8');
|
||||
|
||||
len = typeof msg === 'string'
|
||||
? Buffer.byteLength(msg, 'utf8')
|
||||
: msg.length;
|
||||
|
||||
res.setHeader('Content-Length', len + '');
|
||||
res.write(msg);
|
||||
res.end();
|
||||
} catch (e) {
|
||||
|
||||
@ -24,6 +24,9 @@ var assert = utils.assert;
|
||||
*/
|
||||
|
||||
function HTTPServer(options) {
|
||||
if (!(this instanceof HTTPServer))
|
||||
return new HTTPServer(options);
|
||||
|
||||
if (!options)
|
||||
options = {};
|
||||
|
||||
@ -38,6 +41,8 @@ function HTTPServer(options) {
|
||||
this.pool = this.node.pool;
|
||||
this.loaded = false;
|
||||
|
||||
options.sockets = true;
|
||||
|
||||
this.server = new HTTPBase(options);
|
||||
|
||||
this._init();
|
||||
|
||||
@ -105,7 +105,7 @@ exports.isMapped = function isMapped(ip) {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.toBuffer = function toArray(ip) {
|
||||
exports.toBuffer = function toBuffer(ip) {
|
||||
var out;
|
||||
|
||||
if (Buffer.isBuffer(ip)) {
|
||||
@ -114,7 +114,7 @@ exports.toBuffer = function toArray(ip) {
|
||||
}
|
||||
|
||||
if (!ip)
|
||||
return toArray('0.0.0.0');
|
||||
return toBuffer('0.0.0.0');
|
||||
|
||||
assert(typeof ip === 'string');
|
||||
assert(exports.version(ip) !== -1);
|
||||
|
||||
@ -353,7 +353,7 @@ function MinerBlock(options) {
|
||||
this.workerPool = options.workerPool;
|
||||
this.tip = options.tip;
|
||||
this.height = options.tip.height + 1;
|
||||
this.target = utils.fromCompact(options.target).toBuffer('le', 32);
|
||||
this.target = utils.fromCompact(options.target).toArrayLike(Buffer, 'le', 32);
|
||||
this.extraNonce = new bn(0);
|
||||
this.iterations = 0;
|
||||
this.coinbaseFlags = options.coinbaseFlags;
|
||||
|
||||
@ -156,6 +156,7 @@ Peer.prototype._init = function init() {
|
||||
self.ts = utils.now();
|
||||
self.connected = true;
|
||||
self.emit('connect');
|
||||
self._onconnect();
|
||||
});
|
||||
|
||||
this.socket.once('error', function(err) {
|
||||
@ -180,6 +181,10 @@ Peer.prototype._init = function init() {
|
||||
self.sendReject(null, 'malformed', 'error parsing message', 10);
|
||||
self._error(err, true);
|
||||
});
|
||||
};
|
||||
|
||||
Peer.prototype._onconnect = function _onconnect() {
|
||||
var self = this;
|
||||
|
||||
this.request('verack', function callee(err) {
|
||||
if (err) {
|
||||
@ -277,15 +282,18 @@ Peer.prototype._init = function init() {
|
||||
|
||||
Peer.prototype.createSocket = function createSocket(port, host) {
|
||||
var hostname = IP.hostname(host, port);
|
||||
var socket, net;
|
||||
var socket, proxy, net;
|
||||
|
||||
if (this._createSocket) {
|
||||
socket = this._createSocket(port, host);
|
||||
} else {
|
||||
if (bcoin.isBrowser)
|
||||
throw new Error('Please include a `createSocket` callback.');
|
||||
net = require('n' + 'et');
|
||||
socket = net.connect(port, host);
|
||||
if (bcoin.isBrowser) {
|
||||
proxy = require('../../browser/proxysocket');
|
||||
socket = proxy.connect(bcoin.proxyServer, port, host);
|
||||
} else {
|
||||
net = require('n' + 'et');
|
||||
socket = net.connect(port, host);
|
||||
}
|
||||
}
|
||||
|
||||
bcoin.debug('Connecting to %s.', hostname);
|
||||
|
||||
@ -35,7 +35,7 @@ function ensure() {
|
||||
|
||||
function Profile(name) {
|
||||
if (v8profiler && bcoin.profile) {
|
||||
name = 'profile-' + (name ? name + '-' : '') + Date.now();
|
||||
name = 'profile-' + (name ? name + '-' : '') + utils.ms();
|
||||
bcoin.debug('Starting CPU profile: %s', name);
|
||||
v8profiler.startProfiling(name, true);
|
||||
this.name = name;
|
||||
@ -123,7 +123,7 @@ Profile.prototype.save = function save(callback) {
|
||||
|
||||
function Snapshot(name) {
|
||||
if (v8profiler && bcoin.profile) {
|
||||
name = 'snapshot-' + (name ? name + '-' : '') + Date.now();
|
||||
name = 'snapshot-' + (name ? name + '-' : '') + utils.ms();
|
||||
bcoin.debug('Taking heap snapshot: %s', name);
|
||||
this.snapshot = v8profiler.takeSnapshot(name);
|
||||
this.name = name;
|
||||
@ -247,7 +247,7 @@ profiler.snapshot = function snapshot(name, callback) {
|
||||
name = null;
|
||||
}
|
||||
|
||||
if (bcoin.debugLogs) {
|
||||
if (bcoin.debugLogs && process.memoryUsage) {
|
||||
mem = process.memoryUsage();
|
||||
bcoin.debug('Memory: rss=%dmb, js-heap=%d/%dmb native-heap=%dmb',
|
||||
utils.mb(mem.rss),
|
||||
@ -257,7 +257,7 @@ profiler.snapshot = function snapshot(name, callback) {
|
||||
}
|
||||
|
||||
if (!v8profiler || !bcoin.profile)
|
||||
return callback ? utils.nextTick(callback) : null;
|
||||
return utils.asyncify(callback)();
|
||||
|
||||
snapshot = new Snapshot(name);
|
||||
snapshot.save(callback);
|
||||
|
||||
@ -71,14 +71,16 @@ SPVNode.prototype._init = function _init() {
|
||||
verify: true
|
||||
});
|
||||
|
||||
this.http = new bcoin.http.server({
|
||||
network: this.network,
|
||||
node: this,
|
||||
key: this.options.sslKey,
|
||||
cert: this.options.sslCert,
|
||||
port: this.options.httpPort || this.network.rpcPort,
|
||||
host: '0.0.0.0'
|
||||
});
|
||||
if (!utils.isBrowser) {
|
||||
this.http = new bcoin.http.server({
|
||||
network: this.network,
|
||||
node: this,
|
||||
key: this.options.sslKey,
|
||||
cert: this.options.sslCert,
|
||||
port: this.options.httpPort || this.network.rpcPort,
|
||||
host: '0.0.0.0'
|
||||
});
|
||||
}
|
||||
|
||||
// Bind to errors
|
||||
this.pool.on('error', function(err) {
|
||||
@ -89,14 +91,16 @@ SPVNode.prototype._init = function _init() {
|
||||
self.emit('error', err);
|
||||
});
|
||||
|
||||
this.http.on('error', function(err) {
|
||||
self.emit('error', err);
|
||||
});
|
||||
|
||||
this.walletdb.on('error', function(err) {
|
||||
self.emit('error', err);
|
||||
});
|
||||
|
||||
if (this.http) {
|
||||
this.http.on('error', function(err) {
|
||||
self.emit('error', err);
|
||||
});
|
||||
}
|
||||
|
||||
this.on('tx', function(tx) {
|
||||
self.walletdb.addTX(tx, function(err) {
|
||||
if (err)
|
||||
@ -208,7 +212,11 @@ SPVNode.prototype._init = function _init() {
|
||||
self.chain.reset(height, next);
|
||||
});
|
||||
},
|
||||
this.http.open.bind(this.http)
|
||||
function(next) {
|
||||
if (!self.http)
|
||||
return next();
|
||||
self.http.open(next);
|
||||
}
|
||||
], load);
|
||||
};
|
||||
|
||||
@ -291,9 +299,16 @@ SPVNode.prototype.open = function open(callback) {
|
||||
|
||||
SPVNode.prototype.close =
|
||||
SPVNode.prototype.destroy = function destroy(callback) {
|
||||
var self = this;
|
||||
|
||||
this.wallet.destroy();
|
||||
|
||||
utils.parallel([
|
||||
this.http.close.bind(this.http),
|
||||
function(next) {
|
||||
if (!self.http)
|
||||
return next();
|
||||
self.http.close(next);
|
||||
},
|
||||
this.walletdb.close.bind(this.walletdb),
|
||||
this.pool.close.bind(this.pool),
|
||||
this.chain.close.bind(this.chain)
|
||||
|
||||
@ -548,6 +548,9 @@ utils.equal = function equal(a, b) {
|
||||
* @param {Function} callback
|
||||
*/
|
||||
|
||||
if (utils.isBrowser)
|
||||
require('../../browser/setimmediate');
|
||||
|
||||
if (typeof setImmediate === 'function') {
|
||||
utils.nextTick = setImmediate;
|
||||
} else if (!utils.isBrowser) {
|
||||
@ -907,7 +910,7 @@ utils.error = function error() {
|
||||
msg = typeof args[0] !== 'object'
|
||||
? utils.format(args, false)
|
||||
: args[0];
|
||||
console.error(msg);
|
||||
console.log(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ if (typeof importScripts !== 'undefined') {
|
||||
|
||||
env = JSON.parse(event.data);
|
||||
|
||||
bcoin.set({ useWorkers: true });
|
||||
bcoin.network.set(env.BCOIN_WORKER_NETWORK);
|
||||
bcoin.workers.listen(+env.BCOIN_WORKER_ID, {
|
||||
debug: +env.BCOIN_WORKER_DEBUG === 1
|
||||
@ -25,6 +26,7 @@ if (typeof importScripts !== 'undefined') {
|
||||
} else {
|
||||
env = process.env;
|
||||
bcoin = require('./env');
|
||||
bcoin.set({ useWorkers: true });
|
||||
bcoin.network.set(env.BCOIN_WORKER_NETWORK);
|
||||
bcoin.workers.listen(+env.BCOIN_WORKER_ID, {
|
||||
debug: +env.BCOIN_WORKER_DEBUG === 1
|
||||
|
||||
@ -824,7 +824,7 @@ Framer.item = function _item(item, p) {
|
||||
item.toRaw(p);
|
||||
} else if (bn.isBN(item)) {
|
||||
p.writeU8(50);
|
||||
p.writeVarBytes(item.toBuffer());
|
||||
p.writeVarBytes(item.toArrayLike(Buffer));
|
||||
} else if (Buffer.isBuffer(item)) {
|
||||
p.writeU8(4);
|
||||
p.writeVarBytes(item);
|
||||
@ -1001,7 +1001,7 @@ function getCores() {
|
||||
var os;
|
||||
|
||||
if (utils.isBrowser)
|
||||
return 4;
|
||||
return 2;
|
||||
|
||||
os = require('o' + 's');
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@
|
||||
"browserify": "13.0.0",
|
||||
"hash.js": "1.0.3",
|
||||
"jsdoc": "3.4.0",
|
||||
"level-js": "2.2.3",
|
||||
"level-js": "2.2.4",
|
||||
"mocha": "2.4.5",
|
||||
"uglify-js": "2.6.1",
|
||||
"v8-profiler": "5.6.1"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user