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.3' of https://github.com/LiskHQ/lisk-sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
shuse2 committed Sep 9, 2019
2 parents 7f943c9 + 81b88ef commit d1c1816
Show file tree
Hide file tree
Showing 23 changed files with 197 additions and 136 deletions.
2 changes: 1 addition & 1 deletion elements/lisk-elements/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-elements/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lisk-elements",
"version": "2.4.1",
"version": "2.4.2",
"description": "Elements for building blockchain applications in the Lisk network",
"author": "Lisk Foundation <admin@lisk.io>, lightcurve GmbH <admin@lightcurve.io>",
"license": "Apache-2.0",
Expand Down
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.2",
"version": "0.3.3",
"description": "Unstructured P2P library for use with Lisk-related software",
"author": "Lisk Foundation <admin@lisk.io>, lightcurve GmbH <admin@lightcurve.io>",
"license": "Apache-2.0",
Expand Down
7 changes: 6 additions & 1 deletion elements/lisk-p2p/src/p2p.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export const DEFAULT_POPULATOR_INTERVAL = 10000;
export const DEFAULT_SEND_PEER_LIMIT = 25;
// 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 = 10;
export const DEFAULT_WS_MAX_MESSAGE_RATE_PENALTY = 100;
export const DEFAULT_RATE_CALCULATION_INTERVAL = 1000;
export const DEFAULT_WS_MAX_PAYLOAD = 3048576; // Size in bytes

Expand Down Expand Up @@ -477,6 +477,7 @@ export class P2P extends EventEmitter {
? config.rateCalculationInterval
: DEFAULT_RATE_CALCULATION_INTERVAL,
secret: config.secret ? config.secret : DEFAULT_RANDOM_SECRET,
peerLists: this._sanitizedPeerLists,
});

this._bindHandlersToPeerPool(this._peerPool);
Expand Down Expand Up @@ -897,6 +898,10 @@ export class P2P extends EventEmitter {
}
});

// According to LIP, add whitelist peers to triedPeer by upgrading them initially.
this._sanitizedPeerLists.whitelisted.forEach(whitelistPeer =>
this._peerBook.upgradePeer(whitelistPeer),
);
await this._startPeerServer();

