Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: hash consensus: add more frames tests #576

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions contracts/0.8.9/oracle/HashConsensus.sol
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ contract HashConsensus is AccessControlEnumerable {

/// @notice Returns the parameters required to calculate reporting frame given an epoch.
///
function getFrameConfig() external view returns (uint256 initialEpoch, uint256 epochsPerFrame) {
return (_frameConfig.initialEpoch, _frameConfig.epochsPerFrame);
function getFrameConfig() external view returns (uint256 initialEpoch, uint256 epochsPerFrame, uint256 fastLaneLengthSlots) {
return (_frameConfig.initialEpoch, _frameConfig.epochsPerFrame, _frameConfig.fastLaneLengthSlots);
}

/// @notice Returns the current reporting frame.
Expand Down
110 changes: 74 additions & 36 deletions test/0.8.9/oracle/hash-consensus-access-control.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,20 @@ contract('HashConsensus', ([admin, account1, account2, member1, member2, strange
})

context('MANAGE_MEMBERS_AND_QUORUM_ROLE', () => {
const errorMessage = `AccessControl: account ${account1.toLowerCase()} is missing role ${manageMembersAndQuorumRoleKeccak156}`

beforeEach(deploy)

context('addMember', () => {
it('should revert without manage members and qourum role', async () => {
await assert.reverts(consensus.addMember(member1, 2, { from: account1 }), errorMessage)
it('should revert without MANAGE_MEMBERS_AND_QUORUM_ROLE role', async () => {
await assert.revertsOZAccessControl(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

consensus.addMember(member1, 2, { from: account1 }),
account1,
'MANAGE_MEMBERS_AND_QUORUM_ROLE'
)
assert.equal(await consensus.getIsMember(member1), false)
assert.equal(+(await consensus.getQuorum()), 0)
})

it('should check manage members and qourum role', async () => {
it('should allow calling from a possessor of MANAGE_MEMBERS_AND_QUORUM_ROLE role', async () => {
await consensus.grantRole(manageMembersAndQuorumRoleKeccak156, account2)
await consensus.addMember(member2, 1, { from: account2 })

Expand All @@ -49,13 +51,17 @@ contract('HashConsensus', ([admin, account1, account2, member1, member2, strange
})

context('removeMember', () => {
it('should revert without manage members and qourum role', async () => {
await assert.reverts(consensus.removeMember(member1, 2, { from: account1 }), errorMessage)
it('should revert without MANAGE_MEMBERS_AND_QUORUM_ROLE role', async () => {
await assert.revertsOZAccessControl(
consensus.removeMember(member1, 2, { from: account1 }),
account1,
'MANAGE_MEMBERS_AND_QUORUM_ROLE'
)
assert.equal(await consensus.getIsMember(member1), false)
assert.equal(+(await consensus.getQuorum()), 0)
})

it('should check manage members and qourum role', async () => {
it('should allow calling from a possessor of MANAGE_MEMBERS_AND_QUORUM_ROLE role', async () => {
await consensus.grantRole(manageMembersAndQuorumRoleKeccak156, account2)
await consensus.addMember(member2, 1, { from: account2 })
assert.equal(await consensus.getIsMember(member2), true)
Expand All @@ -68,12 +74,16 @@ contract('HashConsensus', ([admin, account1, account2, member1, member2, strange
})

context('setQuorum', () => {
it('should revert without manage members and qourum role', async () => {
await assert.reverts(consensus.setQuorum(1, { from: account1 }), errorMessage)
it('should revert without MANAGE_MEMBERS_AND_QUORUM_ROLE role', async () => {
await assert.revertsOZAccessControl(
consensus.setQuorum(1, { from: account1 }),
account1,
'MANAGE_MEMBERS_AND_QUORUM_ROLE'
)
assert.equal(+(await consensus.getQuorum()), 0)
})

it('should check manage members and qourum role', async () => {
it('should allow calling from a possessor of MANAGE_MEMBERS_AND_QUORUM_ROLE role', async () => {
await consensus.grantRole(manageMembersAndQuorumRoleKeccak156, account2)
await consensus.setQuorum(1, { from: account2 })

Expand All @@ -82,27 +92,31 @@ contract('HashConsensus', ([admin, account1, account2, member1, member2, strange
})

context('disableConsensus', () => {
it('should revert without manage members and qourum role', async () => {
const errorMessage = `AccessControl: account ${account1.toLowerCase()} is missing role ${disableConsensusRoleKeccak156}`

await assert.reverts(consensus.disableConsensus({ from: account1 }), errorMessage)
it('should revert without MANAGE_MEMBERS_AND_QUORUM_ROLE role', async () => {
await assert.revertsOZAccessControl(
consensus.disableConsensus({ from: account1 }),
account1,
'DISABLE_CONSENSUS_ROLE'
)
assert.equal(+(await consensus.getQuorum()), 0)
})
})
})

context('DISABLE_CONSENSUS_ROLE', () => {
const errorMessage = `AccessControl: account ${account1.toLowerCase()} is missing role ${disableConsensusRoleKeccak156}`

beforeEach(deploy)

context('setQuorum', () => {
it('should revert without disable consensus role', async () => {
await assert.reverts(consensus.setQuorum(MaxUint256, { from: account1 }), errorMessage)
it('should revert without DISABLE_CONSENSUS_ROLE role', async () => {
await assert.revertsOZAccessControl(
consensus.setQuorum(MaxUint256, { from: account1 }),
account1,
'DISABLE_CONSENSUS_ROLE'
)
assert.equal(+(await consensus.getQuorum()), 0)
})

it('should check disable consensus role', async () => {
it('should allow calling from a possessor of DISABLE_CONSENSUS_ROLE role', async () => {
await consensus.grantRole(disableConsensusRoleKeccak156, account2)
await consensus.setQuorum(MaxUint256, { from: account2 })

Expand All @@ -111,12 +125,16 @@ contract('HashConsensus', ([admin, account1, account2, member1, member2, strange
})

context('disableConsensus', () => {
it('should revert without disable consensus role', async () => {
await assert.reverts(consensus.disableConsensus({ from: account1 }), errorMessage)
it('should revert without DISABLE_CONSENSUS_ROLE role', async () => {
await assert.revertsOZAccessControl(
consensus.disableConsensus({ from: account1 }),
account1,
'DISABLE_CONSENSUS_ROLE'
)
assert.equal(+(await consensus.getQuorum()), 0)
})

it('should check disable consensus role', async () => {
it('should allow calling from a possessor of DISABLE_CONSENSUS_ROLE role', async () => {
await consensus.grantRole(disableConsensusRoleKeccak156, account2)
await consensus.disableConsensus({ from: account2 })

Expand All @@ -126,17 +144,19 @@ contract('HashConsensus', ([admin, account1, account2, member1, member2, strange
})

context('MANAGE_FRAME_CONFIG_ROLE', () => {
const errorMessage = `AccessControl: account ${account1.toLowerCase()} is missing role ${manageFrameConfigRoleKeccak156}`

beforeEach(deploy)

context('setFrameConfig', () => {
it('should revert without manage frame config role', async () => {
await assert.reverts(consensus.setFrameConfig(5, 0, { from: account1 }), errorMessage)
it('should revert without MANAGE_FRAME_CONFIG_ROLE role', async () => {
await assert.revertsOZAccessControl(
consensus.setFrameConfig(5, 0, { from: account1 }),
account1,
'MANAGE_FRAME_CONFIG_ROLE'
)
assert.equal(+(await consensus.getFrameConfig()).epochsPerFrame, EPOCHS_PER_FRAME)
})

it('should check manage frame config role', async () => {
it('should allow calling from a possessor of MANAGE_FRAME_CONFIG_ROLE role', async () => {
await consensus.grantRole(manageFrameConfigRoleKeccak156, account2)
await consensus.setFrameConfig(5, 0, { from: account2 })

Expand All @@ -146,25 +166,43 @@ contract('HashConsensus', ([admin, account1, account2, member1, member2, strange
})

context('MANAGE_REPORT_PROCESSOR_ROLE', () => {
const errorMessage = `AccessControl: account ${account1.toLowerCase()} is missing role ${manageReportProcessorRoleKeccak156}`

beforeEach(deploy)

context('setReportProcessor', () => {
it('should revert without manage report processor role', async () => {
await assert.reverts(consensus.setReportProcessor(member1, { from: account1 }), errorMessage)
it('should revert without MANAGE_REPORT_PROCESSOR_ROLE role', async () => {
await assert.revertsOZAccessControl(
consensus.setReportProcessor(member1, { from: account1 }),
account1,
'MANAGE_REPORT_PROCESSOR_ROLE'
)
})

it('should allow calling from a possessor of MANAGE_REPORT_PROCESSOR_ROLE role', async () => {
await consensus.grantRole(manageReportProcessorRoleKeccak156, account2)
await consensus.setReportProcessor(member1, { from: account2 })

assert.equal(+(await consensus.getReportProcessor()), member1)
})
})
})

context('MANAGE_FAST_LANE_CONFIG_ROLE', () => {
const errorMessage = `AccessControl: account ${account1.toLowerCase()} is missing role ${manageFastLineConfigRoleKeccak156}`

beforeEach(deploy)

context('setFastLaneLengthSlots', () => {
it('should revert without manage fast lane config role', async () => {
await assert.reverts(consensus.setFastLaneLengthSlots(member1, { from: account1 }), errorMessage)
it('should revert without MANAGE_FAST_LANE_CONFIG_ROLE role', async () => {
await assert.revertsOZAccessControl(
consensus.setFastLaneLengthSlots(5, { from: account1 }),
account1,
'MANAGE_FAST_LANE_CONFIG_ROLE'
)
})

it('should allow calling from a possessor of MANAGE_FAST_LANE_CONFIG_ROLE role', async () => {
await consensus.grantRole(manageFastLineConfigRoleKeccak156, account2)
await consensus.setFastLaneLengthSlots(64, { from: account2 })

assert.equal(+(await consensus.getFrameConfig()).fastLaneLengthSlots, 64)
})
})
})
Expand Down
65 changes: 43 additions & 22 deletions test/0.8.9/oracle/hash-consensus-deploy.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,19 @@ const SLOTS_PER_EPOCH = 32
const SECONDS_PER_SLOT = 12
const GENESIS_TIME = 100
const EPOCHS_PER_FRAME = 225 // one day
const INITIAL_EPOCH = 1
const INITIAL_FAST_LANE_LENGHT_SLOTS = 0

const SECONDS_PER_EPOCH = SLOTS_PER_EPOCH * SECONDS_PER_SLOT
const SECONDS_PER_FRAME = SECONDS_PER_EPOCH * EPOCHS_PER_FRAME
const SLOTS_PER_FRAME = EPOCHS_PER_FRAME * SLOTS_PER_EPOCH

const computeSlotAt = time => Math.floor((time - GENESIS_TIME) / SECONDS_PER_SLOT)
const computeEpochAt = time => Math.floor(computeSlotAt(time) / SLOTS_PER_EPOCH)
const computeEpochFirstSlot = epoch => epoch * SLOTS_PER_EPOCH
const computeEpochFirstSlotAt = time => computeEpochFirstSlot(computeEpochAt(time))
const computeTimestampAtEpoch = epoch => GENESIS_TIME + epoch * SECONDS_PER_EPOCH
const computeTimestampAtSlot = slot => GENESIS_TIME + slot * SECONDS_PER_SLOT
const computeSlotAt = (time) => Math.floor((time - GENESIS_TIME) / SECONDS_PER_SLOT)
const computeEpochAt = (time) => Math.floor(computeSlotAt(time) / SLOTS_PER_EPOCH)
const computeEpochFirstSlot = (epoch) => epoch * SLOTS_PER_EPOCH
const computeEpochFirstSlotAt = (time) => computeEpochFirstSlot(computeEpochAt(time))
const computeTimestampAtEpoch = (epoch) => GENESIS_TIME + epoch * SECONDS_PER_EPOCH
const computeTimestampAtSlot = (slot) => GENESIS_TIME + slot * SECONDS_PER_SLOT

const ZERO_HASH = '0x0000000000000000000000000000000000000000000000000000000000000000'

Expand All @@ -32,16 +34,19 @@ const HASH_5 = '0x55555555555555555555555555555555555555555555555555555555555555

const CONSENSUS_VERSION = 1

async function deployHashConsensus(admin, {
reportProcessor = null,
reportProcessorAddress = null,
slotsPerEpoch = SLOTS_PER_EPOCH,
secondsPerSlot = SECONDS_PER_SLOT,
genesisTime = GENESIS_TIME,
epochsPerFrame = EPOCHS_PER_FRAME,
fastLaneLengthSlots = 0,
initialEpoch = 1
} = {}) {
async function deployHashConsensus(
admin,
{
reportProcessor = null,
reportProcessorAddress = null,
slotsPerEpoch = SLOTS_PER_EPOCH,
secondsPerSlot = SECONDS_PER_SLOT,
genesisTime = GENESIS_TIME,
epochsPerFrame = EPOCHS_PER_FRAME,
fastLaneLengthSlots = INITIAL_FAST_LANE_LENGHT_SLOTS,
initialEpoch = INITIAL_EPOCH
} = {}
) {
if (!reportProcessor && !reportProcessorAddress) {
reportProcessor = await MockReportProcessor.new(CONSENSUS_VERSION, { from: admin })
}
Expand Down Expand Up @@ -70,11 +75,27 @@ async function deployHashConsensus(admin, {
}

module.exports = {
SLOTS_PER_EPOCH, SECONDS_PER_SLOT, GENESIS_TIME, EPOCHS_PER_FRAME,
SECONDS_PER_EPOCH, SECONDS_PER_FRAME, SLOTS_PER_FRAME,
computeSlotAt, computeEpochAt, computeEpochFirstSlot, computeEpochFirstSlotAt,
computeTimestampAtSlot, computeTimestampAtEpoch,
ZERO_HASH, HASH_1, HASH_2, HASH_3, HASH_4, HASH_5,
INITIAL_FAST_LANE_LENGHT_SLOTS,
INITIAL_EPOCH,
SLOTS_PER_EPOCH,
SECONDS_PER_SLOT,
GENESIS_TIME,
EPOCHS_PER_FRAME,
SECONDS_PER_EPOCH,
SECONDS_PER_FRAME,
SLOTS_PER_FRAME,
computeSlotAt,
computeEpochAt,
computeEpochFirstSlot,
computeEpochFirstSlotAt,
computeTimestampAtSlot,
computeTimestampAtEpoch,
ZERO_HASH,
HASH_1,
HASH_2,
HASH_3,
HASH_4,
HASH_5,
CONSENSUS_VERSION,
deployHashConsensus
}
Expand All @@ -87,7 +108,7 @@ contract('HashConsensus', ([admin, member1]) => {
let reportProcessor

it('deploying hash consensus', async () => {
const deployed = await deployHashConsensus(admin, {initialEpoch: INITIAL_EPOCH})
const deployed = await deployHashConsensus(admin, { initialEpoch: INITIAL_EPOCH })
consensus = deployed.consensus
reportProcessor = deployed.reportProcessor
})
Expand Down
Loading