diff --git a/lib/bcoin/http/rpc.js b/lib/bcoin/http/rpc.js index 08d43c96..7348d108 100644 --- a/lib/bcoin/http/rpc.js +++ b/lib/bcoin/http/rpc.js @@ -268,7 +268,7 @@ RPC.prototype.getinfo = function getinfo(args, callback) { var self = this; if (args.help || args.length !== 0) - return callback(new Error('getinfo')); + return callback(new RPCError('getinfo')); this.wallet.getBalance(function(err, balance) { if (err) @@ -307,7 +307,7 @@ RPC.prototype.help = function help(args, callback) { RPC.prototype.stop = function stop(args, callback) { if (args.help || args.length !== 0) - return callback(new Error('stop')); + return callback(new RPCError('stop')); callback(null, 'Stopping.'); this.node.close(); @@ -358,7 +358,7 @@ RPC.prototype.addnode = function addnode(args, callback) { var i, node, cmd, host, seed; if (args.help || args.length !== 2) - return callback(new Error('addnode "node" "add|remove|onetry"')); + return callback(new RPCError('addnode "node" "add|remove|onetry"')); node = String(args[0]); cmd = String(args[1]); @@ -388,7 +388,7 @@ RPC.prototype.disconnectnode = function disconnectnode(args, callback) { var node, peer; if (args.help || args.length !== 1) - return callback(new Error('disconnectnode "node"')); + return callback(new RPCError('disconnectnode "node"')); node = String(args[0]); node = IP.normalize(node); @@ -402,19 +402,19 @@ RPC.prototype.disconnectnode = function disconnectnode(args, callback) { RPC.prototype.getaddednodeinfo = function getaddednodeinfo(args, callback) { if (args.help || args.length < 1 || args.length > 2) - return callback(new Error('getaddednodeinfo dummy ( "node" )')); + return callback(new RPCError('getaddednodeinfo dummy ( "node" )')); callback(new Error('Not implemented.')); }; RPC.prototype.getconnectioncount = function getconnectioncount(args, callback) { if (args.help || args.length !== 0) - return callback(new Error('getconnectioncount')); + return callback(new RPCError('getconnectioncount')); callback(null, this.pool.peers.all.length); }; RPC.prototype.getnettotals = function getnettotals(args, callback) { if (args.help || args.length > 0) - return callback(new Error('getnettotals')); + return callback(new RPCError('getnettotals')); callback(null, { totalbytesrecv: 0, @@ -438,7 +438,7 @@ RPC.prototype.getpeerinfo = function getpeerinfo(args, callback) { var i, peer; if (args.help || args.length !== 0) - return callback(new Error('getpeerinfo')); + return callback(new RPCError('getpeerinfo')); for (i = 0; i < this.pool.peers.all.length; i++) { peer = this.pool.peers.all[i]; @@ -474,7 +474,7 @@ RPC.prototype.ping = function ping(args, callback) { var i; if (args.help || args.length !== 0) - return callback(new Error('ping')); + return callback(new RPCError('ping')); for (i = 0; i < this.pool.peers.all.length; i++) this.pool.peers.all[i].sendPing(); @@ -488,7 +488,7 @@ RPC.prototype.setban = function setban(args, callback) { if (args.help || args.length < 2 || (args[1] !== 'add' && args[1] !== 'remove')) { - return callback(new Error( + return callback(new RPCError( 'setban "ip(/netmask)" "add|remove" (bantime) (absolute)')); } @@ -514,7 +514,7 @@ RPC.prototype.listbanned = function listbanned(args, callback) { var i, banned, keys, host, time; if (args.help || args.length !== 0) - return callback(new Error('listbanned')); + return callback(new RPCError('listbanned')); banned = []; keys = Object.keys(this.pool.peers.misbehaving); @@ -535,7 +535,7 @@ RPC.prototype.listbanned = function listbanned(args, callback) { RPC.prototype.clearbanned = function clearbanned(args, callback) { if (args.help || args.length !== 0) - return callback(new Error('clearbanned')); + return callback(new RPCError('clearbanned')); this.pool.peers.ignored = {}; this.pool.peers.misbehaving = {}; @@ -617,7 +617,7 @@ RPC.prototype.getblockchaininfo = function getblockchaininfo(args, callback) { var self = this; if (args.help || args.length !== 0) - return callback(new Error('getblockchaininfo')); + return callback(new RPCError('getblockchaininfo')); this.chain.tip.getMedianTimeAsync(function(err, medianTime) { if (err) @@ -674,14 +674,14 @@ RPC.prototype._getDifficulty = function getDifficulty(entry) { RPC.prototype.getbestblockhash = function getbestblockhash(args, callback) { if (args.help || args.length !== 0) - return callback(new Error('getbestblockhash')); + return callback(new RPCError('getbestblockhash')); callback(null, this.chain.tip.rhash); }; RPC.prototype.getblockcount = function getblockcount(args, callback) { if (args.help || args.length !== 0) - return callback(new Error('getblockcount')); + return callback(new RPCError('getblockcount')); callback(null, this.chain.tip.height); }; @@ -691,7 +691,7 @@ RPC.prototype.getblock = function getblock(args, callback) { var hash, verbose; if (args.help || args.length < 1 || args.length > 2) - return callback(new Error('getblock "hash" ( verbose )')); + return callback(new RPCError('getblock "hash" ( verbose )')); hash = utils.revHex(String(args[0])); @@ -705,7 +705,7 @@ RPC.prototype.getblock = function getblock(args, callback) { return callback(err); if (!entry) - return callback(new Error('Block not found')); + return callback(new RPCError('Block not found')); self.chain.db.getBlock(entry.hash, function(err, block) { if (err) @@ -713,8 +713,8 @@ RPC.prototype.getblock = function getblock(args, callback) { if (!block) { if (self.chain.db.prune) - return callback(new Error('Block not available (pruned data)')); - return callback(new Error('Can\'t read block from disk')); + return callback(new RPCError('Block not available (pruned data)')); + return callback(new RPCError('Can\'t read block from disk')); } if (!verbose) @@ -792,19 +792,19 @@ RPC.prototype.getblockhash = function getblockhash(args, callback) { var height; if (args.help || args.length !== 1) - return callback(new Error('getblockhash index')); + return callback(new RPCError('getblockhash index')); height = args[0]; if (height < 0 || height > this.chain.height) - return callback(new Error('Block height out of range.')); + return callback(new RPCError('Block height out of range.')); this.chain.db.get(height, function(err, entry) { if (err) return callback(err); if (!entry) - return callback(new Error('Not found.')); + return callback(new RPCError('Not found.')); return callback(null, entry.rhash); }); @@ -815,7 +815,7 @@ RPC.prototype.getblockheader = function getblockheader(args, callback) { var hash, verbose; if (args.help || args.length < 1 || args.length > 2) - return callback(new Error('getblockheader "hash" ( verbose )')); + return callback(new RPCError('getblockheader "hash" ( verbose )')); hash = utils.revHex(String(args[0])); @@ -829,7 +829,7 @@ RPC.prototype.getblockheader = function getblockheader(args, callback) { return callback(err); if (!entry) - return callback(new Error('Block not found')); + return callback(new RPCError('Block not found')); if (!verbose) return callback(null, entry.toRaw().toString('hex', 0, 80)); @@ -908,7 +908,7 @@ RPC.prototype.blockToJSON = function blockToJSON(entry, block, txDetails, callba RPC.prototype.getchaintips = function getchaintips(args, callback) { if (args.help || args.length !== 0) - return callback(new Error('getchaintips')); + return callback(new RPCError('getchaintips')); callback(null, [{ height: this.chain.height, @@ -920,7 +920,7 @@ RPC.prototype.getchaintips = function getchaintips(args, callback) { RPC.prototype.getdifficulty = function getdifficulty(args, callback) { if (args.help || args.length !== 0) - return callback(new Error('getdifficulty')); + return callback(new RPCError('getdifficulty')); callback(null, this._getDifficulty()); }; @@ -939,7 +939,7 @@ RPC.prototype.getrawmempool = function getrawmempool(args, callback) { var verbose; if (args.help || args.length > 1) - return callback(new Error('getrawmempool ( verbose )')); + return callback(new RPCError('getrawmempool ( verbose )')); verbose = false; @@ -1003,7 +1003,7 @@ RPC.prototype.gettxout = function gettxout(args, callback) { var hash, index, mempool; if (args.help || args.length < 2 || args.length > 3) - return callback(new Error('gettxout "txid" n ( includemempool )')); + return callback(new RPCError('gettxout "txid" n ( includemempool )')); hash = utils.revHex(String(args[0])); index = Number(args[1]); @@ -1046,7 +1046,7 @@ RPC.prototype.verifytxoutproof = function verifytxoutproof(args, callback) { RPC.prototype.gettxoutsetinfo = function gettxoutsetinfo(args, callback) { if (args.help || args.length !== 0) - return callback(new Error('gettxoutsetinfo')); + return callback(new RPCError('gettxoutsetinfo')); callback(null, { height: this.chain.height, @@ -1061,7 +1061,7 @@ RPC.prototype.gettxoutsetinfo = function gettxoutsetinfo(args, callback) { RPC.prototype.verifychain = function verifychain(args, callback) { if (args.help || args.length > 2) - return callback(new Error('verifychain ( checklevel numblocks )')); + return callback(new RPCError('verifychain ( checklevel numblocks )')); callback(); }; @@ -1077,7 +1077,7 @@ RPC.prototype.getblocktemplate = function getblocktemplate(args, callback) { var i, j, tx, deps, input, dep, block; if (args.help || args.length > 1) - return callback(new Error('getblocktemplate ( "jsonrequestobject" )')); + return callback(new RPCError('getblocktemplate ( "jsonrequestobject" )')); this.miner.createBlock(function(err, attempt) { if (err) @@ -1136,14 +1136,14 @@ RPC.prototype.getmininginfo = function getmininginfo(args, callback) { var self = this; if (args.help || args.length !== 0) - return callback(new Error('getmininginfo')); + return callback(new RPCError('getmininginfo')); this.chain.db.getBlock(this.chain.tip.hash, function(err, block) { if (err) return callback(err); if (!block) - return callback(new Error('Block not found.')); + return callback(new RPCError('Block not found.')); self._hashps(120, -1, function(err, hashps) { if (err) @@ -1170,7 +1170,7 @@ RPC.prototype.getnetworkhashps = function getnetworkhashps(args, callback) { var lookup, height; if (args.help || args.length > 2) - return callback(new Error('getnetworkhashps ( blocks height )')); + return callback(new RPCError('getnetworkhashps ( blocks height )')); lookup = args.length > 0 ? Number(args[0]) : 120; height = args.length > 1 ? Number(args[1]) : -1; @@ -1179,14 +1179,14 @@ RPC.prototype.getnetworkhashps = function getnetworkhashps(args, callback) { }; RPC.prototype.prioritisetransaction = function prioritisetransaction(args, callback) { - callback(new Error('Not implemented.')); + callback(new RPCError('Not implemented.')); }; RPC.prototype.submitblock = function submitblock(args, callback) { var block; if (args.help || args.length < 1 || args.length > 2) - return callback(new Error('submitblock "hexdata" ( "jsonparametersobject" )')); + return callback(new RPCError('submitblock "hexdata" ( "jsonparametersobject" )')); block = bcoin.block.fromRaw(args[0], 'hex'); @@ -1230,7 +1230,7 @@ RPC.prototype._hashps = function _hashps(lookup, height, callback) { return callback(err); if (!entry) - return callback(new Error('Not found.')); + return callback(new RPCError('Not found.')); pb0 = entry; time = pb0.ts; @@ -1280,7 +1280,7 @@ RPC.prototype.generate = function generate(args, callback) { var numblocks, hashes; if (args.help || args.length < 1 || args.length > 2) - return callback(new Error('generate numblocks ( maxtries )')); + return callback(new RPCError('generate numblocks ( maxtries )')); numblocks = Number(args[0]); hashes = []; @@ -1304,7 +1304,7 @@ RPC.prototype.generatetoaddress = function generatetoaddress(args, callback) { var address; if (args.help || args.length < 2 || args.length > 3) - return callback(new Error('generatetoaddress numblocks address (maxtries)')); + return callback(new RPCError('generatetoaddress numblocks address (maxtries)')); address = this.miner.address; this.miner.address = bcoin.address.fromBase58(args[1]); @@ -1327,27 +1327,27 @@ RPC.prototype.createrawtransaction = function createrawtransaction(args, callbac var keys, addrs, key, value, address, b58; if (args.help || args.length < 2 || args.length > 3) { - return callback(new Error('createrawtransaction' + return callback(new RPCError('createrawtransaction' + ' [{"txid":"id","vout":n},...]' + ' {"address":amount,"data":"hex",...}' + ' ( locktime )')); } if (!args[0] || !args[1]) - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); inputs = args[0]; sendTo = args[1]; if (!Array.isArray(inputs) || typeof sendTo !== 'object') - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); tx = bcoin.tx(); if (args.length > 2 && args[2] != null) { locktime = Number(args[2]); if (locktime < 0 || locktime > 0xffffffff) - return callback(new Error('Invalid parameter, locktime out of range')); + return callback(new RPCError('Invalid parameter, locktime out of range')); tx.locktime = locktime; } @@ -1355,7 +1355,7 @@ RPC.prototype.createrawtransaction = function createrawtransaction(args, callbac input = inputs[i]; if (!input) - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); hash = input.txid; index = input.vout; @@ -1368,12 +1368,12 @@ RPC.prototype.createrawtransaction = function createrawtransaction(args, callbac || hash.length !== 64 || !utils.isNumber(index) || index < 0) { - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); } if (utils.isNumber(input.sequence)) { if (input.sequence < 0 || input.sequence > 0xffffffff) - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); sequence = input.sequence; } @@ -1409,7 +1409,7 @@ RPC.prototype.createrawtransaction = function createrawtransaction(args, callbac b58 = address.toBase58(); if (addrs[b58]) - return callback(new Error('Duplicate address')); + return callback(new RPCError('Duplicate address')); addrs[b58] = true; @@ -1428,10 +1428,10 @@ RPC.prototype.decoderawtransaction = function decoderawtransaction(args, callbac var tx; if (args.help || args.length !== 1) - return callback(new Error('decoderawtransaction "hexstring"')); + return callback(new RPCError('decoderawtransaction "hexstring"')); if (!utils.isHex(args[0])) - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); tx = bcoin.tx.fromRaw(args[0], 'hex'); @@ -1442,7 +1442,7 @@ RPC.prototype.decodescript = function decodescript(args, callback) { var data, script, hash, address; if (args.help || args.length !== 1) - return callback(new Error('decodescript \"hex\"')); + return callback(new RPCError('decodescript \"hex\"')); data = String(args[0]); script = new bcoin.script(); @@ -1464,12 +1464,12 @@ RPC.prototype.getrawtransaction = function getrawtransaction(args, callback) { var hash, verbose; if (args.help || args.length < 1 || args.length > 2) - return callback(new Error('getrawtransaction "txid" ( verbose )')); + return callback(new RPCError('getrawtransaction "txid" ( verbose )')); hash = args[0]; if (!utils.isHex(hash) || hash.length !== 64) - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); verbose = false; @@ -1481,7 +1481,7 @@ RPC.prototype.getrawtransaction = function getrawtransaction(args, callback) { return callback(err); if (!tx) - return callback(new Error('No information available about transaction')); + return callback(new RPCError('No information available about transaction')); if (!verbose) return callback(null, tx.toRaw().toString('hex')); @@ -1497,12 +1497,12 @@ RPC.prototype.sendrawtransaction = function sendrawtransaction(args, callback) { var tx; if (args.help || args.length < 1 || args.length > 2) { - return callback(new Error('sendrawtransaction' + return callback(new RPCError('sendrawtransaction' + ' "hexstring" ( allowhighfees )')); } if (!utils.isHex(args[0])) - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); tx = bcoin.tx.fromRaw(args[0], 'hex'); @@ -1516,7 +1516,7 @@ RPC.prototype.signrawtransaction = function signrawtransaction(args, callback) { var raw, p, txs, merged; if (args.help || args.length < 1 || args.length > 4) { - return callback(new Error('signrawtransaction' + return callback(new RPCError('signrawtransaction' + ' "hexstring" (' + ' [{"txid":"id","vout":n,"scriptPubKey":"hex",' + 'redeemScript":"hex"},...] ["privatekey1",...]' @@ -1557,7 +1557,7 @@ RPC.prototype._signrawtransaction = function signrawtransaction(merged, txs, arg for (i = 0; i < k.length; i++) { secret = k[i]; if (!utils.isBase58(secret)) - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); key = bcoin.keypair.fromSecret(secret); addr = new bcoin.keyring({ publicKey: key.getPublicKey() }); key = { addr: addr, key: key.getPrivateKey() }; @@ -1572,7 +1572,7 @@ RPC.prototype._signrawtransaction = function signrawtransaction(merged, txs, arg for (i = 0; i < prevout.length; i++) { prev = prevout[i]; if (!prev) - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); hash = prev.txid; index = prev.vout; script = prev.scriptPubKey; @@ -1582,7 +1582,7 @@ RPC.prototype._signrawtransaction = function signrawtransaction(merged, txs, arg || !utils.isNumber(index) || index < 0 || !utils.isHex(script)) { - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); } script = bcoin.script.fromRaw(script, 'hex'); @@ -1624,12 +1624,12 @@ RPC.prototype._signrawtransaction = function signrawtransaction(merged, txs, arg parts = args[3].split('|'); type = constants.hashType[parts[0]]; if (type == null) - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); if (parts.length > 2) - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); if (parts.length === 2) { if (parts[1] !== 'ANYONECANPAY') - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); type |= constants.hashType.ANYONECANPAY; } } @@ -1690,7 +1690,7 @@ RPC.prototype._createRedeem = function _createRedeem(args, callback) { || args[0] < 1 || args[1].length < args[0] || args[1].length > 16) { - return callback(new Error('Invalid parameter.')); + return callback(new RPCError('Invalid parameter.')); } m = args[0]; @@ -1700,21 +1700,21 @@ RPC.prototype._createRedeem = function _createRedeem(args, callback) { utils.forEachSerial(keys, function(key, next, i) { if (!utils.isBase58(key)) { if (!utils.isHex(key)) - return next(new Error('Invalid key.')); + return next(new RPCError('Invalid key.')); keys[i] = new Buffer(key, 'hex'); return next(); } hash = bcoin.address.getHash(key, 'hex'); if (!hash) - return next(new Error('Invalid key.')); + return next(new RPCError('Invalid key.')); self.node.wallet.getKeyring(hash, function(err, address) { if (err) return next(err); if (!address) - return next(new Error('Invalid key.')); + return next(new RPCError('Invalid key.')); keys[i] = address.getPublicKey(); @@ -1727,7 +1727,7 @@ RPC.prototype._createRedeem = function _createRedeem(args, callback) { script = bcoin.script.fromMultisig(m, n, keys); if (script.toRaw().length > constants.script.MAX_PUSH) - return callback(new Error('Redeem script exceeds size limit.')); + return callback(new RPCError('Redeem script exceeds size limit.')); callback(null, script); }); @@ -1736,7 +1736,7 @@ RPC.prototype._createRedeem = function _createRedeem(args, callback) { /* Utility functions */ RPC.prototype.createmultisig = function createmultisig(args, callback) { if (args.help || args.length < 2 || args.length > 2) - return callback(new Error('createmultisig nrequired ["key",...]')); + return callback(new RPCError('createmultisig nrequired ["key",...]')); this._createRedeem(args, function(err, script) { if (err) @@ -1770,12 +1770,12 @@ RPC.prototype.createwitnessaddress = function createwitnessaddress(args, callbac var raw, script, program; if (args.help || args.length !== 1) - return callback(new Error('createwitnessaddress "script"')); + return callback(new RPCError('createwitnessaddress "script"')); raw = args[1]; if (!utils.isHex(raw)) - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); script = bcoin.script.fromRaw(raw, 'hex'); program = this._scriptForWitness(script); @@ -1790,7 +1790,7 @@ RPC.prototype.validateaddress = function validateaddress(args, callback) { var b58, address, json; if (args.help || args.length !== 1) - return callback(new Error('validateaddress "bitcoinaddress"')); + return callback(new RPCError('validateaddress "bitcoinaddress"')); b58 = String(args[0]); @@ -1830,7 +1830,7 @@ RPC.prototype.verifymessage = function verifymessage(args, callback) { var address, sig, msg, key; if (args.help || args.length !== 3) { - return callback(new Error('verifymessage' + return callback(new RPCError('verifymessage' + ' "bitcoinaddress" "signature" "message"')); } @@ -1841,7 +1841,7 @@ RPC.prototype.verifymessage = function verifymessage(args, callback) { address = bcoin.address.getHash(address); if (!address) - return callback(new Error('Invalid address.')); + return callback(new RPCError('Invalid address.')); sig = new Buffer(sig, 'base64'); msg = new Buffer(RPC.magic + msg, 'utf8'); @@ -1861,7 +1861,7 @@ RPC.prototype.signmessagewithprivkey = function signmessagewithprivkey(args, cal var key, msg, sig; if (args.help || args.length !== 2) - return callback(new Error('signmessagewithprivkey "privkey" "message"')); + return callback(new RPCError('signmessagewithprivkey "privkey" "message"')); key = String(args[0]); msg = String(args[1]); @@ -1879,7 +1879,7 @@ RPC.prototype.estimatefee = function estimatefee(args, callback) { var blocks, fee; if (args.help || args.length !== 1) - return callback(new Error('estimatefee nblocks')); + return callback(new RPCError('estimatefee nblocks')); blocks = Number(args[0]); @@ -1903,7 +1903,7 @@ RPC.prototype.estimatepriority = function estimatepriority(args, callback) { var blocks, pri; if (args.help || args.length !== 1) - return callback(new Error('estimatepriority nblocks')); + return callback(new RPCError('estimatepriority nblocks')); blocks = Number(args[0]); @@ -1922,7 +1922,7 @@ RPC.prototype.estimatesmartfee = function estimatesmartfee(args, callback) { var blocks, fee; if (args.help || args.length !== 1) - return callback(new Error('estimatesmartfee nblocks')); + return callback(new RPCError('estimatesmartfee nblocks')); blocks = Number(args[0]); @@ -1949,7 +1949,7 @@ RPC.prototype.estimatesmartpriority = function estimatesmartpriority(args, callb var blocks, pri; if (args.help || args.length !== 1) - return callback(new Error('estimatesmartpriority nblocks')); + return callback(new RPCError('estimatesmartpriority nblocks')); blocks = Number(args[0]); @@ -1971,12 +1971,12 @@ RPC.prototype.invalidateblock = function invalidateblock(args, callback) { var hash; if (args.help || args.length !== 1) - return callback(new Error('invalidateblock "hash"')); + return callback(new RPCError('invalidateblock "hash"')); hash = args[0]; if (!utils.isHex(hash) || hash.length !== 64) - return callback(new Error('Block not found.')); + return callback(new RPCError('Block not found.')); hash = utils.revHex(hash); @@ -1989,12 +1989,12 @@ RPC.prototype.reconsiderblock = function reconsiderblock(args, callback) { var hash; if (args.help || args.length !== 1) - return callback(new Error('reconsiderblock "hash"')); + return callback(new RPCError('reconsiderblock "hash"')); hash = args[0]; if (!utils.isHex(hash) || hash.length !== 64) - return callback(new Error('Block not found.')); + return callback(new RPCError('Block not found.')); hash = utils.revHex(hash); @@ -2007,12 +2007,12 @@ RPC.prototype.setmocktime = function setmocktime(args, callback) { var time, delta; if (args.help || args.length !== 1) - return callback(new Error('setmocktime timestamp')); + return callback(new RPCError('setmocktime timestamp')); time = args[0]; if (!utils.isNumber(time)) - return callback(new Error('Invalid parameter.')); + return callback(new RPCError('Invalid parameter.')); delta = bcoin.now() - time; bcoin.time.offset = -delta; @@ -2030,7 +2030,7 @@ RPC.prototype.resendwallettransactions = function resendwallettransactions(args, var i, tx; if (args.help || args.length !== 0) - return callback(new Error('resendwallettransactions')); + return callback(new RPCError('resendwallettransactions')); this.walletdb.getUnconfirmed(function(err, txs) { if (err) @@ -2048,7 +2048,7 @@ RPC.prototype.resendwallettransactions = function resendwallettransactions(args, RPC.prototype.addmultisigaddress = function addmultisigaddress(args, callback) { if (args.help || args.length < 2 || args.length > 3) { - return callback(new Error('addmultisigaddress' + return callback(new RPCError('addmultisigaddress' + ' nrequired ["key",...] ( "account" )')); } // Impossible to implement in bcoin (no address book). @@ -2057,14 +2057,14 @@ RPC.prototype.addmultisigaddress = function addmultisigaddress(args, callback) { RPC.prototype.addwitnessaddress = function addwitnessaddress(args, callback) { if (args.help || args.length < 1 || args.length > 1) - return callback(new Error('addwitnessaddress \"address\"')); + return callback(new RPCError('addwitnessaddress \"address\"')); // Unlikely to be implemented. callback(new Error('Not implemented.')); }; RPC.prototype.backupwallet = function backupwallet(args, callback) { if (args.help || args.length !== 1) - return callback(new Error('backupwallet "destination"')); + return callback(new RPCError('backupwallet "destination"')); // Unlikely to be implemented. callback(new Error('Not implemented.')); }; @@ -2074,24 +2074,24 @@ RPC.prototype.dumpprivkey = function dumpprivkey(args, callback) { var hash, key; if (args.help || args.length !== 1) - return callback(new Error('dumpprivkey "bitcoinaddress"')); + return callback(new RPCError('dumpprivkey "bitcoinaddress"')); hash = bcoin.address.getHash(String(args[0]), 'hex'); if (!hash) - return callback(new Error('Invalid address.')); + return callback(new RPCError('Invalid address.')); this.wallet.getKeyring(hash, function(err, ring) { if (err) return callback(err); if (!ring) - return callback(new Error('Key not found.')); + return callback(new RPCError('Key not found.')); key = self.wallet.master.key; if (!key) - return callback(new Error('Wallet is locked.')); + return callback(new RPCError('Wallet is locked.')); key = key.deriveAccount44(ring.account); key = key.derive(ring.change).derive(ring.index); @@ -2105,7 +2105,7 @@ RPC.prototype.dumpwallet = function dumpwallet(args, callback) { var file, time, key, address, fmt, str, out; if (args.help || args.length !== 1) - return callback(new Error('dumpwallet "filename"')); + return callback(new RPCError('dumpwallet "filename"')); file = utils.normalize(String(args[0])); time = utils.date(); @@ -2134,7 +2134,7 @@ RPC.prototype.dumpwallet = function dumpwallet(args, callback) { key = self.wallet.master.key; if (!key) - return callback(new Error('Wallet is locked.')); + return callback(new RPCError('Wallet is locked.')); key = key.deriveAccount44(ring.account); key = key.derive(ring.change).derive(ring.index); @@ -2169,15 +2169,15 @@ RPC.prototype.encryptwallet = function encryptwallet(args, callback) { var passphrase; if (!this.wallet.master.encrypted && (args.help || args.help !== 1)) - return callback(new Error('encryptwallet "passphrase"')); + return callback(new RPCError('encryptwallet "passphrase"')); if (this.wallet.master.encrypted) - return callback(new Error('Already running with an encrypted wallet')); + return callback(new RPCError('Already running with an encrypted wallet')); passphrase = args[0]; if (typeof passphrase !== 'string' || passphrase.length < 1) - return callback(new Error('encryptwallet "passphrase"')); + return callback(new RPCError('encryptwallet "passphrase"')); this.wallet.setPassphrase(passphrase, function(err) { if (err) @@ -2190,7 +2190,7 @@ RPC.prototype.getaccountaddress = function getaccountaddress(args, callback) { var account; if (args.help || args.length !== 1) - return callback(new Error('getaccountaddress "account"')); + return callback(new RPCError('getaccountaddress "account"')); account = String(args[0]); @@ -2212,12 +2212,12 @@ RPC.prototype.getaccount = function getaccount(args, callback) { var hash; if (args.help || args.length !== 1) - return callback(new Error('getaccount "bitcoinaddress"')); + return callback(new RPCError('getaccount "bitcoinaddress"')); hash = bcoin.address.getHash(args[0], 'hex'); if (!hash) - return callback(new Error('Invalid address.')); + return callback(new RPCError('Invalid address.')); this.wallet.getKeyring(hash, function(err, address) { if (err) @@ -2235,7 +2235,7 @@ RPC.prototype.getaddressesbyaccount = function getaddressesbyaccount(args, callb var account, addrs; if (args.help || args.length !== 1) - return callback(new Error('getaddressesbyaccount "account"')); + return callback(new RPCError('getaddressesbyaccount "account"')); account = String(args[0]); @@ -2272,7 +2272,7 @@ RPC.prototype.getbalance = function getbalance(args, callback) { var account, value; if (args.help || args.length > 3) - return callback(new Error('getbalance ( "account" minconf includeWatchonly )')); + return callback(new RPCError('getbalance ( "account" minconf includeWatchonly )')); if (args.length >= 1) { account = String(args[0]); @@ -2302,7 +2302,7 @@ RPC.prototype.getnewaddress = function getnewaddress(args, callback) { var account; if (args.help || args.length > 1) - return callback(new Error('getnewaddress ( "account" )')); + return callback(new RPCError('getnewaddress ( "account" )')); if (args.length === 1) account = String(args[0]); @@ -2319,7 +2319,7 @@ RPC.prototype.getnewaddress = function getnewaddress(args, callback) { RPC.prototype.getrawchangeaddress = function getrawchangeaddress(args, callback) { if (args.help || args.length > 1) - return callback(new Error('getrawchangeaddress')); + return callback(new RPCError('getrawchangeaddress')); this.wallet.createChange(function(err, address) { if (err) @@ -2335,7 +2335,7 @@ RPC.prototype.getreceivedbyaccount = function getreceivedbyaccount(args, callbac var i, j, account, tx, output; if (args.help || args.length < 1 || args.length > 2) - return callback(new Error('getreceivedbyaccount "account" ( minconf )')); + return callback(new RPCError('getreceivedbyaccount "account" ( minconf )')); account = String(args[0]); @@ -2374,12 +2374,12 @@ RPC.prototype.getreceivedbyaddress = function getreceivedbyaddress(args, callbac var i, j, hash, tx, output; if (args.help || args.length < 1 || args.length > 2) - return callback(new Error('getreceivedbyaddress "bitcoinaddress" ( minconf )')); + return callback(new RPCError('getreceivedbyaddress "bitcoinaddress" ( minconf )')); hash = bcoin.address.getHash(String(args[0]), 'hex'); if (!hash) - return callback(new Error('Invalid address')); + return callback(new RPCError('Invalid address')); if (args.length === 2) minconf = Number(args[1]); @@ -2415,7 +2415,7 @@ RPC.prototype._toWalletTX = function _toWalletTX(tx, callback) { return callback(err); if (!map) - return callback(new Error('TX not found.')); + return callback(new RPCError('TX not found.')); receive = map.inputs.length === 0; member = receive ? map.outputs[0] : map.inputs[0]; @@ -2452,12 +2452,12 @@ RPC.prototype.gettransaction = function gettransaction(args, callback) { var hash; if (args.help || args.length < 1 || args.length > 2) - return callback(new Error('gettransaction "txid" ( includeWatchonly )')); + return callback(new RPCError('gettransaction "txid" ( includeWatchonly )')); hash = String(args[0]); if (!utils.isHex(hash) || hash.length !== 64) - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); hash = utils.revHex(hash); @@ -2466,7 +2466,7 @@ RPC.prototype.gettransaction = function gettransaction(args, callback) { return callback(err); if (!tx) - return callback(new Error('TX not found.')); + return callback(new RPCError('TX not found.')); self._toWalletTX(tx, callback); }); @@ -2478,7 +2478,7 @@ RPC.prototype.abandontransaction = function abandontransaction(args, callback) { RPC.prototype.getunconfirmedbalance = function getunconfirmedbalance(args, callback) { if (args.help || args.length > 0) - return callback(new Error('getunconfirmedbalance')); + return callback(new RPCError('getunconfirmedbalance')); this.wallet.getBalance(function(err, balance) { if (err) @@ -2492,7 +2492,7 @@ RPC.prototype.getwalletinfo = function getwalletinfo(args, callback) { var self = this; if (args.help || args.length !== 0) - return callback(new Error('getwalletinfo')); + return callback(new RPCError('getwalletinfo')); this.wallet.getBalance(function(err, balance) { if (err) @@ -2520,7 +2520,7 @@ RPC.prototype.getwalletinfo = function getwalletinfo(args, callback) { RPC.prototype.importprivkey = function importprivkey(args, callback) { if (args.help || args.length < 1 || args.length > 3) { - return callback(new Error('importprivkey' + return callback(new RPCError('importprivkey' + ' "bitcoinprivkey" ( "label" rescan )')); } // Impossible to implement in bcoin. @@ -2529,14 +2529,14 @@ RPC.prototype.importprivkey = function importprivkey(args, callback) { RPC.prototype.importwallet = function importwallet(args, callback) { if (args.help || args.length !== 1) - return callback(new Error('importwallet "filename"')); + return callback(new RPCError('importwallet "filename"')); // Impossible to implement in bcoin. callback(new Error('Not implemented.')); }; RPC.prototype.importaddress = function importaddress(args, callback) { if (args.help || args.length < 1 || args.length > 4) { - return callback(new Error('importaddress' + return callback(new RPCError('importaddress' + ' "address" ( "label" rescan p2sh )')); } // Impossible to implement in bcoin. @@ -2545,14 +2545,14 @@ RPC.prototype.importaddress = function importaddress(args, callback) { RPC.prototype.importpubkey = function importpubkey(args, callback) { if (args.help || args.length < 1 || args.length > 4) - return callback(new Error('importpubkey "pubkey" ( "label" rescan )')); + return callback(new RPCError('importpubkey "pubkey" ( "label" rescan )')); // Impossible to implement in bcoin. callback(new Error('Not implemented.')); }; RPC.prototype.keypoolrefill = function keypoolrefill(args, callback) { if (args.help || args.length > 1) - return callback(new Error('keypoolrefill ( newsize )')); + return callback(new RPCError('keypoolrefill ( newsize )')); callback(null, null); }; @@ -2561,7 +2561,7 @@ RPC.prototype.listaccounts = function listaccounts(args, callback) { var map; if (args.help || args.length > 2) - return callback(new Error('listaccounts ( minconf includeWatchonly)')); + return callback(new RPCError('listaccounts ( minconf includeWatchonly)')); map = {}; @@ -2588,7 +2588,7 @@ RPC.prototype.listaccounts = function listaccounts(args, callback) { RPC.prototype.listaddressgroupings = function listaddressgroupings(args, callback) { if (args.help) - return callback(new Error('listaddressgroupings')); + return callback(new RPCError('listaddressgroupings')); callback(new Error('Not implemented.')); }; @@ -2609,14 +2609,14 @@ RPC.prototype.listsinceblock = function listsinceblock(args, callback) { var block, conf, out, highest; if (args.help) { - return callback(new Error('listsinceblock' + return callback(new RPCError('listsinceblock' + ' ( "blockhash" target-confirmations includeWatchonly)')); } if (args.length > 0) { block = String(args[0]); if (!utils.isHex(block) || block.length !== 64) - return callback(new Error('Invalid parameter.')); + return callback(new RPCError('Invalid parameter.')); block = utils.revHex(block); } @@ -2625,7 +2625,7 @@ RPC.prototype.listsinceblock = function listsinceblock(args, callback) { if (args.length > 1) { conf = Number(args[1]); if (!utils.isNumber(conf) || conf < 0) - return callback(new Error('Invalid parameter.')); + return callback(new RPCError('Invalid parameter.')); } out = []; @@ -2680,7 +2680,7 @@ RPC.prototype._toListTX = function _toListTX(tx, callback) { return callback(err); if (!map) - return callback(new Error('TX not found.')); + return callback(new RPCError('TX not found.')); receive = map.inputs.length === 0; member = receive ? map.outputs[0] : map.inputs[0]; @@ -2713,7 +2713,7 @@ RPC.prototype.listtransactions = function listtransactions(args, callback) { var account, count; if (args.help || args.length > 4) { - return callback(new Error('listtransactions' + return callback(new RPCError('listtransactions' + ' ( "account" count from includeWatchonly)')); } @@ -2782,7 +2782,7 @@ RPC.prototype.sendfrom = function sendfrom(args, callback) { var account, address, amount; if (args.help || args.length < 3 || args.length > 6) { - return callback(new Error('sendfrom' + return callback(new RPCError('sendfrom' + ' "fromaccount" "tobitcoinaddress"' + ' amount ( minconf "comment" "comment-to" )')); } @@ -2809,7 +2809,7 @@ RPC.prototype.sendtoaddress = function sendtoaddress(args, callback) { var address, amount, subtractFee; if (args.help || args.length < 2 || args.length > 5) { - return callback(new Error('sendtoaddress' + return callback(new RPCError('sendtoaddress' + ' "bitcoinaddress" amount' + ' ( "comment" "comment-to"' + ' subtractfeefromamount )')); @@ -2828,14 +2828,14 @@ RPC.prototype.sendtoaddress = function sendtoaddress(args, callback) { RPC.prototype.setaccount = function setaccount(args, callback) { if (args.help || args.length < 1 || args.length > 2) - return callback(new Error('setaccount "bitcoinaddress" "account"')); + return callback(new RPCError('setaccount "bitcoinaddress" "account"')); // Impossible to implement in bcoin: callback(new Error('Not implemented.')); }; RPC.prototype.settxfee = function settxfee(args, callback) { if (args.help || args.length < 1 || args.length > 1) - return callback(new Error('settxfee amount')); + return callback(new RPCError('settxfee amount')); this.feeRate = utils.satoshi(args[0]); @@ -2847,7 +2847,7 @@ RPC.prototype.signmessage = function signmessage(args, callback) { var address, msg, key, sig; if (args.help || args.length !== 2) - return callback(new Error('signmessage "bitcoinaddress" "message"')); + return callback(new RPCError('signmessage "bitcoinaddress" "message"')); address = String(args[0]); msg = String(args[1]); @@ -2855,19 +2855,19 @@ RPC.prototype.signmessage = function signmessage(args, callback) { address = bcoin.address.getHash(address, 'hex'); if (!address) - return callback(new Error('Invalid address.')); + return callback(new RPCError('Invalid address.')); this.wallet.getKeyring(address, function(err, address) { if (err) return callback(err); if (!address) - return callback(new Error('Address not found.')); + return callback(new RPCError('Address not found.')); key = self.wallet.master.key; if (!key) - return callback(new Error('Wallet is locked.')); + return callback(new RPCError('Wallet is locked.')); key = key.deriveAccount44(address.account); key = key.derive(address.change).derive(address.index); @@ -2883,10 +2883,10 @@ RPC.prototype.signmessage = function signmessage(args, callback) { RPC.prototype.walletlock = function walletlock(args, callback) { if (args.help || (this.wallet.master.encrypted && args.length !== 0)) - return callback(new Error('walletlock')); + return callback(new RPCError('walletlock')); if (!this.wallet.master.encrypted) - return callback(new Error('Wallet is not encrypted.')); + return callback(new RPCError('Wallet is not encrypted.')); this.wallet.lock(); callback(null, null); @@ -2896,21 +2896,21 @@ RPC.prototype.walletpassphrasechange = function walletpassphrasechange(args, cal var old, new_; if (args.help || (this.wallet.master.encrypted && args.length !== 2)) { - return callback(new Error('walletpassphrasechange' + return callback(new RPCError('walletpassphrasechange' + ' "oldpassphrase" "newpassphrase"')); } if (!this.wallet.master.encrypted) - return callback(new Error('Wallet is not encrypted.')); + return callback(new RPCError('Wallet is not encrypted.')); if (typeof args[0] !== 'string' || typeof args[1] !== 'string') - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); old = args[0]; new_ = args[1]; if (old.length < 1 || new_.length < 1) - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); this.wallet.setPassphrase(old, new_, function(err) { if (err) @@ -2922,16 +2922,16 @@ RPC.prototype.walletpassphrasechange = function walletpassphrasechange(args, cal RPC.prototype.walletpassphrase = function walletpassphrase(args, callback) { if (args.help || (this.wallet.master.encrypted && args.length !== 2)) - return callback(new Error('walletpassphrase "passphrase" timeout')); + return callback(new RPCError('walletpassphrase "passphrase" timeout')); if (!this.wallet.master.encrypted) - return callback(new Error('Wallet is not encrypted.')); + return callback(new RPCError('Wallet is not encrypted.')); if (typeof args[0] !== 'string' || args[0].length < 1) - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); if (!utils.isNumber(args[1]) || args[1] < 0) - return callback(new Error('Invalid parameter')); + return callback(new RPCError('Invalid parameter')); this.wallet.unlock(args[0], args[1], function(err) { if (err) @@ -2940,4 +2940,20 @@ RPC.prototype.walletpassphrase = function walletpassphrase(args, callback) { }); }; +/* + * Helpers + */ + +function RPCError(msg) { + Error.call(this); + + if (Error.captureStackTrace) + Error.captureStackTrace(this, RPCError); + + this.type = 'RPCError'; + this.message = msg; +} + +utils.inherits(RPCError, Error); + module.exports = RPC; diff --git a/lib/bcoin/http/server.js b/lib/bcoin/http/server.js index bafb4c8d..a785e6c4 100644 --- a/lib/bcoin/http/server.js +++ b/lib/bcoin/http/server.js @@ -333,7 +333,16 @@ HTTPServer.prototype._init = function _init() { self.rpc.execute(req.body, function(err, json) { if (err) { self.logger.error(err); - return send(400, { + + 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, @@ -342,6 +351,7 @@ HTTPServer.prototype._init = function _init() { id: req.body.id }); } + send(200, { result: json, error: null,