Skip to content

Commit

Permalink
fix(dashmate): dapi kills host machine on container stop (#1670)
Browse files Browse the repository at this point in the history
  • Loading branch information
shumkov authored Jan 12, 2024
1 parent 31f84e4 commit d320578
Show file tree
Hide file tree
Showing 22 changed files with 107 additions and 81 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ packages/*/dist
packages/*/wasm
packages/*/lib/wasm
packages/*/node_modules
packages/*/.env

!packages/platform-test-suite/test

Expand Down
7 changes: 6 additions & 1 deletion .github/package-filters/js-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,12 @@ dash: &dash
dashmate:
- .github/workflows/tests*
- packages/dashmate/**
- *dash
- *dashpay-contract
- *masternode-reward-shares-contract
- *dpns-contract
- *withdrawals-contract
- *wallet-lib
- *dapi-client

'@dashevo/platform-test-suite':
- .github/workflows/tests*
Expand Down
1 change: 1 addition & 0 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 0 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -392,9 +392,6 @@ LABEL description="DAPI Node.JS"
# Install ZMQ shared library
RUN apk add --no-cache zeromq-dev

# Install pm2
RUN npm install -g pm2

WORKDIR /platform/packages/dapi

COPY --from=build-dapi /platform/.yarn /platform/.yarn
Expand All @@ -411,5 +408,3 @@ RUN cp /platform/packages/dapi/.env.example /platform/packages/dapi/.env

EXPOSE 2500 2501 2510
USER node

ENTRYPOINT ["yarn", "node", "/usr/local/bin/pm2-runtime", "pm2.yml"]
22 changes: 6 additions & 16 deletions packages/dapi/lib/externalApis/tenderdash/WsClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ class WsClient extends EventEmitter {

this.emit(event.type, event);

this.ws.removeAllListeners();
this.ws.terminate();
this.ws = null;
this.isConnected = false;

setTimeout(this.open.bind(this), this.autoReconnectInterval);
} else {
const event = {
Expand Down Expand Up @@ -82,12 +87,6 @@ class WsClient extends EventEmitter {

this.emit(event.type, event);

if (e.code === 1000) { // close normal
this.disconnect();

return;
}

reconnect();
};

Expand All @@ -100,16 +99,7 @@ class WsClient extends EventEmitter {

this.emit(event.type, event);

switch (e.code) {
case 'ENOTFOUND':
case 'EAI_AGAIN':
case 'ECONNREFUSED':
reconnect();
break;
default:
this.disconnect();
break;
}
reconnect();
};

const onMessageListener = (rawData) => {
Expand Down
24 changes: 0 additions & 24 deletions packages/dapi/pm2.yml

This file was deleted.

3 changes: 0 additions & 3 deletions packages/dapi/scripts/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,3 @@ process.on('SIGINT', () => {

process.exit();
});

// Tell PM2 that process ready to receive connections
process.send('ready');
3 changes: 0 additions & 3 deletions packages/dapi/scripts/core-streams.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,3 @@ process.on('SIGINT', () => {

process.exit();
});

// Tell PM2 that process ready to receive connections
process.send('ready');
3 changes: 3 additions & 0 deletions packages/dashmate/configs/defaults/getBaseConfigFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ export default function getBaseConfigFactory(homeDir) {
api: {
docker: {
image: `dashpay/dapi:${dockerImageVersion}`,
deploy: {
replicas: 1,
},
build: {
enabled: false,
context: path.join(PACKAGE_ROOT_DIR, '..', '..'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export default function getTestnetConfigFactory(homeDir, getBaseConfig) {
genesis_time: '2023-11-02T10:18:00.000Z',
chain_id: 'dash-testnet-37',
validator_quorum_type: 6,
initial_core_chain_locked_height: 918609,
},
},
},
Expand Down
3 changes: 2 additions & 1 deletion packages/dashmate/configs/getConfigFileMigrationsFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,9 @@ export default function getConfigFileMigrationsFactory(homeDir, defaultConfigs)
Object.entries(configFile.configs)
.forEach(([name, options]) => {
if (defaultConfigs.has(name)) {
options.platform.drive.tenderdash.genesis = defaultConfigs.get(name).get('options.platform.drive.tenderdash.genesis');
options.platform.drive.tenderdash.genesis = defaultConfigs.get(name).get('platform.drive.tenderdash.genesis');
}
options.platform.dapi.api.docker.deploy = base.get('platform.dapi.api.docker.deploy');
});

return configFile;
Expand Down
15 changes: 13 additions & 2 deletions packages/dashmate/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ services:
labels:
org.dashmate.service.title: "DAPI API"
restart: unless-stopped
deploy:
mode: replicated
replicas: ${PLATFORM_DAPI_API_DOCKER_DEPLOY_REPLICAS:-1}
depends_on:
- drive_tenderdash
environment:
Expand All @@ -120,16 +123,22 @@ services:
- TENDERMINT_RPC_HOST=drive_tenderdash
- TENDERMINT_RPC_PORT=${PLATFORM_DRIVE_TENDERDASH_RPC_PORT:?err}
- NODE_ENV=${ENVIRONMENT:?err}
command: --only api
command: yarn run api
stop_grace_period: 10s
profiles:
- platform
expose:
- 3004
- 3005

dapi_tx_filter_stream:
image: ${PLATFORM_DAPI_API_DOCKER_IMAGE:?err}
labels:
org.dashmate.service.title: "DAPI Transactions Filter Stream"
restart: unless-stopped
deploy:
mode: replicated
replicas: ${PLATFORM_DAPI_API_DOCKER_DEPLOY_REPLICAS:-1}
environment:
- TX_FILTER_STREAM_GRPC_PORT=3006
- DASHCORE_RPC_HOST=core
Expand All @@ -144,10 +153,12 @@ services:
- NETWORK=devnet
- TENDERMINT_RPC_HOST=drive_tenderdash
- TENDERMINT_RPC_PORT=26657
command: --only core-streams
command: yarn run core-streams
stop_grace_period: 10s
profiles:
- platform
expose:
- 3006

dapi_envoy:
image: ${PLATFORM_DAPI_ENVOY_DOCKER_IMAGE:?err}
Expand Down
1 change: 1 addition & 0 deletions packages/dashmate/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"@babel/core": "^7.23.3",
"@babel/eslint-parser": "^7.23.3",
"@dashevo/bls": "~1.2.9",
"@dashevo/dapi-client": "workspace:*",
"@dashevo/dashcore-lib": "~0.21.0",
"@dashevo/dashd-rpc": "^18.2.0",
"@dashevo/dashpay-contract": "workspace:*",
Expand Down
24 changes: 23 additions & 1 deletion packages/dashmate/src/config/configJsonSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,29 @@ export default {
type: 'object',
properties: {
docker: {
$ref: '#/definitions/dockerWithBuild',
type: 'object',
properties: {
image: {
type: 'string',
minLength: 1,
},
deploy: {
type: 'object',
properties: {
replicas: {
type: 'integer',
minimum: 0,
},
},
additionalProperties: false,
required: ['replicas'],
},
build: {
$ref: '#/definitions/dockerBuild',
},
},
required: ['image', 'build', 'deploy'],
additionalProperties: false,
},
},
required: ['docker'],
Expand Down
17 changes: 9 additions & 8 deletions packages/dashmate/src/core/waitForMasternodesSync.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,17 @@ export default async function waitForMasternodesSync(rpcClient, progressCallback
do {
try {
await rpcClient.mnsync('next');

({
result: { IsSynced: isSynced },
} = await rpcClient.mnsync('status'));

({
result: { verificationprogress: verificationProgress },
} = await rpcClient.getBlockchainInfo());
} catch (e) {
// Core RPC is not started yet
if (!e.message.includes('Dash JSON-RPC: Request Error: ') && e.code !== -28) {
if (!e.message.includes('Dash JSON-RPC: Request Error: ') && !e.message.includes('Timeout') && e.code !== -28) {
throw e;
}

Expand All @@ -29,13 +37,6 @@ export default async function waitForMasternodesSync(rpcClient, progressCallback
continue;
}

({
result: { IsSynced: isSynced },
} = await rpcClient.mnsync('status'));
({
result: { verificationprogress: verificationProgress },
} = await rpcClient.getBlockchainInfo());

if (!isSynced) {
progressCallback(verificationProgress);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import DAPIClient from '@dashevo/dapi-client';
import { Listr } from 'listr2';
import wait from '../../../util/wait.js';

/**
*
* @param {createTenderdashRpcClient} createTenderdashRpcClient
* @return {waitForNodeToBeReadyTask}
*/
export default function waitForNodeToBeReadyTaskFactory(
createTenderdashRpcClient,
) {
export default function waitForNodeToBeReadyTaskFactory() {
/**
* @typedef waitForNodeToBeReadyTask
* @param {Config} config
Expand All @@ -19,18 +17,28 @@ export default function waitForNodeToBeReadyTaskFactory(
{
title: `Wait for node ${config.getName()} to be ready`,
task: async () => {
const host = config.get('platform.drive.tenderdash.rpc.host');
const port = config.get('platform.drive.tenderdash.rpc.port');
let host = config.get('platform.dapi.envoy.http.host');
const port = config.get('platform.dapi.envoy.http.port');

const tenderdashRpcClient = createTenderdashRpcClient({ host, port });
if (host === '0.0.0.0') {
host = '127.0.0.1';
}

const dapiClient = new DAPIClient({
dapiAddresses: [`${host}:${port}:no-ssl`],
loggerOptions: {
level: 'silent',
},
});

let success = false;
do {
const response = await tenderdashRpcClient.request('status', {}).catch(() => {});
const response = await dapiClient.platform.getEpochsInfo(0, 1, {
retries: 0,
})
.catch(() => {});

if (response) {
success = !response.result.sync_info.catching_up;
}
success = Boolean(response);

if (!success) {
await wait(500);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import fs from 'fs';
import path from 'path';
import HomeDir from '../../../../../src/config/HomeDir.js';
import { PACKAGE_ROOT_DIR } from '../../../../../src/constants.js';
import createDIContainer from '../../../../../src/createDIContainer.js';
import getConfigFileDataV0250 from '../../../../../src/test/fixtures/getConfigFileDataV0250.js';
import HomeDir from '../../../../src/config/HomeDir.js';
import { PACKAGE_ROOT_DIR } from '../../../../src/constants.js';
import createDIContainer from '../../../../src/createDIContainer.js';
import getConfigFileDataV0250 from '../../../../src/test/fixtures/getConfigFileDataV0250.js';

describe('migrateConfigFileFactory', () => {
let mockConfigFileData;
Expand Down
7 changes: 6 additions & 1 deletion packages/js-dapi-client/lib/DAPIClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class DAPIClient extends EventEmitter {
blockHeadersProviderOptions: BlockHeadersProvider.defaultOptions,
loggerOptions: {
identifier: '',
level: undefined,
},
...options,
};
Expand All @@ -57,7 +58,10 @@ class DAPIClient extends EventEmitter {

this.core = new CoreMethodsFacade(jsonRpcTransport, grpcTransport);
this.platform = new PlatformMethodsFacade(grpcTransport);
this.logger = logger.getForId(this.options.loggerOptions.identifier);
this.logger = logger.getForId(
this.options.loggerOptions.identifier,
this.options.loggerOptions.level,
);

this.initBlockHeadersProvider();
}
Expand Down Expand Up @@ -89,6 +93,7 @@ DAPIClient.EVENTS = EVENTS;
* @property {boolean} [throwDeadlineExceeded]
* @property {object} [loggerOptions]
* @property {string} [loggerOptions.identifier]
* @property {string} [loggerOptions.level]
* @property {BlockHeadersProvider} [blockHeadersProvider]
* @property {BlockHeadersProviderOptions} [blockHeadersProviderOptions]
*/
Expand Down
6 changes: 5 additions & 1 deletion packages/js-dapi-client/lib/logger/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const util = require('util');
const winston = require('winston');

const LOG_LEVEL = process.env.LOG_LEVEL || 'info';
// TODO: Refactor to use params instead on envs

const LOG_LEVEL = process.env.LOG_LEVEL || 'silent';
const LOG_TO_FILE = process.env.LOG_WALLET_TO_FILE || 'false';

// Log levels:
Expand Down Expand Up @@ -36,6 +38,7 @@ const createLogger = (formats = [], id = '') => {
const transports = [
new winston.transports.Console({
format,
silent: LOG_LEVEL === 'silent',
}),
];

Expand All @@ -44,6 +47,7 @@ const createLogger = (formats = [], id = '') => {
new winston.transports.File({
filename: `wallet${id !== '' ? `_${id}` : ''}`,
format,
silent: LOG_LEVEL === 'silent',
}),
);
}
Expand Down
Loading

0 comments on commit d320578

Please sign in to comment.