diff --git a/packages/core-blockchain/src/blockchain.ts b/packages/core-blockchain/src/blockchain.ts index 9e314162d4..8caaf27fa1 100644 --- a/packages/core-blockchain/src/blockchain.ts +++ b/packages/core-blockchain/src/blockchain.ts @@ -234,8 +234,8 @@ export class Blockchain implements blockchain.IBlockchain { /** * Push a block to the process queue. */ - public handleIncomingBlock(block: Interfaces.IBlockData, remoteAddress: string): void { - this.pushPingBlock(block); + public handleIncomingBlock(block: Interfaces.IBlockData, remoteAddress: string, fromForger: boolean = false): void { + this.pushPingBlock(block, fromForger); logger.info( `Received new block at height ${block.height.toLocaleString()} with ${pluralize( @@ -482,7 +482,7 @@ export class Blockchain implements blockchain.IBlockchain { /** * Push ping block. */ - public pushPingBlock(block: Interfaces.IBlockData): void { - this.state.pushPingBlock(block); + public pushPingBlock(block: Interfaces.IBlockData, fromForger: boolean = false): void { + this.state.pushPingBlock(block, fromForger); } } diff --git a/packages/core-blockchain/src/state-storage.ts b/packages/core-blockchain/src/state-storage.ts index 41a77ef47e..f0128b8779 100644 --- a/packages/core-blockchain/src/state-storage.ts +++ b/packages/core-blockchain/src/state-storage.ts @@ -222,7 +222,7 @@ export class StateStorage implements Blockchain.IStateStorage { /** * Push ping block. */ - public pushPingBlock(block: Interfaces.IBlockData): void { + public pushPingBlock(block: Interfaces.IBlockData, fromForger: boolean = false): void { // logging for stats about network health if (this.blockPing) { logger.info( @@ -231,7 +231,7 @@ export class StateStorage implements Blockchain.IStateStorage { } this.blockPing = { - count: 1, + count: fromForger ? 0 : 1, // if block comes from forger, it hasn't "pinged" blockchain even once first: new Date().getTime(), last: new Date().getTime(), block, diff --git a/packages/core-interfaces/src/core-blockchain/blockchain.ts b/packages/core-interfaces/src/core-blockchain/blockchain.ts index cada690ef7..2b469ea011 100644 --- a/packages/core-interfaces/src/core-blockchain/blockchain.ts +++ b/packages/core-interfaces/src/core-blockchain/blockchain.ts @@ -66,7 +66,7 @@ export interface IBlockchain { /** * Push a block to the process queue. */ - handleIncomingBlock(block: Interfaces.IBlockData, remoteAddress: string): void; + handleIncomingBlock(block: Interfaces.IBlockData, remoteAddress: string, fromForger?: boolean): void; /** * Remove N number of blocks. @@ -163,5 +163,5 @@ export interface IBlockchain { * Push ping block. * @return {Object} */ - pushPingBlock(block: Interfaces.IBlockData): void; + pushPingBlock(block: Interfaces.IBlockData, fromForger?: boolean): void; } diff --git a/packages/core-interfaces/src/core-blockchain/state-storage.ts b/packages/core-interfaces/src/core-blockchain/state-storage.ts index df1fd6266b..edd2878baf 100644 --- a/packages/core-interfaces/src/core-blockchain/state-storage.ts +++ b/packages/core-interfaces/src/core-blockchain/state-storage.ts @@ -74,5 +74,5 @@ export interface IStateStorage { /** * Push ping block */ - pushPingBlock(block: Interfaces.IBlockData): void; + pushPingBlock(block: Interfaces.IBlockData, fromForger?: boolean): void; } diff --git a/packages/core-p2p/src/network-monitor.ts b/packages/core-p2p/src/network-monitor.ts index 15d7b9598f..043d9e7db8 100644 --- a/packages/core-p2p/src/network-monitor.ts +++ b/packages/core-p2p/src/network-monitor.ts @@ -310,9 +310,9 @@ export class NetworkMonitor implements P2P.INetworkMonitor { // wait a bit before broadcasting if a bit early const diff = blockPing.last - blockPing.first; const maxHop = 4; - let proba = (maxHop - blockPing.count) / maxHop; + let broadcastQuota: number = (maxHop - blockPing.count) / maxHop; - if (diff < 500 && proba > 0) { + if (diff < 500 && broadcastQuota > 0) { await delay(500 - diff); blockPing = blockchain.getBlockPing(); @@ -322,11 +322,11 @@ export class NetworkMonitor implements P2P.INetworkMonitor { return; } - proba = (maxHop - blockPing.count) / maxHop; + broadcastQuota = (maxHop - blockPing.count) / maxHop; } - // TODO: to be put in config? - peers = peers.filter(p => Math.random() < proba); + peers = broadcastQuota <= 0 ? [] : shuffle(peers).slice(0, Math.ceil(broadcastQuota * peers.length)); + // select a portion of our peers according to quota calculated before } this.logger.info( diff --git a/packages/core-p2p/src/socket-server/versions/peer.ts b/packages/core-p2p/src/socket-server/versions/peer.ts index bff2e26d4a..c30ba8d20d 100644 --- a/packages/core-p2p/src/socket-server/versions/peer.ts +++ b/packages/core-p2p/src/socket-server/versions/peer.ts @@ -63,8 +63,9 @@ export async function postBlock({ req }): Promise { const blockchain: Blockchain.IBlockchain = app.resolvePlugin("blockchain"); const block: Interfaces.IBlockData = req.data.block; + const fromForger: boolean = isWhitelisted(app.resolveOptions("p2p").remoteAccess, req.headers.remoteAddress); - if (!isWhitelisted(app.resolveOptions("p2p").remoteAccess, req.headers.remoteAddress)) { + if (!fromForger) { if (blockchain.pingBlock(block)) { return; } @@ -76,7 +77,7 @@ export async function postBlock({ req }): Promise { } } - blockchain.handleIncomingBlock(block, req.headers.remoteAddress); + blockchain.handleIncomingBlock(block, req.headers.remoteAddress, fromForger); } export async function postTransactions({ service, req }: { service: P2P.IPeerService; req }): Promise {