Skip to content

Commit

Permalink
Merge branch 'release/core-contracts/12' into martinvol/fixFeeHandler
Browse files Browse the repository at this point in the history
  • Loading branch information
martinvol authored Oct 7, 2024
2 parents 939e577 + 38723bc commit aa92315
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 14 deletions.
32 changes: 25 additions & 7 deletions packages/protocol/contracts-0.8/common/EpochManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ contract EpochManager is
uint256 public epochDuration;

uint256 public firstKnownEpoch;
uint256 private currentEpochNumber;
uint256 internal currentEpochNumber;
address public oracleAddress;
address[] public elected;

mapping(address => ProcessedGroup) public processedGroups;

EpochProcessState public epochProcessing;
mapping(uint256 => Epoch) private epochs;
mapping(uint256 => Epoch) internal epochs;
mapping(address => uint256) public validatorPendingPayments;

/**
Expand Down Expand Up @@ -215,7 +215,7 @@ contract EpochManager is
address[] calldata groups,
address[] calldata lessers,
address[] calldata greaters
) external nonReentrant {
) external virtual nonReentrant {
require(isOnEpochProcess(), "Epoch process is not started");
// finalize epoch
// last block should be the block before and timestamp from previous block
Expand Down Expand Up @@ -327,16 +327,19 @@ contract EpochManager is
}

/**
* @return The current epoch info.
* @notice Returns the info of the current epoch.
* @return firstEpoch The first block of the epoch.
* @return lastBlock The first block of the epoch.
* @return startTimestamp The starting timestamp of the epoch.
* @return rewardsBlock The reward block of the epoch.
*/
function getCurrentEpoch()
external
view
onlySystemAlreadyInitialized
returns (uint256, uint256, uint256, uint256)
{
Epoch storage _epoch = epochs[currentEpochNumber];
return (_epoch.firstBlock, _epoch.lastBlock, _epoch.startTimestamp, _epoch.rewardsBlock);
return getEpochByNumber(currentEpochNumber);
}

/**
Expand Down Expand Up @@ -374,7 +377,7 @@ contract EpochManager is
}

/**
* @return The list of elected validators.
* @return The list of currently elected validators.
*/
function getElected() external view returns (address[] memory) {
return elected;
Expand Down Expand Up @@ -457,6 +460,21 @@ contract EpochManager is
return initialized && isSystemInitialized;
}

/**
* @notice Returns the epoch info of a specified epoch.
* @param epochNumber Epoch number where epoch info is retreived.
* @return firstEpoch The first block of the epoch.
* @return lastBlock The first block of the epoch.
* @return startTimestamp The starting timestamp of the epoch.
* @return rewardsBlock The reward block of the epoch.
*/
function getEpochByNumber(
uint256 epochNumber
) public view onlySystemAlreadyInitialized returns (uint256, uint256, uint256, uint256) {
Epoch storage _epoch = epochs[epochNumber];
return (_epoch.firstBlock, _epoch.lastBlock, _epoch.startTimestamp, _epoch.rewardsBlock);
}

