Skip to content

Commit 26bd79a

Browse files
authored
Merge pull request #1262 from ainblockchain/release/v1.2.0
Release/v1.2.0
2 parents 3b0ba96 + 34ce7a5 commit 26bd79a

File tree

6 files changed

+79
-43
lines changed

6 files changed

+79
-43
lines changed

client/protocol_versions.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,5 +137,8 @@
137137
},
138138
"1.1.4": {
139139
"min": "1.0.0"
140+
},
141+
"1.2.0": {
142+
"min": "1.0.0"
140143
}
141144
}

common/constants.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,9 @@ const BlockchainEventMessageTypes = {
681681
DEREGISTER_FILTER: 'DEREGISTER_FILTER',
682682
EMIT_EVENT: 'EMIT_EVENT',
683683
EMIT_ERROR: 'EMIT_ERROR',
684+
// NOTE(platfowner): Message types for custom ping-pong (see https://github.com/ainblockchain/ain-js/issues/171).
685+
PING: 'PING',
686+
PONG: 'PONG',
684687
};
685688

686689
const ValueChangedEventSources = {

event-handler/event-channel-manager.js

Lines changed: 55 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -82,17 +82,39 @@ class EventChannelManager {
8282
// TODO(cshcomcom): Handle MAX connections.
8383

8484
logger.info(`[${LOG_HEADER}] New connection (${channelId})`);
85+
8586
webSocket.on('message', (message) => {
86-
this.handleMessage(channel, message);
87+
try {
88+
const parsedMessage = JSON.parse(message);
89+
const messageType = parsedMessage.type;
90+
if (!messageType) {
91+
throw new EventHandlerError(EventHandlerErrorCode.MISSING_MESSAGE_TYPE_IN_MSG,
92+
`No message type in (${JSON.stringify(message)})`);
93+
}
94+
const messageData = parsedMessage.data;
95+
if (!messageData) {
96+
throw new EventHandlerError(EventHandlerErrorCode.MISSING_MESSAGE_DATA_IN_MSG,
97+
`No message data in (${JSON.stringify(message)})`);
98+
}
99+
// NOTE(platfowner): A custom ping-pong (see https://github.com/ainblockchain/ain-js/issues/171).
100+
if (messageType === BlockchainEventMessageTypes.PONG) {
101+
this.handlePong(webSocket);
102+
} else {
103+
this.handleMessage(channel, messageType, messageData);
104+
}
105+
} catch (err) {
106+
logger.error(`[${LOG_HEADER}] Error while process message ` +
107+
`(message: ${JSON.stringify(message, null, 2)}, ` +
108+
`error message: ${err.message})`);
109+
this.handleEventError(channel, err);
110+
}
87111
});
112+
88113
webSocket.on('close', (_) => {
89114
this.closeChannel(channel);
90115
});
91116

92-
// Heartbeat
93-
webSocket.on('pong', (_) => {
94-
webSocket.isAlive = true;
95-
})
117+
96118
webSocket.isAlive = true;
97119
} catch (err) {
98120
webSocket.terminate();
@@ -222,36 +244,28 @@ class EventChannelManager {
222244
}
223245
}
224246

225-
handleMessage(channel, message) { // TODO(cshcomcom): Manage EVENT_PROTOCOL_VERSION.
226-
const LOG_HEADER = 'handleMessage';
227-
try {
228-
const parsedMessage = JSON.parse(message);
229-
const messageType = parsedMessage.type;
230-
if (!messageType) {
231-
throw new EventHandlerError(EventHandlerErrorCode.MISSING_MESSAGE_TYPE_IN_MSG,
232-
`Can't find type from message (${JSON.stringify(message)})`);
233-
}
234-
const messageData = parsedMessage.data;
235-
if (!messageData) {
236-
throw new EventHandlerError(EventHandlerErrorCode.MISSING_MESSAGE_DATA_IN_MSG,
237-
`Can't find data from message (${JSON.stringify(message)})`);
238-
}
239-
switch (messageType) {
240-
case BlockchainEventMessageTypes.REGISTER_FILTER:
241-
this.handleRegisterFilterMessage(channel, messageData);
242-
break;
243-
case BlockchainEventMessageTypes.DEREGISTER_FILTER:
244-
this.handleDeregisterFilterMessage(channel, messageData);
245-
break;
246-
default:
247-
throw new EventHandlerError(EventHandlerErrorCode.INVALID_MESSAGE_TYPE,
248-
`Invalid message type (${messageType})`);
249-
}
250-
} catch (err) {
251-
logger.error(`[${LOG_HEADER}] Error while process message ` +
252-
`(message: ${JSON.stringify(message, null, 2)}, ` +
253-
`error message: ${err.message})`);
254-
this.handleEventError(channel, err);
247+
/**
248+
* Handles a pong message.
249+
*/
250+
handlePong(webSocket) {
251+
webSocket.isAlive = true;
252+
}
253+
254+
/**
255+
* Handles a (non-pong) message from the channel.
256+
*/
257+
// TODO(cshcomcom): Manage EVENT_PROTOCOL_VERSION.
258+
handleMessage(channel, messageType, messageData) {
259+
switch (messageType) {
260+
case BlockchainEventMessageTypes.REGISTER_FILTER:
261+
this.handleRegisterFilterMessage(channel, messageData);
262+
break;
263+
case BlockchainEventMessageTypes.DEREGISTER_FILTER:
264+
this.handleDeregisterFilterMessage(channel, messageData);
265+
break;
266+
default:
267+
throw new EventHandlerError(EventHandlerErrorCode.INVALID_MESSAGE_TYPE,
268+
`Invalid message type (${messageType})`);
255269
}
256270
}
257271

@@ -325,11 +339,16 @@ class EventChannelManager {
325339
return ws.terminate();
326340
}
327341
ws.isAlive = false;
328-
ws.ping();
342+
this.sendPing(ws);
329343
});
330344
}, NodeConfigs.EVENT_HANDLER_HEARTBEAT_INTERVAL_MS || 15000);
331345
}
332346

