diff --git a/blockchain-configs/afan-shard/node_params.json b/blockchain-configs/afan-shard/node_params.json index bd5d7036f..e6e2cfb0c 100644 --- a/blockchain-configs/afan-shard/node_params.json +++ b/blockchain-configs/afan-shard/node_params.json @@ -33,6 +33,7 @@ "EVENT_HANDLER_CHANNEL_LIFE_TIME_LIMIT_SECS": 3600, "EVENT_HANDLER_FILTER_DELETION_TIMEOUT_MS": 15000, "EVENT_HANDLER_HEARTBEAT_INTERVAL_MS": 15000, + "EVENT_HANDLER_MAX_CUSTOM_CLIENT_ID_LENGTH": 100, "EVENT_HANDLER_PORT": 5100, "EXPRESS_RATE_LIMIT_WINDOW_SECS": 60, "FREE_TX_POOL_SIZE_LIMIT_RATIO": 0.1, diff --git a/blockchain-configs/base/node_params.json b/blockchain-configs/base/node_params.json index ecde6da71..095343862 100644 --- a/blockchain-configs/base/node_params.json +++ b/blockchain-configs/base/node_params.json @@ -33,6 +33,7 @@ "EVENT_HANDLER_CHANNEL_LIFE_TIME_LIMIT_SECS": 3600, "EVENT_HANDLER_FILTER_DELETION_TIMEOUT_MS": 100000, "EVENT_HANDLER_HEARTBEAT_INTERVAL_MS": 15000, + "EVENT_HANDLER_MAX_CUSTOM_CLIENT_ID_LENGTH": 100, "EVENT_HANDLER_PORT": 5100, "EXPRESS_RATE_LIMIT_WINDOW_SECS": 60, "FREE_TX_POOL_SIZE_LIMIT_RATIO": 0.1, diff --git a/blockchain-configs/he-shard/node_params.json b/blockchain-configs/he-shard/node_params.json index 68a07aa5c..050f07072 100644 --- a/blockchain-configs/he-shard/node_params.json +++ b/blockchain-configs/he-shard/node_params.json @@ -33,6 +33,7 @@ "EVENT_HANDLER_CHANNEL_LIFE_TIME_LIMIT_SECS": 3600, "EVENT_HANDLER_FILTER_DELETION_TIMEOUT_MS": 15000, "EVENT_HANDLER_HEARTBEAT_INTERVAL_MS": 15000, + "EVENT_HANDLER_MAX_CUSTOM_CLIENT_ID_LENGTH": 100, "EVENT_HANDLER_PORT": 5100, "EXPRESS_RATE_LIMIT_WINDOW_SECS": 60, "FREE_TX_POOL_SIZE_LIMIT_RATIO": 0.1, diff --git a/blockchain-configs/mainnet-prod/node_params.json b/blockchain-configs/mainnet-prod/node_params.json index a7b7d410c..ee91f27f3 100644 --- a/blockchain-configs/mainnet-prod/node_params.json +++ b/blockchain-configs/mainnet-prod/node_params.json @@ -32,6 +32,7 @@ "EVENT_HANDLER_CHANNEL_LIFE_TIME_LIMIT_SECS": 3600, "EVENT_HANDLER_FILTER_DELETION_TIMEOUT_MS": 100000, "EVENT_HANDLER_HEARTBEAT_INTERVAL_MS": 15000, + "EVENT_HANDLER_MAX_CUSTOM_CLIENT_ID_LENGTH": 100, "EVENT_HANDLER_PORT": 5100, "EXPRESS_RATE_LIMIT_WINDOW_SECS": 60, "FREE_TX_POOL_SIZE_LIMIT_RATIO": 0.1, diff --git a/blockchain-configs/sim-shard/node_params.json b/blockchain-configs/sim-shard/node_params.json index c6b316c98..35c97a9d3 100644 --- a/blockchain-configs/sim-shard/node_params.json +++ b/blockchain-configs/sim-shard/node_params.json @@ -33,6 +33,7 @@ "EVENT_HANDLER_CHANNEL_LIFE_TIME_LIMIT_SECS": 3600, "EVENT_HANDLER_FILTER_DELETION_TIMEOUT_MS": 100000, "EVENT_HANDLER_HEARTBEAT_INTERVAL_MS": 15000, + "EVENT_HANDLER_MAX_CUSTOM_CLIENT_ID_LENGTH": 100, "EVENT_HANDLER_PORT": 5100, "EXPRESS_RATE_LIMIT_WINDOW_SECS": 60, "FREE_TX_POOL_SIZE_LIMIT_RATIO": 0.1, diff --git a/blockchain-configs/testnet-dev/node_params.json b/blockchain-configs/testnet-dev/node_params.json index 8413a0637..2cd2de037 100644 --- a/blockchain-configs/testnet-dev/node_params.json +++ b/blockchain-configs/testnet-dev/node_params.json @@ -33,6 +33,7 @@ "EVENT_HANDLER_CHANNEL_LIFE_TIME_LIMIT_SECS": 3600, "EVENT_HANDLER_FILTER_DELETION_TIMEOUT_MS": 100000, "EVENT_HANDLER_HEARTBEAT_INTERVAL_MS": 15000, + "EVENT_HANDLER_MAX_CUSTOM_CLIENT_ID_LENGTH": 100, "EVENT_HANDLER_PORT": 5100, "EXPRESS_RATE_LIMIT_WINDOW_SECS": 60, "FREE_TX_POOL_SIZE_LIMIT_RATIO": 0.1, diff --git a/blockchain-configs/testnet-exp/node_params.json b/blockchain-configs/testnet-exp/node_params.json index a29a0365d..12f0a6110 100644 --- a/blockchain-configs/testnet-exp/node_params.json +++ b/blockchain-configs/testnet-exp/node_params.json @@ -33,6 +33,7 @@ "EVENT_HANDLER_CHANNEL_LIFE_TIME_LIMIT_SECS": 3600, "EVENT_HANDLER_FILTER_DELETION_TIMEOUT_MS": 100000, "EVENT_HANDLER_HEARTBEAT_INTERVAL_MS": 15000, + "EVENT_HANDLER_MAX_CUSTOM_CLIENT_ID_LENGTH": 100, "EVENT_HANDLER_PORT": 5100, "EXPRESS_RATE_LIMIT_WINDOW_SECS": 60, "FREE_TX_POOL_SIZE_LIMIT_RATIO": 0.1, diff --git a/blockchain-configs/testnet-prod/node_params.json b/blockchain-configs/testnet-prod/node_params.json index 92c2445ed..e7983699b 100644 --- a/blockchain-configs/testnet-prod/node_params.json +++ b/blockchain-configs/testnet-prod/node_params.json @@ -33,6 +33,7 @@ "EVENT_HANDLER_CHANNEL_LIFE_TIME_LIMIT_SECS": 3600, "EVENT_HANDLER_FILTER_DELETION_TIMEOUT_MS": 100000, "EVENT_HANDLER_HEARTBEAT_INTERVAL_MS": 15000, + "EVENT_HANDLER_MAX_CUSTOM_CLIENT_ID_LENGTH": 100, "EVENT_HANDLER_PORT": 5100, "EXPRESS_RATE_LIMIT_WINDOW_SECS": 60, "FREE_TX_POOL_SIZE_LIMIT_RATIO": 0.1, diff --git a/blockchain-configs/testnet-sandbox/node_params.json b/blockchain-configs/testnet-sandbox/node_params.json index a656eb622..04af90f42 100644 --- a/blockchain-configs/testnet-sandbox/node_params.json +++ b/blockchain-configs/testnet-sandbox/node_params.json @@ -33,6 +33,7 @@ "EVENT_HANDLER_CHANNEL_LIFE_TIME_LIMIT_SECS": 3600, "EVENT_HANDLER_FILTER_DELETION_TIMEOUT_MS": 100000, "EVENT_HANDLER_HEARTBEAT_INTERVAL_MS": 15000, + "EVENT_HANDLER_MAX_CUSTOM_CLIENT_ID_LENGTH": 100, "EVENT_HANDLER_PORT": 5100, "EXPRESS_RATE_LIMIT_WINDOW_SECS": 60, "FREE_TX_POOL_SIZE_LIMIT_RATIO": 0.1, diff --git a/blockchain-configs/testnet-staging/node_params.json b/blockchain-configs/testnet-staging/node_params.json index 99d10ddf6..1d5bc123a 100644 --- a/blockchain-configs/testnet-staging/node_params.json +++ b/blockchain-configs/testnet-staging/node_params.json @@ -33,6 +33,7 @@ "EVENT_HANDLER_CHANNEL_LIFE_TIME_LIMIT_SECS": 3600, "EVENT_HANDLER_FILTER_DELETION_TIMEOUT_MS": 100000, "EVENT_HANDLER_HEARTBEAT_INTERVAL_MS": 15000, + "EVENT_HANDLER_MAX_CUSTOM_CLIENT_ID_LENGTH": 100, "EVENT_HANDLER_PORT": 5100, "EXPRESS_RATE_LIMIT_WINDOW_SECS": 60, "FREE_TX_POOL_SIZE_LIMIT_RATIO": 0.1, diff --git a/common/constants.js b/common/constants.js index 1445346d7..03891abb3 100644 --- a/common/constants.js +++ b/common/constants.js @@ -677,6 +677,7 @@ const BlockchainEventTypes = { }; const BlockchainEventMessageTypes = { + SET_CUSTOM_CLIENT_ID: 'SET_CUSTOM_CLIENT_ID', REGISTER_FILTER: 'REGISTER_FILTER', DEREGISTER_FILTER: 'DEREGISTER_FILTER', EMIT_EVENT: 'EMIT_EVENT', diff --git a/common/result-code.js b/common/result-code.js index 5c28ba27c..a7ee44e92 100644 --- a/common/result-code.js +++ b/common/result-code.js @@ -226,6 +226,7 @@ const EventHandlerErrorCode = { EVENT_FILTER_EXCEEDS_SIZE_LIMIT_PER_CHANNEL: 70016, FAILED_TO_REGISTER_FILTER: 70020, FAILED_TO_DEREGISTER_FILTER: 70030, + INVALID_CUSTOM_CLIENT_ID: 70040, // BLOCK_FINALIZED (701XX) NEGATIVE_BLOCK_NUMBER: 70100, INVALID_BLOCK_NUMBER_TYPE: 70101, diff --git a/event-handler/event-channel-manager.js b/event-handler/event-channel-manager.js index 3d6891595..cd5487f13 100644 --- a/event-handler/event-channel-manager.js +++ b/event-handler/event-channel-manager.js @@ -8,6 +8,7 @@ const { BlockchainEventTypes, FilterDeletionReasons, } = require('../common/constants'); +const CommonUtil = require('../common/common-util'); const EventHandlerError = require('./event-handler-error'); const { EventHandlerErrorCode } = require('../common/result-code'); const BlockchainEvent = require('./blockchain-event'); @@ -40,6 +41,7 @@ class EventChannelManager { return { maxNumEventChannels: NodeConfigs.MAX_NUM_EVENT_CHANNELS, numEventChannels: this.getNumEventChannels(), + channelLifeTimeLimitSecs: NodeConfigs.EVENT_HANDLER_CHANNEL_LIFE_TIME_LIMIT_SECS, channelIdleTimeLimitSecs: NodeConfigs.EVENT_HANDLER_CHANNEL_IDLE_TIME_LIMIT_SECS, maxChannelLifeTimeMs: channelStats.maxLifeTimeMs, maxChannelIdleTimeMs: channelStats.maxIdleTimeMs, @@ -157,6 +159,18 @@ class EventChannelManager { } } + handleSetCustomClientId(channel, messageData) { + const LOG_HEADER = 'handleSetCustomClientId'; + const customClientId = messageData.customClientId; + if (!CommonUtil.isString(customClientId)) { + throw new EventHandlerError(EventHandlerErrorCode.INVALID_CUSTOM_CLIENT_ID, + `Invalid custom client id: ${customClientId}`); + } + const normalized = customClientId.slice(0, NodeConfigs.EVENT_HANDLER_MAX_CUSTOM_CLIENT_ID_LENGTH); + logger.info(`[${LOG_HEADER}] Setting custom client id: ${normalized} for channel: ${channel.id}`); + channel.setCustomClientId(normalized); + } + handleRegisterFilterMessage(channel, messageData) { const LOG_HEADER = 'handleRegisterFilterMessage'; const clientFilterId = messageData.id; @@ -292,6 +306,9 @@ class EventChannelManager { // TODO(cshcomcom): Manage EVENT_PROTOCOL_VERSION. handleMessage(channel, messageType, messageData) { switch (messageType) { + case BlockchainEventMessageTypes.SET_CUSTOM_CLIENT_ID: + this.handleSetCustomClientId(channel, messageData); + break; case BlockchainEventMessageTypes.REGISTER_FILTER: this.handleRegisterFilterMessage(channel, messageData); break; @@ -300,7 +317,7 @@ class EventChannelManager { break; default: throw new EventHandlerError(EventHandlerErrorCode.INVALID_MESSAGE_TYPE, - `Invalid message type (${messageType})`); + `Invalid message type: ${messageType}`); } } diff --git a/event-handler/event-channel.js b/event-handler/event-channel.js index 797e360ab..58da0c29b 100644 --- a/event-handler/event-channel.js +++ b/event-handler/event-channel.js @@ -5,12 +5,17 @@ class EventChannel { this.id = id; this.webSocket = webSocket; this.remoteUrl = buildRemoteUrlFromSocket(webSocket); + this.customClientId = ''; this.eventFilterIds = new Set(); const curTimeMs = Date.now(); this.creationTimeMs = curTimeMs; this.lastMessagingTimeMs = curTimeMs; } + setCustomClientId(customClientId) { + this.customClientId = customClientId; + } + setLastMessagingTimeMs(timeMs) { this.lastMessagingTimeMs = timeMs; } @@ -43,7 +48,9 @@ class EventChannel { return { id: this.id, remoteUrl: this.remoteUrl, + customClientId: this.customClientId, eventFilterIds: [...this.eventFilterIds], + creationTimeMs: this.creationTimeMs, lastMessagingTimeMs: this.lastMessagingTimeMs, lifeTimeMs: this.getLifeTimeMs(), idleTimeMs: this.getIdleTimeMs(), diff --git a/event-handler/index.js b/event-handler/index.js index 61bf76d03..d4f166a76 100644 --- a/event-handler/index.js +++ b/event-handler/index.js @@ -48,6 +48,7 @@ class EventHandler { channelStatus: { maxNumEventChannels: NodeConfigs.MAX_NUM_EVENT_CHANNELS, numEventChannels: 0, + channelLifeTimeLimitSecs: NodeConfigs.EVENT_HANDLER_CHANNEL_LIFE_TIME_LIMIT_SECS, channelIdleTimeLimitSecs: NodeConfigs.EVENT_HANDLER_CHANNEL_IDLE_TIME_LIMIT_SECS, maxChannelLifeTimeMs: 0, maxChannelIdleTimeMs: 0, diff --git a/test/unit/p2p.test.js b/test/unit/p2p.test.js index a304fa729..bef1b3b83 100644 --- a/test/unit/p2p.test.js +++ b/test/unit/p2p.test.js @@ -235,6 +235,7 @@ describe("P2p", () => { channelStatus: { maxNumEventChannels: 20, numEventChannels: 0, + channelLifeTimeLimitSecs: 3600, channelIdleTimeLimitSecs: 600, maxChannelIdleTimeMs: 0, maxChannelLifeTimeMs: 0,