// We need this check this._isActive in case the P2P library is shut down while it was in the middle of starting up.
Expand Down
1 change: 0 additions & 1 deletion elements/lisk-p2p/src/peer/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export class Peer extends EventEmitter {
this._wsMessageCount = 0;

if (this._wsMessageRate > this._peerConfig.wsMaxMessageRate) {
this.disconnect(FORBIDDEN_CONNECTION, FORBIDDEN_CONNECTION_REASON);
this.applyPenalty(this._peerConfig.wsMaxMessageRatePenalty);

return;
Expand Down
37 changes: 28 additions & 9 deletions elements/lisk-p2p/src/peer_pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
P2PPenalty,
P2PRequestPacket,
P2PResponsePacket,
PeerLists,
} from './p2p_types';
import {
ConnectionState,
Expand Down Expand Up @@ -109,6 +110,7 @@ interface PeerPoolConfig {
readonly wsMaxMessageRatePenalty: number;
readonly rateCalculationInterval: number;
readonly secret: number;
readonly peerLists: PeerLists;
}

export const MAX_PEER_LIST_BATCH_SIZE = 100;
Expand Down Expand Up @@ -190,6 +192,7 @@ export class PeerPool extends EventEmitter {
private readonly _sendPeerLimit: number;
private readonly _outboundShuffleIntervalId: NodeJS.Timer | undefined;
private readonly _peerConfig: PeerConfig;
private readonly _peerLists: PeerLists;

public constructor(peerPoolConfig: PeerPoolConfig) {
super();
Expand All @@ -207,6 +210,7 @@ export class PeerPool extends EventEmitter {
maxPeerInfoSize: this._peerPoolConfig.maxPeerInfoSize,
secret: this._peerPoolConfig.secret,
};
this._peerLists = peerPoolConfig.peerLists;
this._peerSelectForSend = peerPoolConfig.peerSelectionForSend;
this._peerSelectForRequest = peerPoolConfig.peerSelectionForRequest;
this._peerSelectForConnection = peerPoolConfig.peerSelectionForConnection;
Expand Down Expand Up @@ -397,18 +401,22 @@ export class PeerPool extends EventEmitter {
): void {
// Try to connect to disconnected peers without including the fixed ones which are specially treated thereafter
const disconnectedNewPeers = newPeers.filter(
peer =>
!this._peerMap.has(constructPeerIdFromPeerInfo(peer)) ||
!fixedPeers.includes(peer),
newPeer =>
!this._peerMap.has(constructPeerIdFromPeerInfo(newPeer)) ||
!fixedPeers
.map(fixedPeer => fixedPeer.ipAddress)
.includes(newPeer.ipAddress),
);
const disconnectedTriedPeers = triedPeers.filter(
peer =>
!this._peerMap.has(constructPeerIdFromPeerInfo(peer)) ||
!fixedPeers.includes(peer),
triedPeer =>
!this._peerMap.has(constructPeerIdFromPeerInfo(triedPeer)) ||
!fixedPeers
.map(fixedPeer => fixedPeer.ipAddress)
.includes(triedPeer.ipAddress),
);
const { outboundCount } = this.getPeersCountPerKind();
const disconnectedFixedPeers = fixedPeers
.filter(peer => !this._peerMap.has(constructPeerIdFromPeerInfo(peer)))
.filter(peer => !this._peerMap.get(constructPeerIdFromPeerInfo(peer)))
.map(peer2Convert => peer2Convert as P2PDiscoveredPeerInfo);

// Trigger new connections only if the maximum of outbound connections has not been reached
Expand Down Expand Up @@ -597,7 +605,12 @@ export class PeerPool extends EventEmitter {
}

private _selectPeersForEviction(): Peer[] {
const peers = [...this.getPeers(InboundPeer)];
const peers = [...this.getPeers(InboundPeer)].filter(peer =>
this._peerLists.whitelisted.every(
p => constructPeerIdFromPeerInfo(p) !== peer.id,
),
);

// Cannot predict which netgroups will be protected
const filteredPeersByNetgroup = this._peerPoolConfig.netgroupProtectionRatio
? filterPeersByCategory(peers, {
Expand Down Expand Up @@ -655,7 +668,13 @@ export class PeerPool extends EventEmitter {
}

if (kind === OutboundPeer) {
const selectedPeer = shuffle(peers)[0];
const selectedPeer = shuffle(
peers.filter(peer =>
this._peerLists.fixedPeers.every(
p => constructPeerIdFromPeerInfo(p) !== peer.id,
),
),
)[0];
if (selectedPeer) {
this.removePeer(
selectedPeer.id,
Expand Down
15 changes: 15 additions & 0 deletions elements/lisk-p2p/test/integration/p2p.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2092,6 +2092,12 @@ describe('Integration tests for P2P library', () => {
connectTimeout: 100,
ackTimeout: 200,
seedPeers,
whitelistedPeers: [
{
ipAddress: '127.0.0.3',
wsPort: NETWORK_START_PORT,
},
],
wsEngine: 'ws',
populatorInterval: POPULATOR_INTERVAL_WITH_LIMIT,
maxOutboundConnections: MAX_INBOUND_CONNECTIONS,
Expand Down Expand Up @@ -2146,6 +2152,15 @@ describe('Integration tests for P2P library', () => {
);
});
});

// TODO: add a test to see if it doesn't drop the inbound connection with the whitelist
describe('whitelist peer', () => {
// Test to check if the whitelist peer is added to the sanitized whitelist.
it('should have whitelistpeer from config', async () => {
expect(p2pNodeList[1]['_sanitizedPeerLists'].whitelisted).not.to.be
.empty;
});
});
});

describe('Fully connected network with a custom maximum payload', () => {
Expand Down
7 changes: 7 additions & 0 deletions elements/lisk-p2p/test/unit/peer_pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ describe('peerPool', () => {
maxPeerInfoSize: 10000,
maxPeerDiscoveryResponseLength: 1000,
secret: DEFAULT_RANDOM_SECRET,
peerLists: {
blacklistedPeers: [],
fixedPeers: [],
previousPeers: [],
seedPeers: [],
whitelisted: [],
},
});

describe('#constructor', () => {
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.2",
"version": "0.4.3",
"description": "Lisk blockchain application platform",
"author": "Lisk Foundation <admin@lisk.io>, lightcurve GmbH <admin@lightcurve.io>",
"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.2",
"@liskhq/lisk-p2p": "0.3.3",
"@liskhq/lisk-transaction-pool": "0.1.2",
"@liskhq/lisk-transactions": "2.3.1",
"@liskhq/lisk-validator": "0.2.1",
Expand Down
3 changes: 2 additions & 1 deletion framework/src/modules/chain/blocks/blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ class Blocks extends EventEmitter {
},
);
if (blocksCount === 1) {
this.logger.info('Applying genesis block');
this._lastBlock = await this._reload(blocksCount);
this._isActive = false;
return;
Expand Down Expand Up @@ -580,7 +581,7 @@ class Blocks extends EventEmitter {
this._lastBlock = block;
this.logger.info(
{ blockId: block.id, height: block.height },
'Rebuilding block',
'Reloaded block',
);
},
);
Expand Down
39 changes: 24 additions & 15 deletions framework/src/modules/chain/chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,21 +170,30 @@ module.exports = class Chain {

// Avoid receiving blocks/transactions from the network during snapshotting process
if (!this.options.loading.rebuildUpToRound) {
this.channel.subscribe('network:event', ({ data: { event, data } }) => {
if (event === 'postTransactions') {
this.transport.postTransactions(data);
return;
}
if (event === 'postSignatures') {
this.transport.postSignatures(data);
return;
}
if (event === 'postBlock') {
this.transport.postBlock(data);
// eslint-disable-next-line no-useless-return
return;
}
});
this.channel.subscribe(
'network:event',
async ({ data: { event, data } }) => {
try {
if (event === 'postTransactions') {
await this.transport.postTransactions(data);
return;
}
if (event === 'postSignatures') {
await this.transport.postSignatures(data);
return;
}
if (event === 'postBlock') {
await this.transport.postBlock(data);
return;
}
} catch (error) {
this.logger.warn(
{ error, event },
'Received invalid event message',
);
}
},
);
}
} catch (error) {
this.logger.fatal('Chain initialization', {
Expand Down
34 changes: 10 additions & 24 deletions framework/src/modules/chain/transport/transport.js
Original file line number Diff line number Diff line change
Expand Up @@ -344,13 +344,12 @@ class Transport {
* @todo Add @returns tag
* @todo Add description of the function
*/
async postBlock(query) {
async postBlock(query = {}) {
if (!this.constants.broadcasts.active) {
return this.logger.debug(
'Receiving blocks disabled by user through config.json',
);
}
query = query || {};

const errors = validator.validate(definitions.WSBlocksBroadcast, query);

Expand All @@ -363,39 +362,24 @@ class Transport {
query,
},
);
throw new Error(errors);
// TODO: If there is an error, invoke the applyPenalty action on the Network module once it is implemented.
throw errors;
}

let block;
let success = true;
try {
block = blocksUtils.addBlockProperties(query.block);

// Instantiate transaction classes
block.transactions = this.interfaceAdapters.transactions.fromBlock(block);
let block = blocksUtils.addBlockProperties(query.block);

block = blocksUtils.objectNormalize(block);
} catch (e) {
success = false;
this.logger.debug('Block normalization failed', {
err: e.toString(),
module: 'transport',
block: query.block,
});
// Instantiate transaction classes
block.transactions = this.interfaceAdapters.transactions.fromBlock(block);

// TODO: If there is an error, invoke the applyPenalty action on the Network module once it is implemented.
}
block = blocksUtils.objectNormalize(block);
// TODO: endpoint should be protected before
if (this.loaderModule.syncing()) {
return this.logger.debug(
"Client is syncing. Can't receive block at the moment.",
block.id,
);
}
if (success) {
return this.blocksModule.receiveBlockFromNetwork(block);
}
return null;
return this.blocksModule.receiveBlockFromNetwork(block);
}

/**
Expand Down Expand Up @@ -449,6 +433,7 @@ class Transport {

if (errors.length) {
this.logger.debug('Invalid signatures body', errors);
// TODO: If there is an error, invoke the applyPenalty action on the Network module once it is implemented.
throw errors;
}

Expand Down Expand Up @@ -543,6 +528,7 @@ class Transport {

if (errors.length) {
this.logger.debug('Invalid transactions body', errors);
// TODO: If there is an error, invoke the applyPenalty action on the Network module once it is implemented.
throw errors;
}

Expand Down
Loading

0 comments on commit d1c1816

Please sign in to comment.