347+
sendPing(webSocket) {
348+
const pingMessage = this.makeMessage(BlockchainEventMessageTypes.PING, {});
349+
webSocket.send(JSON.stringify(pingMessage));
350+
}
351+
333352
stopHeartbeat() {
334353
clearInterval(this.heartbeatInterval);
335354
}

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "ain-blockchain",
33
"description": "AI Network Blockchain",
4-
"version": "1.1.4",
4+
"version": "1.2.0",
55
"private": true,
66
"license": "MIT",
77
"author": "[email protected]",
@@ -99,7 +99,7 @@
9999
"web3-eth-accounts": "^1.6.1",
100100
"winston": "^3.3.3",
101101
"winston-daily-rotate-file": "^4.4.2",
102-
"ws": "^7.4.6"
102+
"ws": "^8.16.0"
103103
},
104104
"devDependencies": {
105105
"chai": "^4.2.0",

test/integration/event_handler.test.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,15 +217,19 @@ describe('Event Handler Test', function() {
217217

218218
it('Wait BLOCK_FINALIZED events', function(done) {
219219
this.timeout(3 * epochMs);
220-
wsClient.once('message', (message) => {
220+
function messageHandler(message) {
221221
const parsedMessage = JSON.parse(message);
222222
const messageType = parsedMessage.type;
223223
const eventType = _.get(parsedMessage, 'data.type');
224224
if (messageType === BlockchainEventMessageTypes.EMIT_EVENT &&
225225
eventType === BlockchainEventTypes.BLOCK_FINALIZED) {
226226
done();
227+
// NOTE(platfowner): Avoid test failure with "done() called multiple times".
228+
wsClient.removeListener('message', messageHandler);
227229
}
228-
});
230+
}
231+
// NOTE(platfowner): Use 'on' instead of 'once' due to heartbeats with custom ping-pong.
232+
wsClient.on('message', messageHandler);
229233
});
230234

231235
it('Deregister filter & check number of filters === 0', function(done) {
@@ -324,7 +328,8 @@ describe('Event Handler Test', function() {
324328
block_number: null,
325329
};
326330
registerFilter(wsClient, filterId, BlockchainEventTypes.BLOCK_FINALIZED, config);
327-
wsClient.once('message', (message) => {
331+
// NOTE(platfowner): Use 'on' instead of 'once' due to heartbeats with custom ping-pong.
332+
wsClient.on('message', (message) => {
328333
const parsedMessage = JSON.parse(message);
329334
const messageType = parsedMessage.type;
330335
const eventType = _.get(parsedMessage, 'data.type');
@@ -343,7 +348,8 @@ describe('Event Handler Test', function() {
343348
path: targetPath,
344349
};
345350
registerFilter(wsClient, filterId, BlockchainEventTypes.VALUE_CHANGED, config);
346-
wsClient.once('message', (message) => {
351+
// NOTE(platfowner): Use 'on' instead of 'once' due to heartbeats with custom ping-pong.
352+
wsClient.on('message', (message) => {
347353
const parsedMessage = JSON.parse(message);
348354
const messageType = parsedMessage.type;
349355
const eventType = _.get(parsedMessage, 'data.type');

yarn.lock

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6596,11 +6596,16 @@ [email protected]:
65966596
dependencies:
65976597
mkdirp "^0.5.1"
65986598

6599-
ws@^7.4.5, ws@^7.4.6:
6599+
ws@^7.4.5:
66006600
version "7.5.7"
66016601
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67"
66026602
integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==
66036603

6604+
ws@^8.16.0:
6605+
version "8.16.0"
6606+
resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4"
6607+
integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==
6608+
66046609
xdg-basedir@^4.0.0:
66056610
version "4.0.0"
66066611
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"

0 commit comments

Comments
 (0)