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

Commit

Permalink
Merge branch 'hotfix/2.3.6' of https://github.com/LiskHQ/lisk-sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
shuse2 committed Sep 19, 2019
2 parents a758afd + 69ed929 commit 31c8f37
Show file tree
Hide file tree
Showing 12 changed files with 151 additions and 18 deletions.
2 changes: 1 addition & 1 deletion elements/lisk-p2p/package-lock.json

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

2 changes: 1 addition & 1 deletion elements/lisk-p2p/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@liskhq/lisk-p2p",
"version": "0.3.4",
"version": "0.3.5",
"description": "Unstructured P2P library for use with Lisk-related software",
"author": "Lisk Foundation <[email protected]>, lightcurve GmbH <[email protected]>",
"license": "Apache-2.0",
Expand Down
11 changes: 10 additions & 1 deletion elements/lisk-p2p/src/p2p.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ import {
EVENT_FAILED_TO_FETCH_PEER_INFO,
EVENT_FAILED_TO_FETCH_PEERS,
EVENT_FAILED_TO_PUSH_NODE_INFO,
EVENT_FAILED_TO_SEND_MESSAGE,
EVENT_INBOUND_SOCKET_ERROR,
EVENT_MESSAGE_RECEIVED,
EVENT_OUTBOUND_SOCKET_ERROR,
Expand All @@ -102,6 +103,7 @@ export {
EVENT_CONNECT_OUTBOUND,
EVENT_DISCOVERED_PEER,
EVENT_FAILED_TO_PUSH_NODE_INFO,
EVENT_FAILED_TO_SEND_MESSAGE,
EVENT_REMOVE_PEER,
EVENT_REQUEST_RECEIVED,
EVENT_MESSAGE_RECEIVED,
Expand All @@ -124,7 +126,7 @@ export const DEFAULT_NODE_HOST_IP = '0.0.0.0';
export const DEFAULT_DISCOVERY_INTERVAL = 30000;
export const DEFAULT_BAN_TIME = 86400;
export const DEFAULT_POPULATOR_INTERVAL = 10000;
export const DEFAULT_SEND_PEER_LIMIT = 25;
export const DEFAULT_SEND_PEER_LIMIT = 24;
// Max rate of WebSocket messages per second per peer.
export const DEFAULT_WS_MAX_MESSAGE_RATE = 100;
export const DEFAULT_WS_MAX_MESSAGE_RATE_PENALTY = 100;
Expand Down Expand Up @@ -173,6 +175,7 @@ export class P2P extends EventEmitter {
discoveredPeerInfo: P2PDiscoveredPeerInfo,
) => void;
private readonly _handleFailedToPushNodeInfo: (error: Error) => void;
private readonly _handleFailedToSendMessage: (error: Error) => void;
private readonly _handleOutboundPeerConnect: (
peerInfo: P2PDiscoveredPeerInfo,
) => void;
Expand Down Expand Up @@ -400,6 +403,11 @@ export class P2P extends EventEmitter {
this.emit(EVENT_FAILED_TO_PUSH_NODE_INFO, error);
};

this._handleFailedToSendMessage = (error: Error) => {
// Re-emit the error to allow it to bubble up the class hierarchy.
this.emit(EVENT_FAILED_TO_SEND_MESSAGE, error);
};

this._handleOutboundSocketError = (error: Error) => {
// Re-emit the error to allow it to bubble up the class hierarchy.
this.emit(EVENT_OUTBOUND_SOCKET_ERROR, error);
Expand Down Expand Up @@ -951,6 +959,7 @@ export class P2P extends EventEmitter {
EVENT_FAILED_TO_PUSH_NODE_INFO,
this._handleFailedToPushNodeInfo,
);
peerPool.on(EVENT_FAILED_TO_SEND_MESSAGE, this._handleFailedToSendMessage);
peerPool.on(EVENT_OUTBOUND_SOCKET_ERROR, this._handleOutboundSocketError);
peerPool.on(EVENT_INBOUND_SOCKET_ERROR, this._handleInboundSocketError);
peerPool.on(EVENT_BAN_PEER, this._handleBanPeer);
Expand Down
29 changes: 24 additions & 5 deletions elements/lisk-p2p/src/peer_pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ export const MAX_PEER_DISCOVERY_PROBE_SAMPLE_SIZE = 100;
export const EVENT_REMOVE_PEER = 'removePeer';
export const INTENTIONAL_DISCONNECT_STATUS_CODE = 1000;

// TODO: Move to events.ts.
export const EVENT_FAILED_TO_SEND_MESSAGE = 'failedToSendMessage';

// TODO: Move these to constants.ts
export const PEER_KIND_OUTBOUND = 'outbound';
export const PEER_KIND_INBOUND = 'inbound';

export enum PROTECTION_CATEGORY {
NET_GROUP = 'netgroup',
LATENCY = 'latency',
Expand Down Expand Up @@ -333,9 +340,15 @@ export class PeerPool extends EventEmitter {
}

public async request(packet: P2PRequestPacket): Promise<P2PResponsePacket> {
const outboundPeerInfos = this.getUniqueOutboundConnectedPeers().map(
(peerInfo: P2PDiscoveredPeerInfo) => ({
...peerInfo,
kind: PEER_KIND_OUTBOUND,
}),
);
// This function can be customized so we should pass as much info as possible.
const selectedPeers = this._peerSelectForRequest({
peers: this.getUniqueOutboundConnectedPeers(),
peers: outboundPeerInfos,
nodeInfo: this._nodeInfo,
peerLimit: 1,
requestPacket: packet,
Expand All @@ -353,9 +366,11 @@ export class PeerPool extends EventEmitter {
}

public send(message: P2PMessagePacket): void {
const listOfPeerInfo = [...this._peerMap.values()].map(
(peer: Peer) => peer.peerInfo as P2PDiscoveredPeerInfo,
);
const listOfPeerInfo = [...this._peerMap.values()].map((peer: Peer) => ({
...(peer.peerInfo as P2PDiscoveredPeerInfo),
kind:
peer instanceof OutboundPeer ? PEER_KIND_OUTBOUND : PEER_KIND_INBOUND,
}));
// This function can be customized so we should pass as much info as possible.
const selectedPeers = this._peerSelectForSend({
peers: listOfPeerInfo,
Expand All @@ -366,7 +381,11 @@ export class PeerPool extends EventEmitter {

selectedPeers.forEach((peerInfo: P2PDiscoveredPeerInfo) => {
const selectedPeerId = constructPeerIdFromPeerInfo(peerInfo);
this.sendToPeer(message, selectedPeerId);
try {
this.sendToPeer(message, selectedPeerId);
} catch (error) {
this.emit(EVENT_FAILED_TO_SEND_MESSAGE, error);
}
});
}

Expand Down
37 changes: 35 additions & 2 deletions elements/lisk-p2p/src/peer_selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,41 @@ export const selectPeersForRequest = (

export const selectPeersForSend = (
input: P2PPeerSelectionForSendInput,
): ReadonlyArray<P2PDiscoveredPeerInfo> =>
shuffle(input.peers).slice(0, input.peerLimit);
): ReadonlyArray<P2PDiscoveredPeerInfo> => {
const shuffledPeers = shuffle(input.peers);
const peerLimit = input.peerLimit as number;
// tslint:disable: no-magic-numbers
const halfPeerLimit = Math.round(peerLimit / 2);

// TODO: Get outbound string from constants.ts file.
const outboundPeers = shuffledPeers.filter(
(peerInfo: P2PDiscoveredPeerInfo) => peerInfo.kind === 'outbound',
);

// TODO: Get inbound string from constants.ts file.
const inboundPeers = shuffledPeers.filter(
(peerInfo: P2PDiscoveredPeerInfo) => peerInfo.kind === 'inbound',
);

// tslint:disable: no-let
let shortestPeersList;
// tslint:disable: no-let
let longestPeersList;

if (outboundPeers.length < inboundPeers.length) {
shortestPeersList = outboundPeers;
longestPeersList = inboundPeers;
} else {
shortestPeersList = inboundPeers;
longestPeersList = outboundPeers;
}

const selectedFirstKindPeers = shortestPeersList.slice(0, halfPeerLimit);
const remainingPeerLimit = peerLimit - selectedFirstKindPeers.length;
const selectedSecondKindPeers = longestPeersList.slice(0, remainingPeerLimit);

return selectedFirstKindPeers.concat(selectedSecondKindPeers);
};

export const selectPeersForConnection = (
input: P2PPeerSelectionForConnectionInput,
Expand Down
7 changes: 7 additions & 0 deletions elements/lisk-p2p/test/integration/p2p.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1228,6 +1228,13 @@ describe('Integration tests for P2P library', () => {
) => {
const { peers: peersList, nodeInfo } = input;

peersList.forEach(peerInfo => {
// TODO: Use inbound and outbound strings from constants.ts
if (peerInfo.kind !== 'inbound' && peerInfo.kind !== 'outbound') {
throw new Error(`Invalid peer kind: ${peerInfo.kind}`);
}
});

const filteredPeers = peersList.filter(peer => {
if (nodeInfo && nodeInfo.height <= peer.height) {
const nodesModules = nodeInfo.modules
Expand Down
49 changes: 47 additions & 2 deletions elements/lisk-p2p/test/unit/peer_selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,60 @@
*/

import { expect } from 'chai';
import { initializePeerInfoList } from '../utils/peers';
import {
initializePeerInfoList,
initializeLongPeerInfoList,
} from '../utils/peers';
import {
selectPeersForConnection,
selectPeersForRequest,
selectPeersForSend,
getUniquePeersbyIp,
} from '../../src/peer_selection';
import { P2PNodeInfo, P2PDiscoveredPeerInfo } from '../../src/p2p_types';
import {
P2PNodeInfo,
P2PDiscoveredPeerInfo,
P2PPeerInfo,
} from '../../src/p2p_types';

describe('peer selector', () => {
describe('#selectPeersForSend', () => {
let peerList = initializeLongPeerInfoList();

const nodeInfo: P2PNodeInfo = {
height: 545777,
nethash: '73458irc3yb7rg37r7326dbt7236',
os: 'linux',
version: '1.1.1',
protocolVersion: '1.1',
wsPort: 5000,
};

it('should return an array containing an even number of inbound and outbound peers', () => {
const selectedPeers = selectPeersForSend({
peers: peerList,
nodeInfo,
peerLimit: 24,
messagePacket: { event: 'foo', data: {} },
});

let peerKindCounts = selectedPeers.reduce(
(peerKindTracker: any, peerInfo: P2PPeerInfo) => {
const kind = peerInfo.kind as string;
if (!peerKindTracker[kind]) {
peerKindTracker[kind] = 0;
}
peerKindTracker[kind]++;
return peerKindTracker;
},
{},
);

expect(peerKindCounts.inbound)
.to.equal(peerKindCounts.outbound)
.to.equal(12);
});
});
describe('#selectPeersForRequest', () => {
let peerList = initializePeerInfoList();
const nodeInfo: P2PNodeInfo = {
Expand Down
20 changes: 20 additions & 0 deletions elements/lisk-p2p/test/utils/peers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,26 @@ export const initializePeerInfoList = (): ReadonlyArray<
return [peerOption1, peerOption2, peerOption3, peerOption4, peerOption5];
};

export const initializeLongPeerInfoList = (): ReadonlyArray<
P2PDiscoveredPeerInfo
> => {
let peerInfos = [];
// Generate a realistic list in which 1 in 4 peers is outbound.
for (let i = 0; i < 120; i++) {
// TODO: Get inbound and outbound strings from constants.ts.
peerInfos.push({
ipAddress: `204.120.0.${i}`,
wsPort: 5001,
height: 645980,
kind: i % 4 === 0 ? 'outbound' : 'inbound',
isDiscoveredPeer: false,
version: '1.1.1',
protocolVersion: '1.1',
});
}
return peerInfos;
};

export const initializePeerList = (): ReadonlyArray<Peer> =>
initializePeerInfoList().map(
(peerInfo: P2PDiscoveredPeerInfo) =>
Expand Down
2 changes: 1 addition & 1 deletion framework/package-lock.json

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

4 changes: 2 additions & 2 deletions framework/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lisk-framework",
"version": "0.4.5",
"version": "0.4.6",
"description": "Lisk blockchain application platform",
"author": "Lisk Foundation <[email protected]>, lightcurve GmbH <[email protected]>",
"license": "Apache-2.0",
Expand Down Expand Up @@ -50,7 +50,7 @@
"dependencies": {
"@liskhq/bignum": "1.3.1",
"@liskhq/lisk-cryptography": "2.3.0",
"@liskhq/lisk-p2p": "0.3.4",
"@liskhq/lisk-p2p": "0.3.5",
"@liskhq/lisk-transaction-pool": "0.1.2",
"@liskhq/lisk-transactions": "2.3.1",
"@liskhq/lisk-validator": "0.2.1",
Expand Down
2 changes: 1 addition & 1 deletion sdk/package-lock.json

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

4 changes: 2 additions & 2 deletions sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lisk-sdk",
"version": "2.3.5",
"version": "2.3.6",
"description": "Official SDK for the Lisk blockchain application platform",
"author": "Lisk Foundation <[email protected]>, lightcurve GmbH <[email protected]>",
"license": "Apache-2.0",
Expand All @@ -25,6 +25,6 @@
"@liskhq/bignum": "1.3.1",
"@liskhq/lisk-cryptography": "2.3.0",
"@liskhq/lisk-transactions": "2.3.1",
"lisk-framework": "0.4.5"
"lisk-framework": "0.4.6"
}
}

0 comments on commit 31c8f37

Please sign in to comment.