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

feat(contracts): support validator system V2 from genesis #322

Merged
merged 1 commit into from
May 21, 2024
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
feat(contracts): support validator system V2 from genesis
  • Loading branch information
seolaoh committed May 21, 2024
commit cffe3ed9914971a35235adf7162e092846ec6a77
90 changes: 45 additions & 45 deletions kroma-bindings/bindings/l2outputoracle.go

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions kroma-bindings/bindings/l2outputoracle_more.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion kroma-bindings/bindings/validatormanager.go

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions kroma-bindings/bindings/validatormanager_more.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion kroma-bindings/bindings/validatorpool.go

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions kroma-bindings/bindings/validatorpool_more.go

Large diffs are not rendered by default.

270 changes: 135 additions & 135 deletions packages/contracts/.gas-snapshot

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions packages/contracts/.storage-layout
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,14 @@
➡ contracts/L1/L2OutputOracle.sol:L2OutputOracle
=======================

| Name | Type | Slot | Offset | Bytes | Contract |
|----------------------------|---------------------------------|------|--------|-------|------------------------------------------------|
| _initialized | uint8 | 0 | 0 | 1 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
| _initializing | bool | 0 | 1 | 1 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
| startingBlockNumber | uint256 | 1 | 0 | 32 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
| startingTimestamp | uint256 | 2 | 0 | 32 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
| l2Outputs | struct Types.CheckpointOutput[] | 3 | 0 | 32 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
| latestFinalizedOutputIndex | uint256 | 4 | 0 | 32 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
| Name | Type | Slot | Offset | Bytes | Contract |
|-------------------------|---------------------------------|------|--------|-------|------------------------------------------------|
| _initialized | uint8 | 0 | 0 | 1 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
| _initializing | bool | 0 | 1 | 1 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
| startingBlockNumber | uint256 | 1 | 0 | 32 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
| startingTimestamp | uint256 | 2 | 0 | 32 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
| l2Outputs | struct Types.CheckpointOutput[] | 3 | 0 | 32 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
| nextFinalizeOutputIndex | uint256 | 4 | 0 | 32 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |

