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

fix(protocol): fix cooldown/proof window caused by pausing (TKO-12) #15585

Merged
merged 4 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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: 4 additions & 0 deletions packages/protocol/contracts/L1/TaikoData.sol
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ library TaikoData {
uint64 numBlocks;
uint64 lastVerifiedBlockId;
bool provingPaused;
uint8 __reserved1;
uint16 __reserved2;
uint32 __reserved3;
uint64 lastUnpausedAt;
}

/// @dev Struct holding the state variables for the {TaikoL1} contract.
Expand Down
11 changes: 11 additions & 0 deletions packages/protocol/contracts/L1/TaikoL1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ contract TaikoL1 is
LibVerifying.verifyBlocks(state, getConfig(), AddressResolver(this), maxBlocksToVerify);
}

function unpause() public override {
OwnerUUPSUpgradable.unpause();
state.slotB.lastUnpausedAt = uint64(block.timestamp);
}

/// @notice Pause block proving.
/// @param pause True if paused.
function pauseProving(bool pause) external onlyOwner {
Expand Down Expand Up @@ -242,4 +247,10 @@ contract TaikoL1 is
function isConfigValid() public view returns (bool) {
return LibVerifying.isConfigValid(getConfig());
}

function _authorizePause(address) internal override {
if (msg.sender != owner() && msg.sender != resolve("rollup_watchdog", true)) {
revert L1_UNAUTHORIZED();
}
}
}
9 changes: 8 additions & 1 deletion packages/protocol/contracts/L1/libs/LibProving.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pragma solidity 0.8.20;

import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import "../../common/AddressResolver.sol";
import "../../libs/LibMath.sol";
import "../tiers/ITierProvider.sol";
import "../verifiers/IVerifier.sol";
import "../TaikoData.sol";
Expand All @@ -25,6 +26,8 @@ import "./LibUtils.sol";
/// @notice A library for handling block contestation and proving in the Taiko
/// protocol.
library LibProving {
using LibMath for uint256;

bytes32 public constant RETURN_LIVENESS_BOND = keccak256("RETURN_LIVENESS_BOND");
// Warning: Any events defined here must also be defined in TaikoEvents.sol.

Expand Down Expand Up @@ -335,7 +338,11 @@ library LibProving {
revert L1_ALREADY_PROVED();
}

if (tid == 1 && ts.tier == 0 && block.timestamp <= ts.timestamp + tier.provingWindow) {
if (
tid == 1 && ts.tier == 0
&& block.timestamp
<= uint256(ts.timestamp).max(state.slotB.lastUnpausedAt) + tier.provingWindow
) {
// For the first transition, (1) if the previous prover is
// still the assigned prover, we exclusively grant permission to
// the assigned approver to re-prove the block, (2) unless the
Expand Down
9 changes: 7 additions & 2 deletions packages/protocol/contracts/L1/libs/LibProvingAlt.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pragma solidity 0.8.20;

import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import "../../common/AddressResolver.sol";
import "../../libs/LibMath.sol";
import "../tiers/ITierProvider.sol";
import "../verifiers/IVerifier.sol";
import "../TaikoData.sol";
Expand All @@ -25,6 +26,8 @@ import "./LibUtils.sol";
/// @notice An alternative library for handling block contestation and proving in the Taiko
/// protocol.
library LibProvingAlt {
using LibMath for uint256;

bytes32 public constant RETURN_LIVENESS_BOND = keccak256("RETURN_LIVENESS_BOND");
// Warning: Any events defined here must also be defined in TaikoEvents.sol.

Expand Down Expand Up @@ -118,7 +121,7 @@ library LibProvingAlt {
ITierProvider.Tier memory tier =
ITierProvider(resolver.resolve("tier_provider", false)).getTier(proof.tier);

_checkProverPermission(blk, ts, tid, tier);
_checkProverPermission(state, blk, ts, tid, tier);

// We must verify the proof, and any failure in proof verification will
// result in a revert.
Expand Down Expand Up @@ -373,6 +376,7 @@ library LibProvingAlt {

/// @dev Check the msg.sender (the new prover) against the block's assigned prover.
function _checkProverPermission(
TaikoData.State storage state,
TaikoData.Block storage blk,
TaikoData.TransitionState storage ts,
uint32 tid,
Expand All @@ -384,7 +388,8 @@ library LibProvingAlt {
// The highest tier proof can always submit new proofs
if (tier.contestBond == 0) return;

bool inProvingWindow = block.timestamp <= ts.timestamp + tier.provingWindow;
bool inProvingWindow = uint256(ts.timestamp).max(state.slotB.lastUnpausedAt)
+ tier.provingWindow >= block.timestamp;
bool isAssignedPover = msg.sender == blk.assignedProver;

// The assigned prover can only submit the very first transition.
Expand Down
5 changes: 4 additions & 1 deletion packages/protocol/contracts/L1/libs/LibVerifying.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pragma solidity 0.8.20;

import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import "../../common/AddressResolver.sol";
import "../../libs/LibMath.sol";
import "../../signal/ISignalService.sol";
import "../tiers/ITierProvider.sol";
import "../TaikoData.sol";
Expand All @@ -24,6 +25,8 @@ import "./LibUtils.sol";
/// @title LibVerifying
/// @notice A library for handling block verification in the Taiko protocol.
library LibVerifying {
using LibMath for uint256;

// Warning: Any events defined here must also be defined in TaikoEvents.sol.
event BlockVerified(
uint256 indexed blockId,
Expand Down Expand Up @@ -166,7 +169,7 @@ library LibVerifying {
}
if (
uint256(ITierProvider(tierProvider).getTier(ts.tier).cooldownWindow)
+ ts.timestamp > block.timestamp
+ uint256(ts.timestamp).max(state.slotB.lastUnpausedAt) > block.timestamp
) {
// If cooldownWindow is 0, the block can theoretically
// be proved and verified within the same L1 block.
Expand Down
9 changes: 6 additions & 3 deletions packages/protocol/contracts/common/OwnerUUPSUpgradable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,14 @@ abstract contract OwnerUUPSUpgradable is UUPSUpgradeable, OwnableUpgradeable {
_disableInitializers();
}

function pause() external whenNotPaused onlyOwner {
function pause() public virtual whenNotPaused {
_authorizePause(msg.sender);
_paused = _TRUE;
emit Paused(msg.sender);
}

function unpause() external whenPaused onlyOwner {
function unpause() public virtual whenPaused {
_authorizePause(msg.sender);
_paused = _FALSE;
emit Unpaused(msg.sender);
}
Expand All @@ -71,7 +73,8 @@ abstract contract OwnerUUPSUpgradable is UUPSUpgradeable, OwnableUpgradeable {
return _paused == _TRUE;
}

function _authorizeUpgrade(address) internal override onlyOwner { }
function _authorizeUpgrade(address) internal virtual override onlyOwner { }
function _authorizePause(address) internal virtual onlyOwner { }

/// @notice Initializes the contract with an address manager.
// solhint-disable-next-line func-name-mixedcase
Expand Down
Loading