http: rpc improvements. minor fixes.
This commit is contained in:
parent
5ed8c0f4fe
commit
a87260c959
17
bin/cli
17
bin/cli
@ -7,6 +7,13 @@ const util = require('../lib/utils/util');
|
||||
const Client = require('../lib/http/client');
|
||||
const Wallet = require('../lib/http/wallet');
|
||||
|
||||
const ports = {
|
||||
main: 8332,
|
||||
testnet: 18332,
|
||||
regtest: 48332,
|
||||
simnet: 18556
|
||||
};
|
||||
|
||||
const ANTIREPLAY = ''
|
||||
+ '6a2e426974636f696e3a204120506565722d746f2d5065657'
|
||||
+ '220456c656374726f6e696320436173682053797374656d';
|
||||
@ -536,7 +543,10 @@ CLI.prototype.handleWallet = async function handleWallet() {
|
||||
this.wallet = new Wallet({
|
||||
url: this.config.str(['url', 'uri']),
|
||||
apiKey: this.config.str('api-key'),
|
||||
network: this.config.str('network'),
|
||||
host: this.config.str('http-host'),
|
||||
port: this.config.uint('http-port')
|
||||
|| ports[this.config.str('network', '')]
|
||||
|| ports.main,
|
||||
id: this.config.str('id', 'primary'),
|
||||
token: this.config.str('token')
|
||||
});
|
||||
@ -695,7 +705,10 @@ CLI.prototype.handleNode = async function handleNode() {
|
||||
this.client = new Client({
|
||||
url: this.config.str(['url', 'uri']),
|
||||
apiKey: this.config.str('api-key'),
|
||||
network: this.config.str('network')
|
||||
host: this.config.str('http-host'),
|
||||
port: this.config.uint('http-port')
|
||||
|| ports[this.config.str('network', '')]
|
||||
|| ports.main
|
||||
});
|
||||
|
||||
switch (this.argv.shift()) {
|
||||
|
||||
105
lib/http/rpc.js
105
lib/http/rpc.js
@ -36,14 +36,54 @@ const pkg = require('../pkg');
|
||||
const Lock = require('../utils/lock');
|
||||
const RPCBase = bweb.RPC;
|
||||
const RPCError = bweb.RPCError;
|
||||
const errs = bweb.errors;
|
||||
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
|
||||
const errs = {
|
||||
// Standard JSON-RPC 2.0 errors
|
||||
INVALID_REQUEST: bweb.errors.INVALID_REQUEST,
|
||||
METHOD_NOT_FOUND: bweb.errors.METHOD_NOT_FOUND,
|
||||
INVALID_PARAMS: bweb.errors.INVALID_PARAMS,
|
||||
INTERNAL_ERROR: bweb.errors.INTERNAL_ERROR,
|
||||
PARSE_ERROR: bweb.errors.PARSE_ERROR,
|
||||
|
||||
// General application defined errors
|
||||
MISC_ERROR: -1,
|
||||
FORBIDDEN_BY_SAFE_MODE: -2,
|
||||
TYPE_ERROR: -3,
|
||||
INVALID_ADDRESS_OR_KEY: -5,
|
||||
OUT_OF_MEMORY: -7,
|
||||
INVALID_PARAMETER: -8,
|
||||
DATABASE_ERROR: -20,
|
||||
DESERIALIZATION_ERROR: -22,
|
||||
VERIFY_ERROR: -25,
|
||||
VERIFY_REJECTED: -26,
|
||||
VERIFY_ALREADY_IN_CHAIN: -27,
|
||||
IN_WARMUP: -28,
|
||||
|
||||
// P2P client errors
|
||||
CLIENT_NOT_CONNECTED: -9,
|
||||
CLIENT_IN_INITIAL_DOWNLOAD: -10,
|
||||
CLIENT_NODE_ALREADY_ADDED: -23,
|
||||
CLIENT_NODE_NOT_ADDED: -24,
|
||||
CLIENT_NODE_NOT_CONNECTED: -29,
|
||||
CLIENT_INVALID_IP_OR_SUBNET: -30,
|
||||
CLIENT_P2P_DISABLED: -31
|
||||
};
|
||||
|
||||
const MAGIC_STRING = 'Bitcoin Signed Message:\n';
|
||||
|
||||
/**
|
||||
* Bitcoin RPC
|
||||
* @alias module:http.RPC
|
||||
* @extends bweb.RPC
|
||||
*/
|
||||
|
||||
class RPC extends RPCBase {
|
||||
/**
|
||||
* Bitcoin Core RPC
|
||||
* @alias module:http.RPC
|
||||
* @constructor
|
||||
* Create RPC.
|
||||
* @param {Node} node
|
||||
*/
|
||||
|
||||
@ -76,6 +116,41 @@ class RPC extends RPCBase {
|
||||
this.init();
|
||||
}
|
||||
|
||||
getCode(err) {
|
||||
switch (err.type) {
|
||||
case 'RPCError':
|
||||
return err.code;
|
||||
case 'ValidationError':
|
||||
return errors.TYPE_ERROR;
|
||||
case 'EncodingError':
|
||||
return errors.DESERIALIZATION_ERROR;
|
||||
default:
|
||||
return errors.INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
handleCall(cmd, query) {
|
||||
if (cmd.method !== 'getwork'
|
||||
&& cmd.method !== 'getblocktemplate'
|
||||
&& cmd.method !== 'getbestblockhash') {
|
||||
this.logger.debug('Handling RPC call: %s.', cmd.method);
|
||||
if (cmd.method !== 'submitblock'
|
||||
&& cmd.method !== 'getmemorypool') {
|
||||
this.logger.debug(cmd.params);
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd.method === 'getwork') {
|
||||
if (query.longpoll)
|
||||
cmd.method = 'getworklp';
|
||||
}
|
||||
}
|
||||
|
||||
handleError(err) {
|
||||
this.logger.error('RPC internal error.');
|
||||
this.logger.error(err);
|
||||
}
|
||||
|
||||
init() {
|
||||
this.add('stop', this.stop);
|
||||
this.add('help', this.help);
|
||||
@ -154,28 +229,6 @@ class RPC extends RPCBase {
|
||||
|
||||
this.add('getmemoryinfo', this.getMemoryInfo);
|
||||
this.add('setloglevel', this.setLogLevel);
|
||||
|
||||
this.on('error', (err) => {
|
||||
this.logger.error('RPC internal error.');
|
||||
this.logger.error(err);
|
||||
});
|
||||
|
||||
this.on('call', (cmd, query) => {
|
||||
if (cmd.method !== 'getwork'
|
||||
&& cmd.method !== 'getblocktemplate'
|
||||
&& cmd.method !== 'getbestblockhash') {
|
||||
this.logger.debug('Handling RPC call: %s.', cmd.method);
|
||||
if (cmd.method !== 'submitblock'
|
||||
&& cmd.method !== 'getmemorypool') {
|
||||
this.logger.debug(cmd.params);
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd.method === 'getwork') {
|
||||
if (query.longpoll)
|
||||
cmd.method = 'getworklp';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -95,6 +95,17 @@ class HTTPServer extends Server {
|
||||
this.use(this.jsonRPC());
|
||||
this.use(this.router());
|
||||
|
||||
this.error((err, req, res) => {
|
||||
const code = err.statusCode || 500;
|
||||
res.json(code, {
|
||||
error: {
|
||||
type: err.type,
|
||||
code: err.code,
|
||||
message: err.message
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.get('/', async (req, res) => {
|
||||
const totalTX = this.mempool ? this.mempool.map.size : 0;
|
||||
const size = this.mempool ? this.mempool.getSize() : 0;
|
||||
@ -163,7 +174,7 @@ class HTTPServer extends Server {
|
||||
const coin = await this.node.getCoin(hash, index);
|
||||
|
||||
if (!coin) {
|
||||
res.send(404);
|
||||
res.json(404);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -198,7 +209,7 @@ class HTTPServer extends Server {
|
||||
const meta = await this.node.getMeta(hash);
|
||||
|
||||
if (!meta) {
|
||||
res.send(404);
|
||||
res.json(404);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -256,14 +267,14 @@ class HTTPServer extends Server {
|
||||
const block = await this.chain.getBlock(hash);
|
||||
|
||||
if (!block) {
|
||||
res.send(404);
|
||||
res.json(404);
|
||||
return;
|
||||
}
|
||||
|
||||
const view = await this.chain.getBlockView(block);
|
||||
|
||||
if (!view) {
|
||||
res.send(404);
|
||||
res.json(404);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -306,7 +317,7 @@ class HTTPServer extends Server {
|
||||
const blocks = valid.u32('blocks');
|
||||
|
||||
if (!this.fees) {
|
||||
res.send(200, { rate: this.network.feeRate });
|
||||
res.json(200, { rate: this.network.feeRate });
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -93,6 +93,17 @@ class HTTPServer extends Server {
|
||||
this.use(this.jsonRPC());
|
||||
this.use(this.router());
|
||||
|
||||
this.error((err, req, res) => {
|
||||
const code = err.statusCode || 500;
|
||||
res.json(code, {
|
||||
error: {
|
||||
type: err.type,
|
||||
code: err.code,
|
||||
message: err.message
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.hook(async (req, res) => {
|
||||
const valid = Validator.fromRequest(req);
|
||||
|
||||
@ -112,7 +123,7 @@ class HTTPServer extends Server {
|
||||
const wallet = await this.wdb.get(id);
|
||||
|
||||
if (!wallet) {
|
||||
res.send(404);
|
||||
res.json(404);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -131,7 +142,7 @@ class HTTPServer extends Server {
|
||||
}
|
||||
|
||||
if (!wallet) {
|
||||
res.send(404);
|
||||
res.json(404);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -234,7 +245,7 @@ class HTTPServer extends Server {
|
||||
const account = await req.wallet.getAccount(acct);
|
||||
|
||||
if (!account) {
|
||||
res.send(404);
|
||||
res.json(404);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -490,7 +501,7 @@ class HTTPServer extends Server {
|
||||
const block = await req.wallet.getBlock(height);
|
||||
|
||||
if (!block) {
|
||||
res.send(404);
|
||||
res.json(404);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -538,7 +549,7 @@ class HTTPServer extends Server {
|
||||
const key = await req.wallet.getKey(addr);
|
||||
|
||||
if (!key) {
|
||||
res.send(404);
|
||||
res.json(404);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -557,7 +568,7 @@ class HTTPServer extends Server {
|
||||
const key = await req.wallet.getPrivateKey(addr, passphrase);
|
||||
|
||||
if (!key) {
|
||||
res.send(404);
|
||||
res.json(404);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -598,7 +609,7 @@ class HTTPServer extends Server {
|
||||
const balance = await req.wallet.getBalance(acct);
|
||||
|
||||
if (!balance) {
|
||||
res.send(404);
|
||||
res.json(404);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -675,7 +686,7 @@ class HTTPServer extends Server {
|
||||
const coin = await req.wallet.getCoin(hash, index);
|
||||
|
||||
if (!coin) {
|
||||
res.send(404);
|
||||
res.json(404);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -764,7 +775,7 @@ class HTTPServer extends Server {
|
||||
const tx = await req.wallet.getTX(hash);
|
||||
|
||||
if (!tx) {
|
||||
res.send(404);
|
||||
res.json(404);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -27,14 +27,56 @@ const Lock = require('../utils/lock');
|
||||
const common = require('./common');
|
||||
const RPCBase = bweb.RPC;
|
||||
const RPCError = bweb.RPCError;
|
||||
const errs = bweb.errors;
|
||||
|
||||
/*
|
||||
* Constants
|
||||
*/
|
||||
|
||||
const errs = {
|
||||
// Standard JSON-RPC 2.0 errors
|
||||
INVALID_REQUEST: bweb.errors.INVALID_REQUEST,
|
||||
METHOD_NOT_FOUND: bweb.errors.METHOD_NOT_FOUND,
|
||||
INVALID_PARAMS: bweb.errors.INVALID_PARAMS,
|
||||
INTERNAL_ERROR: bweb.errors.INTERNAL_ERROR,
|
||||
PARSE_ERROR: bweb.errors.PARSE_ERROR,
|
||||
|
||||
// General application defined errors
|
||||
MISC_ERROR: -1,
|
||||
FORBIDDEN_BY_SAFE_MODE: -2,
|
||||
TYPE_ERROR: -3,
|
||||
INVALID_ADDRESS_OR_KEY: -5,
|
||||
OUT_OF_MEMORY: -7,
|
||||
INVALID_PARAMETER: -8,
|
||||
DATABASE_ERROR: -20,
|
||||
DESERIALIZATION_ERROR: -22,
|
||||
VERIFY_ERROR: -25,
|
||||
VERIFY_REJECTED: -26,
|
||||
VERIFY_ALREADY_IN_CHAIN: -27,
|
||||
IN_WARMUP: -28,
|
||||
|
||||
// Wallet errors
|
||||
WALLET_ERROR: -4,
|
||||
WALLET_INSUFFICIENT_FUNDS: -6,
|
||||
WALLET_INVALID_ACCOUNT_NAME: -11,
|
||||
WALLET_KEYPOOL_RAN_OUT: -12,
|
||||
WALLET_UNLOCK_NEEDED: -13,
|
||||
WALLET_PASSPHRASE_INCORRECT: -14,
|
||||
WALLET_WRONG_ENC_STATE: -15,
|
||||
WALLET_ENCRYPTION_FAILED: -16,
|
||||
WALLET_ALREADY_UNLOCKED: -17
|
||||
};
|
||||
|
||||
const MAGIC_STRING = 'Bitcoin Signed Message:\n';
|
||||
|
||||
/**
|
||||
* Wallet RPC
|
||||
* @alias module:wallet.RPC
|
||||
* @extends bweb.RPC
|
||||
*/
|
||||
|
||||
class RPC extends RPCBase {
|
||||
/**
|
||||
* Bitcoin Core RPC
|
||||
* @alias module:wallet.RPC
|
||||
* @constructor
|
||||
* Create an RPC.
|
||||
* @param {WalletDB} wdb
|
||||
*/
|
||||
|
||||
@ -54,6 +96,21 @@ class RPC extends RPCBase {
|
||||
this.init();
|
||||
}
|
||||
|
||||
getCode(err) {
|
||||
switch (err.type) {
|
||||
case 'RPCError':
|
||||
return err.code;
|
||||
case 'ValidationError':
|
||||
return errors.TYPE_ERROR;
|
||||
case 'EncodingError':
|
||||
return errors.DESERIALIZATION_ERROR;
|
||||
case 'FundingError':
|
||||
return errors.WALLET_INSUFFICIENT_FUNDS;
|
||||
default:
|
||||
return errors.INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
this.add('help', this.help);
|
||||
this.add('stop', this.stop);
|
||||
@ -175,9 +232,9 @@ class RPC extends RPCBase {
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Wallet
|
||||
*/
|
||||
/*
|
||||
* Wallet
|
||||
*/
|
||||
|
||||
async resendWalletTransactions(args, help) {
|
||||
if (help || args.length !== 0)
|
||||
|
||||
@ -160,8 +160,7 @@ WalletDB.prototype._open = async function _open() {
|
||||
this.primary = wallet;
|
||||
this.rpc.wallet = wallet;
|
||||
|
||||
if (this.http && this.options.listen)
|
||||
await this.http.open();
|
||||
await this.http.open();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -172,9 +171,7 @@ WalletDB.prototype._open = async function _open() {
|
||||
|
||||
WalletDB.prototype._close = async function _close() {
|
||||
await this.disconnect();
|
||||
|
||||
if (this.http && this.options.listen)
|
||||
await this.http.close();
|
||||
await this.http.close();
|
||||
|
||||
for (const wallet of this.wallets.values()) {
|
||||
await wallet.destroy();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user