=======================
➡ contracts/L1/KromaPortal.sol:KromaPortal
Expand Down
20 changes: 10 additions & 10 deletions packages/contracts/contracts/L1/L2OutputOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ contract L2OutputOracle is Initializable, ISemver {
Types.CheckpointOutput[] internal l2Outputs;

/**
* @notice The output index of the latest finalized output.
* @notice The output index of the next finalization target output.
*/
uint256 public latestFinalizedOutputIndex;
uint256 public nextFinalizeOutputIndex;

/**
* @notice Emitted when an output is submitted.
Expand Down Expand Up @@ -279,26 +279,26 @@ contract L2OutputOracle is Initializable, ISemver {
}

/**
* @notice Updates the latest finalized output index. This function may only be called by the
* validator pool contract before terminated, after that by the validator manager
* @notice Updates the next output index to be finalized. This function may only be called by
* the validator pool contract before terminated, after that by the validator manager
* contract.
*
* @param _outputIndex Index of the latest finalized output.
* @param _outputIndex Index of the next output to be finalized.
*/
function setLatestFinalizedOutputIndex(uint256 _outputIndex) external {
if (VALIDATOR_POOL.isTerminated(_outputIndex)) {
function setNextFinalizeOutputIndex(uint256 _outputIndex) external {
if (VALIDATOR_POOL.isTerminated(_outputIndex - 1)) {
require(
msg.sender == address(VALIDATOR_MANAGER),
"L2OutputOracle: only the validator manager contract can set latest finalized output index"
"L2OutputOracle: only the validator manager contract can set next finalize output index"
);
} else {
require(
msg.sender == address(VALIDATOR_POOL),
"L2OutputOracle: only the validator pool contract can set latest finalized output index"
"L2OutputOracle: only the validator pool contract can set next finalize output index"
);
}

latestFinalizedOutputIndex = _outputIndex;
nextFinalizeOutputIndex = _outputIndex;
}

/**
Expand Down
16 changes: 9 additions & 7 deletions packages/contracts/contracts/L1/ValidatorManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,9 @@ contract ValidatorManager is ISemver, IValidatorManager {
}

// Select the next priority validator.
_updatePriorityValidator();
unchecked {
_updatePriorityValidator();
}
}

/**
Expand Down Expand Up @@ -302,7 +304,7 @@ contract ValidatorManager is ISemver, IValidatorManager {

_sendToJail(loser);

if (L2_ORACLE.latestFinalizedOutputIndex() < outputIndex) {
if (L2_ORACLE.nextFinalizeOutputIndex() <= outputIndex) {
// If output is not rewarded yet, add slashing asset to the pending challenge reward.
unchecked {
_pendingChallengeReward[outputIndex] += challengeReward;
Expand Down Expand Up @@ -490,7 +492,7 @@ contract ValidatorManager is ISemver, IValidatorManager {
* @return Whether the reward distribution is done at least once or not.
*/
function _distributeReward() private returns (bool) {
uint256 outputIndex = L2_ORACLE.latestFinalizedOutputIndex() + 1;
uint256 outputIndex = L2_ORACLE.nextFinalizeOutputIndex();
uint256 latestOutputIndex = L2_ORACLE.latestOutputIndex();

if (!L2_ORACLE.VALIDATOR_POOL().isTerminated(outputIndex)) {
Expand Down Expand Up @@ -539,7 +541,7 @@ contract ValidatorManager is ISemver, IValidatorManager {
}

if (finalizedOutputNum > 0) {
L2_ORACLE.setLatestFinalizedOutputIndex(outputIndex - 1);
L2_ORACLE.setNextFinalizeOutputIndex(outputIndex);

return true;
}
Expand Down Expand Up @@ -600,11 +602,11 @@ contract ValidatorManager is ISemver, IValidatorManager {
*/
function _updatePriorityValidator() private {
uint120 weightSum = activatedValidatorTotalWeight();
uint256 nextFinalizeOutputIndex = L2_ORACLE.nextFinalizeOutputIndex();

if (weightSum > 0) {
uint256 latestFinalizedOutputIndex = L2_ORACLE.latestFinalizedOutputIndex();
if (weightSum > 0 && nextFinalizeOutputIndex > 0) {
sm-stack marked this conversation as resolved.
Show resolved Hide resolved
Types.CheckpointOutput memory output = L2_ORACLE.getL2Output(
latestFinalizedOutputIndex
nextFinalizeOutputIndex - 1
);

uint120 weight = uint120(
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts/contracts/L1/ValidatorPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,8 @@ contract ValidatorPool is ReentrancyGuardUpgradeable, ISemver {
nextUnbondOutputIndex = outputIndex;
}

// Set the latest finalized output index in L2OutputOracle.
L2_ORACLE.setLatestFinalizedOutputIndex(outputIndex - 1);
// Set the next output index to be finalized in L2OutputOracle.
L2_ORACLE.setNextFinalizeOutputIndex(outputIndex);

return true;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts/contracts/test/AssetManager.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,12 @@ contract AssetManagerTest is ValidatorSystemUpgrade_Initializer {
// KRO bridged from L2 Validator Reward Vault
kro.transfer(address(assetManager), 1e22);

// Submit until terminateOutputIndex and set it latest finalized output
// Submit until terminateOutputIndex and set next output index to be finalized after it
for (uint256 i = mockOracle.nextOutputIndex(); i <= terminateOutputIndex; i++) {
_submitOutputRoot(pool.nextValidator());
}
vm.warp(mockOracle.finalizedAt(terminateOutputIndex));
mockOracle.mockSetLatestFinalizedOutputIndex(terminateOutputIndex);
mockOracle.mockSetNextFinalizeOutputIndex(terminateOutputIndex + 1);
}

function _submitOutputRoot(address _validator) internal {
Expand Down
40 changes: 13 additions & 27 deletions packages/contracts/contracts/test/L2OutputOracle.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -482,50 +482,36 @@ contract L2OutputOracle_ValidatorSystemUpgrade_Test is ValidatorSystemUpgrade_In
oracle.submitL2Output(outputRoot, nextBlockNumber, 0, 0);
}

function test_setLatestFinalizedOutputIndex_succeeds() external {
function test_setNextFinalizeOutputIndex_succeeds() external {
// Only ValidatorPool can set finalized output before upgrade
uint256 outputIndex = oracle.latestOutputIndex();
vm.prank(address(pool));
oracle.setLatestFinalizedOutputIndex(outputIndex);
oracle.setNextFinalizeOutputIndex(1);
assertEq(oracle.nextFinalizeOutputIndex(), 1);

assertEq(oracle.latestFinalizedOutputIndex(), outputIndex);

// Submit more outputs to progress after upgrade
for (uint256 i = oracle.nextOutputIndex(); i <= terminateOutputIndex + 1; i++) {
_submitL2OutputV1();
}
vm.prank(address(pool));
oracle.setNextFinalizeOutputIndex(terminateOutputIndex + 1);
assertEq(oracle.nextFinalizeOutputIndex(), terminateOutputIndex + 1);

// Now only ValidatorManager can set finalized output after upgrade
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS());
outputIndex = oracle.latestOutputIndex();
vm.prank(address(valMgr));
oracle.setLatestFinalizedOutputIndex(outputIndex);

assertEq(oracle.latestFinalizedOutputIndex(), outputIndex);
oracle.setNextFinalizeOutputIndex(terminateOutputIndex + 2);
assertEq(oracle.nextFinalizeOutputIndex(), terminateOutputIndex + 2);
}

function test_setLatestFinalizedOutputIndex_wrongCaller_reverts() external {
function test_setNextFinalizeOutputIndex_wrongCaller_reverts() external {
// Only ValidatorPool can set finalized output before upgrade
uint256 outputIndex = oracle.latestOutputIndex();
vm.prank(address(valMgr));
vm.expectRevert(
"L2OutputOracle: only the validator pool contract can set latest finalized output index"
"L2OutputOracle: only the validator pool contract can set next finalize output index"
);
oracle.setLatestFinalizedOutputIndex(outputIndex);

// Submit more outputs to progress after upgrade
for (uint256 i = oracle.nextOutputIndex(); i <= terminateOutputIndex + 1; i++) {
_submitL2OutputV1();
}
oracle.setNextFinalizeOutputIndex(1);

// Now only ValidatorManager can set finalized output after upgrade
vm.warp(block.timestamp + oracle.FINALIZATION_PERIOD_SECONDS());
outputIndex = oracle.latestOutputIndex();
vm.prank(address(pool));
vm.expectRevert(
"L2OutputOracle: only the validator manager contract can set latest finalized output index"
"L2OutputOracle: only the validator manager contract can set next finalize output index"
);
oracle.setLatestFinalizedOutputIndex(outputIndex);
oracle.setNextFinalizeOutputIndex(terminateOutputIndex + 2);
}
}

Expand Down
18 changes: 9 additions & 9 deletions packages/contracts/contracts/test/ValidatorManager.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ contract MockL2OutputOracle is L2OutputOracle {
l2Outputs[outputIndex].outputRoot = bytes32(0);
}

function mockSetLatestFinalizedOutputIndex(uint256 l2OutputIndex) external {
latestFinalizedOutputIndex = l2OutputIndex;
function mockSetNextFinalizeOutputIndex(uint256 l2OutputIndex) external {
nextFinalizeOutputIndex = l2OutputIndex;
}
}

Expand Down Expand Up @@ -144,14 +144,14 @@ contract ValidatorManagerTest is ValidatorSystemUpgrade_Initializer {

VKRO_PER_KGH = assetMan.VKRO_PER_KGH();

// Submit until terminateOutputIndex and set it latest finalized output
// Submit until terminateOutputIndex and set next output index to be finalized after it
vm.prank(trusted);
pool.deposit{ value: trusted.balance }();
for (uint256 i = oracle.nextOutputIndex(); i <= terminateOutputIndex; i++) {
_submitL2OutputV1();
}
vm.warp(oracle.finalizedAt(terminateOutputIndex));
mockOracle.mockSetLatestFinalizedOutputIndex(terminateOutputIndex);
mockOracle.mockSetNextFinalizeOutputIndex(terminateOutputIndex + 1);
}

function test_constructor_succeeds() external {
Expand Down Expand Up @@ -388,7 +388,7 @@ contract ValidatorManagerTest is ValidatorSystemUpgrade_Initializer {
validatorReward
);

assertEq(oracle.latestFinalizedOutputIndex(), terminateOutputIndex + 1);
assertEq(oracle.nextFinalizeOutputIndex(), terminateOutputIndex + 2);
}

function test_afterSubmitL2Output_updatePriorityValidator_succeeds() external {
Expand All @@ -403,8 +403,8 @@ contract ValidatorManagerTest is ValidatorSystemUpgrade_Initializer {
// Submit the first output which interacts with ValidatorManager
_submitL2OutputV2(false);

// Check if lastest finalized output is not updated
assertEq(oracle.latestFinalizedOutputIndex(), terminateOutputIndex);
// Check if next finalize output is not updated
assertEq(oracle.nextFinalizeOutputIndex(), terminateOutputIndex + 1);
// Check if next priority validator is set in ValidatorManager
address nextValidator = mockValMgr.nextPriorityValidator();
assertTrue(nextValidator != address(0));
Expand All @@ -416,8 +416,8 @@ contract ValidatorManagerTest is ValidatorSystemUpgrade_Initializer {
_submitL2OutputV2(true);
vm.stopPrank();

// Check if lastest finalized output is updated
assertEq(oracle.latestFinalizedOutputIndex(), terminateOutputIndex + 1);
// Check if next finalize output is updated
assertEq(oracle.nextFinalizeOutputIndex(), terminateOutputIndex + 2);

// Submit 10 outputs
uint256 tries = 10;
Expand Down
14 changes: 7 additions & 7 deletions packages/contracts/contracts/test/ValidatorPool.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ contract ValidatorPoolTest is L2OutputOracle_Initializer {
emit Unbonded(0, firstOutput.submitter, uint128(firstBond.amount));
vm.expectCall(
address(oracle),
abi.encodeWithSelector(L2OutputOracle.setLatestFinalizedOutputIndex.selector, 0)
abi.encodeWithSelector(L2OutputOracle.setNextFinalizeOutputIndex.selector, 1)
);
pool.createBond(nextOutputIndex, expiresAt);
assertEq(pool.balanceOf(firstOutput.submitter), requiredBondAmount);
Expand Down Expand Up @@ -391,8 +391,8 @@ contract ValidatorPoolTest is L2OutputOracle_Initializer {
vm.expectCall(
address(oracle),
abi.encodeWithSelector(
L2OutputOracle.setLatestFinalizedOutputIndex.selector,
outputIndex
L2OutputOracle.setNextFinalizeOutputIndex.selector,
outputIndex + 1
)
);
vm.prank(trusted);
Expand Down Expand Up @@ -465,8 +465,8 @@ contract ValidatorPoolTest is L2OutputOracle_Initializer {
vm.expectCall(
address(oracle),
abi.encodeWithSelector(
L2OutputOracle.setLatestFinalizedOutputIndex.selector,
secondOutputIndex
L2OutputOracle.setNextFinalizeOutputIndex.selector,
secondOutputIndex + 1
)
);
vm.prank(trusted);
Expand Down Expand Up @@ -518,8 +518,8 @@ contract ValidatorPoolTest is L2OutputOracle_Initializer {
bond = pool.getBond(tries - 1);
assertEq(bond.amount, requiredBondAmount);

// check if latest finalized output index is set correctly
assertEq(oracle.latestFinalizedOutputIndex(), outputIndex - 1);
// check if next finalize output index is set correctly
assertEq(oracle.nextFinalizeOutputIndex(), outputIndex);
}

function test_unbond_notExpired_reverts() external {
Expand Down
Loading