spruce things up for the browser.

This commit is contained in:
Christopher Jeffrey 2016-06-05 06:55:35 -07:00
parent 10efd549ce
commit f71aa44acc
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
18 changed files with 149 additions and 61 deletions

View File

@ -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

View File

@ -575,7 +575,6 @@ Block.prototype.inspect = function inspect() {
ts: this.ts,
bits: this.bits,
nonce: this.nonce,
totalTX: this.totalTX,
txs: this.txs
};
};

View File

@ -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();

View File

@ -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));
};
/**

View File

@ -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);

View File

@ -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),

View File

@ -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);

View File

@ -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) {

View File

@ -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();

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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;
}

View File

@ -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

View File

@ -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');

View File

@ -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"