Skip to content
This repository has been archived by the owner on Jan 11, 2024. It is now read-only.

Update epoch processing #155

Merged
merged 6 commits into from
Jul 25, 2023
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
15 changes: 15 additions & 0 deletions src/gateway/GatewayGetterFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,19 @@ contract GatewayGetterFacet {
function majorityPercentage() public view returns (uint64) {
return LibVoting.majorityPercentage();
}

/// @notice returns the list of registered subnets in IPC
/// @return subnet - the list of subnets
function listSubnets() external view returns (Subnet[] memory) {
uint256 size = s.subnetKeys.length;
Subnet[] memory out = new Subnet[](size);
for (uint256 i = 0; i < size; ) {
bytes32 key = s.subnetKeys[i];
out[i] = s.subnets[key];
unchecked {
++i;
}
}
return out;
}
}
5 changes: 4 additions & 1 deletion src/gateway/GatewayManagerFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ contract GatewayManagerFacet is GatewayActorModifiers, ReentrancyGuard {
s.initialized = true;
}

/// @notice register a subnet in the gateway. called by a subnet when it reaches the threshold stake
/// @notice register a subnet in the gateway. It is called by a subnet when it reaches the threshold stake
function register() external payable {
if (msg.value < s.minStake) {
revert NotEnoughFunds();
Expand All @@ -49,6 +49,9 @@ contract GatewayManagerFacet is GatewayActorModifiers, ReentrancyGuard {
subnet.stake = msg.value;
subnet.status = Status.Active;
subnet.genesisEpoch = block.number;

s.subnetKeys.push(subnetId.toHash());

s.totalSubnets += 1;
}

Expand Down
6 changes: 3 additions & 3 deletions src/lib/ExecutableQueueHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import {ExecutableQueue} from "../structs/ExecutableQueue.sol";

library ExecutableQueueHelper {
function push(ExecutableQueue storage queue, uint64 epoch) public {
if (epoch == 0) {
if (epoch == queue.genesisEpoch) {
return;
}

if (queue.first == 0 || queue.first > epoch) {
if (queue.first == queue.genesisEpoch || queue.first > epoch) {
queue.first = epoch;
}
if (queue.last == 0 || queue.last < epoch) {
if (queue.last == queue.genesisEpoch || queue.last < epoch) {
queue.last = epoch;
}

Expand Down
2 changes: 2 additions & 0 deletions src/lib/LibGatewayActorStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ struct GatewayActorStorage {
/// @notice List of subnets
/// SubnetID => Subnet
mapping(bytes32 => Subnet) subnets;
/// @notice Keys of the registered subnets. Useful to iterate through them
bytes32[] subnetKeys;
/// @notice bottom-up period in number of epochs for the subnet
uint64 bottomUpCheckPeriod;
/// @notice Postbox keeps track of all the cross-net messages triggered by
Expand Down
12 changes: 8 additions & 4 deletions src/lib/LibVoting.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ struct VotingStorage {
uint64 lastVotingExecutedEpoch;
/// @notice Initial epoch number
uint64 genesisEpoch;
/// @notice Percentage of majority
uint8 majorityPercentage;
/// @notice Checkpoint submission period
uint64 submissionPeriod;
/// @notice Contains the executable epochs that are ready to be executed, but has yet to be executed.
/// This usually happens when previous submission epoch has not executed, but the next submission
Expand Down Expand Up @@ -51,10 +53,11 @@ library LibVoting {
if (epoch <= s.lastVotingExecutedEpoch) {
revert EpochAlreadyExecuted();
}
if (epoch > s.genesisEpoch) {
if ((epoch - s.genesisEpoch) % s.submissionPeriod != 0) {
revert EpochNotVotable();
}
if (epoch < s.genesisEpoch) {
revert EpochNotVotable();
}
if ((epoch - s.genesisEpoch) % s.submissionPeriod != 0) {
revert EpochNotVotable();
}
}

Expand All @@ -73,6 +76,7 @@ library LibVoting {
function initGenesisEpoch(uint64 genesisEpoch) internal {
VotingStorage storage s = votingStorage();
s.genesisEpoch = genesisEpoch;
s.executableQueue.genesisEpoch = genesisEpoch;
}

/// @notice method that gives the epoch for a given block number and checkpoint period
Expand Down
1 change: 1 addition & 0 deletions src/structs/ExecutableQueue.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity 0.8.19;

struct ExecutableQueue {
uint64 genesisEpoch; // genesis epoch
uint64 period; // number of blocks per epoch
uint64 first; // next epoch
uint64 last; // last epoch
Expand Down
15 changes: 15 additions & 0 deletions test/ExecutableQueueHelper.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ contract ExecutableQueueHelperTest is Test {

function setUp() public {
queue.period = BLOCKS_PER_EPOCH;
queue.genesisEpoch = 0;
}

function test_Push_Works_ZeroEpoch() public {
Expand All @@ -27,6 +28,20 @@ contract ExecutableQueueHelperTest is Test {
require(queue.epochs[0] == false);
}

function test_Push_Works_GenesisEpochInvalid() public {
queue.genesisEpoch = 10;
queue.push(10);

require(queue.epochs[10] == false);
}

function test_Push_Works_NonGenesisEpochValid() public {
queue.genesisEpoch = 10;
queue.push(11);

require(queue.epochs[11]);
}

function test_Push_Works_OneEpoch() public {
_assertPush(EPOCH_ONE);

Expand Down
Loading