generators: refactor http.
This commit is contained in:
parent
ae83aa6fba
commit
8c11a2aa3f
13
bin/cli
13
bin/cli
@ -8,6 +8,7 @@ var spawn = require('../lib/utils/spawn');
|
||||
var Client = require('../lib/http/client');
|
||||
var Wallet = require('../lib/http/wallet');
|
||||
var assert = utils.assert;
|
||||
var main;
|
||||
|
||||
function CLI() {
|
||||
this.config = config({
|
||||
@ -444,13 +445,11 @@ CLI.prototype.destroy = function destroy() {
|
||||
return Promise.resolve(null);
|
||||
};
|
||||
|
||||
function main() {
|
||||
return spawn(function *() {
|
||||
var cli = new CLI();
|
||||
yield cli.open();
|
||||
yield cli.destroy();
|
||||
}, this);
|
||||
}
|
||||
main = co(function* main() {
|
||||
var cli = new CLI();
|
||||
yield cli.open();
|
||||
yield cli.destroy();
|
||||
});
|
||||
|
||||
main().then(process.exit).catch(function(err) {
|
||||
console.error(err.stack + '');
|
||||
|
||||
13
bin/spvnode
13
bin/spvnode
@ -25,6 +25,19 @@ node.on('error', function(err) {
|
||||
;
|
||||
});
|
||||
|
||||
process.on('uncaughtException', function(err) {
|
||||
node.logger.debug(err.stack);
|
||||
node.logger.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
process.on('unhandledRejection', function(err, promise) {
|
||||
node.logger.debug('Unhandled Rejection');
|
||||
node.logger.debug(err.stack);
|
||||
node.logger.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
node.open().then(function() {
|
||||
if (process.argv.indexOf('--test') !== -1) {
|
||||
node.pool.watchAddress('1VayNert3x1KzbpzMGt2qdqrAThiRovi8');
|
||||
|
||||
@ -1185,7 +1185,7 @@ ChainDB.prototype.scan = co(function* scan(start, filter, iter) {
|
||||
}
|
||||
}
|
||||
|
||||
yield* iter(entry, txs);
|
||||
yield iter(entry, txs);
|
||||
entry = yield entry.getNext();
|
||||
}
|
||||
|
||||
|
||||
@ -126,6 +126,7 @@ function Environment() {
|
||||
this.require('bloom', './utils/bloom');
|
||||
this.require('uri', './utils/uri');
|
||||
this.require('errors', './utils/errors');
|
||||
this.require('spawn', './utils/spawn');
|
||||
|
||||
// Crypto
|
||||
this.require('ec', './crypto/ec');
|
||||
@ -207,6 +208,7 @@ function Environment() {
|
||||
|
||||
// HTTP
|
||||
this.require('http', './http');
|
||||
this.require('rpc', './http/rpc');
|
||||
|
||||
// Workers
|
||||
this.require('workers', './workers/workers');
|
||||
@ -343,6 +345,7 @@ Environment.prototype.cache = function cache() {
|
||||
require('./utils/bloom');
|
||||
require('./utils/uri');
|
||||
require('./utils/errors');
|
||||
require('./utils/spawn');
|
||||
require('./crypto/ec');
|
||||
require('./crypto/crypto');
|
||||
require('./crypto/chachapoly');
|
||||
@ -399,6 +402,7 @@ Environment.prototype.cache = function cache() {
|
||||
require('./wallet/walletdb');
|
||||
require('./wallet/path');
|
||||
require('./http');
|
||||
require('./http/rpc');
|
||||
require('./workers/workers');
|
||||
require('./bip70/bip70');
|
||||
};
|
||||
|
||||
@ -162,7 +162,7 @@ HTTPBase.prototype._initRouter = function _initRouter() {
|
||||
// Avoid stack overflows
|
||||
utils.nextTick(function() {
|
||||
try {
|
||||
callback(req, res, next, _send);
|
||||
callback.call(route.ctx, req, res, _send, next);
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
@ -264,11 +264,11 @@ HTTPBase.prototype._handle = function _handle(req, res, _send, callback) {
|
||||
handler = self.stack[i++];
|
||||
|
||||
utils.nextTick(function() {
|
||||
if (handler.path && req.pathname.indexOf(handler.path) === -1)
|
||||
if (handler.path && req.pathname.indexOf(handler.path) !== 0)
|
||||
return next();
|
||||
|
||||
try {
|
||||
handler.callback(req, res, next, _send);
|
||||
handler.callback.call(handler.ctx, req, res, _send, next);
|
||||
} catch (e) {
|
||||
next(e);
|
||||
}
|
||||
@ -291,7 +291,7 @@ HTTPBase.prototype._handle = function _handle(req, res, _send, callback) {
|
||||
* @param {RouteCallback} callback
|
||||
*/
|
||||
|
||||
HTTPBase.prototype.use = function use(path, callback) {
|
||||
HTTPBase.prototype.use = function use(path, callback, ctx) {
|
||||
if (!callback) {
|
||||
callback = path;
|
||||
path = null;
|
||||
@ -299,12 +299,12 @@ HTTPBase.prototype.use = function use(path, callback) {
|
||||
|
||||
if (Array.isArray(path)) {
|
||||
path.forEach(function(path) {
|
||||
this.use(path, callback);
|
||||
this.use(path, callback, ctx);
|
||||
}, this);
|
||||
return;
|
||||
}
|
||||
|
||||
this.stack.push({ path: path, callback: callback });
|
||||
this.stack.push({ ctx: ctx, path: path, callback: callback });
|
||||
};
|
||||
|
||||
/**
|
||||
@ -313,14 +313,14 @@ HTTPBase.prototype.use = function use(path, callback) {
|
||||
* @param {RouteCallback} callback
|
||||
*/
|
||||
|
||||
HTTPBase.prototype.get = function get(path, callback) {
|
||||
HTTPBase.prototype.get = function get(path, callback, ctx) {
|
||||
if (Array.isArray(path)) {
|
||||
path.forEach(function(path) {
|
||||
this.get(path, callback);
|
||||
this.get(path, callback, ctx);
|
||||
}, this);
|
||||
return;
|
||||
}
|
||||
this.routes.get.push({ path: path, callback: callback });
|
||||
this.routes.get.push({ ctx: ctx, path: path, callback: callback });
|
||||
};
|
||||
|
||||
/**
|
||||
@ -329,14 +329,14 @@ HTTPBase.prototype.get = function get(path, callback) {
|
||||
* @param {RouteCallback} callback
|
||||
*/
|
||||
|
||||
HTTPBase.prototype.post = function post(path, callback) {
|
||||
HTTPBase.prototype.post = function post(path, callback, ctx) {
|
||||
if (Array.isArray(path)) {
|
||||
path.forEach(function(path) {
|
||||
this.post(path, callback);
|
||||
this.post(path, callback, ctx);
|
||||
}, this);
|
||||
return;
|
||||
}
|
||||
this.routes.post.push({ path: path, callback: callback });
|
||||
this.routes.post.push({ ctx: ctx, path: path, callback: callback });
|
||||
};
|
||||
|
||||
/**
|
||||
@ -345,14 +345,14 @@ HTTPBase.prototype.post = function post(path, callback) {
|
||||
* @param {RouteCallback} callback
|
||||
*/
|
||||
|
||||
HTTPBase.prototype.put = function put(path, callback) {
|
||||
HTTPBase.prototype.put = function put(path, callback, ctx) {
|
||||
if (Array.isArray(path)) {
|
||||
path.forEach(function(path) {
|
||||
this.put(path, callback);
|
||||
this.put(path, callback, ctx);
|
||||
}, this);
|
||||
return;
|
||||
}
|
||||
this.routes.put.push({ path: path, callback: callback });
|
||||
this.routes.put.push({ ctx: ctx, path: path, callback: callback });
|
||||
};
|
||||
|
||||
/**
|
||||
@ -361,14 +361,14 @@ HTTPBase.prototype.put = function put(path, callback) {
|
||||
* @param {RouteCallback} callback
|
||||
*/
|
||||
|
||||
HTTPBase.prototype.del = function del(path, callback) {
|
||||
HTTPBase.prototype.del = function del(path, callback, ctx) {
|
||||
if (Array.isArray(path)) {
|
||||
path.forEach(function(path) {
|
||||
this.del(path, callback);
|
||||
this.del(path, callback, ctx);
|
||||
}, this);
|
||||
return;
|
||||
}
|
||||
this.routes.del.push({ path: path, callback: callback });
|
||||
this.routes.del.push({ ctx: ctx, path: path, callback: callback });
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -1393,14 +1393,10 @@ RPC.prototype._getwork = co(function* _getwork() {
|
||||
};
|
||||
});
|
||||
|
||||
RPC.prototype.getworklp = function getworklp(args) {
|
||||
var self = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
self.once('clear block', function() {
|
||||
self._getwork().then(resolve).catch(reject);
|
||||
});
|
||||
});
|
||||
};
|
||||
RPC.prototype.getworklp = co(function* getworklp(args) {
|
||||
yield this._onBlock();
|
||||
return yield this._getwork();
|
||||
});
|
||||
|
||||
RPC.prototype.getwork = co(function* getwork(args) {
|
||||
var unlock = yield this.locker.lock();
|
||||
@ -1686,27 +1682,32 @@ RPC.prototype._tmpl = co(function* _tmpl(version, coinbase, rules) {
|
||||
return template;
|
||||
});
|
||||
|
||||
RPC.prototype._poll = function _poll(lpid) {
|
||||
RPC.prototype._poll = co(function* _poll(lpid) {
|
||||
var self = this;
|
||||
var watched, lastTX;
|
||||
|
||||
if (typeof lpid !== 'string')
|
||||
return Promise.resolve(null);
|
||||
return null;
|
||||
|
||||
if (lpid.length !== 74)
|
||||
return Promise.reject(new RPCError('Invalid parameter.'));
|
||||
throw new RPCError('Invalid parameter.');
|
||||
|
||||
watched = lpid.slice(0, 64);
|
||||
lastTX = +lpid.slice(64, 74);
|
||||
|
||||
if (!utils.isHex(watched) || !utils.isNumber(lastTX))
|
||||
return Promise.reject(new RPCError('Invalid parameter.'));
|
||||
throw new RPCError('Invalid parameter.');
|
||||
|
||||
watched = utils.revHex(watched);
|
||||
|
||||
if (this.chain.tip.hash !== watched)
|
||||
return Promise.resolve(null);
|
||||
return null;
|
||||
|
||||
yield this._onBlock();
|
||||
});
|
||||
|
||||
RPC.prototype._onBlock = function _onBlock() {
|
||||
var self = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
self.once('clear block', resolve);
|
||||
});
|
||||
@ -1855,42 +1856,39 @@ RPC.prototype.prioritisetransaction = function prioritisetransaction(args) {
|
||||
};
|
||||
|
||||
RPC.prototype._hashps = co(function* _hashps(lookup, height) {
|
||||
var i, minTime, maxTime, pb0, time;
|
||||
var workDiff, timeDiff, ps, pb, entry;
|
||||
var i, minTime, maxTime, workDiff, timeDiff, ps, tip, entry;
|
||||
|
||||
pb = this.chain.tip;
|
||||
tip = this.chain.tip;
|
||||
if (height >= 0 && height < this.chain.tip.height)
|
||||
pb = yield this.chain.db.get(height);
|
||||
tip = yield this.chain.db.get(height);
|
||||
|
||||
if (!pb)
|
||||
if (!tip)
|
||||
return 0;
|
||||
|
||||
if (lookup <= 0)
|
||||
lookup = pb.height % this.network.pow.retargetInterval + 1;
|
||||
lookup = tip.height % this.network.pow.retargetInterval + 1;
|
||||
|
||||
if (lookup > pb.height)
|
||||
lookup = pb.height;
|
||||
if (lookup > tip.height)
|
||||
lookup = tip.height;
|
||||
|
||||
minTime = pb.ts;
|
||||
minTime = tip.ts;
|
||||
maxTime = minTime;
|
||||
pb0 = pb;
|
||||
entry = tip;
|
||||
|
||||
for (i = 0; i < lookup; i++) {
|
||||
entry = yield pb0.getPrevious();
|
||||
entry = yield entry.getPrevious();
|
||||
|
||||
if (!entry)
|
||||
throw new RPCError('Not found.');
|
||||
|
||||
pb0 = entry;
|
||||
time = pb0.ts;
|
||||
minTime = Math.min(time, minTime);
|
||||
maxTime = Math.max(time, maxTime);
|
||||
minTime = Math.min(entry.ts, minTime);
|
||||
maxTime = Math.max(entry.ts, maxTime);
|
||||
}
|
||||
|
||||
if (minTime === maxTime)
|
||||
return 0;
|
||||
|
||||
workDiff = pb.chainwork.sub(pb0.chainwork);
|
||||
workDiff = tip.chainwork.sub(entry.chainwork);
|
||||
timeDiff = maxTime - minTime;
|
||||
ps = +workDiff.toString(10) / timeDiff;
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ var HTTPBase = http.base;
|
||||
var utils = require('../utils/utils');
|
||||
var spawn = require('../utils/spawn');
|
||||
var co = spawn.co;
|
||||
var con = spawn.con;
|
||||
var crypto = require('../crypto/crypto');
|
||||
var assert = utils.assert;
|
||||
var RPC; /*= require('./rpc'); - load lazily */
|
||||
@ -101,7 +102,7 @@ HTTPServer.prototype._init = function _init() {
|
||||
address.address, address.port);
|
||||
});
|
||||
|
||||
this.use(function(req, res, next, send) {
|
||||
this.use(function(req, res, send, next) {
|
||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||
res.setHeader('Access-Control-Allow-Credentials', 'true');
|
||||
res.setHeader(
|
||||
@ -115,14 +116,14 @@ HTTPServer.prototype._init = function _init() {
|
||||
|
||||
res.setHeader('X-Bcoin-Version', constants.USER_VERSION);
|
||||
res.setHeader('X-Bcoin-Agent', constants.USER_AGENT);
|
||||
res.setHeader('X-Bcoin-Network', self.network.type);
|
||||
res.setHeader('X-Bcoin-Height', self.chain.height + '');
|
||||
res.setHeader('X-Bcoin-Tip', utils.revHex(self.chain.tip.hash));
|
||||
res.setHeader('X-Bcoin-Network', this.network.type);
|
||||
res.setHeader('X-Bcoin-Height', this.chain.height + '');
|
||||
res.setHeader('X-Bcoin-Tip', utils.revHex(this.chain.tip.hash));
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
this.use(function(req, res, next, send) {
|
||||
this.use(function(req, res, send, next) {
|
||||
var auth = req.headers['authorization'];
|
||||
var parts;
|
||||
|
||||
@ -145,11 +146,11 @@ HTTPServer.prototype._init = function _init() {
|
||||
next();
|
||||
});
|
||||
|
||||
this.use(function(req, res, next, send) {
|
||||
if (!self.apiHash)
|
||||
this.use(function(req, res, send, next) {
|
||||
if (!this.apiHash)
|
||||
return next();
|
||||
|
||||
if (crypto.ccmp(hash256(req.password), self.apiHash))
|
||||
if (crypto.ccmp(hash256(req.password), this.apiHash))
|
||||
return next();
|
||||
|
||||
res.setHeader('WWW-Authenticate', 'Basic realm="node"');
|
||||
@ -170,7 +171,7 @@ HTTPServer.prototype._init = function _init() {
|
||||
send(401, { error: 'Bad API key.' });
|
||||
});
|
||||
|
||||
this.use(function(req, res, next, send) {
|
||||
this.use(function(req, res, send, next) {
|
||||
var i, params, options, output, address;
|
||||
|
||||
if (req.method === 'POST' && req.pathname === '/') {
|
||||
@ -187,8 +188,8 @@ HTTPServer.prototype._init = function _init() {
|
||||
softMerge(params, req.query, true);
|
||||
softMerge(params, req.body);
|
||||
|
||||
self.logger.debug('Params:');
|
||||
self.logger.debug(params);
|
||||
this.logger.debug('Params:');
|
||||
this.logger.debug(params);
|
||||
|
||||
if (params.id) {
|
||||
assert(typeof params.id === 'string', 'ID must be a string.');
|
||||
@ -374,37 +375,16 @@ HTTPServer.prototype._init = function _init() {
|
||||
next();
|
||||
});
|
||||
|
||||
this.use(function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var wallet;
|
||||
this.use(con(function *(req, res, send, next) {
|
||||
var wallet;
|
||||
|
||||
if (req.path.length < 2 || req.path[0] !== 'wallet') {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
if (req.path.length < 2 || req.path[0] !== 'wallet') {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!self.options.walletAuth) {
|
||||
wallet = yield self.walletdb.get(req.options.id);
|
||||
|
||||
if (!wallet) {
|
||||
send(404);
|
||||
return;
|
||||
}
|
||||
|
||||
req.wallet = wallet;
|
||||
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
wallet = yield self.walletdb.auth(req.options.id, req.options.token);
|
||||
} catch (err) {
|
||||
self.logger.info('Auth failure for %s: %s.',
|
||||
req.options.id, err.message);
|
||||
send(403, { error: err.message });
|
||||
return;
|
||||
}
|
||||
if (!this.options.walletAuth) {
|
||||
wallet = yield this.walletdb.get(req.options.id);
|
||||
|
||||
if (!wallet) {
|
||||
send(404);
|
||||
@ -412,458 +392,411 @@ HTTPServer.prototype._init = function _init() {
|
||||
}
|
||||
|
||||
req.wallet = wallet;
|
||||
self.logger.info('Successful auth for %s.', req.options.id);
|
||||
|
||||
next();
|
||||
}).catch(next);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
wallet = yield this.walletdb.auth(req.options.id, req.options.token);
|
||||
} catch (err) {
|
||||
this.logger.info('Auth failure for %s: %s.',
|
||||
req.options.id, err.message);
|
||||
send(403, { error: err.message });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wallet) {
|
||||
send(404);
|
||||
return;
|
||||
}
|
||||
|
||||
req.wallet = wallet;
|
||||
this.logger.info('Successful auth for %s.', req.options.id);
|
||||
next();
|
||||
}));
|
||||
|
||||
// JSON RPC
|
||||
this.post('/', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var json;
|
||||
this.post('/', con(function *(req, res, send, next) {
|
||||
var json;
|
||||
|
||||
if (!self.rpc) {
|
||||
RPC = require('./rpc');
|
||||
self.rpc = new RPC(self.node);
|
||||
}
|
||||
if (!this.rpc) {
|
||||
RPC = require('./rpc');
|
||||
this.rpc = new RPC(this.node);
|
||||
}
|
||||
|
||||
if (req.body.method === 'getwork') {
|
||||
res.setHeader('X-Long-Polling', '/?longpoll=1');
|
||||
if (req.query.longpoll)
|
||||
req.body.method = 'getworklp';
|
||||
}
|
||||
if (req.body.method === 'getwork') {
|
||||
res.setHeader('X-Long-Polling', '/?longpoll=1');
|
||||
if (req.query.longpoll)
|
||||
req.body.method = 'getworklp';
|
||||
}
|
||||
|
||||
try {
|
||||
json = yield self.rpc.execute(req.body);
|
||||
} catch (err) {
|
||||
self.logger.error(err);
|
||||
try {
|
||||
json = yield this.rpc.execute(req.body);
|
||||
} catch (err) {
|
||||
this.logger.error(err);
|
||||
|
||||
if (err.type === 'RPCError') {
|
||||
return send(400, {
|
||||
result: err.message,
|
||||
error: null,
|
||||
id: req.body.id
|
||||
});
|
||||
}
|
||||
|
||||
return send(500, {
|
||||
result: null,
|
||||
error: {
|
||||
message: err.message,
|
||||
code: 1
|
||||
},
|
||||
if (err.type === 'RPCError') {
|
||||
return send(400, {
|
||||
result: err.message,
|
||||
error: null,
|
||||
id: req.body.id
|
||||
});
|
||||
}
|
||||
|
||||
send(200, {
|
||||
result: json != null ? json : null,
|
||||
error: null,
|
||||
return send(500, {
|
||||
result: null,
|
||||
error: {
|
||||
message: err.message,
|
||||
code: 1
|
||||
},
|
||||
id: req.body.id
|
||||
});
|
||||
}).catch(next);
|
||||
});
|
||||
}
|
||||
|
||||
this.get('/', function(req, res, next, send) {
|
||||
send(200, {
|
||||
result: json != null ? json : null,
|
||||
error: null,
|
||||
id: req.body.id
|
||||
});
|
||||
}));
|
||||
|
||||
this.get('/', function(req, res, send, next) {
|
||||
send(200, {
|
||||
version: constants.USER_VERSION,
|
||||
agent: constants.USER_AGENT,
|
||||
services: self.pool.services,
|
||||
network: self.network.type,
|
||||
height: self.chain.height,
|
||||
tip: self.chain.tip.rhash,
|
||||
peers: self.pool.peers.all.length,
|
||||
progress: self.chain.getProgress()
|
||||
services: this.pool.services,
|
||||
network: this.network.type,
|
||||
height: this.chain.height,
|
||||
tip: this.chain.tip.rhash,
|
||||
peers: this.pool.peers.all.length,
|
||||
progress: this.chain.getProgress()
|
||||
});
|
||||
});
|
||||
|
||||
// UTXO by address
|
||||
this.get('/coin/address/:address', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var coins = yield self.node.getCoinsByAddress(req.options.address);
|
||||
send(200, coins.map(function(coin) {
|
||||
return coin.toJSON();
|
||||
}));
|
||||
}).catch(next);
|
||||
});
|
||||
this.get('/coin/address/:address', con(function *(req, res, send, next) {
|
||||
var coins = yield this.node.getCoinsByAddress(req.options.address);
|
||||
send(200, coins.map(function(coin) {
|
||||
return coin.toJSON();
|
||||
}));
|
||||
}));
|
||||
|
||||
// UTXO by id
|
||||
this.get('/coin/:hash/:index', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var coin = yield self.node.getCoin(req.options.hash, req.options.index);
|
||||
this.get('/coin/:hash/:index', con(function *(req, res, send, next) {
|
||||
var coin = yield this.node.getCoin(req.options.hash, req.options.index);
|
||||
|
||||
if (!coin)
|
||||
return send(404);
|
||||
if (!coin)
|
||||
return send(404);
|
||||
|
||||
send(200, coin.toJSON());
|
||||
}).catch(next);
|
||||
});
|
||||
send(200, coin.toJSON());
|
||||
}));
|
||||
|
||||
// Bulk read UTXOs
|
||||
this.post('/coin/address', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var coins = yield self.node.getCoinsByAddress(req.options.address);
|
||||
send(200, coins.map(function(coin) {
|
||||
return coin.toJSON();
|
||||
}));
|
||||
}).catch(next);
|
||||
});
|
||||
this.post('/coin/address', con(function *(req, res, send, next) {
|
||||
var coins = yield this.node.getCoinsByAddress(req.options.address);
|
||||
send(200, coins.map(function(coin) {
|
||||
return coin.toJSON();
|
||||
}));
|
||||
}));
|
||||
|
||||
// TX by hash
|
||||
this.get('/tx/:hash', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var tx = yield self.node.getTX(req.options.hash);
|
||||
this.get('/tx/:hash', con(function *(req, res, send, next) {
|
||||
var tx = yield this.node.getTX(req.options.hash);
|
||||
|
||||
if (!tx)
|
||||
return send(404);
|
||||
if (!tx)
|
||||
return send(404);
|
||||
|
||||
yield self.node.fillHistory(tx);
|
||||
yield this.node.fillHistory(tx);
|
||||
|
||||
send(200, tx.toJSON());
|
||||
}).catch(next);
|
||||
});
|
||||
send(200, tx.toJSON());
|
||||
}));
|
||||
|
||||
// TX by address
|
||||
this.get('/tx/address/:address', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var txs = yield self.node.getTXByAddress(req.options.address);
|
||||
var i, tx;
|
||||
this.get('/tx/address/:address', con(function *(req, res, send, next) {
|
||||
var txs = yield this.node.getTXByAddress(req.options.address);
|
||||
var i, tx;
|
||||
|
||||
for (i = 0; i < txs.length; i++) {
|
||||
tx = txs[i];
|
||||
yield self.node.fillHistory(tx);
|
||||
}
|
||||
for (i = 0; i < txs.length; i++) {
|
||||
tx = txs[i];
|
||||
yield this.node.fillHistory(tx);
|
||||
}
|
||||
|
||||
send(200, txs.map(function(tx) {
|
||||
return tx.toJSON();
|
||||
}));
|
||||
}).catch(next);
|
||||
});
|
||||
send(200, txs.map(function(tx) {
|
||||
return tx.toJSON();
|
||||
}));
|
||||
}));
|
||||
|
||||
// Bulk read TXs
|
||||
this.post('/tx/address', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var txs = yield self.node.getTXByAddress(req.options.address);
|
||||
var i, tx;
|
||||
this.post('/tx/address', con(function *(req, res, send, next) {
|
||||
var txs = yield this.node.getTXByAddress(req.options.address);
|
||||
var i, tx;
|
||||
|
||||
for (i = 0; i < txs.length; i++) {
|
||||
tx = txs[i];
|
||||
yield self.node.fillHistory(tx);
|
||||
}
|
||||
for (i = 0; i < txs.length; i++) {
|
||||
tx = txs[i];
|
||||
yield this.node.fillHistory(tx);
|
||||
}
|
||||
|
||||
send(200, txs.map(function(tx) {
|
||||
return tx.toJSON();
|
||||
}));
|
||||
}).catch(next);
|
||||
});
|
||||
send(200, txs.map(function(tx) {
|
||||
return tx.toJSON();
|
||||
}));
|
||||
}));
|
||||
|
||||
// Block by hash/height
|
||||
this.get('/block/:hash', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var hash = req.options.hash || req.options.height;
|
||||
var block = yield self.node.getFullBlock(hash);
|
||||
this.get('/block/:hash', con(function *(req, res, send, next) {
|
||||
var hash = req.options.hash || req.options.height;
|
||||
var block = yield this.node.getFullBlock(hash);
|
||||
|
||||
if (!block)
|
||||
return send(404);
|
||||
if (!block)
|
||||
return send(404);
|
||||
|
||||
send(200, block.toJSON());
|
||||
}).catch(next);
|
||||
});
|
||||
send(200, block.toJSON());
|
||||
}));
|
||||
|
||||
// Mempool snapshot
|
||||
this.get('/mempool', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var i, txs, tx;
|
||||
this.get('/mempool', con(function *(req, res, send, next) {
|
||||
var i, txs, tx;
|
||||
|
||||
if (!self.mempool)
|
||||
return send(400, { error: 'No mempool available.' });
|
||||
if (!this.mempool)
|
||||
return send(400, { error: 'No mempool available.' });
|
||||
|
||||
txs = self.mempool.getHistory();
|
||||
txs = this.mempool.getHistory();
|
||||
|
||||
for (i = 0; i < txs.length; i++) {
|
||||
tx = txs[i];
|
||||
yield self.node.fillHistory(tx);
|
||||
}
|
||||
for (i = 0; i < txs.length; i++) {
|
||||
tx = txs[i];
|
||||
yield this.node.fillHistory(tx);
|
||||
}
|
||||
|
||||
send(200, txs.map(function(tx) {
|
||||
return tx.toJSON();
|
||||
}));
|
||||
}).catch(next);
|
||||
});
|
||||
send(200, txs.map(function(tx) {
|
||||
return tx.toJSON();
|
||||
}));
|
||||
}));
|
||||
|
||||
// Broadcast TX
|
||||
this.post('/broadcast', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
yield self.node.sendTX(req.options.tx);
|
||||
send(200, { success: true });
|
||||
}).catch(next);
|
||||
});
|
||||
this.post('/broadcast', con(function *(req, res, send, next) {
|
||||
yield this.node.sendTX(req.options.tx);
|
||||
send(200, { success: true });
|
||||
}));
|
||||
|
||||
// Estimate fee
|
||||
this.get('/fee', function(req, res, next, send) {
|
||||
this.get('/fee', function(req, res, send, next) {
|
||||
var fee;
|
||||
|
||||
if (!self.fees)
|
||||
if (!this.fees)
|
||||
return send(400, { error: 'Fee estimation not available.' });
|
||||
|
||||
fee = self.fees.estimateFee(req.options.blocks);
|
||||
fee = this.fees.estimateFee(req.options.blocks);
|
||||
|
||||
send(200, { rate: utils.btc(fee) });
|
||||
});
|
||||
|
||||
// Get wallet
|
||||
this.get('/wallet/:id', function(req, res, next, send) {
|
||||
this.get('/wallet/:id', function(req, res, send, next) {
|
||||
send(200, req.wallet.toJSON());
|
||||
});
|
||||
|
||||
// Create wallet
|
||||
this.post('/wallet/:id?', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var wallet = yield self.walletdb.create(req.options);
|
||||
send(200, wallet.toJSON());
|
||||
}).catch(next);
|
||||
});
|
||||
this.post('/wallet/:id?', con(function *(req, res, send, next) {
|
||||
var wallet = yield this.walletdb.create(req.options);
|
||||
send(200, wallet.toJSON());
|
||||
}));
|
||||
|
||||
// List accounts
|
||||
this.get('/wallet/:id/account', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var accounts = yield req.wallet.getAccounts();
|
||||
send(200, accounts);
|
||||
}).catch(next);
|
||||
});
|
||||
this.get('/wallet/:id/account', con(function *(req, res, send, next) {
|
||||
var accounts = yield req.wallet.getAccounts();
|
||||
send(200, accounts);
|
||||
}));
|
||||
|
||||
// Get account
|
||||
this.get('/wallet/:id/account/:account', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var account = yield req.wallet.getAccount(req.options.account);
|
||||
this.get('/wallet/:id/account/:account', con(function *(req, res, send, next) {
|
||||
var account = yield req.wallet.getAccount(req.options.account);
|
||||
|
||||
if (!account)
|
||||
return send(404);
|
||||
if (!account)
|
||||
return send(404);
|
||||
|
||||
send(200, account.toJSON());
|
||||
}).catch(next);
|
||||
});
|
||||
send(200, account.toJSON());
|
||||
}));
|
||||
|
||||
// Create/get account
|
||||
this.post('/wallet/:id/account/:account?', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var account = yield req.wallet.createAccount(req.options);
|
||||
this.post('/wallet/:id/account/:account?', con(function *(req, res, send, next) {
|
||||
var account = yield req.wallet.createAccount(req.options);
|
||||
|
||||
if (!account)
|
||||
return send(404);
|
||||
if (!account)
|
||||
return send(404);
|
||||
|
||||
send(200, account.toJSON());
|
||||
}).catch(next);
|
||||
});
|
||||
send(200, account.toJSON());
|
||||
}));
|
||||
|
||||
// Change passphrase
|
||||
this.post('/wallet/:id/passphrase', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var options = req.options;
|
||||
var old = options.old;
|
||||
var new_ = options.passphrase;
|
||||
yield req.wallet.setPassphrase(old, new_);
|
||||
send(200, { success: true });
|
||||
}).catch(next);
|
||||
});
|
||||
this.post('/wallet/:id/passphrase', con(function *(req, res, send, next) {
|
||||
var options = req.options;
|
||||
var old = options.old;
|
||||
var new_ = options.passphrase;
|
||||
yield req.wallet.setPassphrase(old, new_);
|
||||
send(200, { success: true });
|
||||
}));
|
||||
|
||||
// Generate new token
|
||||
this.post('/wallet/:id/retoken', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var options = req.options;
|
||||
var token = yield req.wallet.retoken(options.passphrase);
|
||||
send(200, { token: token.toString('hex') });
|
||||
}).catch(next);
|
||||
});
|
||||
this.post('/wallet/:id/retoken', con(function *(req, res, send, next) {
|
||||
var options = req.options;
|
||||
var token = yield req.wallet.retoken(options.passphrase);
|
||||
send(200, { token: token.toString('hex') });
|
||||
}));
|
||||
|
||||
// Send TX
|
||||
this.post('/wallet/:id/send', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var options = req.options;
|
||||
var tx = yield req.wallet.send(options);
|
||||
send(200, tx.toJSON());
|
||||
}).catch(next);
|
||||
});
|
||||
this.post('/wallet/:id/send', con(function *(req, res, send, next) {
|
||||
var options = req.options;
|
||||
var tx = yield req.wallet.send(options);
|
||||
send(200, tx.toJSON());
|
||||
}));
|
||||
|
||||
// Create TX
|
||||
this.post('/wallet/:id/create', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var options = req.options;
|
||||
var tx = yield req.wallet.createTX(options);
|
||||
yield req.wallet.sign(tx, options);
|
||||
send(200, tx.toJSON());
|
||||
}).catch(next);
|
||||
});
|
||||
this.post('/wallet/:id/create', con(function *(req, res, send, next) {
|
||||
var options = req.options;
|
||||
var tx = yield req.wallet.createTX(options);
|
||||
yield req.wallet.sign(tx, options);
|
||||
send(200, tx.toJSON());
|
||||
}));
|
||||
|
||||
// Sign TX
|
||||
this.post('/wallet/:id/sign', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var options = req.options;
|
||||
var tx = req.options.tx;
|
||||
yield req.wallet.sign(tx, options);
|
||||
send(200, tx.toJSON());
|
||||
}).catch(next);
|
||||
});
|
||||
this.post('/wallet/:id/sign', con(function *(req, res, send, next) {
|
||||
var options = req.options;
|
||||
var tx = req.options.tx;
|
||||
yield req.wallet.sign(tx, options);
|
||||
send(200, tx.toJSON());
|
||||
}));
|
||||
|
||||
// Fill TX
|
||||
this.post('/wallet/:id/fill', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var tx = req.options.tx;
|
||||
yield req.wallet.fillHistory(tx);
|
||||
send(200, tx.toJSON());
|
||||
}).catch(next);
|
||||
});
|
||||
this.post('/wallet/:id/fill', con(function *(req, res, send, next) {
|
||||
var tx = req.options.tx;
|
||||
yield req.wallet.fillHistory(tx);
|
||||
send(200, tx.toJSON());
|
||||
}));
|
||||
|
||||
// Zap Wallet TXs
|
||||
this.post('/wallet/:id/zap', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var account = req.options.account;
|
||||
var age = req.options.age;
|
||||
yield req.wallet.zap(account, age);
|
||||
send(200, { success: true });
|
||||
}).catch(next);
|
||||
});
|
||||
this.post('/wallet/:id/zap', con(function *(req, res, send, next) {
|
||||
var account = req.options.account;
|
||||
var age = req.options.age;
|
||||
yield req.wallet.zap(account, age);
|
||||
send(200, { success: true });
|
||||
}));
|
||||
|
||||
// Abandon Wallet TX
|
||||
this.del('/wallet/:id/tx/:hash', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var hash = req.options.hash;
|
||||
yield req.wallet.abandon(hash);
|
||||
send(200, { success: true });
|
||||
}).catch(next);
|
||||
});
|
||||
this.del('/wallet/:id/tx/:hash', con(function *(req, res, send, next) {
|
||||
var hash = req.options.hash;
|
||||
yield req.wallet.abandon(hash);
|
||||
send(200, { success: true });
|
||||
}));
|
||||
|
||||
// Add key
|
||||
this.put('/wallet/:id/key', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var account = req.options.account;
|
||||
var key = req.options.key;
|
||||
yield req.wallet.addKey(account, key);
|
||||
send(200, { success: true });
|
||||
}).catch(next);
|
||||
});
|
||||
this.put('/wallet/:id/key', con(function *(req, res, send, next) {
|
||||
var account = req.options.account;
|
||||
var key = req.options.key;
|
||||
yield req.wallet.addKey(account, key);
|
||||
send(200, { success: true });
|
||||
}));
|
||||
|
||||
// Remove key
|
||||
this.del('/wallet/:id/key', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var account = req.options.account;
|
||||
var key = req.options.key;
|
||||
yield req.wallet.removeKey(account, key);
|
||||
send(200, { success: true });
|
||||
}).catch(next);
|
||||
});
|
||||
this.del('/wallet/:id/key', con(function *(req, res, send, next) {
|
||||
var account = req.options.account;
|
||||
var key = req.options.key;
|
||||
yield req.wallet.removeKey(account, key);
|
||||
send(200, { success: true });
|
||||
}));
|
||||
|
||||
// Create address
|
||||
this.post('/wallet/:id/address', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var account = req.options.account;
|
||||
var address = yield req.wallet.createReceive(account);
|
||||
send(200, address.toJSON());
|
||||
}).catch(next);
|
||||
});
|
||||
this.post('/wallet/:id/address', con(function *(req, res, send, next) {
|
||||
var account = req.options.account;
|
||||
var address = yield req.wallet.createReceive(account);
|
||||
send(200, address.toJSON());
|
||||
}));
|
||||
|
||||
// Wallet Balance
|
||||
this.get('/wallet/:id/balance', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var account = req.options.account;
|
||||
var balance = yield req.wallet.getBalance(account);
|
||||
this.get('/wallet/:id/balance', con(function *(req, res, send, next) {
|
||||
var account = req.options.account;
|
||||
var balance = yield req.wallet.getBalance(account);
|
||||
|
||||
if (!balance)
|
||||
return send(404);
|
||||
if (!balance)
|
||||
return send(404);
|
||||
|
||||
send(200, balance.toJSON());
|
||||
}).catch(next);
|
||||
});
|
||||
send(200, balance.toJSON());
|
||||
}));
|
||||
|
||||
// Wallet UTXOs
|
||||
this.get('/wallet/:id/coin', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var account = req.options.account;
|
||||
var coins = yield req.wallet.getCoins(account);
|
||||
send(200, coins.map(function(coin) {
|
||||
return coin.toJSON();
|
||||
}));
|
||||
}).catch(next);
|
||||
});
|
||||
this.get('/wallet/:id/coin', con(function *(req, res, send, next) {
|
||||
var account = req.options.account;
|
||||
var coins = yield req.wallet.getCoins(account);
|
||||
send(200, coins.map(function(coin) {
|
||||
return coin.toJSON();
|
||||
}));
|
||||
}));
|
||||
|
||||
// Wallet Coin
|
||||
this.get('/wallet/:id/coin/:hash/:index', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var hash = req.options.hash;
|
||||
var index = req.options.index;
|
||||
var coin = yield req.wallet.getCoin(hash, index);
|
||||
this.get('/wallet/:id/coin/:hash/:index', con(function *(req, res, send, next) {
|
||||
var hash = req.options.hash;
|
||||
var index = req.options.index;
|
||||
var coin = yield req.wallet.getCoin(hash, index);
|
||||
|
||||
if (!coin)
|
||||
return send(404);
|
||||
if (!coin)
|
||||
return send(404);
|
||||
|
||||
send(200, coin.toJSON());
|
||||
}).catch(next);
|
||||
});
|
||||
send(200, coin.toJSON());
|
||||
}));
|
||||
|
||||
// Wallet TXs
|
||||
this.get('/wallet/:id/tx/history', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var account = req.options.account;
|
||||
var txs = yield req.wallet.getHistory(account);
|
||||
var details = yield req.wallet.toDetails(txs);
|
||||
send(200, details.map(function(tx) {
|
||||
return tx.toJSON();
|
||||
}));
|
||||
}).catch(next);
|
||||
});
|
||||
this.get('/wallet/:id/tx/history', con(function *(req, res, send, next) {
|
||||
var account = req.options.account;
|
||||
var txs = yield req.wallet.getHistory(account);
|
||||
var details = yield req.wallet.toDetails(txs);
|
||||
send(200, details.map(function(tx) {
|
||||
return tx.toJSON();
|
||||
}));
|
||||
}));
|
||||
|
||||
// Wallet Pending TXs
|
||||
this.get('/wallet/:id/tx/unconfirmed', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var account = req.options.account;
|
||||
var txs = yield req.wallet.getUnconfirmed(account);
|
||||
var details = yield req.wallet.toDetails(txs);
|
||||
send(200, details.map(function(tx) {
|
||||
return tx.toJSON();
|
||||
}));
|
||||
}).catch(next);
|
||||
});
|
||||
this.get('/wallet/:id/tx/unconfirmed', con(function *(req, res, send, next) {
|
||||
var account = req.options.account;
|
||||
var txs = yield req.wallet.getUnconfirmed(account);
|
||||
var details = yield req.wallet.toDetails(txs);
|
||||
send(200, details.map(function(tx) {
|
||||
return tx.toJSON();
|
||||
}));
|
||||
}));
|
||||
|
||||
// Wallet TXs within time range
|
||||
this.get('/wallet/:id/tx/range', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var account = req.options.account;
|
||||
var options = req.options;
|
||||
var txs = yield req.wallet.getRange(account, options);
|
||||
var details = yield req.wallet.toDetails(txs);
|
||||
send(200, details.map(function(tx) {
|
||||
return tx.toJSON();
|
||||
}));
|
||||
}).catch(next);
|
||||
});
|
||||
this.get('/wallet/:id/tx/range', con(function *(req, res, send, next) {
|
||||
var account = req.options.account;
|
||||
var options = req.options;
|
||||
var txs = yield req.wallet.getRange(account, options);
|
||||
var details = yield req.wallet.toDetails(txs);
|
||||
send(200, details.map(function(tx) {
|
||||
return tx.toJSON();
|
||||
}));
|
||||
}));
|
||||
|
||||
// Last Wallet TXs
|
||||
this.get('/wallet/:id/tx/last', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var account = req.options.account;
|
||||
var limit = req.options.limit;
|
||||
var txs = yield req.wallet.getLast(account, limit);
|
||||
var details = yield req.wallet.toDetails(txs);
|
||||
send(200, details.map(function(tx) {
|
||||
return tx.toJSON();
|
||||
}));
|
||||
}).catch(next);
|
||||
});
|
||||
this.get('/wallet/:id/tx/last', con(function *(req, res, send, next) {
|
||||
var account = req.options.account;
|
||||
var limit = req.options.limit;
|
||||
var txs = yield req.wallet.getLast(account, limit);
|
||||
var details = yield req.wallet.toDetails(txs);
|
||||
send(200, details.map(function(tx) {
|
||||
return tx.toJSON();
|
||||
}));
|
||||
}));
|
||||
|
||||
// Wallet TX
|
||||
this.get('/wallet/:id/tx/:hash', function(req, res, next, send) {
|
||||
spawn(function *() {
|
||||
var hash = req.options.hash;
|
||||
var tx = yield req.wallet.getTX(hash);
|
||||
var details;
|
||||
this.get('/wallet/:id/tx/:hash', con(function *(req, res, send, next) {
|
||||
var hash = req.options.hash;
|
||||
var tx = yield req.wallet.getTX(hash);
|
||||
var details;
|
||||
|
||||
if (!tx)
|
||||
return send(404);
|
||||
if (!tx)
|
||||
return send(404);
|
||||
|
||||
details = yield req.wallet.toDetails(tx);
|
||||
send(200, details.toJSON());
|
||||
}).catch(next);
|
||||
});
|
||||
details = yield req.wallet.toDetails(tx);
|
||||
send(200, details.toJSON());
|
||||
}));
|
||||
|
||||
this.server.on('error', function(err) {
|
||||
self.emit('error', err);
|
||||
@ -1090,7 +1023,7 @@ HTTPServer.prototype.close = function close() {
|
||||
*/
|
||||
|
||||
HTTPServer.prototype.use = function use(path, callback) {
|
||||
return this.server.use(path, callback);
|
||||
return this.server.use(path, callback, this);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1098,7 +1031,7 @@ HTTPServer.prototype.use = function use(path, callback) {
|
||||
*/
|
||||
|
||||
HTTPServer.prototype.get = function get(path, callback) {
|
||||
return this.server.get(path, callback);
|
||||
return this.server.get(path, callback, this);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1106,7 +1039,7 @@ HTTPServer.prototype.get = function get(path, callback) {
|
||||
*/
|
||||
|
||||
HTTPServer.prototype.post = function post(path, callback) {
|
||||
return this.server.post(path, callback);
|
||||
return this.server.post(path, callback, this);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1114,7 +1047,7 @@ HTTPServer.prototype.post = function post(path, callback) {
|
||||
*/
|
||||
|
||||
HTTPServer.prototype.put = function put(path, callback) {
|
||||
return this.server.put(path, callback);
|
||||
return this.server.put(path, callback, this);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1122,7 +1055,7 @@ HTTPServer.prototype.put = function put(path, callback) {
|
||||
*/
|
||||
|
||||
HTTPServer.prototype.del = function del(path, callback) {
|
||||
return this.server.del(path, callback);
|
||||
return this.server.del(path, callback, this);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1337,14 +1270,14 @@ ClientSocket.prototype.scan = function scan(start) {
|
||||
if (this.chain.db.options.prune)
|
||||
return Promise.reject(new Error('Cannot scan in pruned mode.'));
|
||||
|
||||
return this.chain.db.scan(start, this.filter, function *(entry, txs) {
|
||||
return this.chain.db.scan(start, this.filter, co(function *(entry, txs) {
|
||||
for (i = 0; i < txs.length; i++)
|
||||
txs[i] = txs[i].toJSON();
|
||||
|
||||
self.emit('block tx', entry.toJSON(), txs);
|
||||
|
||||
yield utils.wait();
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
ClientSocket.prototype.join = function join(id) {
|
||||
|
||||
@ -253,36 +253,36 @@ Miner.prototype.createBlock = co(function* createBlock(tip) {
|
||||
// Find target
|
||||
target = yield this.chain.getTargetAsync(ts, tip);
|
||||
|
||||
if (this.version != null) {
|
||||
version = this.version;
|
||||
} else {
|
||||
if (this.version != null) {
|
||||
version = this.version;
|
||||
} else {
|
||||
// Calculate version with versionbits
|
||||
version = yield this.chain.computeBlockVersion(tip);
|
||||
version = yield this.chain.computeBlockVersion(tip);
|
||||
}
|
||||
|
||||
attempt = new MinerBlock({
|
||||
workerPool: this.workerPool,
|
||||
tip: tip,
|
||||
version: version,
|
||||
target: target,
|
||||
address: this.address,
|
||||
coinbaseFlags: this.coinbaseFlags,
|
||||
witness: this.chain.segwitActive,
|
||||
parallel: this.options.parallel,
|
||||
network: this.network
|
||||
});
|
||||
attempt = new MinerBlock({
|
||||
workerPool: this.workerPool,
|
||||
tip: tip,
|
||||
version: version,
|
||||
target: target,
|
||||
address: this.address,
|
||||
coinbaseFlags: this.coinbaseFlags,
|
||||
witness: this.chain.segwitActive,
|
||||
parallel: this.options.parallel,
|
||||
network: this.network
|
||||
});
|
||||
|
||||
if (!this.mempool)
|
||||
return attempt;
|
||||
if (!this.mempool)
|
||||
return attempt;
|
||||
|
||||
txs = this.mempool.getHistory();
|
||||
txs = this.mempool.getHistory();
|
||||
|
||||
for (i = 0; i < txs.length; i++) {
|
||||
tx = txs[i];
|
||||
attempt.addTX(tx);
|
||||
}
|
||||
for (i = 0; i < txs.length; i++) {
|
||||
tx = txs[i];
|
||||
attempt.addTX(tx);
|
||||
}
|
||||
|
||||
return attempt;
|
||||
return attempt;
|
||||
});
|
||||
|
||||
/**
|
||||
@ -292,8 +292,8 @@ Miner.prototype.createBlock = co(function* createBlock(tip) {
|
||||
*/
|
||||
|
||||
Miner.prototype.mineBlock = co(function* mineBlock(tip) {
|
||||
// Create a new block and start hashing
|
||||
var attempt = yield this.createBlock(tip);
|
||||
// Create a new block and start hashing
|
||||
var attempt = yield this.createBlock(tip);
|
||||
return yield attempt.mineAsync();
|
||||
});
|
||||
|
||||
|
||||
@ -102,7 +102,47 @@ function cob(generator) {
|
||||
|
||||
gen = generator.apply(this, args);
|
||||
|
||||
return cb(exec(gen), callback);
|
||||
return cb(exec(gen), function(err, result) {
|
||||
// Escape the promise's scope:
|
||||
utils.nextTick(function() {
|
||||
callback(err, result);
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a generator function to be
|
||||
* executed into a function that
|
||||
* accepts a node.js style callback.
|
||||
* Only executes callback on error.
|
||||
* @param {GeneratorFunction}
|
||||
* @returns {Function}
|
||||
*/
|
||||
|
||||
function con(generator) {
|
||||
return function() {
|
||||
var i, args, callback, gen;
|
||||
|
||||
if (arguments.length === 0
|
||||
|| typeof arguments[arguments.length - 1] !== 'function') {
|
||||
throw new Error('Function must accept a callback.');
|
||||
}
|
||||
|
||||
args = new Array(arguments.length);
|
||||
callback = arguments[arguments.length - 1];
|
||||
|
||||
for (i = 0; i < args.length; i++)
|
||||
args[i] = arguments[i];
|
||||
|
||||
gen = generator.apply(this, args);
|
||||
|
||||
return exec(gen).catch(function(err) {
|
||||
// Escape the promise's scope:
|
||||
utils.nextTick(function() {
|
||||
callback(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@ -223,6 +263,7 @@ exports.exec = exec;
|
||||
exports.spawn = spawn;
|
||||
exports.co = co;
|
||||
exports.cob = cob;
|
||||
exports.con = con;
|
||||
exports.cb = cb;
|
||||
exports.wait = wait;
|
||||
exports.timeout = timeout;
|
||||
|
||||
@ -975,9 +975,9 @@ WalletDB.prototype.rescan = co(function* rescan(chaindb, height) {
|
||||
this.logger.info('Scanning for %d addresses.', hashes.length);
|
||||
|
||||
try {
|
||||
yield chaindb.scan(height, hashes, function *(block, txs) {
|
||||
yield chaindb.scan(height, hashes, co(function *(block, txs) {
|
||||
yield self.addBlock(block, txs, true);
|
||||
});
|
||||
}));
|
||||
} catch (e) {
|
||||
unlock();
|
||||
throw e;
|
||||
|
||||
@ -8,6 +8,7 @@ var crypto = require('../lib/crypto/crypto');
|
||||
var assert = require('assert');
|
||||
var opcodes = constants.opcodes;
|
||||
var spawn = require('../lib/utils/spawn');
|
||||
var co = require('../lib/utils/spawn').co;
|
||||
var c = require('../lib/utils/spawn').cb;
|
||||
|
||||
describe('Chain', function() {
|
||||
@ -234,10 +235,10 @@ describe('Chain', function() {
|
||||
var total = 0;
|
||||
c(walletdb.getAddressHashes(), function(err, hashes) {
|
||||
assert.ifError(err);
|
||||
c(chain.db.scan(null, hashes, function *(block, txs) {
|
||||
c(chain.db.scan(null, hashes, co(function *(block, txs) {
|
||||
total += txs.length;
|
||||
yield spawn.wait();
|
||||
}), function(err) {
|
||||
})), function(err) {
|
||||
assert.ifError(err);
|
||||
assert.equal(total, 25);
|
||||
cb();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user