Skip to content

Commit

Permalink
fix(protocol): fix cooldown/proof window caused by pausing (TKO-12) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
dantaik authored Jan 29, 2024
1 parent bfcab5e commit b2176d3
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 11 deletions.
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();
}
}
}
21 changes: 16 additions & 5 deletions 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 @@ -58,11 +61,15 @@ library LibProving {
error L1_NOT_ASSIGNED_PROVER();
error L1_UNEXPECTED_TRANSITION_TIER();

function pauseProving(TaikoData.State storage state, bool pause) external {
if (state.slotB.provingPaused == pause) revert L1_INVALID_PAUSE_STATUS();
function pauseProving(TaikoData.State storage state, bool toPause) external {
if (state.slotB.provingPaused == toPause) revert L1_INVALID_PAUSE_STATUS();

state.slotB.provingPaused = toPause;

state.slotB.provingPaused = pause;
emit ProvingPaused(pause);
if (!toPause) {
state.slotB.lastUnpausedAt = uint64(block.timestamp);
}
emit ProvingPaused(toPause);
}

/// @dev Proves or contests a block transition.
Expand Down Expand Up @@ -335,7 +342,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

0 comments on commit b2176d3

Please sign in to comment.