mirror of
https://github.com/mempool/mempool.git
synced 2025-03-30 04:32:06 +02:00
295 lines
9.9 KiB
TypeScript
295 lines
9.9 KiB
TypeScript
import * as fs from 'fs';
|
|
|
|
describe('Mempool Backend Config', () => {
|
|
beforeEach(() => {
|
|
jest.resetAllMocks();
|
|
jest.resetModules();
|
|
});
|
|
|
|
test('should return defaults when no file is present', () => {
|
|
jest.isolateModules(() => {
|
|
jest.mock('../../mempool-config.json', () => ({}), { virtual: true });
|
|
|
|
const config = jest.requireActual('../config').default;
|
|
|
|
expect(config.MEMPOOL).toStrictEqual({
|
|
ENABLED: true,
|
|
OFFICIAL: false,
|
|
NETWORK: 'mainnet',
|
|
BACKEND: 'none',
|
|
BLOCKS_SUMMARIES_INDEXING: false,
|
|
GOGGLES_INDEXING: false,
|
|
HTTP_PORT: 8999,
|
|
UNIX_SOCKET_PATH: '',
|
|
SPAWN_CLUSTER_PROCS: 0,
|
|
API_URL_PREFIX: '/api/v1/',
|
|
AUTOMATIC_POOLS_UPDATE: false,
|
|
POLL_RATE_MS: 2000,
|
|
CACHE_DIR: './cache',
|
|
CACHE_ENABLED: true,
|
|
CLEAR_PROTECTION_MINUTES: 20,
|
|
RECOMMENDED_FEE_PERCENTILE: 50,
|
|
BLOCK_WEIGHT_UNITS: 4000000,
|
|
INITIAL_BLOCKS_AMOUNT: 8,
|
|
MEMPOOL_BLOCKS_AMOUNT: 8,
|
|
INDEXING_BLOCKS_AMOUNT: 11000,
|
|
USE_SECOND_NODE_FOR_MINFEE: false,
|
|
EXTERNAL_ASSETS: [],
|
|
EXTERNAL_MAX_RETRY: 1,
|
|
EXTERNAL_RETRY_INTERVAL: 0,
|
|
USER_AGENT: 'mempool',
|
|
STDOUT_LOG_MIN_PRIORITY: 'debug',
|
|
POOLS_JSON_TREE_URL: 'https://api.github.com/repos/mempool/mining-pools/git/trees/master',
|
|
POOLS_JSON_URL: 'https://raw.githubusercontent.com/mempool/mining-pools/master/pools-v2.json',
|
|
AUDIT: false,
|
|
RUST_GBT: true,
|
|
LIMIT_GBT: false,
|
|
CPFP_INDEXING: false,
|
|
MAX_BLOCKS_BULK_QUERY: 0,
|
|
DISK_CACHE_BLOCK_INTERVAL: 6,
|
|
MAX_PUSH_TX_SIZE_WEIGHT: 400000,
|
|
ALLOW_UNREACHABLE: true,
|
|
PRICE_UPDATES_PER_HOUR: 1,
|
|
MAX_TRACKED_ADDRESSES: 1,
|
|
});
|
|
|
|
expect(config.ELECTRUM).toStrictEqual({ HOST: '127.0.0.1', PORT: 3306, TLS_ENABLED: true });
|
|
|
|
expect(config.ESPLORA).toStrictEqual({
|
|
REST_API_URL: 'http://127.0.0.1:3000',
|
|
UNIX_SOCKET_PATH: null,
|
|
BATCH_QUERY_BASE_SIZE: 1000,
|
|
RETRY_UNIX_SOCKET_AFTER: 30000,
|
|
REQUEST_TIMEOUT: 10000,
|
|
FALLBACK_TIMEOUT: 5000,
|
|
FALLBACK: [],
|
|
MAX_BEHIND_TIP: 2,
|
|
});
|
|
|
|
expect(config.CORE_RPC).toStrictEqual({
|
|
HOST: '127.0.0.1',
|
|
PORT: 8332,
|
|
USERNAME: 'mempool',
|
|
PASSWORD: 'mempool',
|
|
TIMEOUT: 60000,
|
|
COOKIE: false,
|
|
COOKIE_PATH: '/bitcoin/.cookie'
|
|
});
|
|
|
|
expect(config.SECOND_CORE_RPC).toStrictEqual({
|
|
HOST: '127.0.0.1',
|
|
PORT: 8332,
|
|
USERNAME: 'mempool',
|
|
PASSWORD: 'mempool',
|
|
TIMEOUT: 60000,
|
|
COOKIE: false,
|
|
COOKIE_PATH: '/bitcoin/.cookie'
|
|
});
|
|
|
|
expect(config.DATABASE).toStrictEqual({
|
|
ENABLED: true,
|
|
HOST: '127.0.0.1',
|
|
SOCKET: '',
|
|
PORT: 3306,
|
|
DATABASE: 'mempool',
|
|
USERNAME: 'mempool',
|
|
PASSWORD: 'mempool',
|
|
TIMEOUT: 180000,
|
|
PID_DIR: '',
|
|
POOL_SIZE: 100,
|
|
});
|
|
|
|
expect(config.SYSLOG).toStrictEqual({
|
|
ENABLED: true,
|
|
HOST: '127.0.0.1',
|
|
PORT: 514,
|
|
MIN_PRIORITY: 'info',
|
|
FACILITY: 'local7'
|
|
});
|
|
|
|
expect(config.STATISTICS).toStrictEqual({ ENABLED: true, TX_PER_SECOND_SAMPLE_PERIOD: 150 });
|
|
|
|
expect(config.SOCKS5PROXY).toStrictEqual({
|
|
ENABLED: false,
|
|
USE_ONION: true,
|
|
HOST: '127.0.0.1',
|
|
PORT: 9050,
|
|
USERNAME: '',
|
|
PASSWORD: ''
|
|
});
|
|
|
|
expect(config.EXTERNAL_DATA_SERVER).toStrictEqual({
|
|
MEMPOOL_API: 'https://mempool.space/api/v1',
|
|
MEMPOOL_ONION: 'http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/api/v1',
|
|
LIQUID_API: 'https://liquid.network/api/v1',
|
|
LIQUID_ONION: 'http://liquidmom47f6s3m53ebfxn47p76a6tlnxib3wp6deux7wuzotdr6cyd.onion/api/v1'
|
|
});
|
|
|
|
expect(config.MAXMIND).toStrictEqual({
|
|
ENABLED: false,
|
|
GEOLITE2_CITY: '/usr/local/share/GeoIP/GeoLite2-City.mmdb',
|
|
GEOLITE2_ASN: '/usr/local/share/GeoIP/GeoLite2-ASN.mmdb',
|
|
GEOIP2_ISP: '/usr/local/share/GeoIP/GeoIP2-ISP.mmdb'
|
|
});
|
|
|
|
expect(config.REPLICATION).toStrictEqual({
|
|
ENABLED: false,
|
|
AUDIT: false,
|
|
AUDIT_START_HEIGHT: 774000,
|
|
STATISTICS: false,
|
|
STATISTICS_START_TIME: 1481932800,
|
|
SERVERS: []
|
|
});
|
|
|
|
expect(config.MEMPOOL_SERVICES).toStrictEqual({
|
|
API: "",
|
|
ACCELERATIONS: false,
|
|
});
|
|
|
|
expect(config.REDIS).toStrictEqual({
|
|
ENABLED: false,
|
|
UNIX_SOCKET_PATH: '',
|
|
BATCH_QUERY_BASE_SIZE: 5000,
|
|
});
|
|
|
|
expect(config.FIAT_PRICE).toStrictEqual({
|
|
ENABLED: true,
|
|
PAID: false,
|
|
API_KEY: '',
|
|
});
|
|
});
|
|
});
|
|
|
|
test('should override the default values with the passed values', () => {
|
|
jest.isolateModules(() => {
|
|
const fixture = JSON.parse(fs.readFileSync(`${__dirname}/../__fixtures__/mempool-config.template.json`, 'utf8'));
|
|
jest.mock('../../mempool-config.json', () => (fixture), { virtual: true });
|
|
|
|
const config = jest.requireActual('../config').default;
|
|
|
|
expect(config.MEMPOOL).toStrictEqual(fixture.MEMPOOL);
|
|
|
|
expect(config.ELECTRUM).toStrictEqual(fixture.ELECTRUM);
|
|
|
|
expect(config.ESPLORA).toStrictEqual(fixture.ESPLORA);
|
|
|
|
expect(config.CORE_RPC).toStrictEqual(fixture.CORE_RPC);
|
|
|
|
expect(config.SECOND_CORE_RPC).toStrictEqual(fixture.SECOND_CORE_RPC);
|
|
|
|
expect(config.DATABASE).toStrictEqual(fixture.DATABASE);
|
|
|
|
expect(config.SYSLOG).toStrictEqual(fixture.SYSLOG);
|
|
|
|
expect(config.STATISTICS).toStrictEqual(fixture.STATISTICS);
|
|
|
|
expect(config.SOCKS5PROXY).toStrictEqual(fixture.SOCKS5PROXY);
|
|
|
|
expect(config.EXTERNAL_DATA_SERVER).toStrictEqual(fixture.EXTERNAL_DATA_SERVER);
|
|
|
|
expect(config.MEMPOOL_SERVICES).toStrictEqual(fixture.MEMPOOL_SERVICES);
|
|
|
|
expect(config.REDIS).toStrictEqual(fixture.REDIS);
|
|
});
|
|
});
|
|
|
|
test('should ensure the docker start.sh script has default values', () => {
|
|
jest.isolateModules(() => {
|
|
const startSh = fs.readFileSync(`${__dirname}/../../../docker/backend/start.sh`, 'utf-8');
|
|
const fixture = JSON.parse(fs.readFileSync(`${__dirname}/../__fixtures__/mempool-config.template.json`, 'utf8'));
|
|
|
|
function parseJson(jsonObj, root?) {
|
|
for (const [key, value] of Object.entries(jsonObj)) {
|
|
// We have a few cases where we can't follow the pattern
|
|
if (root === 'MEMPOOL' && key === 'HTTP_PORT') {
|
|
if (process.env.CI) {
|
|
console.log('skipping check for MEMPOOL_HTTP_PORT');
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (root) {
|
|
//The flattened string, i.e, __MEMPOOL_ENABLED__
|
|
const replaceStr = `${root ? '__' + root + '_' : '__'}${key}__`;
|
|
|
|
//The string used as the environment variable, i.e, MEMPOOL_ENABLED
|
|
const envVarStr = `${root ? root : ''}_${key}`;
|
|
|
|
let defaultEntry;
|
|
//The string used as the default value, to be checked as a regex, i.e, __MEMPOOL_ENABLED__=${MEMPOOL_ENABLED:=(.*)}
|
|
if (Array.isArray(value)) {
|
|
defaultEntry = `${replaceStr}=\${${envVarStr}:=[]}`;
|
|
if (process.env.CI) {
|
|
console.log(`looking for ${defaultEntry} in the start.sh script`);
|
|
}
|
|
//Regex matching does not work with the array values
|
|
expect(startSh).toContain(defaultEntry);
|
|
} else {
|
|
defaultEntry = replaceStr + '=' + '\\${' + envVarStr + ':=(.*)' + '}';
|
|
if (process.env.CI) {
|
|
console.log(`looking for ${defaultEntry} in the start.sh script`);
|
|
}
|
|
const re = new RegExp(defaultEntry);
|
|
expect(startSh).toMatch(re);
|
|
}
|
|
|
|
//The string that actually replaces the values in the config file
|
|
const sedStr = 'sed -i "s!' + replaceStr + '!${' + replaceStr + '}!g" mempool-config.json';
|
|
if (process.env.CI) {
|
|
console.log(`looking for ${sedStr} in the start.sh script`);
|
|
}
|
|
expect(startSh).toContain(sedStr);
|
|
}
|
|
else {
|
|
parseJson(value, key);
|
|
}
|
|
}
|
|
}
|
|
|
|
parseJson(fixture);
|
|
});
|
|
});
|
|
|
|
test('should ensure that the mempool-config.json Docker template has all the keys', () => {
|
|
jest.isolateModules(() => {
|
|
const fixture = JSON.parse(fs.readFileSync(`${__dirname}/../__fixtures__/mempool-config.template.json`, 'utf8'));
|
|
const dockerJson = fs.readFileSync(`${__dirname}/../../../docker/backend/mempool-config.json`, 'utf-8');
|
|
|
|
function parseJson(jsonObj, root?) {
|
|
for (const [key, value] of Object.entries(jsonObj)) {
|
|
switch (typeof value) {
|
|
case 'object': {
|
|
if (Array.isArray(value)) {
|
|
// numbers, arrays and booleans won't be enclosed by quotes
|
|
const replaceStr = `${root ? '__' + root + '_' : '__'}${key}__`;
|
|
expect(dockerJson).toContain(`"${key}": ${replaceStr}`);
|
|
break;
|
|
} else {
|
|
//Check for top level config keys
|
|
expect(dockerJson).toContain(`"${key}"`);
|
|
parseJson(value, key);
|
|
break;
|
|
}
|
|
}
|
|
case 'string': {
|
|
// strings should be enclosed by quotes
|
|
const replaceStr = `${root ? '__' + root + '_' : '__'}${key}__`;
|
|
expect(dockerJson).toContain(`"${key}": "${replaceStr}"`);
|
|
break;
|
|
}
|
|
default: {
|
|
// numbers, arrays and booleans won't be enclosed by quotes
|
|
const replaceStr = `${root ? '__' + root + '_' : '__'}${key}__`;
|
|
expect(dockerJson).toContain(`"${key}": ${replaceStr}`);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
parseJson(fixture);
|
|
});
|
|
});
|
|
|
|
|
|
});
|