Add Bitcoin Core RPC cookie authentication option
This commit is contained in:
		
							parent
							
								
									e5efc2957a
								
							
						
					
					
						commit
						e9386ec003
					
				@ -35,7 +35,9 @@
 | 
			
		||||
    "PORT": 8332,
 | 
			
		||||
    "USERNAME": "mempool",
 | 
			
		||||
    "PASSWORD": "mempool",
 | 
			
		||||
    "TIMEOUT": 60000
 | 
			
		||||
    "TIMEOUT": 60000,
 | 
			
		||||
    "COOKIE": false,
 | 
			
		||||
    "COOKIE_PATH": "/path/to/bitcoin/.cookie"
 | 
			
		||||
  },
 | 
			
		||||
  "ELECTRUM": {
 | 
			
		||||
    "HOST": "127.0.0.1",
 | 
			
		||||
@ -52,7 +54,9 @@
 | 
			
		||||
    "PORT": 8332,
 | 
			
		||||
    "USERNAME": "mempool",
 | 
			
		||||
    "PASSWORD": "mempool",
 | 
			
		||||
    "TIMEOUT": 60000
 | 
			
		||||
    "TIMEOUT": 60000,
 | 
			
		||||
    "COOKIE": false,
 | 
			
		||||
    "COOKIE_PATH": "/path/to/bitcoin/.cookie"
 | 
			
		||||
  },
 | 
			
		||||
  "DATABASE": {
 | 
			
		||||
    "ENABLED": true,
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,9 @@
 | 
			
		||||
    "PORT": 15,
 | 
			
		||||
    "USERNAME": "__CORE_RPC_USERNAME__",
 | 
			
		||||
    "PASSWORD": "__CORE_RPC_PASSWORD__",
 | 
			
		||||
    "TIMEOUT": 1000
 | 
			
		||||
    "TIMEOUT": 1000,
 | 
			
		||||
    "COOKIE": "__CORE_RPC_COOKIE__",
 | 
			
		||||
    "COOKIE_PATH": "__CORE_RPC_COOKIE_PATH__"
 | 
			
		||||
  },
 | 
			
		||||
  "ELECTRUM": {
 | 
			
		||||
    "HOST": "__ELECTRUM_HOST__",
 | 
			
		||||
@ -53,7 +55,9 @@
 | 
			
		||||
    "PORT": 17,
 | 
			
		||||
    "USERNAME": "__SECOND_CORE_RPC_USERNAME__",
 | 
			
		||||
    "PASSWORD": "__SECOND_CORE_RPC_PASSWORD__",
 | 
			
		||||
    "TIMEOUT": 2000
 | 
			
		||||
    "TIMEOUT": 2000,
 | 
			
		||||
    "COOKIE": "__SECOND_CORE_RPC_COOKIE__",
 | 
			
		||||
    "COOKIE_PATH": "__SECOND_CORE_RPC_COOKIE_PATH__"
 | 
			
		||||
  },
 | 
			
		||||
  "DATABASE": {
 | 
			
		||||
    "ENABLED": false,
 | 
			
		||||
@ -119,4 +123,4 @@
 | 
			
		||||
  "CLIGHTNING": {
 | 
			
		||||
    "SOCKET": "__CLIGHTNING_SOCKET__"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -54,7 +54,9 @@ describe('Mempool Backend Config', () => {
 | 
			
		||||
        PORT: 8332,
 | 
			
		||||
        USERNAME: 'mempool',
 | 
			
		||||
        PASSWORD: 'mempool',
 | 
			
		||||
        TIMEOUT: 60000
 | 
			
		||||
        TIMEOUT: 60000,
 | 
			
		||||
        COOKIE: false,
 | 
			
		||||
        COOKIE_PATH: ''
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      expect(config.SECOND_CORE_RPC).toStrictEqual({
 | 
			
		||||
@ -62,7 +64,9 @@ describe('Mempool Backend Config', () => {
 | 
			
		||||
        PORT: 8332,
 | 
			
		||||
        USERNAME: 'mempool',
 | 
			
		||||
        PASSWORD: 'mempool',
 | 
			
		||||
        TIMEOUT: 60000
 | 
			
		||||
        TIMEOUT: 60000,
 | 
			
		||||
        COOKIE: false,
 | 
			
		||||
        COOKIE_PATH: ''
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      expect(config.DATABASE).toStrictEqual({
 | 
			
		||||
 | 
			
		||||
@ -25,4 +25,5 @@ export interface BitcoinRpcCredentials {
 | 
			
		||||
  user: string;
 | 
			
		||||
  pass: string;
 | 
			
		||||
  timeout: number;
 | 
			
		||||
  cookie?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2,12 +2,15 @@ import config from '../../config';
 | 
			
		||||
const bitcoin = require('../../rpc-api/index');
 | 
			
		||||
import { BitcoinRpcCredentials } from './bitcoin-api-abstract-factory';
 | 
			
		||||
 | 
			
		||||
export const defaultCookiePath = `${process.env.HOME}/.bitcoin/${{mainnet:'',testnet:'testnet3/',signet:'signet/'}[config.MEMPOOL.NETWORK]}.cookie`;
 | 
			
		||||
 | 
			
		||||
const nodeRpcCredentials: BitcoinRpcCredentials = {
 | 
			
		||||
  host: config.CORE_RPC.HOST,
 | 
			
		||||
  port: config.CORE_RPC.PORT,
 | 
			
		||||
  user: config.CORE_RPC.USERNAME,
 | 
			
		||||
  pass: config.CORE_RPC.PASSWORD,
 | 
			
		||||
  timeout: config.CORE_RPC.TIMEOUT,
 | 
			
		||||
  cookie: config.CORE_RPC.COOKIE ? config.CORE_RPC.COOKIE_PATH || defaultCookiePath : undefined,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default new bitcoin.Client(nodeRpcCredentials);
 | 
			
		||||
 | 
			
		||||
@ -2,12 +2,15 @@ import config from '../../config';
 | 
			
		||||
const bitcoin = require('../../rpc-api/index');
 | 
			
		||||
import { BitcoinRpcCredentials } from './bitcoin-api-abstract-factory';
 | 
			
		||||
 | 
			
		||||
import { defaultCookiePath } from './bitcoin-client';
 | 
			
		||||
 | 
			
		||||
const nodeRpcCredentials: BitcoinRpcCredentials = {
 | 
			
		||||
  host: config.SECOND_CORE_RPC.HOST,
 | 
			
		||||
  port: config.SECOND_CORE_RPC.PORT,
 | 
			
		||||
  user: config.SECOND_CORE_RPC.USERNAME,
 | 
			
		||||
  pass: config.SECOND_CORE_RPC.PASSWORD,
 | 
			
		||||
  timeout: config.SECOND_CORE_RPC.TIMEOUT,
 | 
			
		||||
  cookie: config.SECOND_CORE_RPC.COOKIE ? config.SECOND_CORE_RPC.COOKIE_PATH || defaultCookiePath : undefined,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default new bitcoin.Client(nodeRpcCredentials);
 | 
			
		||||
 | 
			
		||||
@ -70,6 +70,8 @@ interface IConfig {
 | 
			
		||||
    USERNAME: string;
 | 
			
		||||
    PASSWORD: string;
 | 
			
		||||
    TIMEOUT: number;
 | 
			
		||||
    COOKIE: boolean;
 | 
			
		||||
    COOKIE_PATH: string;
 | 
			
		||||
  };
 | 
			
		||||
  SECOND_CORE_RPC: {
 | 
			
		||||
    HOST: string;
 | 
			
		||||
@ -77,6 +79,8 @@ interface IConfig {
 | 
			
		||||
    USERNAME: string;
 | 
			
		||||
    PASSWORD: string;
 | 
			
		||||
    TIMEOUT: number;
 | 
			
		||||
    COOKIE: boolean;
 | 
			
		||||
    COOKIE_PATH: string;
 | 
			
		||||
  };
 | 
			
		||||
  DATABASE: {
 | 
			
		||||
    ENABLED: boolean;
 | 
			
		||||
@ -180,6 +184,8 @@ const defaults: IConfig = {
 | 
			
		||||
    'USERNAME': 'mempool',
 | 
			
		||||
    'PASSWORD': 'mempool',
 | 
			
		||||
    'TIMEOUT': 60000,
 | 
			
		||||
    'COOKIE': false,
 | 
			
		||||
    'COOKIE_PATH': '' // default value depends on network, see src/api/bitcoin/bitcoin-client
 | 
			
		||||
  },
 | 
			
		||||
  'SECOND_CORE_RPC': {
 | 
			
		||||
    'HOST': '127.0.0.1',
 | 
			
		||||
@ -187,6 +193,8 @@ const defaults: IConfig = {
 | 
			
		||||
    'USERNAME': 'mempool',
 | 
			
		||||
    'PASSWORD': 'mempool',
 | 
			
		||||
    'TIMEOUT': 60000,
 | 
			
		||||
    'COOKIE': false,
 | 
			
		||||
    'COOKIE_PATH': ''
 | 
			
		||||
  },
 | 
			
		||||
  'DATABASE': {
 | 
			
		||||
    'ENABLED': true,
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
var http = require('http')
 | 
			
		||||
var https = require('https')
 | 
			
		||||
import { readFileSync } from 'fs';
 | 
			
		||||
 | 
			
		||||
var JsonRPC = function (opts) {
 | 
			
		||||
  // @ts-ignore
 | 
			
		||||
@ -55,7 +56,13 @@ JsonRPC.prototype.call = function (method, params) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // use HTTP auth if user and password set
 | 
			
		||||
    if (this.opts.user && this.opts.pass) {
 | 
			
		||||
    if (this.opts.cookie) {
 | 
			
		||||
      if (!this.cachedCookie) {
 | 
			
		||||
        this.cachedCookie = readFileSync(this.opts.cookie).toString();
 | 
			
		||||
      }
 | 
			
		||||
      // @ts-ignore
 | 
			
		||||
      requestOptions.auth = this.cachedCookie;
 | 
			
		||||
    } else if (this.opts.user && this.opts.pass) {
 | 
			
		||||
      // @ts-ignore
 | 
			
		||||
      requestOptions.auth = this.opts.user + ':' + this.opts.pass
 | 
			
		||||
    }
 | 
			
		||||
@ -93,7 +100,7 @@ JsonRPC.prototype.call = function (method, params) {
 | 
			
		||||
      reject(err)
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    request.on('response', function (response) {
 | 
			
		||||
    request.on('response', (response) => {
 | 
			
		||||
      clearTimeout(reqTimeout)
 | 
			
		||||
 | 
			
		||||
      // We need to buffer the response chunks in a nonblocking way.
 | 
			
		||||
@ -104,7 +111,7 @@ JsonRPC.prototype.call = function (method, params) {
 | 
			
		||||
      // When all the responses are finished, we decode the JSON and
 | 
			
		||||
      // depending on whether it's got a result or an error, we call
 | 
			
		||||
      // emitSuccess or emitError on the promise.
 | 
			
		||||
      response.on('end', function () {
 | 
			
		||||
      response.on('end', () => {
 | 
			
		||||
        var err
 | 
			
		||||
 | 
			
		||||
        if (cbCalled) return
 | 
			
		||||
@ -113,6 +120,14 @@ JsonRPC.prototype.call = function (method, params) {
 | 
			
		||||
        try {
 | 
			
		||||
          var decoded = JSON.parse(buffer)
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
          // if we authenticated using a cookie and it failed, read the cookie file again
 | 
			
		||||
          if (
 | 
			
		||||
            response.statusCode === 401 /* Unauthorized */ &&
 | 
			
		||||
            this.opts.cookie
 | 
			
		||||
          ) {
 | 
			
		||||
            this.cachedCookie = undefined;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          if (response.statusCode !== 200) {
 | 
			
		||||
            err = new Error('Invalid params, response status code: ' + response.statusCode)
 | 
			
		||||
            err.code = -32602
 | 
			
		||||
 | 
			
		||||
@ -162,7 +162,9 @@ Corresponding `docker-compose.yml` overrides:
 | 
			
		||||
    "PORT": 8332,
 | 
			
		||||
    "USERNAME": "mempool",
 | 
			
		||||
    "PASSWORD": "mempool",
 | 
			
		||||
    "TIMEOUT": 60000
 | 
			
		||||
    "TIMEOUT": 60000,
 | 
			
		||||
    "COOKIE": "false",
 | 
			
		||||
    "COOKIE_PATH": ""
 | 
			
		||||
  },
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@ -174,7 +176,9 @@ Corresponding `docker-compose.yml` overrides:
 | 
			
		||||
      CORE_RPC_PORT: ""
 | 
			
		||||
      CORE_RPC_USERNAME: ""
 | 
			
		||||
      CORE_RPC_PASSWORD: ""
 | 
			
		||||
      CORE_RPC_TIMEOUT: 60000
 | 
			
		||||
      CORE_RPC_TIMEOUT: 60000,
 | 
			
		||||
      CORE_RPC_COOKIE: ""
 | 
			
		||||
      CORE_RPC_COOKIE_PATH: ""
 | 
			
		||||
      ...
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@ -229,7 +233,9 @@ Corresponding `docker-compose.yml` overrides:
 | 
			
		||||
    "PORT": 8332,
 | 
			
		||||
    "USERNAME": "mempool",
 | 
			
		||||
    "PASSWORD": "mempool",
 | 
			
		||||
    "TIMEOUT": 60000
 | 
			
		||||
    "TIMEOUT": 60000,
 | 
			
		||||
    "COOKIE": "false",
 | 
			
		||||
    "COOKIE_PATH": ""
 | 
			
		||||
  },
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@ -241,7 +247,9 @@ Corresponding `docker-compose.yml` overrides:
 | 
			
		||||
      SECOND_CORE_RPC_PORT: ""
 | 
			
		||||
      SECOND_CORE_RPC_USERNAME: ""
 | 
			
		||||
      SECOND_CORE_RPC_PASSWORD: ""
 | 
			
		||||
      SECOND_CORE_RPC_TIMEOUT: ""
 | 
			
		||||
      SECOND_CORE_RPC_TIMEOUT: "",
 | 
			
		||||
      SECOND_CORE_RPC_COOKIE: ""
 | 
			
		||||
      SECOND_CORE_RPC_COOKIE_PATH: ""
 | 
			
		||||
      ...
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,9 @@
 | 
			
		||||
    "PORT": __CORE_RPC_PORT__,
 | 
			
		||||
    "USERNAME": "__CORE_RPC_USERNAME__",
 | 
			
		||||
    "PASSWORD": "__CORE_RPC_PASSWORD__",
 | 
			
		||||
    "TIMEOUT": __CORE_RPC_TIMEOUT__
 | 
			
		||||
    "TIMEOUT": __CORE_RPC_TIMEOUT__,
 | 
			
		||||
    "COOKIE": __CORE_RPC_COOKIE__,
 | 
			
		||||
    "COOKIE_PATH": "__CORE_RPC_COOKIE_PATH__"
 | 
			
		||||
  },
 | 
			
		||||
  "ELECTRUM": {
 | 
			
		||||
    "HOST": "__ELECTRUM_HOST__",
 | 
			
		||||
@ -53,7 +55,9 @@
 | 
			
		||||
    "PORT": __SECOND_CORE_RPC_PORT__,
 | 
			
		||||
    "USERNAME": "__SECOND_CORE_RPC_USERNAME__",
 | 
			
		||||
    "PASSWORD": "__SECOND_CORE_RPC_PASSWORD__",
 | 
			
		||||
    "TIMEOUT": __SECOND_CORE_RPC_TIMEOUT__
 | 
			
		||||
    "TIMEOUT": __SECOND_CORE_RPC_TIMEOUT__,
 | 
			
		||||
    "COOKIE": __SECOND_CORE_RPC_COOKIE__,
 | 
			
		||||
    "COOKIE_PATH": "__SECOND_CORE_RPC_COOKIE_PATH__"
 | 
			
		||||
  },
 | 
			
		||||
  "DATABASE": {
 | 
			
		||||
    "ENABLED": __DATABASE_ENABLED__,
 | 
			
		||||
 | 
			
		||||
@ -38,6 +38,8 @@ __CORE_RPC_PORT__=${CORE_RPC_PORT:=8332}
 | 
			
		||||
__CORE_RPC_USERNAME__=${CORE_RPC_USERNAME:=mempool}
 | 
			
		||||
__CORE_RPC_PASSWORD__=${CORE_RPC_PASSWORD:=mempool}
 | 
			
		||||
__CORE_RPC_TIMEOUT__=${CORE_RPC_TIMEOUT:=60000}
 | 
			
		||||
__CORE_RPC_COOKIE__=${CORE_RPC_COOKIE:=false}
 | 
			
		||||
__CORE_RPC_COOKIE_PATH__=${CORE_RPC_COOKIE:=""}
 | 
			
		||||
 | 
			
		||||
# ELECTRUM
 | 
			
		||||
__ELECTRUM_HOST__=${ELECTRUM_HOST:=127.0.0.1}
 | 
			
		||||
@ -55,6 +57,8 @@ __SECOND_CORE_RPC_PORT__=${SECOND_CORE_RPC_PORT:=8332}
 | 
			
		||||
__SECOND_CORE_RPC_USERNAME__=${SECOND_CORE_RPC_USERNAME:=mempool}
 | 
			
		||||
__SECOND_CORE_RPC_PASSWORD__=${SECOND_CORE_RPC_PASSWORD:=mempool}
 | 
			
		||||
__SECOND_CORE_RPC_TIMEOUT__=${SECOND_CORE_RPC_TIMEOUT:=60000}
 | 
			
		||||
__SECOND_CORE_RPC_COOKIE__=${SECOND_CORE_RPC_COOKIE:=false}
 | 
			
		||||
__SECOND_CORE_RPC_COOKIE_PATH__=${SECOND_CORE_RPC_COOKIE:=""}
 | 
			
		||||
 | 
			
		||||
# DATABASE
 | 
			
		||||
__DATABASE_ENABLED__=${DATABASE_ENABLED:=true}
 | 
			
		||||
@ -165,6 +169,8 @@ sed -i "s!__CORE_RPC_PORT__!${__CORE_RPC_PORT__}!g" mempool-config.json
 | 
			
		||||
sed -i "s!__CORE_RPC_USERNAME__!${__CORE_RPC_USERNAME__}!g" mempool-config.json
 | 
			
		||||
sed -i "s!__CORE_RPC_PASSWORD__!${__CORE_RPC_PASSWORD__}!g" mempool-config.json
 | 
			
		||||
sed -i "s!__CORE_RPC_TIMEOUT__!${__CORE_RPC_TIMEOUT__}!g" mempool-config.json
 | 
			
		||||
sed -i "s!__CORE_RPC_COOKIE__!${__CORE_RPC_COOKIE__}!g" mempool-config.json
 | 
			
		||||
sed -i "s!__CORE_RPC_COOKIE_PATH__!${__CORE_RPC_COOKIE_PATH__}!g" mempool-config.json
 | 
			
		||||
 | 
			
		||||
sed -i "s!__ELECTRUM_HOST__!${__ELECTRUM_HOST__}!g" mempool-config.json
 | 
			
		||||
sed -i "s!__ELECTRUM_PORT__!${__ELECTRUM_PORT__}!g" mempool-config.json
 | 
			
		||||
@ -179,6 +185,8 @@ sed -i "s!__SECOND_CORE_RPC_PORT__!${__SECOND_CORE_RPC_PORT__}!g" mempool-config
 | 
			
		||||
sed -i "s!__SECOND_CORE_RPC_USERNAME__!${__SECOND_CORE_RPC_USERNAME__}!g" mempool-config.json
 | 
			
		||||
sed -i "s!__SECOND_CORE_RPC_PASSWORD__!${__SECOND_CORE_RPC_PASSWORD__}!g" mempool-config.json
 | 
			
		||||
sed -i "s!__SECOND_CORE_RPC_TIMEOUT__!${__SECOND_CORE_RPC_TIMEOUT__}!g" mempool-config.json
 | 
			
		||||
sed -i "s!__SECOND_CORE_RPC_COOKIE__!${__SECOND_CORE_RPC_COOKIE__}!g" mempool-config.json
 | 
			
		||||
sed -i "s!__SECOND_CORE_RPC_COOKIE_PATH__!${__SECOND_CORE_RPC_COOKIE_PATH__}!g" mempool-config.json
 | 
			
		||||
 | 
			
		||||
sed -i "s!__DATABASE_ENABLED__!${__DATABASE_ENABLED__}!g" mempool-config.json
 | 
			
		||||
sed -i "s!__DATABASE_HOST__!${__DATABASE_HOST__}!g" mempool-config.json
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user