From 588e8f82b1f6f680890051a6bb54cfe8bce3e130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Tue, 14 Jan 2020 19:14:18 +0200 Subject: [PATCH 1/4] fixing it? --- packages/protocol/contracts/governance/DowntimeSlasher.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/protocol/contracts/governance/DowntimeSlasher.sol b/packages/protocol/contracts/governance/DowntimeSlasher.sol index ed37cee69f9..6844655c547 100644 --- a/packages/protocol/contracts/governance/DowntimeSlasher.sol +++ b/packages/protocol/contracts/governance/DowntimeSlasher.sol @@ -83,7 +83,7 @@ contract DowntimeSlasher is SlasherUtil { uint256 signerIndex = epochNumberOfBlock(n, sz) == startEpoch ? startSignerIndex : endSignerIndex; - if (uint256(getParentSealBitmap(n)) & (1 << signerIndex) != 0) return false; + if (uint256(getParentSealBitmap(n + 1)) & (1 << signerIndex) != 0) return false; } return true; } From 56a116aef972757a0110a07c71825dc872df622d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Wed, 15 Jan 2020 12:27:33 +0200 Subject: [PATCH 2/4] seems to work now --- .../test/governance/downtime_slasher.ts | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/packages/protocol/test/governance/downtime_slasher.ts b/packages/protocol/test/governance/downtime_slasher.ts index d5c3128356a..2bf440c63f0 100644 --- a/packages/protocol/test/governance/downtime_slasher.ts +++ b/packages/protocol/test/governance/downtime_slasher.ts @@ -1,5 +1,5 @@ import { CeloContractName } from '@celo/protocol/lib/registry-utils' -import { assertContainSubset, assertRevert } from '@celo/protocol/lib/test-utils' +import { assertContainSubset, assertRevert, jsonRpc } from '@celo/protocol/lib/test-utils' import BigNumber from 'bignumber.js' import { AccountsContract, @@ -37,7 +37,7 @@ contract('DowntimeSlasher', (accounts: string[]) => { const slashingPenalty = 10000 const slashingReward = 100 - const slashableDowntime = 3 + const slashableDowntime = 10 beforeEach(async () => { accountsInstance = await Accounts.new() @@ -70,7 +70,7 @@ contract('DowntimeSlasher', (accounts: string[]) => { }) it('should have set slashable downtime', async () => { const res = await slasher.slashableDowntime() - assert.equal(res.toNumber(), 3) + assert.equal(res.toNumber(), slashableDowntime) }) it('can only be called once', async () => { await assertRevert(slasher.initialize(registry.address, 10000, 100, 2)) @@ -132,28 +132,54 @@ contract('DowntimeSlasher', (accounts: string[]) => { describe('#slash()', () => { let blockNumber: number let startBlock: number + let changeBlock: number const validatorIndex = 0 + before(async () => { + let bn: number = 0 + do { + bn = await web3.eth.getBlockNumber() + await jsonRpc(web3, 'evm_mine', []) + } while (bn < 350) + }) beforeEach(async () => { blockNumber = await web3.eth.getBlockNumber() startBlock = blockNumber - 50 const epoch = (await slasher.getEpochNumberOfBlock(blockNumber)).toNumber() await slasher.setEpochSigner(epoch, validatorIndex, validator) await slasher.setEpochSigner(epoch - 1, validatorIndex, validator) + await slasher.setEpochSigner(epoch - 2, 1, validator) await slasher.setEpochSigner(epoch + 1, validatorIndex, validator) // Signed by validators 0 and 1 const bitmap = '0x0000000000000000000000000000000000000000000000000000000000000003' // Signed by validator 1 const bitmap2 = '0x0000000000000000000000000000000000000000000000000000000000000002' + // Signed by validator 0 + const bitmap3 = '0x0000000000000000000000000000000000000000000000000000000000000001' await slasher.setParentSealBitmap(blockNumber, bitmap) await slasher.setParentSealBitmap(blockNumber + 1, bitmap) await slasher.setParentSealBitmap(blockNumber + 2, bitmap2) await slasher.setNumberValidators(2) + // when epoch-2 changes to epoch-1, the validator to be slashed is down, but our signer number changes + // another validator is up around the epoch change + changeBlock = (epoch - 1) * 100 - 3 + async function prepareBlock(bn) { + const parentEpoch = (await slasher.getEpochNumberOfBlock(bn - 1)).toNumber() + await slasher.setParentSealBitmap(bn, parentEpoch === epoch - 2 ? bitmap3 : bitmap2) + } + for (let i = 0; i < 7; i++) { + await prepareBlock(changeBlock + i) + } }) it('fails if they were signed', async () => { await assertRevert( slasher.slash(blockNumber, validatorIndex, validatorIndex, 0, [], [], [], [], [], []) ) }) + it('success with validator index change', async () => { + await slasher.slash(changeBlock, 1, validatorIndex, 0, [], [], [], [], [], []) + const balance = await mockLockedGold.accountTotalLockedGold(validator) + assert.equal(balance.toNumber(), 40000) + }) it('decrements gold when success', async () => { await slasher.slash(startBlock, validatorIndex, validatorIndex, 0, [], [], [], [], [], []) const balance = await mockLockedGold.accountTotalLockedGold(validator) From bb166b3e821e9c7a3182c5df90f82e38a3a2b55e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Fri, 17 Jan 2020 13:00:45 +0200 Subject: [PATCH 3/4] added comment --- packages/protocol/contracts/governance/DowntimeSlasher.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/protocol/contracts/governance/DowntimeSlasher.sol b/packages/protocol/contracts/governance/DowntimeSlasher.sol index 6844655c547..7c33a8d777a 100644 --- a/packages/protocol/contracts/governance/DowntimeSlasher.sol +++ b/packages/protocol/contracts/governance/DowntimeSlasher.sol @@ -83,6 +83,7 @@ contract DowntimeSlasher is SlasherUtil { uint256 signerIndex = epochNumberOfBlock(n, sz) == startEpoch ? startSignerIndex : endSignerIndex; + // We want to check signers for this block, so we get the parent seal bitmap for the next block if (uint256(getParentSealBitmap(n + 1)) & (1 << signerIndex) != 0) return false; } return true; From d7ff23a3a2c36dba688aa495f8e0784c66ebfc4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kel=C3=A4?= Date: Fri, 17 Jan 2020 13:22:43 +0200 Subject: [PATCH 4/4] lint --- packages/protocol/contracts/governance/DowntimeSlasher.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/protocol/contracts/governance/DowntimeSlasher.sol b/packages/protocol/contracts/governance/DowntimeSlasher.sol index 7c33a8d777a..ce2ea171dcd 100644 --- a/packages/protocol/contracts/governance/DowntimeSlasher.sol +++ b/packages/protocol/contracts/governance/DowntimeSlasher.sol @@ -83,7 +83,8 @@ contract DowntimeSlasher is SlasherUtil { uint256 signerIndex = epochNumberOfBlock(n, sz) == startEpoch ? startSignerIndex : endSignerIndex; - // We want to check signers for this block, so we get the parent seal bitmap for the next block + // We want to check signers for block n, + // so we get the parent seal bitmap for the next block if (uint256(getParentSealBitmap(n + 1)) & (1 << signerIndex) != 0) return false; } return true;