diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol index 9e93278828c..d7f2444dc9e 100644 --- a/packages/protocol/contracts/L1/TaikoData.sol +++ b/packages/protocol/contracts/L1/TaikoData.sol @@ -95,7 +95,7 @@ library TaikoData { } /// @dev Struct representing state transition data. - /// 10 slots reserved for upgradability, 6 slots used. + /// 6 slots used. struct TransitionState { bytes32 key; // slot 1, only written/read for the 1st state transition. bytes32 blockHash; // slot 2 @@ -106,7 +106,6 @@ library TaikoData { uint96 contestBond; uint64 timestamp; // slot 6 (90 bits) uint16 tier; - uint8 __reserved1; } /// @dev Struct containing data required for verifying a block. diff --git a/packages/protocol/contracts/L1/libs/LibProving.sol b/packages/protocol/contracts/L1/libs/LibProving.sol index 210525f7ddb..cf89c40a120 100644 --- a/packages/protocol/contracts/L1/libs/LibProving.sol +++ b/packages/protocol/contracts/L1/libs/LibProving.sol @@ -18,6 +18,7 @@ library LibProving { ITierProvider.Tier minTier; bytes32 metaHash; address assignedProver; + uint96 livenessBond; uint64 slot; uint64 blockId; uint32 tid; @@ -125,6 +126,7 @@ library LibProving { local.blockId = blk.blockId; local.assignedProver = blk.assignedProver; + local.livenessBond = blk.livenessBond; local.metaHash = blk.metaHash; // Check the integrity of the block data. It's worth noting that in @@ -138,7 +140,7 @@ library LibProving { // blockHash and stateRoot open for later updates as higher-tier proofs // become available. In cases where a transition with the specified // parentHash does not exist, the transition ID (tid) will be set to 0. - TaikoData.TransitionState storage ts; + TaikoData.TransitionState memory ts; (local.tid, ts) = _fetchOrCreateTransition(_state, blk, _tran, local); // The new proof must meet or exceed the minimum tier required by the @@ -279,6 +281,8 @@ library LibProving { } ts.timestamp = uint64(block.timestamp); + _state.transitions[local.slot][local.tid] = ts; + return local.tier.maxBlocksToVerifyPerProof; } @@ -290,7 +294,7 @@ library LibProving { Local memory _local ) private - returns (uint32 tid_, TaikoData.TransitionState storage ts_) + returns (uint32 tid_, TaikoData.TransitionState memory ts_) { tid_ = LibUtils.getTransitionId(_state, _blk, _local.slot, _tran.parentHash); @@ -313,15 +317,7 @@ library LibProving { // Keep in mind that state.transitions are also reusable storage // slots, so it's necessary to reinitialize all transition fields // below. - ts_ = _state.transitions[_local.slot][tid_]; - ts_.blockHash = 0; - ts_.stateRoot = 0; - ts_.validityBond = 0; - ts_.contester = address(0); - ts_.contestBond = 1; // to save gas ts_.timestamp = _blk.proposedAt; - ts_.tier = 0; - ts_.__reserved1 = 0; if (tid_ == 1) { // This approach serves as a cost-saving technique for the @@ -343,19 +339,14 @@ library LibProving { // such changes would require additional if-else logic. ts_.prover = _local.assignedProver; } else { - // In scenarios where this transition is not the first one, we - // straightforwardly reset the transition prover to address - // zero. - ts_.prover = address(0); - // Furthermore, we index the transition for future retrieval. // It's worth emphasizing that this mapping for indexing is not // reusable. However, given that the majority of blocks will // only possess one transition — the correct one — we don't need // to be concerned about the cost in this case. - _state.transitionIds[_local.blockId][_tran.parentHash] = tid_; // There is no need to initialize ts.key here because it's only used when tid == 1 + _state.transitionIds[_local.blockId][_tran.parentHash] = tid_; } } else { // A transition with the provided parentHash has been located. @@ -376,7 +367,7 @@ library LibProving { // 6.5625. function _overrideWithHigherProof( TaikoData.Block storage _blk, - TaikoData.TransitionState storage _ts, + TaikoData.TransitionState memory _ts, TaikoData.Transition memory _tran, TaikoData.TierProof memory _proof, Local memory _local, @@ -411,17 +402,16 @@ library LibProving { // - 2) the transition is contested. reward = _rewardAfterFriction(_ts.validityBond); - uint256 livenessBond = _blk.livenessBond; - if (livenessBond != 0) { + if (_local.livenessBond != 0) { // After the first proof, the block's liveness bond will always be reset to 0. // This means liveness bond will be handled only once for any given block. _blk.livenessBond = 0; if (_returnLivenessBond(_local, _proof.data)) { - if (_blk.assignedProver == msg.sender) { - reward += livenessBond; + if (_local.assignedProver == msg.sender) { + reward += _local.livenessBond; } else { - _tko.transfer(_blk.assignedProver, livenessBond); + _tko.transfer(_local.assignedProver, _local.livenessBond); } } } @@ -436,7 +426,6 @@ library LibProving { } _ts.validityBond = _local.tier.validityBond; - _ts.contestBond = 1; // to save gas _ts.contester = address(0); _ts.prover = msg.sender; _ts.tier = _proof.tier; diff --git a/packages/protocol/test/L1/TaikoL1TestGroup1.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup1.t.sol index a9f8bd93f30..e5523931445 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup1.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup1.t.sol @@ -77,7 +77,6 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_OPTIMISTIC); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); // not zero assertEq(ts.prover, Bob); assertEq(ts.validityBond, tierOp.validityBond); assertEq(ts.timestamp, block.timestamp); @@ -105,7 +104,6 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_OPTIMISTIC); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); // not zero assertEq(ts.prover, Bob); assertEq(ts.validityBond, tierOp.validityBond); assertEq(ts.timestamp, provenAt); @@ -175,7 +173,6 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_OPTIMISTIC); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); // not zero assertEq(ts.prover, Taylor); assertEq(ts.validityBond, tierOp.validityBond); assertEq(ts.timestamp, block.timestamp); @@ -204,7 +201,6 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_OPTIMISTIC); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); // not zero assertEq(ts.prover, Taylor); assertEq(ts.validityBond, tierOp.validityBond); assertEq(ts.timestamp, provenAt); @@ -258,7 +254,6 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 2); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); // not zero assertEq(ts.prover, Taylor); assertEq(ts.validityBond, tierOp.validityBond); @@ -311,7 +306,6 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); // not zero assertEq(ts.prover, Bob); assertEq(ts.validityBond, tierOp.validityBond); @@ -365,7 +359,6 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 2); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); // not zero assertEq(ts.prover, Taylor); assertEq(ts.validityBond, tierOp.validityBond); @@ -435,7 +428,6 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_OPTIMISTIC); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); // not zero assertEq(ts.prover, Bob); assertEq(ts.validityBond, tierOp.validityBond); assertEq(ts.timestamp, block.timestamp); @@ -463,7 +455,6 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_OPTIMISTIC); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); // not zero assertEq(ts.prover, Bob); assertEq(ts.validityBond, tierOp.validityBond); assertEq(ts.timestamp, provenAt); diff --git a/packages/protocol/test/L1/TaikoL1TestGroup2.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup2.t.sol index 94f8a2f166d..92d9b4dbc00 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup2.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup2.t.sol @@ -78,7 +78,6 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_SGX); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); // not zero assertEq(ts.validityBond, tierSgx.validityBond); assertEq(ts.prover, William); assertEq(ts.timestamp, block.timestamp); // not zero @@ -108,7 +107,6 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { assertEq(ts.blockHash, blockHash); assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_SGX); - assertEq(ts.contestBond, 1); assertEq(ts.prover, William); assertEq(tko.balanceOf(William), 10_000 ether + tierOp.contestBond * 7 / 8); @@ -189,7 +187,6 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot2); assertEq(ts.tier, LibTiers.TIER_SGX); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); // not zero assertEq(ts.validityBond, tierSgx.validityBond); assertEq(ts.prover, William); assertEq(ts.timestamp, block.timestamp); @@ -218,7 +215,6 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot2); assertEq(ts.tier, LibTiers.TIER_SGX); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); // not zero assertEq(ts.validityBond, tierSgx.validityBond); assertEq(ts.prover, William); diff --git a/packages/protocol/test/L1/TaikoL1TestGroup3.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup3.t.sol index ee181cda4a0..69d2f215f1f 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup3.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup3.t.sol @@ -82,7 +82,6 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_SGX); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); // not zero assertEq(ts.validityBond, tierSgx.validityBond); assertEq(ts.prover, William); assertEq(ts.timestamp, block.timestamp); // not zero @@ -112,7 +111,6 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { assertEq(ts.blockHash, blockHash); assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_SGX); - assertEq(ts.contestBond, 1); assertEq(ts.prover, William); assertEq(tko.balanceOf(William), 10_000 ether + tierOp.contestBond * 7 / 8); @@ -197,7 +195,6 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot2); assertEq(ts.tier, LibTiers.TIER_SGX); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); // not zero assertEq(ts.validityBond, tierSgx.validityBond); assertEq(ts.prover, William); assertEq(ts.timestamp, block.timestamp); @@ -227,7 +224,6 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot2); assertEq(ts.tier, LibTiers.TIER_SGX); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); // not zero assertEq(ts.validityBond, tierSgx.validityBond); assertEq(ts.prover, William); diff --git a/packages/protocol/test/L1/TaikoL1TestGroup4.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup4.t.sol index 4c0cf35c3a4..d77857ba756 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup4.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup4.t.sol @@ -50,7 +50,6 @@ contract TaikoL1TestGroup4 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot2); assertEq(ts.tier, LibTiers.TIER_SGX); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); assertEq(ts.validityBond, tierSgx.validityBond); assertEq(ts.prover, Taylor); assertEq(ts.timestamp, block.timestamp); @@ -79,7 +78,6 @@ contract TaikoL1TestGroup4 is TaikoL1TestGroupBase { assertEq(ts.blockHash, blockHash2); assertEq(ts.stateRoot, stateRoot2); assertEq(ts.tier, LibTiers.TIER_SGX); - assertEq(ts.contestBond, 1); assertEq(ts.prover, Taylor); assertEq(tko.balanceOf(Taylor), 10_000 ether + tierOp.validityBond * 7 / 8); @@ -135,7 +133,6 @@ contract TaikoL1TestGroup4 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot2); assertEq(ts.tier, LibTiers.TIER_SGX); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); assertEq(ts.validityBond, tierSgx.validityBond); assertEq(ts.prover, Taylor); assertEq(ts.timestamp, block.timestamp); @@ -165,7 +162,6 @@ contract TaikoL1TestGroup4 is TaikoL1TestGroupBase { assertEq(ts.blockHash, blockHash2); assertEq(ts.stateRoot, stateRoot2); assertEq(ts.tier, LibTiers.TIER_SGX); - assertEq(ts.contestBond, 1); assertEq(ts.prover, Taylor); assertEq(tko.balanceOf(Taylor), 10_000 ether + tierOp.validityBond * 7 / 8); diff --git a/packages/protocol/test/L1/TaikoL1TestGroup5.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup5.t.sol index 7e263b24caf..552542702a6 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup5.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup5.t.sol @@ -42,7 +42,6 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_GUARDIAN); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); assertEq(ts.validityBond, 0); assertEq(ts.prover, address(gp)); assertEq(ts.timestamp, block.timestamp); @@ -83,7 +82,6 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot2); assertEq(ts.tier, LibTiers.TIER_GUARDIAN); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); assertEq(ts.validityBond, 0); assertEq(ts.prover, address(gp)); assertEq(ts.timestamp, block.timestamp); @@ -121,7 +119,6 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.blockHash, blockHash2); assertEq(ts.stateRoot, stateRoot2); assertEq(ts.tier, LibTiers.TIER_GUARDIAN); - assertEq(ts.contestBond, 1); assertEq(ts.prover, address(gp)); assertEq(tko.balanceOf(Bob), 10_000 ether); @@ -186,7 +183,6 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot2); assertEq(ts.tier, LibTiers.TIER_GUARDIAN); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); assertEq(ts.validityBond, 0); assertEq(ts.prover, address(gp)); assertEq(ts.timestamp, block.timestamp); @@ -212,7 +208,6 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.blockHash, blockHash2); assertEq(ts.stateRoot, stateRoot2); assertEq(ts.tier, LibTiers.TIER_GUARDIAN); - assertEq(ts.contestBond, 1); assertEq(ts.prover, address(gp)); assertEq(tko.balanceOf(Bob), 10_000 ether - tierOp.validityBond); @@ -280,7 +275,6 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot2); assertEq(ts.tier, LibTiers.TIER_GUARDIAN); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); assertEq(ts.validityBond, 0); assertEq(ts.prover, address(gp)); assertEq(ts.timestamp, block.timestamp); @@ -307,7 +301,6 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.blockHash, blockHash2); assertEq(ts.stateRoot, stateRoot2); assertEq(ts.tier, LibTiers.TIER_GUARDIAN); - assertEq(ts.contestBond, 1); assertEq(ts.prover, address(gp)); assertEq(tko.balanceOf(Bob), 10_000 ether - livenessBond); @@ -351,7 +344,6 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_GUARDIAN); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); assertEq(ts.validityBond, 0); assertEq(ts.prover, address(gp)); assertEq(ts.timestamp, block.timestamp); diff --git a/packages/protocol/test/L1/TaikoL1TestGroup6.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup6.t.sol index 012f7321f36..3241a3efef4 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup6.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup6.t.sol @@ -54,7 +54,6 @@ contract TaikoL1TestGroup6 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_SGX); assertEq(ts.contester, address(0)); - assertEq(ts.contestBond, 1); // not zero assertEq(ts.validityBond, tierSgx.validityBond); assertEq(ts.prover, Bob); assertEq(ts.timestamp, block.timestamp); // not zero @@ -82,7 +81,6 @@ contract TaikoL1TestGroup6 is TaikoL1TestGroupBase { assertEq(ts.blockHash, blockHash); assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_SGX); - assertEq(ts.contestBond, 1); assertEq(ts.prover, Bob); assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.contestBond);