Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1986 from LiskHQ/1985-limit-max-web-socket-connec…
Browse files Browse the repository at this point in the history
…tion-initialisation

Limit max web socket connection initialisation
  • Loading branch information
sameersubudhi authored Dec 12, 2023
2 parents f209f34 + 4e17140 commit 26e8fe8
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 10 deletions.
3 changes: 3 additions & 0 deletions docker/redis.persistent.conf
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ save ""
# Memory management
maxmemory 2gb
maxmemory-policy volatile-lru

# Replication
slave-read-only no
3 changes: 3 additions & 0 deletions docker/redis.volatile.conf
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ save ""
# Memory management
maxmemory 512mb
maxmemory-policy allkeys-lru

# Replication
slave-read-only no
3 changes: 2 additions & 1 deletion services/blockchain-connector/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ config.job = {
config.apiClient = {
heartbeatAckMaxWaitTime: Number(process.env.HEARTBEAT_ACK_MAX_WAIT_TIME) || 1000, // in millisecs
aliveAssumptionTime: Number(process.env.CLIENT_ALIVE_ASSUMPTION_TIME) || 5 * 1000, // in millisecs
aliveAssumptionTimeBeforeGenesis: Number(30 * 1000),
aliveAssumptionTimeBeforeGenesis: 30 * 1000,
wsConnectionLimit: 10,
instantiation: {
maxWaitTime: Number(process.env.CLIENT_INSTANTIATION_MAX_WAIT_TIME) || 5 * 1000, // in millisecs
retryInterval: Number(process.env.CLIENT_INSTANTIATION_RETRY_INTERVAL) || 1, // in millisecs
Expand Down
22 changes: 21 additions & 1 deletion services/blockchain-connector/shared/sdk/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const CLIENT_ALIVE_ASSUMPTION_TIME = config.apiClient.aliveAssumptionTime;
const CLIENT_ALIVE_ASSUMPTION_TIME_BEFORE_GENESIS =
config.apiClient.aliveAssumptionTimeBeforeGenesis;
const HEARTBEAT_ACK_MAX_WAIT_TIME = config.apiClient.heartbeatAckMaxWaitTime;
const WS_CONNECTION_LIMIT = config.apiClient.wsConnectionLimit;

// Caching and flags
let clientCache;
Expand All @@ -45,6 +46,7 @@ let heartbeatCheckBeginTime;
let isInstantiating = false;
let isClientAlive = false;
let isGenesisBlockIndexed = false;
let wsConnectionsEstablished = 0;

const pongListener = res => {
isClientAlive = true;
Expand Down Expand Up @@ -89,9 +91,27 @@ const checkIsClientAlive = async () =>
const instantiateClient = async (isForceReInstantiate = false) => {
try {
if (!isInstantiating || isForceReInstantiate) {
const isNodeClientAlive = await checkIsClientAlive();

if (!config.isUseLiskIPCClient) {
if (isNodeClientAlive) {
wsConnectionsEstablished = 0;
} else {
let numRetries = NUM_REQUEST_RETRIES;
while (wsConnectionsEstablished >= WS_CONNECTION_LIMIT && numRetries--) {
await delay(MAX_INSTANTIATION_WAIT_TIME);
if (await checkIsClientAlive()) {
wsConnectionsEstablished = 0;
return clientCache;
}
}
}
}

isInstantiating = true;
if (!isNodeClientAlive || isForceReInstantiate) {
if (!config.isUseLiskIPCClient) wsConnectionsEstablished++;

if (!(await checkIsClientAlive()) || isForceReInstantiate) {
instantiationBeginTime = Date.now();

if (clientCache) {
Expand Down
11 changes: 6 additions & 5 deletions services/blockchain-connector/shared/sdk/formatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,12 @@ const formatTransaction = (transaction, additionalFee = 0) => {
const txParamsSchema = getTransactionParamsSchema(transaction);

// Encode transaction params to calculate transaction size
if (typeof transaction.params === 'object' && !Buffer.isBuffer(transaction.params)) {
transaction.params = codec.encode(
txParamsSchema,
parseInputBySchema(transaction.params, txParamsSchema),
);
if (typeof transaction.params === 'object') {
transaction.params = Buffer.isBuffer(transaction.params)
? transaction.params.toString('hex')
: codec
.encode(txParamsSchema, parseInputBySchema(transaction.params, txParamsSchema))
.toString('hex');
}
const schemaCompliantTransaction = parseInputBySchema(transaction, txSchema);

Expand Down
21 changes: 19 additions & 2 deletions services/blockchain-connector/shared/sdk/transactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* Removal or modification of this copyright notice is prohibited.
*
*/
const { Logger } = require('lisk-service-framework');
const { encodeTransaction } = require('./encoder');
const { formatTransaction, formatEvent } = require('./formatter');
const {
Expand All @@ -23,6 +24,8 @@ const {
dryRunTransaction,
} = require('./endpoints');

const logger = Logger();

const getTransactionByIDFormatted = async id => {
const transaction = await getTransactionByID(id);
const formattedTransaction = formatTransaction(transaction);
Expand All @@ -37,8 +40,22 @@ const getTransactionsByIDsFormatted = async ids => {

const getTransactionsFromPoolFormatted = async () => {
const transactions = await getTransactionsFromPool();
const formattedTransactions = transactions.map(t => formatTransaction(t));
return formattedTransactions;
const formattedTransactions = transactions.map(t => {
try {
return formatTransaction(t);
} catch (error) {
logger.warn(
`Formatting transaction failed due to: ${error.message}\nTransaction: ${JSON.stringify(
t,
null,
'\t',
)}`,
);
return null;
}
});

return formattedTransactions.filter(t => t);
};

const dryRunTransactionWrapper = async params => {
Expand Down
4 changes: 3 additions & 1 deletion tests/schemas/api_v3/transaction.schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ const pendingTransactionSchema = {
size: Joi.number().integer().positive().required(),
sender: Joi.object(sender).required(),
params: Joi.object().required(),
signatures: Joi.array().items(Joi.string().required()).required(),
signatures: Joi.array()
.items(Joi.string().pattern(regex.HASH_SHA512).allow('').required())
.required(),
executionStatus: Joi.string().valid('pending').required(),
meta: Joi.object(transactionMetaSchema).optional(),
};
Expand Down

0 comments on commit 26e8fe8

Please sign in to comment.