Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(dashmate): dapi kills host machine on container stop #1670

Merged
merged 9 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading