diff --git a/elements/lisk-dpos/src/delegates_list.ts b/elements/lisk-dpos/src/delegates_list.ts index a82f09344ff..2633bff88a1 100644 --- a/elements/lisk-dpos/src/delegates_list.ts +++ b/elements/lisk-dpos/src/delegates_list.ts @@ -213,6 +213,7 @@ const _pickStandByDelegate = ( ): number => { const seedNumber = randomSeed.readBigUInt64BE(); const totalVoteWeight = _getTotalVoteWeight(delegateWeights); + // tslint:disable-next-line no-let let threshold = seedNumber % totalVoteWeight; // tslint:disable-next-line no-let @@ -378,22 +379,26 @@ export class DelegatesList { throw new Error(`Corresponding vote weight for round ${round} not found`); } // Expect that voteWeight is stored in order of voteWeight and address - const hasStandbySlot = - voteWeight.delegates.length > - this.activeDelegates + this.standbyDelegates; - const activeDelegateSlots = hasStandbySlot - ? this.activeDelegates - : this.activeDelegates + this.standbyDelegates; + const hasStandbySlot = voteWeight.delegates.length > this.activeDelegates; const activeDelegateAddresses = voteWeight.delegates - .slice(0, activeDelegateSlots) + .slice(0, this.activeDelegates) .map(vw => vw.address); const standbyDelegateAddresses = []; const standbyDelegateVoteWeights = hasStandbySlot - ? voteWeight.delegates.slice(activeDelegateSlots) + ? voteWeight.delegates.slice(this.activeDelegates) : []; - // Only choose standby delegate if it exists - if (standbyDelegateVoteWeights.length !== 0) { + // If standby delegates are less or equal to what required + // Then don't choose based on random seed and consider those as standby + if ( + standbyDelegateVoteWeights.length > 0 && + standbyDelegateVoteWeights.length <= this.standbyDelegates + ) { + for (const delegate of standbyDelegateVoteWeights) { + standbyDelegateAddresses.push(delegate.address); + } + // If standby delegates are more than what required then choose based on random seed + } else if (standbyDelegateVoteWeights.length > this.standbyDelegates) { // tslint:disable-next-line no-let for (let i = 0; i < this.standbyDelegates; i += 1) { const standbyDelegateIndex = _pickStandByDelegate( diff --git a/elements/lisk-dpos/test/unit/vote_weight_snapshot.spec.ts b/elements/lisk-dpos/test/unit/vote_weight_snapshot.spec.ts index 8ae8eba744f..33a66fbeaa3 100644 --- a/elements/lisk-dpos/test/unit/vote_weight_snapshot.spec.ts +++ b/elements/lisk-dpos/test/unit/vote_weight_snapshot.spec.ts @@ -774,7 +774,8 @@ describe('Vote weight snapshot', () => { const mockedForgersList = JSON.stringify([ { round: 10, - delegates: [...forgers.map(d => d.address).slice(0, 102)], + delegates: [...forgers.map(d => d.address).slice(0, 100)], + standby: [...forgers.map(d => d.address).slice(101, 102)], }, ]); @@ -782,7 +783,13 @@ describe('Vote weight snapshot', () => { { round: 11, delegates: [ - ...delegates.map(d => ({ + ...delegates.slice(0, 100).map(d => ({ + address: d.address, + voteWeight: d.totalVotesReceived.toString(), + })), + ], + standby: [ + ...delegates.slice(101, 102).map(d => ({ address: d.address, voteWeight: d.totalVotesReceived.toString(), })),