/**
* @notice Allocates rewards to elected validator accounts.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,22 @@ contract EpochManager_WithMocks is EpochManager(true) {
function _setPaymentAllocation(address validator, uint256 amount) external {
validatorPendingPayments[validator] = amount;
}

// mocks finishNextEpochProcess to increment the epoch number.
function finishNextEpochProcess(
address[] calldata groups,
address[] calldata lessers,
address[] calldata greaters
) external override nonReentrant {
require(isOnEpochProcess(), "Epoch process is not started");

epochs[currentEpochNumber].lastBlock = block.number - 1;

currentEpochNumber++;
epochs[currentEpochNumber].firstBlock = block.number;
epochs[currentEpochNumber].startTimestamp = block.timestamp;

EpochProcessState storage _epochProcessing = epochProcessing;
_epochProcessing.status = EpochProcessStatus.NotStarted;
}
}
1 change: 1 addition & 0 deletions packages/protocol/test-sol/constants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ contract TestConstants {
uint256 public constant MONTH = 30 * DAY;
uint256 constant WEEK = 7 * DAY;
uint256 public constant YEAR = 365 * DAY;
uint256 public constant L2_BLOCK_IN_EPOCH = 43200;

// Contract names
string constant ElectionContract = "Election";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ contract EpochManagerIntegrationTest is IntegrationTest, MigrationsConstants {
function test_SetsCurrentRewardBlock() public {
_MockL2Migration(validatorsList);

blockTravel(vm, 43200);
blockTravel(vm, L2_BLOCK_IN_EPOCH);
timeTravel(vm, DAY);

epochManager.startNextEpochProcess();
Expand Down
93 changes: 91 additions & 2 deletions packages/protocol/test-sol/unit/common/EpochManager.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,7 @@ contract EpochManagerTest is Test, TestConstants, Utils08 {
vm.prank(epochManagerEnabler);
epochManager.initializeSystem(firstEpochNumber, firstEpochBlock, firstElected);

blockTravel(vm, 43200);
timeTravel(vm, DAY);
travelEpochL2(vm);
}
}

Expand Down Expand Up @@ -469,3 +468,93 @@ contract EpochManagerTest_sendValidatorPayment is EpochManagerTest {
assertEq(epochManagerBalanceAfter, epochManagerBalanceBefore - paymentAmount);
}
}

contract EpochManagerTest_getEpochByNumber is EpochManagerTest {
function _travelAndProcess_N_L2Epoch(uint256 n) public {
for (uint256 i = 0; i < n; i++) {
travelEpochL2(vm);
epochManager.startNextEpochProcess();

address[] memory groups = new address[](0);
address[] memory lessers = new address[](0);
address[] memory greaters = new address[](0);
epochManager.finishNextEpochProcess(groups, lessers, greaters);
}
}

function test_shouldReturnTheEpochInfoOfSpecifiedEpoch() public {
uint256 numberOfEpochsToTravel = 9;

initializeEpochManagerSystem();
uint256 _startingEpochNumber = epochManager.getCurrentEpochNumber();

(
uint256 startingEpochFirstBlock,
uint256 startingEpochLastBlock,
uint256 startingEpochStartTimestamp,
uint256 startingEpochRewardBlock
) = epochManager.getCurrentEpoch();

_travelAndProcess_N_L2Epoch(numberOfEpochsToTravel);

(
uint256 _firstBlock,
uint256 _lastBlock,
uint256 _startTimestamp,
uint256 _rewardBlock
) = epochManager.getEpochByNumber(_startingEpochNumber + numberOfEpochsToTravel);

assertEq(
startingEpochFirstBlock + (L2_BLOCK_IN_EPOCH * (numberOfEpochsToTravel + 1)) + 1,
_firstBlock
);
assertEq(_lastBlock, 0);
assertEq(startingEpochStartTimestamp + (DAY * (numberOfEpochsToTravel + 1)), _startTimestamp);
assertEq(_rewardBlock, 0);
}

function test_ReturnsHistoricalEpochInfoAfter_N_Epochs() public {
initializeEpochManagerSystem();
uint256 _startingEpochNumber = epochManager.getCurrentEpochNumber();
uint256 numberOfEpochsToTravel = 7;
(
uint256 _startingEpochFirstBlock,
uint256 _startingLastBlock,
uint256 _startingStartTimestamp,
uint256 _startingRewardBlock
) = epochManager.getCurrentEpoch();

_travelAndProcess_N_L2Epoch(numberOfEpochsToTravel);

(
uint256 _initialFirstBlock,
uint256 _initialLastBlock,
uint256 _initialStartTimestamp,
uint256 _initialRewardBlock
) = epochManager.getEpochByNumber(_startingEpochNumber);

assertEq(_initialFirstBlock, _startingEpochFirstBlock);
assertEq(_initialLastBlock, _startingLastBlock + (L2_BLOCK_IN_EPOCH * 2) + firstEpochBlock);
assertEq(_initialStartTimestamp, _startingStartTimestamp);
assertEq(
_initialRewardBlock,
_startingRewardBlock + (L2_BLOCK_IN_EPOCH * 2) + firstEpochBlock + 1
);
}

function test_ReturnsZeroForFutureEpochs() public {
initializeEpochManagerSystem();

(
uint256 _firstBlock,
uint256 _lastBlock,
uint256 _startTimestamp,
uint256 _rewardBlock
) = epochManager.getEpochByNumber(500);

assertEq(_firstBlock, 0);
assertEq(_lastBlock, 0);
assertEq(_startTimestamp, 0);
assertEq(_rewardBlock, 0);
}
}
17 changes: 13 additions & 4 deletions packages/protocol/test-sol/utils08.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
pragma solidity >=0.5.13 <0.9.0;

import "celo-foundry-8/Test.sol";
import { TestConstants } from "@test-sol/constants.sol";

contract Utils08 {
contract Utils08 is TestConstants {
uint256 public constant secondsInOneBlock = 5;

function timeTravel(Vm vm, uint256 timeDelta) public {
Expand All @@ -20,12 +21,20 @@ contract Utils08 {
timeTravel(vm, timeDelta);
}

// This function can be also found in OpenZeppelin's library, but in a newer version than the one
function compareStrings(string memory a, string memory b) public pure returns (bool) {
return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))));
// XXX: this function only increases the block number and timestamp, but does not actually change epoch.
// XXX: you must start and finish epoch processing to change epochs.
function travelEpochL2(Vm vm) public {
uint256 blocksInEpoch = L2_BLOCK_IN_EPOCH;
blockTravel(vm, blocksInEpoch);
timeTravel(vm, DAY);
}

function whenL2(Vm vm) public {
vm.etch(0x4200000000000000000000000000000000000018, abi.encodePacked(bytes1(0x01)));
}

// This function can be also found in OpenZeppelin's library, but in a newer version than the one
function compareStrings(string memory a, string memory b) public pure returns (bool) {
return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))));
}
}

0 comments on commit aa92315

Please sign in to comment.