diff --git a/packages/protocol/contract_layout.md b/packages/protocol/contract_layout.md index a195744f511..2158c4921f9 100644 --- a/packages/protocol/contract_layout.md +++ b/packages/protocol/contract_layout.md @@ -360,22 +360,6 @@ | __gap | uint256[46] | 355 | 0 | 1472 | contracts/tokenvault/BridgedERC1155.sol:BridgedERC1155 | ## AssignmentHook -| Name | Type | Slot | Offset | Bytes | Contract | -|----------------|-------------|------|--------|-------|------------------------------------------------------| -| _initialized | uint8 | 0 | 0 | 1 | contracts/L1/hooks/AssignmentHook.sol:AssignmentHook | -| _initializing | bool | 0 | 1 | 1 | contracts/L1/hooks/AssignmentHook.sol:AssignmentHook | -| __gap | uint256[50] | 1 | 0 | 1600 | contracts/L1/hooks/AssignmentHook.sol:AssignmentHook | -| _owner | address | 51 | 0 | 20 | contracts/L1/hooks/AssignmentHook.sol:AssignmentHook | -| __gap | uint256[49] | 52 | 0 | 1568 | contracts/L1/hooks/AssignmentHook.sol:AssignmentHook | -| _pendingOwner | address | 101 | 0 | 20 | contracts/L1/hooks/AssignmentHook.sol:AssignmentHook | -| __gap | uint256[49] | 102 | 0 | 1568 | contracts/L1/hooks/AssignmentHook.sol:AssignmentHook | -| addressManager | address | 151 | 0 | 20 | contracts/L1/hooks/AssignmentHook.sol:AssignmentHook | -| __gap | uint256[49] | 152 | 0 | 1568 | contracts/L1/hooks/AssignmentHook.sol:AssignmentHook | -| __reentry | uint8 | 201 | 0 | 1 | contracts/L1/hooks/AssignmentHook.sol:AssignmentHook | -| __paused | uint8 | 201 | 1 | 1 | contracts/L1/hooks/AssignmentHook.sol:AssignmentHook | -| lastUnpausedAt | uint64 | 201 | 2 | 8 | contracts/L1/hooks/AssignmentHook.sol:AssignmentHook | -| __gap | uint256[49] | 202 | 0 | 1568 | contracts/L1/hooks/AssignmentHook.sol:AssignmentHook | -| __gap | uint256[50] | 251 | 0 | 1600 | contracts/L1/hooks/AssignmentHook.sol:AssignmentHook | ## ERC20Airdrop | Name | Type | Slot | Offset | Bytes | Contract | diff --git a/packages/protocol/contracts/L1/ITaikoL1.sol b/packages/protocol/contracts/L1/ITaikoL1.sol index 2663c8b532e..ebf189497d9 100644 --- a/packages/protocol/contracts/L1/ITaikoL1.sol +++ b/packages/protocol/contracts/L1/ITaikoL1.sol @@ -10,14 +10,13 @@ interface ITaikoL1 { /// @param _params Block parameters, currently an encoded BlockParams object. /// @param _txList txList data if calldata is used for DA. /// @return meta_ The metadata of the proposed L2 block. - /// @return deposits_ The Ether deposits processed. function proposeBlock( bytes calldata _params, bytes calldata _txList ) external payable - returns (TaikoData.BlockMetadata memory meta_, TaikoData.EthDeposit[] memory deposits_); + returns (TaikoData.BlockMetadataV2 memory meta_); /// @notice Proves or contests a block transition. /// @param _blockId The index of the block to prove. This is also used to diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol index 518ef721b6c..bb49d7198b3 100644 --- a/packages/protocol/contracts/L1/TaikoData.sol +++ b/packages/protocol/contracts/L1/TaikoData.sol @@ -34,8 +34,9 @@ library TaikoData { // Group 4: Cross-chain sync // --------------------------------------------------------------------- // The max number of L2 blocks that can stay unsynced on L1 - uint8 blockSyncThreshold; + uint8 stateRootSyncInternal; bool checkEOAForCalldataDA; + uint64 forkHeight; } /// @dev Struct representing prover fees per given tier @@ -66,6 +67,13 @@ library TaikoData { bytes signature; } + struct BlockParamsV2 { + address coinbase; + bytes32 extraData; + bytes32 parentMetaHash; + bytes signature; + } + /// @dev Struct containing data only required for proving a block /// Note: On L2, `block.difficulty` is the pseudo name of /// `block.prevrandao`, which returns a random number provided by the layer @@ -84,7 +92,25 @@ library TaikoData { uint16 minTier; bool blobUsed; bytes32 parentMetaHash; - address sender; // a.k.a proposer + address sender; + } + + struct BlockMetadataV2 { + bytes32 l1Hash; + bytes32 difficulty; + bytes32 blobHash; //or txListHash (if Blob not yet supported) + bytes32 extraData; + bytes32 depositsHash; + address coinbase; // L2 coinbase, + uint64 id; + uint32 gasLimit; + uint64 timestamp; + uint64 l1Height; + uint16 minTier; + bool blobUsed; + bytes32 parentMetaHash; + address proposer; + uint96 livenessBond; } /// @dev Struct representing transition to be proven. @@ -114,11 +140,12 @@ library TaikoData { /// 3 slots used. struct Block { bytes32 metaHash; // slot 1 - address assignedProver; // slot 2 - uint96 livenessBond; + address assignedProver; // slot 2, DEPRECATED and will always be zero + uint96 livenessBond; // DEPRECATED and will always be zero uint64 blockId; // slot 3 uint64 proposedAt; // timestamp - uint64 proposedIn; // L1 block number, required/used by node/client. + uint48 proposedIn; // L1 block number, required/used by node/client. + bool livenessBondNotReturned; uint32 nextTransitionId; // The ID of the transaction that is used to verify this block. However, if // this block is not verified as the last block in a batch, verifiedTransitionId @@ -126,15 +153,6 @@ library TaikoData { uint32 verifiedTransitionId; } - /// @dev Struct representing an Ethereum deposit. - /// 2 slot used. Currently removed from protocol, but to be backwards compatible, the struct and - /// return values stayed for now. - struct EthDeposit { - address recipient; - uint96 amount; - uint64 id; - } - /// @dev Forge is only able to run coverage in case the contracts by default /// capable of compiling without any optimization (neither optimizer runs, /// no compiling --via-ir flag). diff --git a/packages/protocol/contracts/L1/TaikoErrors.sol b/packages/protocol/contracts/L1/TaikoErrors.sol index b5779fe8472..e471f70ad01 100644 --- a/packages/protocol/contracts/L1/TaikoErrors.sol +++ b/packages/protocol/contracts/L1/TaikoErrors.sol @@ -18,7 +18,6 @@ abstract contract TaikoErrors { error L1_INVALID_BLOCK_ID(); error L1_INVALID_CONFIG(); error L1_INVALID_GENESIS_HASH(); - error L1_INVALID_HOOK(); error L1_INVALID_PARAM(); error L1_INVALID_PAUSE_STATUS(); error L1_INVALID_PROVER(); diff --git a/packages/protocol/contracts/L1/TaikoEvents.sol b/packages/protocol/contracts/L1/TaikoEvents.sol index d64e492bf62..a7174375aa1 100644 --- a/packages/protocol/contracts/L1/TaikoEvents.sol +++ b/packages/protocol/contracts/L1/TaikoEvents.sol @@ -11,21 +11,11 @@ import "./TaikoData.sol"; /// L1 libraries. /// @custom:security-contact security@taiko.xyz abstract contract TaikoEvents { - /// @dev Emitted when a block is proposed. + // Warning: Any events defined here must also be defined in TaikoEvents.sol. + /// @notice Emitted when a block is proposed. /// @param blockId The ID of the proposed block. - /// @param assignedProver The block's assigned prover. - /// @param livenessBond The bond in Taiko token from the assigned prover. - /// @param meta The block metadata containing information about the proposed - /// block. - /// @param depositsProcessed Ether deposits processed. - event BlockProposed( - uint256 indexed blockId, - address indexed assignedProver, - uint96 livenessBond, - TaikoData.BlockMetadata meta, - TaikoData.EthDeposit[] depositsProcessed - ); - + /// @param meta The metadata of the proposed block. + event BlockProposedV2(uint256 indexed blockId, TaikoData.BlockMetadataV2 meta); /// @dev Emitted when a block is verified. /// @param blockId The ID of the verified block. /// @param prover The prover whose transition is used for verifying the diff --git a/packages/protocol/contracts/L1/TaikoL1.sol b/packages/protocol/contracts/L1/TaikoL1.sol index 9b8d5000e99..16b7134843e 100644 --- a/packages/protocol/contracts/L1/TaikoL1.sol +++ b/packages/protocol/contracts/L1/TaikoL1.sol @@ -76,12 +76,12 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents, TaikoErrors { whenNotPaused nonReentrant emitEventForClient - returns (TaikoData.BlockMetadata memory meta_, TaikoData.EthDeposit[] memory deposits_) + returns (TaikoData.BlockMetadataV2 memory meta_) { TaikoData.Config memory config = getConfig(); IERC20 tko = IERC20(resolve(LibStrings.B_TAIKO_TOKEN, false)); - (meta_, deposits_) = LibProposing.proposeBlock(state, tko, config, this, _params, _txList); + meta_ = LibProposing.proposeBlock(state, tko, config, this, _params, _txList); if (LibUtils.shouldVerifyBlocks(config, meta_.id, true) && !state.slotB.provingPaused) { LibVerifying.verifyBlocks(state, tko, config, this, config.maxBlocksToVerify); @@ -100,10 +100,12 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents, TaikoErrors { emitEventForClient { ( - TaikoData.BlockMetadata memory meta, + TaikoData.BlockMetadataV2 memory meta, TaikoData.Transition memory tran, TaikoData.TierProof memory proof - ) = abi.decode(_input, (TaikoData.BlockMetadata, TaikoData.Transition, TaikoData.TierProof)); + ) = abi.decode( + _input, (TaikoData.BlockMetadataV2, TaikoData.Transition, TaikoData.TierProof) + ); if (_blockId != meta.id) revert L1_INVALID_BLOCK_ID(); @@ -241,8 +243,9 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents, TaikoErrors { // read Taiko's gas limit to be 240_250_000. blockMaxGasLimit: 240_000_000, livenessBond: 250e18, // 250 Taiko token - blockSyncThreshold: 32, - checkEOAForCalldataDA: true + stateRootSyncInternal: 16, + checkEOAForCalldataDA: true, + forkHeight: 0 }); } diff --git a/packages/protocol/contracts/L1/hooks/AssignmentHook.sol b/packages/protocol/contracts/L1/hooks/AssignmentHook.sol deleted file mode 100644 index adef51ea434..00000000000 --- a/packages/protocol/contracts/L1/hooks/AssignmentHook.sol +++ /dev/null @@ -1,194 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.24; - -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; -import "../../common/EssentialContract.sol"; -import "../../common/LibStrings.sol"; -import "../../libs/LibAddress.sol"; -import "../ITaikoL1.sol"; -import "./IHook.sol"; - -/// @title AssignmentHook -/// @notice A hook that handles prover assignment verification and fee processing. -/// @custom:security-contact security@taiko.xyz -contract AssignmentHook is EssentialContract, IHook { - using LibAddress for address; - using SignatureChecker for address; - using SafeERC20 for IERC20; - - struct ProverAssignment { - address feeToken; - uint64 expiry; - uint64 maxBlockId; - uint64 maxProposedIn; - bytes32 metaHash; - bytes32 parentMetaHash; - TaikoData.TierFee[] tierFees; - bytes signature; - } - - struct Input { - ProverAssignment assignment; - uint256 tip; // A tip to L1 block builder - } - - event EtherPaymentFailed(address to, uint256 maxGas); - - /// @notice Max gas paying the prover. - /// @dev This should be large enough to prevent the worst cases for the prover. - /// To assure a trustless relationship between the proposer and the prover it's - /// the prover's job to make sure it can get paid within this limit. - uint256 public constant MAX_GAS_PAYING_PROVER = 50_000; - - uint256[50] private __gap; - - error HOOK_ASSIGNMENT_EXPIRED(); - error HOOK_ASSIGNMENT_INVALID_SIG(); - error HOOK_TIER_NOT_FOUND(); - - /// @notice Initializes the contract. - /// @param _owner The owner of this contract. msg.sender will be used if this value is zero. - /// @param _addressManager The address of the {AddressManager} contract. - function init(address _owner, address _addressManager) external initializer { - __Essential_init(_owner, _addressManager); - } - - /// @inheritdoc IHook - function onBlockProposed( - TaikoData.Block calldata _blk, - TaikoData.BlockMetadata calldata _meta, - bytes calldata _data - ) - external - payable - onlyFromNamed(LibStrings.B_TAIKO) - nonReentrant - { - // Note that - // - 'msg.sender' is the TaikoL1 contract address - // - 'block.coinbase' is the L1 block builder - // - 'meta.coinbase' is the L2 block proposer (chosen by block's proposer) - - Input memory input = abi.decode(_data, (Input)); - ProverAssignment memory assignment = input.assignment; - - // Check assignment validity - if ( - block.timestamp > assignment.expiry - || assignment.metaHash != 0 && _blk.metaHash != assignment.metaHash - || assignment.parentMetaHash != 0 && _meta.parentMetaHash != assignment.parentMetaHash - || assignment.maxBlockId != 0 && _meta.id > assignment.maxBlockId - || assignment.maxProposedIn != 0 && block.number > assignment.maxProposedIn - ) { - revert HOOK_ASSIGNMENT_EXPIRED(); - } - - // Hash the assignment with the blobHash, this hash will be signed by - // the prover, therefore, we add a string as a prefix. - - // msg.sender is taikoL1Address - bytes32 hash = hashAssignment( - assignment, msg.sender, _meta.sender, _blk.assignedProver, _meta.blobHash - ); - - if (!_blk.assignedProver.isValidSignatureNow(hash, assignment.signature)) { - revert HOOK_ASSIGNMENT_INVALID_SIG(); - } - - // Send the liveness bond to the Taiko contract - IERC20 tko = IERC20(resolve(LibStrings.B_TAIKO_TOKEN, false)); - - // Note that we don't have to worry about - // https://github.com/crytic/slither/wiki/Detector-Documentation#arbitrary-from-in-transferfrom - // as `assignedProver` has provided a signature above to authorize this hook. - tko.safeTransferFrom(_blk.assignedProver, msg.sender, _blk.livenessBond); - - // Find the prover fee using the minimal tier - uint256 proverFee = _getProverFee(assignment.tierFees, _meta.minTier); - - // The proposer irrevocably pays a fee to the assigned prover, either in - // Ether or ERC20 tokens. - if (assignment.feeToken == address(0)) { - // Paying Ether even when proverFee is 0 to trigger a potential receive() function call. - // Note that this payment may fail if it cost more gas - bool success = _blk.assignedProver.sendEther(proverFee, MAX_GAS_PAYING_PROVER, ""); - if (!success) emit EtherPaymentFailed(_blk.assignedProver, MAX_GAS_PAYING_PROVER); - } else if (proverFee != 0 && _meta.sender != _blk.assignedProver) { - // Paying ERC20 tokens - IERC20(assignment.feeToken).safeTransferFrom( - _meta.sender, _blk.assignedProver, proverFee - ); - } - - // block.coinbase can be address(0) in tests - if (input.tip != 0 && block.coinbase != address(0)) { - address(block.coinbase).sendEtherAndVerify(input.tip); - } - - // Send all remaining Ether back to TaikoL1 contract - if (address(this).balance != 0) { - msg.sender.sendEtherAndVerify(address(this).balance); - } - } - - /// @notice Hashes the prover assignment. - /// @param _assignment The prover assignment. - /// @param _taikoL1Address The address of the TaikoL1 contract. - /// @param _blockProposer The block proposer address. - /// @param _assignedProver The assigned prover address. - /// @param _blobHash The blob hash. - /// @return The hash of the prover assignment. - function hashAssignment( - ProverAssignment memory _assignment, - address _taikoL1Address, - address _blockProposer, - address _assignedProver, - bytes32 _blobHash - ) - public - view - returns (bytes32) - { - // split up into two parts otherwise stack is too deep - bytes32 hash = keccak256( - abi.encode( - _assignment.metaHash, - _assignment.parentMetaHash, - _assignment.feeToken, - _assignment.expiry, - _assignment.maxBlockId, - _assignment.maxProposedIn, - _assignment.tierFees - ) - ); - - return keccak256( - abi.encodePacked( - LibStrings.B_PROVER_ASSIGNMENT, - ITaikoL1(_taikoL1Address).getConfig().chainId, - _taikoL1Address, - _blockProposer, - _assignedProver, - _blobHash, - hash, - address(this) - ) - ); - } - - function _getProverFee( - TaikoData.TierFee[] memory _tierFees, - uint16 _tierId - ) - private - pure - returns (uint256) - { - for (uint256 i; i < _tierFees.length; ++i) { - if (_tierFees[i].tier == _tierId) return _tierFees[i].fee; - } - revert HOOK_TIER_NOT_FOUND(); - } -} diff --git a/packages/protocol/contracts/L1/hooks/IHook.sol b/packages/protocol/contracts/L1/hooks/IHook.sol deleted file mode 100644 index d78109f5447..00000000000 --- a/packages/protocol/contracts/L1/hooks/IHook.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.24; - -import "../TaikoData.sol"; - -/// @title IHook -/// @custom:security-contact security@taiko.xyz -interface IHook { - /// @notice Called when a block is proposed. - /// @param _blk The proposed block. - /// @param _meta The metadata of the proposed block. - /// @param _data The data of the proposed block. - function onBlockProposed( - TaikoData.Block calldata _blk, - TaikoData.BlockMetadata calldata _meta, - bytes calldata _data - ) - external - payable; -} diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 9c8244e3439..216f35bab36 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -4,7 +4,6 @@ pragma solidity 0.8.24; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "../../libs/LibAddress.sol"; import "../../libs/LibNetwork.sol"; -import "../hooks/IHook.sol"; import "./LibUtils.sol"; /// @title LibProposing @@ -20,24 +19,13 @@ library LibProposing { // Warning: Any events defined here must also be defined in TaikoEvents.sol. /// @notice Emitted when a block is proposed. /// @param blockId The ID of the proposed block. - /// @param assignedProver The address of the assigned prover. - /// @param livenessBond The liveness bond of the proposed block. /// @param meta The metadata of the proposed block. - /// @param depositsProcessed The EthDeposit array about processed deposits in this proposed - /// block. - event BlockProposed( - uint256 indexed blockId, - address indexed assignedProver, - uint96 livenessBond, - TaikoData.BlockMetadata meta, - TaikoData.EthDeposit[] depositsProcessed - ); + event BlockProposedV2(uint256 indexed blockId, TaikoData.BlockMetadataV2 meta); // Warning: Any errors defined here must also be defined in TaikoErrors.sol. error L1_BLOB_NOT_AVAILABLE(); error L1_BLOB_NOT_FOUND(); - error L1_INVALID_HOOK(); - error L1_INVALID_PROVER(); + error L1_INVALID_PARAM(); error L1_INVALID_SIG(); error L1_LIVENESS_BOND_NOT_RECEIVED(); error L1_NOT_SAME_ADDRESS(); @@ -61,19 +49,8 @@ library LibProposing { bytes calldata _txList ) internal - returns (TaikoData.BlockMetadata memory meta_, TaikoData.EthDeposit[] memory deposits_) + returns (TaikoData.BlockMetadataV2 memory meta_) { - TaikoData.BlockParams memory params = abi.decode(_data, (TaikoData.BlockParams)); - - // We need a prover that will submit proofs after the block has been submitted - if (params.assignedProver == address(0)) { - revert L1_INVALID_PROVER(); - } - - if (params.coinbase == address(0)) { - params.coinbase = msg.sender; - } - // Taiko, as a Based Rollup, enables permissionless block proposals. TaikoData.SlotB memory b = _state.slotB; @@ -83,6 +60,19 @@ library LibProposing { revert L1_TOO_MANY_BLOCKS(); } + // Convert params to the version 1 + TaikoData.BlockParams memory params = b.numBlocks < _config.forkHeight + ? abi.decode(_data, (TaikoData.BlockParams)) + : _paramsToV1(abi.decode(_data, (TaikoData.BlockParamsV2))); + + if (params.assignedProver != address(0) || params.hookCalls.length != 0) { + revert L1_INVALID_PARAM(); + } + + if (params.coinbase == address(0)) { + params.coinbase = msg.sender; + } + bytes32 parentMetaHash = _state.blocks[(b.numBlocks - 1) % _config.blockRingBufferSize].metaHash; // assert(parentMetaHash != 0); @@ -98,7 +88,7 @@ library LibProposing { // If we choose to persist all data fields in the metadata, it will // require additional storage slots. unchecked { - meta_ = TaikoData.BlockMetadata({ + meta_ = TaikoData.BlockMetadataV2({ l1Hash: blockhash(block.number - 1), difficulty: 0, // to be initialized below blobHash: 0, // to be initialized below @@ -112,7 +102,8 @@ library LibProposing { minTier: 0, // to be initialized below blobUsed: _txList.length == 0, parentMetaHash: parentMetaHash, - sender: msg.sender + proposer: msg.sender, + livenessBond: _config.livenessBond }); } @@ -158,19 +149,20 @@ library LibProposing { // Create the block that will be stored onchain TaikoData.Block memory blk = TaikoData.Block({ - metaHash: keccak256(abi.encode(meta_)), + metaHash: LibUtils.hashMetadata(meta_), // Safeguard the liveness bond to ensure its preservation, // particularly in scenarios where it might be altered after the // block's proposal but before it has been proven or verified. - livenessBond: _config.livenessBond, + assignedProver: address(0), // DEPRECATED, always 0 + livenessBond: 0, // DEPRECATED, always 0 blockId: b.numBlocks, proposedAt: meta_.timestamp, - proposedIn: uint64(block.number), + proposedIn: uint48(block.number), + livenessBondNotReturned: true, // For a new block, the next transition ID is always 1, not 0. nextTransitionId: 1, // For unverified block, its verifiedTransitionId is always 0. - verifiedTransitionId: 0, - assignedProver: params.assignedProver + verifiedTransitionId: 0 }); // Store the block in the ring buffer @@ -181,53 +173,28 @@ library LibProposing { ++_state.slotB.numBlocks; } - if (params.hookCalls.length == 0) { - if (params.assignedProver != msg.sender) revert L1_NOT_SAME_ADDRESS(); - _tko.transferFrom(msg.sender, address(this), _config.livenessBond); - } else { - uint256 tkoBalance = _tko.balanceOf(address(this)); - - // Run all hooks. - // Note that address(this).balance has been updated with msg.value, - // prior to any code in this function has been executed. - address prevHook; - for (uint256 i; i < params.hookCalls.length; ++i) { - if (uint160(prevHook) >= uint160(params.hookCalls[i].hook)) { - revert L1_INVALID_HOOK(); - } - - // When a hook is called, all ether in this contract will be sent to the hook. - // If the ether sent to the hook is not used entirely, the hook shall send the Ether - // back to this contract for the next hook to use. - // Proposers shall choose to use extra hooks wisely. - IHook(params.hookCalls[i].hook).onBlockProposed{ value: address(this).balance }( - blk, meta_, params.hookCalls[i].data - ); - - prevHook = params.hookCalls[i].hook; - } - - // Check that after hooks, the Taiko Token balance of this contract - // have increased by the same amount as _config.livenessBond (to prevent) - // multiple draining payments by a malicious proposer nesting the same - // hook. - if (_tko.balanceOf(address(this)) != tkoBalance + _config.livenessBond) { - revert L1_LIVENESS_BOND_NOT_RECEIVED(); - } - } + _tko.transferFrom(msg.sender, address(this), _config.livenessBond); // Refund Ether if (address(this).balance != 0) { msg.sender.sendEtherAndVerify(address(this).balance); } - deposits_ = new TaikoData.EthDeposit[](0); - emit BlockProposed({ - blockId: blk.blockId, - assignedProver: blk.assignedProver, - livenessBond: _config.livenessBond, - meta: meta_, - depositsProcessed: deposits_ + emit BlockProposedV2({ blockId: blk.blockId, meta: meta_ }); + } + + function _paramsToV1(TaikoData.BlockParamsV2 memory v2) + private + pure + returns (TaikoData.BlockParams memory) + { + return TaikoData.BlockParams({ + assignedProver: address(0), + coinbase: v2.coinbase, + extraData: v2.extraData, + parentMetaHash: v2.parentMetaHash, + hookCalls: new TaikoData.HookCall[](0), + signature: v2.signature }); } } diff --git a/packages/protocol/contracts/L1/libs/LibProving.sol b/packages/protocol/contracts/L1/libs/LibProving.sol index 62d5b081d7f..827eabf8a0f 100644 --- a/packages/protocol/contracts/L1/libs/LibProving.sol +++ b/packages/protocol/contracts/L1/libs/LibProving.sol @@ -99,7 +99,7 @@ library LibProving { IERC20 _tko, TaikoData.Config memory _config, IAddressResolver _resolver, - TaikoData.BlockMetadata memory _meta, + TaikoData.BlockMetadataV2 memory _meta, TaikoData.Transition memory _tran, TaikoData.TierProof memory _proof ) @@ -108,10 +108,19 @@ library LibProving { // Make sure parentHash is not zero // To contest an existing transition, simply use any non-zero value as // the blockHash and stateRoot. - if (_tran.parentHash == 0 || _tran.blockHash == 0 || _tran.stateRoot == 0) { + if (_tran.parentHash == 0 || _tran.blockHash == 0) { revert L1_INVALID_TRANSITION(); } + bool verifyingStateRoot = + _meta.id < _config.forkHeight || _meta.id % _config.stateRootSyncInternal == 0; + + if (verifyingStateRoot) { + if (_tran.stateRoot == 0) revert L1_INVALID_TRANSITION(); + } else { + if (_tran.stateRoot != 0) revert L1_INVALID_TRANSITION(); + } + Local memory local; local.tko = _tko; local.b = _state.slotB; @@ -125,14 +134,22 @@ library LibProving { TaikoData.Block storage blk = _state.blocks[local.slot]; local.blockId = blk.blockId; + local.assignedProver = blk.assignedProver; - local.livenessBond = blk.livenessBond; + if (local.assignedProver == address(0)) { + local.assignedProver = _meta.proposer; + } + + if (_meta.livenessBond == 0) { + local.livenessBond = blk.livenessBond; + } + local.metaHash = blk.metaHash; // Check the integrity of the block data. It's worth noting that in // theory, this check may be skipped, but it's included for added // caution. - if (local.blockId != _meta.id || local.metaHash != keccak256(abi.encode(_meta))) { + if (local.blockId != _meta.id || local.metaHash != LibUtils.hashMetadata(_meta)) { revert L1_BLOCK_MISMATCH(); } @@ -207,13 +224,17 @@ library LibProving { } local.isTopTier = local.tier.contestBond == 0; - local.sameTransition = _tran.blockHash == ts.blockHash && _tran.stateRoot == ts.stateRoot; + + local.sameTransition = _tran.blockHash == ts.blockHash; + if (local.sameTransition && verifyingStateRoot) { + local.sameTransition = _tran.stateRoot == ts.stateRoot; + } if (_proof.tier > ts.tier) { // Handles the case when an incoming tier is higher than the current transition's tier. // Reverts when the incoming proof tries to prove the same transition // (L1_ALREADY_PROVED). - _overrideWithHigherProof(blk, ts, _tran, _proof, local); + _overrideWithHigherProof(blk, ts, _meta, _tran, _proof, local); emit TransitionProved({ blockId: local.blockId, @@ -366,6 +387,7 @@ library LibProving { function _overrideWithHigherProof( TaikoData.Block storage _blk, TaikoData.TransitionState memory _ts, + TaikoData.BlockMetadataV2 memory _meta, TaikoData.Transition memory _tran, TaikoData.TierProof memory _proof, Local memory _local @@ -376,8 +398,6 @@ library LibProving { uint256 reward; // reward to the new (current) prover if (_ts.contester != address(0)) { - // assert(_blk.livenessBond == 0); - if (_local.sameTransition) { // The contested transition is proven to be valid, contester loses the game reward = _rewardAfterFriction(_ts.contestBond); @@ -399,16 +419,22 @@ library LibProving { // - 2) the transition is contested. reward = _rewardAfterFriction(_ts.validityBond); - if (_local.livenessBond != 0) { + // `_local.livenessBond !=0` can be removed once we are sure all ringbuffer + // has been written. + if (_blk.livenessBondNotReturned || _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; + _blk.livenessBondNotReturned = false; if (_returnLivenessBond(_local, _proof.data)) { + uint96 livenessBond = + _meta.livenessBond == 0 ? _local.livenessBond : _meta.livenessBond; + if (_local.assignedProver == msg.sender) { - reward += _local.livenessBond; + reward += livenessBond; } else { - _local.tko.transfer(_local.assignedProver, _local.livenessBond); + _local.tko.transfer(_local.assignedProver, livenessBond); } } } diff --git a/packages/protocol/contracts/L1/libs/LibUtils.sol b/packages/protocol/contracts/L1/libs/LibUtils.sol index 304981229c6..c9743b5eefb 100644 --- a/packages/protocol/contracts/L1/libs/LibUtils.sol +++ b/packages/protocol/contracts/L1/libs/LibUtils.sol @@ -228,4 +228,33 @@ library LibUtils { return _blockId % segmentSize == (_isBlockProposed ? 0 : segmentSize >> 1); } + + function hashMetadata(TaikoData.BlockMetadataV2 memory _meta) internal pure returns (bytes32) { + return _meta.livenessBond != 0 + ? keccak256(abi.encode(_meta)) + : keccak256(abi.encode(_metaV2ToV1(_meta))); + } + + function _metaV2ToV1(TaikoData.BlockMetadataV2 memory _v2) + private + pure + returns (TaikoData.BlockMetadata memory) + { + return TaikoData.BlockMetadata({ + l1Hash: _v2.l1Hash, + difficulty: _v2.difficulty, + blobHash: _v2.blobHash, + extraData: _v2.extraData, + depositsHash: _v2.depositsHash, + coinbase: _v2.coinbase, + id: _v2.id, + gasLimit: _v2.gasLimit, + timestamp: _v2.timestamp, + l1Height: _v2.l1Height, + minTier: _v2.minTier, + blobUsed: _v2.blobUsed, + parentMetaHash: _v2.parentMetaHash, + sender: _v2.proposer + }); + } } diff --git a/packages/protocol/contracts/L1/libs/LibVerifying.sol b/packages/protocol/contracts/L1/libs/LibVerifying.sol index 5c4e1b179d5..83fe9d8b219 100644 --- a/packages/protocol/contracts/L1/libs/LibVerifying.sol +++ b/packages/protocol/contracts/L1/libs/LibVerifying.sol @@ -19,8 +19,10 @@ library LibVerifying { uint32 lastVerifiedTransitionId; uint16 tier; bytes32 blockHash; + bytes32 stateRoot; address prover; ITierRouter tierRouter; + ISignalService signalService; } // Warning: Any errors defined here must also be defined in TaikoErrors.sol. @@ -30,6 +32,7 @@ library LibVerifying { error L1_TOO_LATE(); /// @dev Verifies up to N blocks. + /// This methid is made public to reduce TaikoL1 code size. function verifyBlocks( TaikoData.State storage _state, IERC20 _tko, @@ -37,7 +40,7 @@ library LibVerifying { IAddressResolver _resolver, uint64 _maxBlocksToVerify ) - internal + public { if (_maxBlocksToVerify == 0) { return; @@ -131,6 +134,25 @@ library LibVerifying { tier: local.tier }); + if (local.blockId % _config.stateRootSyncInternal == 0) { + local.stateRoot = ts.stateRoot; + + if (local.stateRoot != 0) { + _state.slotA.lastSyncedBlockId = local.blockId; + _state.slotA.lastSynecdAt = uint64(block.timestamp); + + if (local.signalService == ISignalService(address(0))) { + local.signalService = ISignalService( + _resolver.resolve(LibStrings.B_SIGNAL_SERVICE, false) + ); + } + + local.signalService.syncChainData( + _config.chainId, LibStrings.H_STATE_ROOT, local.blockId, local.stateRoot + ); + } + } + ++local.blockId; ++local.numBlocksVerified; } @@ -141,23 +163,6 @@ library LibVerifying { _state.slotB.lastVerifiedBlockId = lastVerifiedBlockId; _state.blocks[local.slot].verifiedTransitionId = local.lastVerifiedTransitionId; - - // Sync chain data when necessary - if ( - lastVerifiedBlockId - > _state.slotA.lastSyncedBlockId + _config.blockSyncThreshold - ) { - _state.slotA.lastSyncedBlockId = lastVerifiedBlockId; - _state.slotA.lastSynecdAt = uint64(block.timestamp); - - bytes32 stateRoot = - _state.transitions[local.slot][local.lastVerifiedTransitionId].stateRoot; - - ISignalService(_resolver.resolve(LibStrings.B_SIGNAL_SERVICE, false)) - .syncChainData( - _config.chainId, LibStrings.H_STATE_ROOT, lastVerifiedBlockId, stateRoot - ); - } } } } diff --git a/packages/protocol/contracts/L1/provers/GuardianProver.sol b/packages/protocol/contracts/L1/provers/GuardianProver.sol index eec69566ca1..8c34bd835be 100644 --- a/packages/protocol/contracts/L1/provers/GuardianProver.sol +++ b/packages/protocol/contracts/L1/provers/GuardianProver.sol @@ -178,7 +178,7 @@ contract GuardianProver is IVerifier, EssentialContract { /// @param _proof The tier proof. /// @return approved_ True if the minimum number of approval is acquired, false otherwise. function approve( - TaikoData.BlockMetadata calldata _meta, + TaikoData.BlockMetadataV2 calldata _meta, TaikoData.Transition calldata _tran, TaikoData.TierProof calldata _proof ) diff --git a/packages/protocol/script/DeployOnL1.s.sol b/packages/protocol/script/DeployOnL1.s.sol index 4a6619668a3..024e24d470e 100644 --- a/packages/protocol/script/DeployOnL1.s.sol +++ b/packages/protocol/script/DeployOnL1.s.sol @@ -9,7 +9,6 @@ import "../contracts/L1/TaikoL1.sol"; import "../contracts/L1/provers/GuardianProver.sol"; import "../contracts/L1/tiers/DevnetTierProvider.sol"; import "../contracts/L1/tiers/TierProviderV2.sol"; -import "../contracts/L1/hooks/AssignmentHook.sol"; import "../contracts/bridge/Bridge.sol"; import "../contracts/tokenvault/BridgedERC20.sol"; import "../contracts/tokenvault/BridgedERC721.sol"; @@ -261,13 +260,6 @@ contract DeployOnL1 is DeployCapability { registerTo: rollupAddressManager }); - deployProxy({ - name: "assignment_hook", - impl: address(new AssignmentHook()), - data: abi.encodeCall(AssignmentHook.init, (owner, rollupAddressManager)), - registerTo: rollupAddressManager - }); - deployProxy({ name: "tier_sgx", impl: address(new SgxVerifier()), diff --git a/packages/protocol/script/upgrade/UpgradeAssignmentHook.s.sol b/packages/protocol/script/upgrade/UpgradeAssignmentHook.s.sol deleted file mode 100644 index 6532fd8278a..00000000000 --- a/packages/protocol/script/upgrade/UpgradeAssignmentHook.s.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.24; - -import "forge-std/src/Script.sol"; -import "forge-std/src/console2.sol"; -import "../../contracts/L1/hooks/AssignmentHook.sol"; -import "./UpgradeScript.s.sol"; - -contract UpgradeAssignmentHook is UpgradeScript { - function run() external setUp { - upgrade("AssignmentHook", address(new AssignmentHook())); - } -} diff --git a/packages/protocol/test/L1/TaikoL1.t.sol b/packages/protocol/test/L1/TaikoL1.t.sol index ad041011d78..d81f21b8504 100644 --- a/packages/protocol/test/L1/TaikoL1.t.sol +++ b/packages/protocol/test/L1/TaikoL1.t.sol @@ -38,23 +38,19 @@ contract TaikoL1Test is TaikoL1TestBase { // If this line (or Bob's query balance) is uncommented, // Alice/Bob has no balance.. (Causing reverts !!!) console2.log("Alice balance:", tko.balanceOf(Alice)); - giveEthAndTko(Bob, 1e8 ether, 100 ether); - console2.log("Bob balance:", tko.balanceOf(Bob)); giveEthAndTko(Carol, 1e8 ether, 100 ether); - // Bob - vm.prank(Bob, Bob); bytes32 parentHash = GENESIS_BLOCK_HASH; for (uint256 blockId = 1; blockId < conf.blockMaxProposals * 3; blockId++) { //printVariables("before propose"); - (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, 1_000_000, 1024); //printVariables("after propose"); mine(1); bytes32 blockHash = bytes32(1e10 + blockId); bytes32 stateRoot = bytes32(1e9 + blockId); - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); vm.roll(block.number + 15 * 12); uint16 minTier = meta.minTier; @@ -69,25 +65,20 @@ contract TaikoL1Test is TaikoL1TestBase { /// @dev Test more than one block can be proposed, proven, & verified in the /// same L1 block. function test_L1_multiple_blocks_in_one_L1_block() external { - giveEthAndTko(Alice, 1000 ether, 1000 ether); + giveEthAndTko(Alice, 1_000_000 ether, 1000 ether); console2.log("Alice balance:", tko.balanceOf(Alice)); - giveEthAndTko(Bob, 1e8 ether, 100 ether); - console2.log("Bob balance:", tko.balanceOf(Bob)); giveEthAndTko(Carol, 1e8 ether, 100 ether); - // Bob - vm.prank(Bob, Bob); - bytes32 parentHash = GENESIS_BLOCK_HASH; for (uint256 blockId = 1; blockId <= 20; ++blockId) { printVariables("before propose"); - (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, 1_000_000, 1024); printVariables("after propose"); bytes32 blockHash = bytes32(1e10 + blockId); bytes32 stateRoot = bytes32(1e9 + blockId); - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); vm.roll(block.number + 15 * 12); uint16 minTier = meta.minTier; vm.warp(block.timestamp + tierProvider().getTier(minTier).cooldownWindow * 60 + 1); @@ -98,7 +89,7 @@ contract TaikoL1Test is TaikoL1TestBase { assertEq(meta.id, blk.blockId); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, parentHash); - assertEq(ts.prover, Bob); + assertEq(ts.prover, Alice); parentHash = blockHash; } @@ -107,25 +98,21 @@ contract TaikoL1Test is TaikoL1TestBase { /// @dev Test verifying multiple blocks in one transaction function test_L1_verifying_multiple_blocks_once() external { - giveEthAndTko(Alice, 1000 ether, 1000 ether); + giveEthAndTko(Alice, 10_000_000 ether, 1000 ether); console2.log("Alice balance:", tko.balanceOf(Alice)); - giveEthAndTko(Bob, 1e8 ether, 100 ether); - console2.log("Bob balance:", tko.balanceOf(Bob)); giveEthAndTko(Carol, 1e8 ether, 100 ether); - // Bob - vm.prank(Bob, Bob); bytes32 parentHash = GENESIS_BLOCK_HASH; for (uint256 blockId = 1; blockId <= conf.blockMaxProposals; blockId++) { printVariables("before propose"); - (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, 1_000_000, 1024); printVariables("after propose"); bytes32 blockHash = bytes32(1e10 + blockId); bytes32 stateRoot = bytes32(1e9 + blockId); - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); parentHash = blockHash; } @@ -140,14 +127,12 @@ contract TaikoL1Test is TaikoL1TestBase { function test_L1_in_proving_window_logic() external { giveEthAndTko(Alice, 1000 ether, 1000 ether); console2.log("Alice balance:", tko.balanceOf(Alice)); - giveEthAndTko(Bob, 1e8 ether, 100 ether); - console2.log("Bob balance:", tko.balanceOf(Bob)); giveEthAndTko(Carol, 1e8 ether, 100 ether); bytes32 parentHash = GENESIS_BLOCK_HASH; for (uint256 blockId = 1; blockId <= conf.blockMaxProposals; blockId++) { - (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, 1_000_000, 1024); bytes32 blockHash; bytes32 stateRoot; if (blockId % 2 == 0) { @@ -173,7 +158,7 @@ contract TaikoL1Test is TaikoL1TestBase { // Only guardian or assigned prover is allowed if (blockId % 4 == 0) { - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); } else { proveBlock( Carol, meta, parentHash, blockHash, stateRoot, LibTiers.TIER_GUARDIAN, "" @@ -202,16 +187,15 @@ contract TaikoL1Test is TaikoL1TestBase { function test_pauseProving() external { L1.pauseProving(true); - TaikoData.BlockMetadata memory meta; + TaikoData.BlockMetadataV2 memory meta; giveEthAndTko(Alice, 1000 ether, 1000 ether); - giveEthAndTko(Bob, 1e8 ether, 100 ether); // Proposing is still possible - (meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); + meta = proposeBlock(Alice, 1_000_000, 1024); // Proving is not, so supply the revert reason to proveBlock proveBlock( - Bob, + Alice, meta, GENESIS_BLOCK_HASH, bytes32("01"), @@ -225,16 +209,15 @@ contract TaikoL1Test is TaikoL1TestBase { L1.pause(); giveEthAndTko(Alice, 1000 ether, 1000 ether); - giveEthAndTko(Bob, 1e8 ether, 100 ether); // Proposing is also not possible - proposeButRevert(Alice, Bob, 1024, EssentialContract.INVALID_PAUSE_STATUS.selector); + proposeButRevert(Alice, 1024, EssentialContract.INVALID_PAUSE_STATUS.selector); // unpause L1.unpause(); // Proposing is possible again - proposeBlock(Alice, Bob, 1_000_000, 1024); + proposeBlock(Alice, 1_000_000, 1024); } function test_getTierIds() external { @@ -247,24 +230,20 @@ contract TaikoL1Test is TaikoL1TestBase { cp.getTier(123); } - function proposeButRevert( - address proposer, - address prover, - uint24 txListSize, - bytes4 revertReason - ) - internal - { + function proposeButRevert(address proposer, uint24 txListSize, bytes4 revertReason) internal { uint256 msgValue = 2 ether; - AssignmentHook.ProverAssignment memory assignment; - TaikoData.HookCall[] memory hookcalls = new TaikoData.HookCall[](1); - hookcalls[0] = TaikoData.HookCall(address(assignmentHook), abi.encode(assignment)); + TaikoData.HookCall[] memory hookcalls; + + (, TaikoData.SlotB memory b) = L1.getStateVariables(); + + TaikoData.Config memory config = L1.getConfig(); + + bytes memory paramEncoded = b.numBlocks < config.forkHeight + ? abi.encode(TaikoData.BlockParams(address(0), address(0), 0, 0, hookcalls, "")) + : abi.encode(TaikoData.BlockParamsV2(address(0), 0, 0, "")); vm.prank(proposer, proposer); vm.expectRevert(revertReason); - L1.proposeBlock{ value: msgValue }( - abi.encode(TaikoData.BlockParams(prover, address(0), 0, 0, hookcalls, "")), - new bytes(txListSize) - ); + L1.proposeBlock{ value: msgValue }(paramEncoded, new bytes(txListSize)); } } diff --git a/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol b/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol index 2ce9972410b..79ad09d0643 100644 --- a/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol +++ b/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol @@ -29,7 +29,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { } function proveHigherTierProof( - TaikoData.BlockMetadata memory meta, + TaikoData.BlockMetadataV2 memory meta, bytes32 parentHash, bytes32 stateRoot, bytes32 blockHash, @@ -62,7 +62,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { bytes32 parentHash = GENESIS_BLOCK_HASH; for (uint256 blockId = 1; blockId < conf.blockMaxProposals * 3; blockId++) { printVariables("before propose"); - (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, 1_000_000, 1024); //printVariables("after propose"); mine(1); @@ -70,7 +70,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { bytes32 stateRoot = bytes32(1e9 + blockId); // This proof cannot be verified obviously because of // blockhash:blockId - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); // Try to contest - but should revert with L1_ALREADY_PROVED proveBlock( @@ -111,7 +111,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { bytes32 parentHash = GENESIS_BLOCK_HASH; for (uint256 blockId = 1; blockId < conf.blockMaxProposals * 3; blockId++) { printVariables("before propose"); - (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, 1_000_000, 1024); //printVariables("after propose"); mine(1); @@ -121,7 +121,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { // stateRoot instead of blockHash uint16 minTier = meta.minTier; - proveBlock(Bob, meta, parentHash, stateRoot, stateRoot, minTier, ""); + proveBlock(Alice, meta, parentHash, stateRoot, stateRoot, minTier, ""); // Try to contest proveBlock(Carol, meta, parentHash, blockHash, stateRoot, minTier, ""); @@ -164,7 +164,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { bytes32 parentHash = GENESIS_BLOCK_HASH; for (uint256 blockId = 1; blockId < conf.blockMaxProposals * 3; blockId++) { printVariables("before propose"); - (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, 1_000_000, 1024); //printVariables("after propose"); mine(1); @@ -173,7 +173,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { // This proof cannot be verified obviously because of // stateRoot instead of blockHash uint16 minTier = meta.minTier; - proveBlock(Bob, meta, parentHash, stateRoot, stateRoot, minTier, ""); + proveBlock(Alice, meta, parentHash, stateRoot, stateRoot, minTier, ""); // Try to contest proveBlock(Carol, meta, parentHash, blockHash, stateRoot, minTier, ""); @@ -216,7 +216,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { bytes32 parentHash = GENESIS_BLOCK_HASH; for (uint256 blockId = 1; blockId < conf.blockMaxProposals * 3; blockId++) { printVariables("before propose"); - (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, 1_000_000, 1024); //printVariables("after propose"); mine(1); @@ -226,7 +226,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { // stateRoot instead of blockHash uint16 minTier = meta.minTier; - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, minTier, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, minTier, ""); if (minTier == LibTiers.TIER_OPTIMISTIC) { // Try to contest @@ -273,7 +273,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { bytes32 parentHash = GENESIS_BLOCK_HASH; for (uint256 blockId = 1; blockId < 10; blockId++) { printVariables("before propose"); - (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, 1_000_000, 1024); //printVariables("after propose"); mine(1); @@ -282,7 +282,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { // This proof cannot be verified obviously because of // stateRoot instead of blockHash uint16 minTier = meta.minTier; - proveBlock(Bob, meta, parentHash, stateRoot, stateRoot, minTier, ""); + proveBlock(Alice, meta, parentHash, stateRoot, stateRoot, minTier, ""); if (minTier == LibTiers.TIER_OPTIMISTIC) { // Try to contest @@ -338,7 +338,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { for (uint256 blockId = 1; blockId < 10; blockId++) { //printVariables("before propose"); - (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, 1_000_000, 1024); //printVariables("after propose"); mine(1); @@ -380,7 +380,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { bytes32 parentHash = GENESIS_BLOCK_HASH; for (uint256 blockId = 1; blockId < conf.blockMaxProposals * 3; blockId++) { printVariables("before propose"); - (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, 1_000_000, 1024); //printVariables("after propose"); mine(1); @@ -391,7 +391,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { (, TaikoData.SlotB memory b) = L1.getStateVariables(); uint64 lastVerifiedBlockBefore = b.lastVerifiedBlockId; - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); console2.log("mintTier is:", meta.minTier); // Try to contest proveBlock( @@ -442,7 +442,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { bytes32 parentHash = GENESIS_BLOCK_HASH; for (uint256 blockId = 1; blockId < conf.blockMaxProposals * 3; blockId++) { printVariables("before propose"); - (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, 1_000_000, 1024); //printVariables("after propose"); mine(1); @@ -450,7 +450,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { bytes32 stateRoot = bytes32(1e9 + blockId); // This proof cannot be verified obviously because of // blockhash:blockId - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); // Try to contest - but should revert with L1_ALREADY_PROVED proveBlock( @@ -491,7 +491,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { bytes32 parentHash = GENESIS_BLOCK_HASH; for (uint256 blockId = 1; blockId < conf.blockMaxProposals * 3; blockId++) { printVariables("before propose"); - (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, 1_000_000, 1024); //printVariables("after propose"); mine(1); @@ -499,7 +499,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { bytes32 stateRoot = bytes32(1e9 + blockId); // This proof cannot be verified obviously because of // blockhash:blockId - proveBlock(Bob, meta, parentHash, stateRoot, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash, stateRoot, stateRoot, meta.minTier, ""); // Prove as guardian proveBlock( @@ -539,7 +539,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { bytes32 parentHash = GENESIS_BLOCK_HASH; for (uint256 blockId = 1; blockId < 10; blockId++) { printVariables("before propose"); - (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, 1_000_000, 1024); //printVariables("after propose"); mine(1); @@ -580,7 +580,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { bytes32 parentHash = GENESIS_BLOCK_HASH; for (uint256 blockId = 1; blockId < 10; blockId++) { printVariables("before propose"); - (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, 1_000_000, 1024); //printVariables("after propose"); mine(1); @@ -590,7 +590,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { // Mess up metahash meta.l1Height = 200; proveBlock( - Bob, + Alice, meta, parentHash, blockHash, @@ -620,7 +620,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { bytes32 parentHash = GENESIS_BLOCK_HASH; for (uint256 blockId = 1; blockId < conf.blockMaxProposals * 3; blockId++) { printVariables("before propose"); - (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, 1_000_000, 1024); //printVariables("after propose"); mine(1); @@ -628,14 +628,14 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { bytes32 stateRoot = bytes32(1e9 + blockId); // This proof cannot be verified obviously because of blockhash is // exchanged with stateRoot - proveBlock(Bob, meta, parentHash, stateRoot, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash, stateRoot, stateRoot, meta.minTier, ""); // Prove as guardian proveBlock(Carol, meta, parentHash, blockHash, stateRoot, LibTiers.TIER_GUARDIAN, ""); // Try to re-prove but reverts proveBlock( - Bob, + Alice, meta, parentHash, stateRoot, @@ -671,13 +671,13 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { bytes32 parentHash = GENESIS_BLOCK_HASH; printVariables("before propose"); - (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, 1_000_000, 1024); //printVariables("after propose"); mine(1); bytes32 blockHash = bytes32(uint256(1)); bytes32 stateRoot = bytes32(uint256(1)); - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, LibTiers.TIER_GUARDIAN, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, LibTiers.TIER_GUARDIAN, ""); // Try to contest with a lower tier proof- but should revert with L1_INVALID_TIER proveBlock( diff --git a/packages/protocol/test/L1/TaikoL1TestBase.sol b/packages/protocol/test/L1/TaikoL1TestBase.sol index adf4cbed7e8..ef0db00318d 100644 --- a/packages/protocol/test/L1/TaikoL1TestBase.sol +++ b/packages/protocol/test/L1/TaikoL1TestBase.sol @@ -5,7 +5,6 @@ import "../TaikoTest.sol"; abstract contract TaikoL1TestBase is TaikoTest { AddressManager public addressManager; - AssignmentHook public assignmentHook; TaikoToken public tko; SignalService public ss; TaikoL1 public L1; @@ -88,14 +87,6 @@ abstract contract TaikoL1TestBase is TaikoTest { ) ); - assignmentHook = AssignmentHook( - deployProxy({ - name: "assignment_hook", - impl: address(new AssignmentHook()), - data: abi.encodeCall(AssignmentHook.init, (address(0), address(addressManager))) - }) - ); - registerAddress("taiko", address(L1)); registerAddress("tier_sgx", address(sv)); registerAddress("tier_guardian", address(gp)); @@ -122,12 +113,11 @@ abstract contract TaikoL1TestBase is TaikoTest { function proposeBlock( address proposer, - address prover, uint32 gasLimit, uint24 txListSize ) internal - returns (TaikoData.BlockMetadata memory meta, TaikoData.EthDeposit[] memory ethDeposits) + returns (TaikoData.BlockMetadataV2 memory meta) { TaikoData.TierFee[] memory tierFees = new TaikoData.TierFee[](3); // Register the tier fees @@ -143,21 +133,6 @@ abstract contract TaikoL1TestBase is TaikoTest { // anyways uint256 msgValue = 2 ether; - AssignmentHook.ProverAssignment memory assignment = AssignmentHook.ProverAssignment({ - feeToken: address(0), - tierFees: tierFees, - expiry: uint64(block.timestamp + 60 minutes), - maxBlockId: 0, - maxProposedIn: 0, - metaHash: 0, - parentMetaHash: 0, - signature: new bytes(0) - }); - - assignment.signature = _signAssignment( - prover, assignment, address(L1), proposer, keccak256(new bytes(txListSize)) - ); - (, TaikoData.SlotB memory b) = L1.getStateVariables(); uint256 _difficulty; @@ -173,22 +148,20 @@ abstract contract TaikoL1TestBase is TaikoTest { meta.gasLimit = gasLimit; TaikoData.HookCall[] memory hookcalls; - if (prover != proposer) { - hookcalls = new TaikoData.HookCall[](1); - hookcalls[0] = TaikoData.HookCall(address(assignmentHook), abi.encode(assignment)); - } else { - hookcalls = new TaikoData.HookCall[](0); - } + + TaikoData.Config memory config = L1.getConfig(); + + bytes memory paramEncoded = b.numBlocks < config.forkHeight + ? abi.encode(TaikoData.BlockParams(address(0), address(0), 0, 0, hookcalls, "")) + : abi.encode(TaikoData.BlockParamsV2(address(0), 0, 0, "")); + vm.prank(proposer, proposer); - (meta, ethDeposits) = L1.proposeBlock{ value: msgValue }( - abi.encode(TaikoData.BlockParams(prover, address(0), 0, 0, hookcalls, "")), - new bytes(txListSize) - ); + meta = L1.proposeBlock{ value: msgValue }(paramEncoded, new bytes(txListSize)); } function proveBlock( address prover, - TaikoData.BlockMetadata memory meta, + TaikoData.BlockMetadataV2 memory meta, bytes32 parentHash, bytes32 blockHash, bytes32 stateRoot, @@ -281,36 +254,6 @@ abstract contract TaikoL1TestBase is TaikoTest { console2.log(conf.chainId, string(abi.encodePacked(nameHash)), unicode"→", addr); } - function _signAssignment( - address prover, - AssignmentHook.ProverAssignment memory assignment, - address taikoAddr, - address blockProposer, - bytes32 blobHash - ) - internal - view - returns (bytes memory signature) - { - uint256 signerPrivateKey; - - // In the test suite these are the 3 which acts as provers - if (prover == Alice) { - signerPrivateKey = 0x1; - } else if (prover == Bob) { - signerPrivateKey = 0x2; - } else if (prover == Carol) { - signerPrivateKey = 0x3; - } else { - revert("unexpected"); - } - - bytes32 assignmentHash = - assignmentHook.hashAssignment(assignment, taikoAddr, blockProposer, prover, blobHash); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPrivateKey, assignmentHash); - signature = abi.encodePacked(r, s, v); - } - function createSgxSignatureProof( TaikoData.Transition memory tran, address newInstance, @@ -345,8 +288,6 @@ abstract contract TaikoL1TestBase is TaikoTest { vm.prank(to, to); tko.approve(address(L1), amountTko); - vm.prank(to, to); - tko.approve(address(assignmentHook), amountTko); console2.log("TKO balance:", to, tko.balanceOf(to)); console2.log("ETH balance:", to, to.balance); diff --git a/packages/protocol/test/L1/TaikoL1TestGroup1.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup1.t.sol index e5523931445..8e34915c578 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup1.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup1.t.sol @@ -5,22 +5,23 @@ import "./TaikoL1TestGroupBase.sol"; contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { // Test summary: - // 1. Alice proposes a block, assigning Bob as the prover. - // 2. Bob proves the block within the proving window, using the correct parent hash. - // 3. Bob's proof is used to verify the block. + // 1. Alice proposes a block + // 2. Alice proves the block within the proving window, using the correct parent hash. + // 3. Alice's proof is used to verify the block. function test_taikoL1_group_1_case_1() external { vm.warp(1_000_000); printBlockAndTrans(0); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); giveEthAndTko(Taylor, 10_000 ether, 1000 ether); ITierProvider.Tier memory tierOp = TestTierProvider(cp).getTier(LibTiers.TIER_OPTIMISTIC); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); uint96 livenessBond = L1.getConfig().livenessBond; + assertEq(meta.livenessBond, livenessBond); + uint256 proposedAt; { printBlockAndTrans(meta.id); @@ -30,13 +31,11 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 1); assertEq(blk.verifiedTransitionId, 0); assertEq(blk.proposedAt, block.timestamp); - assertEq(blk.assignedProver, Bob); - assertEq(blk.livenessBond, livenessBond); + assertEq(blk.livenessBond, 0); + assertEq(blk.livenessBondNotReturned, true); proposedAt = blk.proposedAt; - - assertEq(tko.balanceOf(Alice), 10_000 ether); - assertEq(tko.balanceOf(Bob), 10_000 ether - livenessBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); } // Prove the block @@ -56,9 +55,9 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { TaikoErrors.L1_NOT_ASSIGNED_PROVER.selector ); - console2.log("====== Bob proves the block"); + console2.log("====== Alice proves the block"); mineAndWrap(10 seconds); - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); uint256 provenAt; @@ -69,21 +68,21 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); assertEq(blk.proposedAt, proposedAt); - assertEq(blk.assignedProver, Bob); assertEq(blk.livenessBond, 0); + assertEq(blk.livenessBondNotReturned, false); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); assertEq(ts.blockHash, blockHash); assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_OPTIMISTIC); assertEq(ts.contester, address(0)); - assertEq(ts.prover, Bob); + assertEq(ts.prover, Alice); assertEq(ts.validityBond, tierOp.validityBond); assertEq(ts.timestamp, block.timestamp); provenAt = ts.timestamp; - assertEq(tko.balanceOf(Bob), 10_000 ether - tierOp.validityBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); } console2.log("====== Verify block"); @@ -96,7 +95,7 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 1); assertEq(blk.proposedAt, proposedAt); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -104,29 +103,28 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_OPTIMISTIC); assertEq(ts.contester, address(0)); - assertEq(ts.prover, Bob); + assertEq(ts.prover, Alice); assertEq(ts.validityBond, tierOp.validityBond); assertEq(ts.timestamp, provenAt); - assertEq(tko.balanceOf(Bob), 10_000 ether); + assertEq(tko.balanceOf(Alice), 10_000 ether); } } // Test summary: - // 1. Alice proposes a block, assigning Bob as the prover. - // 2. Taylor proposes the block outside the proving window. + // 1. Alice proposes a block + // 2. Taylor proves the block outside the proving window. // 3. Taylor's proof is used to verify the block. function test_taikoL1_group_1_case_2() external { vm.warp(1_000_000); printBlockAndTrans(0); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); giveEthAndTko(Taylor, 10_000 ether, 1000 ether); ITierProvider.Tier memory tierOp = TestTierProvider(cp).getTier(LibTiers.TIER_OPTIMISTIC); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); uint96 livenessBond = L1.getConfig().livenessBond; uint256 proposedAt; @@ -138,13 +136,13 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 1); assertEq(blk.verifiedTransitionId, 0); assertEq(blk.proposedAt, block.timestamp); - assertEq(blk.assignedProver, Bob); - assertEq(blk.livenessBond, livenessBond); + + assertEq(blk.livenessBond, 0); + assertEq(blk.livenessBondNotReturned, true); proposedAt = blk.proposedAt; - assertEq(tko.balanceOf(Alice), 10_000 ether); - assertEq(tko.balanceOf(Bob), 10_000 ether - livenessBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); } // Prove the block @@ -165,8 +163,9 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); assertEq(blk.proposedAt, proposedAt); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); + assertEq(blk.livenessBondNotReturned, false); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); assertEq(ts.blockHash, blockHash); @@ -179,7 +178,7 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { provenAt = ts.timestamp; - assertEq(tko.balanceOf(Bob), 10_000 ether - livenessBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.validityBond); } @@ -193,8 +192,9 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 1); assertEq(blk.proposedAt, proposedAt); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); + assertEq(blk.livenessBondNotReturned, false); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); assertEq(ts.blockHash, blockHash); @@ -205,25 +205,24 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(ts.validityBond, tierOp.validityBond); assertEq(ts.timestamp, provenAt); - assertEq(tko.balanceOf(Bob), 10_000 ether - livenessBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); assertEq(tko.balanceOf(Taylor), 10_000 ether); } } // Test summary: - // 1. Alice proposes a block, assigning Bob as the prover. - // 2. Bob proves the block within the proving window. + // 1. Alice proposes a block + // 2. Alice proves the block within the proving window. // 3. Taylor proves the block outside the proving window. // 4. Taylor's proof is used to verify the block. function test_taikoL1_group_1_case_3() external { vm.warp(1_000_000); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); giveEthAndTko(Taylor, 10_000 ether, 1000 ether); ITierProvider.Tier memory tierOp = TestTierProvider(cp).getTier(LibTiers.TIER_OPTIMISTIC); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); // Prove the block bytes32 parentHash1 = bytes32(uint256(9)); @@ -233,8 +232,8 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { mineAndWrap(10 seconds); - console2.log("====== Bob proves the block first"); - proveBlock(Bob, meta, parentHash1, blockHash, stateRoot, meta.minTier, ""); + console2.log("====== Alice proves the block first"); + proveBlock(Alice, meta, parentHash1, blockHash, stateRoot, meta.minTier, ""); console2.log("====== Taylor proves the block later"); mineAndWrap(10 seconds); @@ -249,33 +248,33 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 3); assertEq(blk.verifiedTransitionId, 2); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); + assertEq(blk.livenessBondNotReturned, false); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 2); assertEq(ts.contester, address(0)); assertEq(ts.prover, Taylor); assertEq(ts.validityBond, tierOp.validityBond); - assertEq(tko.balanceOf(Bob), 10_000 ether - tierOp.validityBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); assertEq(tko.balanceOf(Taylor), 10_000 ether); } } // Test summary: - // 1. Alice proposes a block, assigning Bob as the prover. - // 2. Bob proves the block within the proving window. + // 1. Alice proposes a block + // 2. Alice proves the block within the proving window. // 3. Taylor proves the block outside the proving window. - // 4. Bob's proof is used to verify the block. + // 4. Alice's proof is used to verify the block. function test_taikoL1_group_1_case_4() external { vm.warp(1_000_000); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); giveEthAndTko(Taylor, 10_000 ether, 1000 ether); ITierProvider.Tier memory tierOp = TestTierProvider(cp).getTier(LibTiers.TIER_OPTIMISTIC); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); // Prove the block bytes32 parentHash1 = GENESIS_BLOCK_HASH; @@ -285,8 +284,8 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { mineAndWrap(10 seconds); - console2.log("====== Bob proves the block first"); - proveBlock(Bob, meta, parentHash1, blockHash, stateRoot, meta.minTier, ""); + console2.log("====== Alice proves the block first"); + proveBlock(Alice, meta, parentHash1, blockHash, stateRoot, meta.minTier, ""); console2.log("====== Taylor proves the block later"); mineAndWrap(10 seconds); @@ -301,34 +300,34 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 3); assertEq(blk.verifiedTransitionId, 1); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); + assertEq(blk.livenessBondNotReturned, false); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); assertEq(ts.contester, address(0)); - assertEq(ts.prover, Bob); + assertEq(ts.prover, Alice); assertEq(ts.validityBond, tierOp.validityBond); - assertEq(tko.balanceOf(Bob), 10_000 ether); + assertEq(tko.balanceOf(Alice), 10_000 ether); assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.validityBond); } } // Test summary: - // 1. Alice proposes a block, assigning Bob as the prover. + // 1. Alice proposes a block // 2. William proves the block outside the proving window. // 3. Taylor also proves the block outside the proving window. // 4. Taylor's proof is used to verify the block. function test_taikoL1_group_1_case_5() external { vm.warp(1_000_000); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); giveEthAndTko(Taylor, 10_000 ether, 1000 ether); giveEthAndTko(William, 10_000 ether, 1000 ether); ITierProvider.Tier memory tierOp = TestTierProvider(cp).getTier(LibTiers.TIER_OPTIMISTIC); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); // Prove the block bytes32 parentHash1 = bytes32(uint256(9)); @@ -354,34 +353,34 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 3); assertEq(blk.verifiedTransitionId, 2); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); + assertEq(blk.livenessBondNotReturned, false); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 2); assertEq(ts.contester, address(0)); assertEq(ts.prover, Taylor); assertEq(ts.validityBond, tierOp.validityBond); - assertEq(tko.balanceOf(Bob), 10_000 ether - L1.getConfig().livenessBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - L1.getConfig().livenessBond); assertEq(tko.balanceOf(Taylor), 10_000 ether); } } // Test summary: - // 1. Alice proposes a block, assigning Bob as the prover. - // 2. Bob proves the block outside the proving window, using the correct parent hash. - // 3. Bob's proof is used to verify the block. + // 1. Alice proposes a block + // 2. Alice proves the block outside the proving window, using the correct parent hash. + // 3. Alice's proof is used to verify the block. function test_taikoL1_group_1_case_6() external { vm.warp(1_000_000); printBlockAndTrans(0); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); giveEthAndTko(Taylor, 10_000 ether, 1000 ether); ITierProvider.Tier memory tierOp = TestTierProvider(cp).getTier(LibTiers.TIER_OPTIMISTIC); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); uint96 livenessBond = L1.getConfig().livenessBond; uint256 proposedAt; @@ -393,13 +392,13 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 1); assertEq(blk.verifiedTransitionId, 0); assertEq(blk.proposedAt, block.timestamp); - assertEq(blk.assignedProver, Bob); - assertEq(blk.livenessBond, livenessBond); + + assertEq(blk.livenessBond, 0); + assertEq(blk.livenessBondNotReturned, true); proposedAt = blk.proposedAt; - assertEq(tko.balanceOf(Alice), 10_000 ether); - assertEq(tko.balanceOf(Bob), 10_000 ether - livenessBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); } // Prove the block @@ -407,9 +406,9 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { bytes32 blockHash = bytes32(uint256(10)); bytes32 stateRoot = bytes32(uint256(11)); - console2.log("====== Bob proves the block outside the proving window"); + console2.log("====== Alice proves the block outside the proving window"); mineAndWrap(7 days); - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); uint256 provenAt; @@ -420,21 +419,22 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); assertEq(blk.proposedAt, proposedAt); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); + assertEq(blk.livenessBondNotReturned, false); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); assertEq(ts.blockHash, blockHash); assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_OPTIMISTIC); assertEq(ts.contester, address(0)); - assertEq(ts.prover, Bob); + assertEq(ts.prover, Alice); assertEq(ts.validityBond, tierOp.validityBond); assertEq(ts.timestamp, block.timestamp); provenAt = ts.timestamp; - assertEq(tko.balanceOf(Bob), 10_000 ether - tierOp.validityBond - livenessBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond - livenessBond); } console2.log("====== Verify block"); @@ -447,48 +447,19 @@ contract TaikoL1TestGroup1 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 1); assertEq(blk.proposedAt, proposedAt); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); + assertEq(blk.livenessBondNotReturned, false); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); assertEq(ts.blockHash, blockHash); assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_OPTIMISTIC); assertEq(ts.contester, address(0)); - assertEq(ts.prover, Bob); + assertEq(ts.prover, Alice); assertEq(ts.validityBond, tierOp.validityBond); assertEq(ts.timestamp, provenAt); - assertEq(tko.balanceOf(Bob), 10_000 ether - livenessBond); - } - } - - // Test summary: - // 1. Alice proposes a block, assigning herself as the prover. - function test_taikoL1_group_1_case_7_no_hooks() external { - vm.warp(1_000_000); - printBlockAndTrans(0); - - giveEthAndTko(Alice, 10_000 ether, 1000 ether); - - console2.log("====== Alice propose a block with herself as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Alice, ""); - - uint96 livenessBond = L1.getConfig().livenessBond; - uint256 proposedAt; - { - printBlockAndTrans(meta.id); - TaikoData.Block memory blk = L1.getBlock(meta.id); - assertEq(meta.minTier, LibTiers.TIER_OPTIMISTIC); - - assertEq(blk.nextTransitionId, 1); - assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.proposedAt, block.timestamp); - assertEq(blk.assignedProver, Alice); - assertEq(blk.livenessBond, livenessBond); - - proposedAt = blk.proposedAt; - assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); } } diff --git a/packages/protocol/test/L1/TaikoL1TestGroup2.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup2.t.sol index 92d9b4dbc00..bc93867bba2 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup2.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup2.t.sol @@ -5,33 +5,32 @@ import "./TaikoL1TestGroupBase.sol"; contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { // Test summary: - // 1. Alice proposes a block, Bob as the prover. - // 2. Bob proves the block within the proving window, with correct parent hash. - // 3. Taylor contests Bob's proof. - // 4. William proves Bob is correct and Taylor is wrong. + // 1. Alice proposes a block + // 2. Alice proves the block within the proving window, with correct parent hash. + // 3. Taylor contests Alice's proof. + // 4. William proves Alice is correct and Taylor is wrong. // 5. William's proof is used to verify the block. function test_taikoL1_group_2_case_1() external { vm.warp(1_000_000); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); giveEthAndTko(Taylor, 10_000 ether, 1000 ether); giveEthAndTko(William, 10_000 ether, 1000 ether); ITierProvider.Tier memory tierOp = TestTierProvider(cp).getTier(LibTiers.TIER_OPTIMISTIC); ITierProvider.Tier memory tierSgx = TestTierProvider(cp).getTier(LibTiers.TIER_SGX); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); - console2.log("====== Bob proves the block as the assigned prover"); + console2.log("====== Alice proves the block as the assigned prover"); bytes32 parentHash = GENESIS_BLOCK_HASH; bytes32 blockHash = bytes32(uint256(10)); bytes32 stateRoot = bytes32(uint256(11)); mineAndWrap(10 seconds); - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); - console2.log("====== Taylor contests Bob"); + console2.log("====== Taylor contests Alice"); bytes32 blockHash2 = bytes32(uint256(20)); bytes32 stateRoot2 = bytes32(uint256(21)); mineAndWrap(10 seconds); @@ -43,7 +42,7 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -53,14 +52,14 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { assertEq(ts.contester, Taylor); assertEq(ts.contestBond, tierOp.contestBond); assertEq(ts.validityBond, tierOp.validityBond); - assertEq(ts.prover, Bob); + assertEq(ts.prover, Alice); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Bob), 10_000 ether - tierOp.validityBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.contestBond); } - console2.log("====== William proves Bob is right"); + console2.log("====== William proves Alice is right"); mineAndWrap(10 seconds); proveBlock(William, meta, parentHash, blockHash, stateRoot, LibTiers.TIER_SGX, ""); @@ -70,7 +69,7 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -82,7 +81,7 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { assertEq(ts.prover, William); assertEq(ts.timestamp, block.timestamp); // not zero - assertEq(tko.balanceOf(Bob), 10_000 ether); + assertEq(tko.balanceOf(Alice), 10_000 ether); assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.contestBond); assertEq( tko.balanceOf(William), @@ -100,7 +99,7 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 1); - assertEq(blk.assignedProver, Bob); + // assertEq(blk.livenessBond, livenessBond); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -114,33 +113,32 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { } // Test summary: - // 1. Alice proposes a block, Bob as the prover. - // 2. Bob proves the block within the proving window, with correct parent hash. - // 3. Taylor contests Bob's proof. - // 4. William proves Taylor is correct and Bob is wrong. + // 1. Alice proposes a block + // 2. Alice proves the block within the proving window, with correct parent hash. + // 3. Taylor contests Alice's proof. + // 4. William proves Taylor is correct and Alice is wrong. // 5. William's proof is used to verify the block. function test_taikoL1_group_2_case_2() external { vm.warp(1_000_000); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); giveEthAndTko(Taylor, 10_000 ether, 1000 ether); giveEthAndTko(William, 10_000 ether, 1000 ether); ITierProvider.Tier memory tierOp = TestTierProvider(cp).getTier(LibTiers.TIER_OPTIMISTIC); ITierProvider.Tier memory tierSgx = TestTierProvider(cp).getTier(LibTiers.TIER_SGX); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); - console2.log("====== Bob proves the block as the assigned prover"); + console2.log("====== Alice proves the block as the assigned prover"); bytes32 parentHash = GENESIS_BLOCK_HASH; bytes32 blockHash = bytes32(uint256(10)); bytes32 stateRoot = bytes32(uint256(11)); mineAndWrap(10 seconds); - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); - console2.log("====== Taylor contests Bob"); + console2.log("====== Taylor contests Alice"); bytes32 blockHash2 = bytes32(uint256(20)); bytes32 stateRoot2 = bytes32(uint256(21)); mineAndWrap(10 seconds); @@ -152,7 +150,7 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -162,10 +160,10 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { assertEq(ts.contester, Taylor); assertEq(ts.contestBond, tierOp.contestBond); assertEq(ts.validityBond, tierOp.validityBond); - assertEq(ts.prover, Bob); + assertEq(ts.prover, Alice); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Bob), 10_000 ether - tierOp.validityBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.contestBond); } @@ -179,7 +177,7 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -191,7 +189,7 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { assertEq(ts.prover, William); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Bob), 10_000 ether - tierOp.validityBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); uint256 quarterReward = tierOp.validityBond * 7 / 8 / 4; assertEq(tko.balanceOf(Taylor), 10_000 ether + quarterReward * 3); @@ -208,7 +206,6 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 1); - assertEq(blk.assignedProver, Bob); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); assertEq(ts.blockHash, blockHash2); @@ -218,7 +215,7 @@ contract TaikoL1TestGroup2 is TaikoL1TestGroupBase { assertEq(ts.validityBond, tierSgx.validityBond); assertEq(ts.prover, William); - assertEq(tko.balanceOf(Bob), 10_000 ether - tierOp.validityBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); uint256 quarterReward = tierOp.validityBond * 7 / 8 / 4; assertEq(tko.balanceOf(Taylor), 10_000 ether + quarterReward * 3); diff --git a/packages/protocol/test/L1/TaikoL1TestGroup3.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup3.t.sol index 69d2f215f1f..795aaceb51b 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup3.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup3.t.sol @@ -5,7 +5,7 @@ import "./TaikoL1TestGroupBase.sol"; contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { // Test summary: - // 1. Alice proposes a block, assigning Bob as the prover. + // 1. Alice proposes a block // 2. James proves the block outside the proving window, using the correct parent hash. // 3. Taylor contests James' proof. // 4. William proves James is correct and Taylor is wrong. @@ -14,15 +14,14 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { vm.warp(1_000_000); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); giveEthAndTko(James, 10_000 ether, 1000 ether); giveEthAndTko(Taylor, 10_000 ether, 1000 ether); giveEthAndTko(William, 10_000 ether, 1000 ether); ITierProvider.Tier memory tierOp = TestTierProvider(cp).getTier(LibTiers.TIER_OPTIMISTIC); ITierProvider.Tier memory tierSgx = TestTierProvider(cp).getTier(LibTiers.TIER_SGX); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); uint96 livenessBond = L1.getConfig().livenessBond; @@ -46,7 +45,7 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -59,7 +58,7 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { assertEq(ts.prover, James); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Bob), 10_000 ether - livenessBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); assertEq(tko.balanceOf(James), 10_000 ether - tierOp.validityBond); assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.contestBond); } @@ -74,7 +73,7 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -86,7 +85,7 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { assertEq(ts.prover, William); assertEq(ts.timestamp, block.timestamp); // not zero - assertEq(tko.balanceOf(Bob), 10_000 ether - livenessBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.contestBond); assertEq( tko.balanceOf(William), @@ -104,7 +103,7 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 1); - assertEq(blk.assignedProver, Bob); + // assertEq(blk.livenessBond, livenessBond); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -118,7 +117,7 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { } // Test summary: - // 1. Alice proposes a block, Bob as the prover. + // 1. Alice proposes a block // 2. James proves the block outside the proving window, with correct parent hash. // 3. Taylor contests James' proof. // 4. William proves Taylor is correct and James is wrong. @@ -127,15 +126,14 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { vm.warp(1_000_000); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); giveEthAndTko(James, 10_000 ether, 1000 ether); giveEthAndTko(Taylor, 10_000 ether, 1000 ether); giveEthAndTko(William, 10_000 ether, 1000 ether); ITierProvider.Tier memory tierOp = TestTierProvider(cp).getTier(LibTiers.TIER_OPTIMISTIC); ITierProvider.Tier memory tierSgx = TestTierProvider(cp).getTier(LibTiers.TIER_SGX); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); uint96 livenessBond = L1.getConfig().livenessBond; @@ -159,7 +157,7 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -172,7 +170,7 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { assertEq(ts.prover, James); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Bob), 10_000 ether - livenessBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); assertEq(tko.balanceOf(James), 10_000 ether - tierOp.validityBond); assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.contestBond); } @@ -187,7 +185,7 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -199,7 +197,7 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { assertEq(ts.prover, William); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Bob), 10_000 ether - livenessBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); assertEq(tko.balanceOf(James), 10_000 ether - tierOp.validityBond); uint256 quarterReward = tierOp.validityBond * 7 / 8 / 4; @@ -217,7 +215,6 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 1); - assertEq(blk.assignedProver, Bob); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); assertEq(ts.blockHash, blockHash2); @@ -227,7 +224,7 @@ contract TaikoL1TestGroup3 is TaikoL1TestGroupBase { assertEq(ts.validityBond, tierSgx.validityBond); assertEq(ts.prover, William); - assertEq(tko.balanceOf(Bob), 10_000 ether - livenessBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); uint256 quarterReward = tierOp.validityBond * 7 / 8 / 4; assertEq(tko.balanceOf(James), 10_000 ether - tierOp.validityBond); diff --git a/packages/protocol/test/L1/TaikoL1TestGroup4.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup4.t.sol index d77857ba756..a4d74062498 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup4.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup4.t.sol @@ -5,32 +5,31 @@ import "./TaikoL1TestGroupBase.sol"; contract TaikoL1TestGroup4 is TaikoL1TestGroupBase { // Test summary: - // 1. Alice proposes a block, Bob is the prover. - // 2. Bob proves the block within the proving window, using the correct parent hash. - // 3. Taylor contests then proves Bob is wrong in the same transaction with a higher-tier + // 1. Alice proposes a block + // 2. Alice proves the block within the proving window, using the correct parent hash. + // 3. Taylor contests then proves Alice is wrong in the same transaction with a higher-tier // proof. // 4. Taylor's proof is used to verify the block. function test_taikoL1_group_4_case_1() external { vm.warp(1_000_000); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); giveEthAndTko(Taylor, 10_000 ether, 1000 ether); ITierProvider.Tier memory tierOp = TestTierProvider(cp).getTier(LibTiers.TIER_OPTIMISTIC); ITierProvider.Tier memory tierSgx = TestTierProvider(cp).getTier(LibTiers.TIER_SGX); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); - console2.log("====== Bob proves the block as the assigned prover"); + console2.log("====== Alice proves the block as the assigned prover"); bytes32 parentHash = GENESIS_BLOCK_HASH; bytes32 blockHash = bytes32(uint256(10)); bytes32 stateRoot = bytes32(uint256(11)); mineAndWrap(10 seconds); - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); - console2.log("====== Taylor contests Bob with a higher tier proof"); + console2.log("====== Taylor contests Alice with a higher tier proof"); bytes32 blockHash2 = bytes32(uint256(20)); bytes32 stateRoot2 = bytes32(uint256(21)); mineAndWrap(10 seconds); @@ -42,7 +41,7 @@ contract TaikoL1TestGroup4 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -54,7 +53,7 @@ contract TaikoL1TestGroup4 is TaikoL1TestGroupBase { assertEq(ts.prover, Taylor); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Bob), 10_000 ether - tierOp.validityBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); assertEq( tko.balanceOf(Taylor), 10_000 ether - tierSgx.validityBond + tierOp.validityBond * 7 / 8 @@ -71,7 +70,7 @@ contract TaikoL1TestGroup4 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 1); - assertEq(blk.assignedProver, Bob); + // assertEq(blk.livenessBond, livenessBond); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -85,7 +84,7 @@ contract TaikoL1TestGroup4 is TaikoL1TestGroupBase { } // Test summary: - // 1. Alice proposes a block, assigning Bob as the prover. + // 1. Alice proposes a block // 2. David proves the block outside the proving window, using the correct parent hash. // 3. Taylor contests then proves David is wrong in the same transaction with a higher-tier // proof. @@ -94,18 +93,17 @@ contract TaikoL1TestGroup4 is TaikoL1TestGroupBase { vm.warp(1_000_000); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); giveEthAndTko(David, 10_000 ether, 1000 ether); giveEthAndTko(Taylor, 10_000 ether, 1000 ether); ITierProvider.Tier memory tierOp = TestTierProvider(cp).getTier(LibTiers.TIER_OPTIMISTIC); ITierProvider.Tier memory tierSgx = TestTierProvider(cp).getTier(LibTiers.TIER_SGX); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); uint96 livenessBond = L1.getConfig().livenessBond; - console2.log("====== Bob proves the block as the assigned prover"); + console2.log("====== Alice proves the block as the assigned prover"); bytes32 parentHash = GENESIS_BLOCK_HASH; bytes32 blockHash = bytes32(uint256(10)); bytes32 stateRoot = bytes32(uint256(11)); @@ -125,7 +123,7 @@ contract TaikoL1TestGroup4 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -137,7 +135,7 @@ contract TaikoL1TestGroup4 is TaikoL1TestGroupBase { assertEq(ts.prover, Taylor); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Bob), 10_000 ether - livenessBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); assertEq(tko.balanceOf(David), 10_000 ether - tierOp.validityBond); assertEq( tko.balanceOf(Taylor), @@ -155,7 +153,7 @@ contract TaikoL1TestGroup4 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 1); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); diff --git a/packages/protocol/test/L1/TaikoL1TestGroup5.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup5.t.sol index 552542702a6..33092602c05 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup5.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup5.t.sol @@ -5,7 +5,7 @@ import "./TaikoL1TestGroupBase.sol"; contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { // Test summary: - // 1. Alice proposes a block, assigning Bob as the prover. + // 1. Alice proposes a block // 2. Guardian prover directly proves the block. // 3. Guardian prover re-proves the same transition and fails. // 4. Guardian prover proves the block again with a different transition. @@ -17,8 +17,8 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { giveEthAndTko(Bob, 10_000 ether, 1000 ether); giveEthAndTko(William, 10_000 ether, 1000 ether); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); console2.log("====== Guardian prover proves"); bytes32 parentHash = GENESIS_BLOCK_HASH; @@ -34,7 +34,7 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -74,7 +74,7 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -112,7 +112,7 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 1); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -127,8 +127,8 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { } // Test summary: - // 1. Alice proposes a block, Bob is the prover. - // 2. Bob proves the block. + // 1. Alice proposes a block. + // 2. Alice proves the block. // 3. Guardian prover re-proves the same transition and fails. // 4. Guardian prover proves the block with a different transition. // 5. William contests the guardian prover using a lower-tier proof and fails. @@ -136,12 +136,11 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { vm.warp(1_000_000); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); giveEthAndTko(William, 10_000 ether, 1000 ether); ITierProvider.Tier memory tierOp = TestTierProvider(cp).getTier(LibTiers.TIER_OPTIMISTIC); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); console2.log("====== Bob proves the block"); bytes32 parentHash = GENESIS_BLOCK_HASH; @@ -149,7 +148,7 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { bytes32 stateRoot = bytes32(uint256(11)); mineAndWrap(10 seconds); - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); console2.log("====== Guardian re-approve with the same transition"); mineAndWrap(10 seconds); @@ -175,7 +174,7 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -187,7 +186,7 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.prover, address(gp)); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Bob), 10_000 ether - tierOp.validityBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); assertEq(tko.balanceOf(William), 10_000 ether); } @@ -201,7 +200,7 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 1); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -210,13 +209,13 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.tier, LibTiers.TIER_GUARDIAN); assertEq(ts.prover, address(gp)); - assertEq(tko.balanceOf(Bob), 10_000 ether - tierOp.validityBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - tierOp.validityBond); assertEq(tko.balanceOf(William), 10_000 ether); } } // Test summary: - // 1. Alice proposes a block, assigning Bob as the prover. + // 1. Alice proposes a block // 2. David proves the block outside the proving window. // 3. Guardian prover re-proves the same transition and fails. // 4. Guardian prover proves the block with a different transition. @@ -225,13 +224,12 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { vm.warp(1_000_000); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); giveEthAndTko(David, 10_000 ether, 1000 ether); giveEthAndTko(William, 10_000 ether, 1000 ether); ITierProvider.Tier memory tierOp = TestTierProvider(cp).getTier(LibTiers.TIER_OPTIMISTIC); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); uint96 livenessBond = L1.getConfig().livenessBond; @@ -267,7 +265,6 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.assignedProver, Bob); assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -279,7 +276,7 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.prover, address(gp)); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Bob), 10_000 ether - livenessBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); assertEq(tko.balanceOf(David), 10_000 ether - tierOp.validityBond); assertEq(tko.balanceOf(William), 10_000 ether); } @@ -294,7 +291,6 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 1); - assertEq(blk.assignedProver, Bob); assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -303,24 +299,23 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.tier, LibTiers.TIER_GUARDIAN); assertEq(ts.prover, address(gp)); - assertEq(tko.balanceOf(Bob), 10_000 ether - livenessBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - livenessBond); assertEq(tko.balanceOf(David), 10_000 ether - tierOp.validityBond); assertEq(tko.balanceOf(William), 10_000 ether); } } // Test summary: - // 1. Alice proposes a block, assigning Bob as the prover. + // 1. Alice proposes a block // 2. Guardian prover directly proves the block out of proving window function test_taikoL1_group_5_case_4() external { vm.warp(1_000_000); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); giveEthAndTko(William, 10_000 ether, 1000 ether); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); console2.log("====== Guardian prover proves"); bytes32 parentHash = GENESIS_BLOCK_HASH; @@ -336,7 +331,7 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -348,7 +343,7 @@ contract TaikoL1TestGroup5 is TaikoL1TestGroupBase { assertEq(ts.prover, address(gp)); assertEq(ts.timestamp, block.timestamp); - assertEq(tko.balanceOf(Bob), 10_000 ether - L1.getConfig().livenessBond); + assertEq(tko.balanceOf(Alice), 10_000 ether - L1.getConfig().livenessBond); assertEq(tko.balanceOf(William), 10_000 ether); } } diff --git a/packages/protocol/test/L1/TaikoL1TestGroup6.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup6.t.sol index 3241a3efef4..c42794b3bcc 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup6.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup6.t.sol @@ -5,7 +5,7 @@ import "./TaikoL1TestGroupBase.sol"; contract TaikoL1TestGroup6 is TaikoL1TestGroupBase { // Test summary: - // 1. Alice proposes a block, assigning Bob as the prover. + // 1. Alice proposes a block // 2. Bob proves the block within the proving window, using the correct parent hash. // 3. Taylor contests Bob's proof. // 4. Bob re-proves his proof, showing Taylor is incorrect. @@ -19,8 +19,8 @@ contract TaikoL1TestGroup6 is TaikoL1TestGroupBase { ITierProvider.Tier memory tierOp = TestTierProvider(cp).getTier(LibTiers.TIER_OPTIMISTIC); ITierProvider.Tier memory tierSgx = TestTierProvider(cp).getTier(LibTiers.TIER_SGX); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); console2.log("====== Bob proves the block as the assigned prover"); bytes32 parentHash = GENESIS_BLOCK_HASH; @@ -28,7 +28,7 @@ contract TaikoL1TestGroup6 is TaikoL1TestGroupBase { bytes32 stateRoot = bytes32(uint256(11)); mineAndWrap(10 seconds); - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); console2.log("====== Taylor contests Bob"); bytes32 blockHash2 = bytes32(uint256(20)); @@ -38,7 +38,7 @@ contract TaikoL1TestGroup6 is TaikoL1TestGroupBase { console2.log("====== Bob cannot proves himself is right"); mineAndWrap(10 seconds); - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, LibTiers.TIER_SGX, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, LibTiers.TIER_SGX, ""); { printBlockAndTrans(meta.id); @@ -46,7 +46,7 @@ contract TaikoL1TestGroup6 is TaikoL1TestGroupBase { TaikoData.Block memory blk = L1.getBlock(meta.id); assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); @@ -55,12 +55,13 @@ contract TaikoL1TestGroup6 is TaikoL1TestGroupBase { assertEq(ts.tier, LibTiers.TIER_SGX); assertEq(ts.contester, address(0)); assertEq(ts.validityBond, tierSgx.validityBond); - assertEq(ts.prover, Bob); + assertEq(ts.prover, Alice); assertEq(ts.timestamp, block.timestamp); // not zero assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.contestBond); assertEq( - tko.balanceOf(Bob), 10_000 ether - tierSgx.validityBond + tierOp.contestBond * 7 / 8 + tko.balanceOf(Alice), + 10_000 ether - tierSgx.validityBond + tierOp.contestBond * 7 / 8 ); } @@ -74,17 +75,17 @@ contract TaikoL1TestGroup6 is TaikoL1TestGroupBase { assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 1); - assertEq(blk.assignedProver, Bob); + assertEq(blk.livenessBond, 0); TaikoData.TransitionState memory ts = L1.getTransition(meta.id, 1); assertEq(ts.blockHash, blockHash); assertEq(ts.stateRoot, stateRoot); assertEq(ts.tier, LibTiers.TIER_SGX); - assertEq(ts.prover, Bob); + assertEq(ts.prover, Alice); assertEq(tko.balanceOf(Taylor), 10_000 ether - tierOp.contestBond); - assertEq(tko.balanceOf(Bob), 10_000 ether + tierOp.contestBond * 7 / 8); + assertEq(tko.balanceOf(Alice), 10_000 ether + tierOp.contestBond * 7 / 8); } } } diff --git a/packages/protocol/test/L1/TaikoL1TestGroup7.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup7.t.sol index e2b9897e46a..bc0da12f0a9 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup7.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup7.t.sol @@ -5,19 +5,18 @@ import "./TaikoL1TestGroupBase.sol"; contract TaikoL1TestGroup7 is TaikoL1TestGroupBase { // Test summary: - // 1. Alice proposes a block, assigning Bob as the prover. - // 2. Bob proves the block within the proving window, using the correct parent hash. - // 3. After the cooldown window, Taylor contests Bob's proof, and fails. + // 1. Alice proposes a block + // 2. Alice proves the block within the proving window, using the correct parent hash. + // 3. After the cooldown window, Taylor contests Alice's proof, and fails. function test_taikoL1_group_7_case_1() external { vm.warp(1_000_000); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); giveEthAndTko(Taylor, 10_000 ether, 1000 ether); ITierProvider.Tier memory tierOp = TestTierProvider(cp).getTier(LibTiers.TIER_OPTIMISTIC); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); console2.log("====== Bob proves the block as the assigned prover"); bytes32 parentHash = GENESIS_BLOCK_HASH; @@ -25,7 +24,7 @@ contract TaikoL1TestGroup7 is TaikoL1TestGroupBase { bytes32 stateRoot = bytes32(uint256(11)); mineAndWrap(10 seconds); - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); mineAndWrap(tierOp.cooldownWindow * 60); bytes32 blockHash2 = bytes32(uint256(20)); @@ -43,29 +42,28 @@ contract TaikoL1TestGroup7 is TaikoL1TestGroupBase { } // Test summary: - // 1. Alice proposes a block, assigning Bob as the prover. - // 2. Bob proves the block within the proving window, using the correct parent hash. - // 3. Taylor contests Bob's proof. - // 4. William attempts but fails to contest Bob again. + // 1. Alice proposes a block + // 2. Alice proves the block within the proving window, using the correct parent hash. + // 3. Taylor contests Alice's proof. + // 4. William attempts but fails to contest Alice again. function test_taikoL1_group_7_case_2() external { vm.warp(1_000_000); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); giveEthAndTko(Taylor, 10_000 ether, 1000 ether); giveEthAndTko(William, 10_000 ether, 1000 ether); ITierProvider.Tier memory tierOp = TestTierProvider(cp).getTier(LibTiers.TIER_OPTIMISTIC); - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); - console2.log("====== Bob proves the block as the assigned prover"); + console2.log("====== Alice proves the block as the assigned prover"); bytes32 parentHash = GENESIS_BLOCK_HASH; bytes32 blockHash = bytes32(uint256(10)); bytes32 stateRoot = bytes32(uint256(11)); mineAndWrap(10 seconds); - proveBlock(Bob, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash, blockHash, stateRoot, meta.minTier, ""); mineAndWrap(tierOp.cooldownWindow * 60 - 1); bytes32 blockHash2 = bytes32(uint256(20)); diff --git a/packages/protocol/test/L1/TaikoL1TestGroup8.t.sol b/packages/protocol/test/L1/TaikoL1TestGroup8.t.sol index 913ad55eef1..cf504c82799 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroup8.t.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroup8.t.sol @@ -5,34 +5,31 @@ import "./TaikoL1TestGroupBase.sol"; contract TaikoL1TestGroup8 is TaikoL1TestGroupBase { // Test summary: - // 1. Alice proposes a block, assigning Bob as the prover. + // 1. Alice proposes a block. // 2. TaikoL1 is paused. - // 3. Bob attempts to prove the block within the proving window. + // 3. Alice attempts to prove the block within the proving window. // 4. Alice tries to propose another block. // 5. TaikoL1 is unpaused. - // 6. Bob attempts again to prove the first block within the proving window. + // 6. Alice attempts again to prove the first block within the proving window. // 7. Alice tries to propose another block. function test_taikoL1_group_8_case_1() external { vm.warp(1_000_000); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); - - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); console2.log("====== Pause TaikoL1"); mineAndWrap(10 seconds); vm.prank(L1.owner()); L1.pause(); - console2.log("====== Bob proves the block first after L1 paused"); - + console2.log("====== Alice proves the block first after L1 paused"); bytes32 parentHash1 = GENESIS_BLOCK_HASH; bytes32 blockHash = bytes32(uint256(10)); bytes32 stateRoot = bytes32(uint256(11)); proveBlock( - Bob, + Alice, meta, parentHash1, blockHash, @@ -42,21 +39,21 @@ contract TaikoL1TestGroup8 is TaikoL1TestGroupBase { ); console2.log("====== Alice tries to propose another block after L1 paused"); - proposeBlock(Alice, Bob, EssentialContract.INVALID_PAUSE_STATUS.selector); + proposeBlock(Alice, EssentialContract.INVALID_PAUSE_STATUS.selector); console2.log("====== Unpause TaikoL1"); mineAndWrap(10 seconds); vm.prank(L1.owner()); L1.unpause(); - console2.log("====== Bob proves the block first after L1 unpaused"); - proveBlock(Bob, meta, parentHash1, blockHash, stateRoot, meta.minTier, ""); + console2.log("====== Alice proves the block first after L1 unpaused"); + proveBlock(Alice, meta, parentHash1, blockHash, stateRoot, meta.minTier, ""); console2.log("====== Alice tries to propose another block after L1 unpaused"); - proposeBlock(Alice, Bob, ""); + proposeBlock(Alice, ""); } // Test summary: - // 1. Alice proposes a block, assigning Bob as the prover. + // 1. Alice proposes a block. // 2. TaikoL1 proving is paused. // 3. Bob attempts to prove the block within the proving window. // 4. Alice tries to propose another block. @@ -66,24 +63,22 @@ contract TaikoL1TestGroup8 is TaikoL1TestGroupBase { function test_taikoL1_group_8_case_2() external { vm.warp(1_000_000); giveEthAndTko(Alice, 10_000 ether, 1000 ether); - giveEthAndTko(Bob, 10_000 ether, 1000 ether); - - console2.log("====== Alice propose a block with bob as the assigned prover"); - TaikoData.BlockMetadata memory meta = proposeBlock(Alice, Bob, ""); + console2.log("====== Alice propose a block"); + TaikoData.BlockMetadataV2 memory meta = proposeBlock(Alice, ""); console2.log("====== Pause TaikoL1 proving"); mineAndWrap(10 seconds); vm.prank(L1.owner()); L1.pauseProving(true); - console2.log("====== Bob proves the block first after L1 proving paused"); + console2.log("====== Alice proves the block first after L1 proving paused"); bytes32 parentHash1 = GENESIS_BLOCK_HASH; bytes32 blockHash = bytes32(uint256(10)); bytes32 stateRoot = bytes32(uint256(11)); proveBlock( - Bob, + Alice, meta, parentHash1, blockHash, @@ -93,7 +88,7 @@ contract TaikoL1TestGroup8 is TaikoL1TestGroupBase { ); console2.log("====== Alice tries to propose another block after L1 proving paused"); - proposeBlock(Alice, Bob, ""); + proposeBlock(Alice, ""); console2.log("====== Unpause TaikoL1 proving"); mineAndWrap(10 seconds); @@ -101,7 +96,7 @@ contract TaikoL1TestGroup8 is TaikoL1TestGroupBase { L1.pauseProving(false); console2.log("====== Bob proves the block first after L1 proving unpaused"); - proveBlock(Bob, meta, parentHash1, blockHash, stateRoot, meta.minTier, ""); + proveBlock(Alice, meta, parentHash1, blockHash, stateRoot, meta.minTier, ""); } // Test summary: diff --git a/packages/protocol/test/L1/TaikoL1TestGroupBase.sol b/packages/protocol/test/L1/TaikoL1TestGroupBase.sol index c92462a030a..b53fc82422c 100644 --- a/packages/protocol/test/L1/TaikoL1TestGroupBase.sol +++ b/packages/protocol/test/L1/TaikoL1TestGroupBase.sol @@ -22,33 +22,16 @@ abstract contract TaikoL1TestGroupBase is TaikoL1TestBase { function proposeBlock( address proposer, - address assignedProver, bytes4 revertReason ) internal - returns (TaikoData.BlockMetadata memory meta) + returns (TaikoData.BlockMetadataV2 memory meta) { TaikoData.TierFee[] memory tierFees = new TaikoData.TierFee[](2); tierFees[0] = TaikoData.TierFee(LibTiers.TIER_OPTIMISTIC, 1 ether); tierFees[1] = TaikoData.TierFee(LibTiers.TIER_SGX, 2 ether); - AssignmentHook.ProverAssignment memory assignment = AssignmentHook.ProverAssignment({ - feeToken: address(0), - tierFees: tierFees, - expiry: uint64(block.timestamp + 60 minutes), - maxBlockId: 0, - maxProposedIn: 0, - metaHash: 0, - parentMetaHash: 0, - signature: new bytes(0) - }); - bytes memory txList = new bytes(10); - assignment.signature = - _signAssignment(assignedProver, assignment, address(L1), proposer, keccak256(txList)); - - TaikoData.HookCall[] memory hookcalls = new TaikoData.HookCall[](1); - hookcalls[0] = TaikoData.HookCall(address(assignmentHook), abi.encode(assignment)); bytes memory eoaSig; { @@ -67,17 +50,23 @@ abstract contract TaikoL1TestGroupBase is TaikoL1TestBase { eoaSig = abi.encodePacked(r, s, v); } + (, TaikoData.SlotB memory b) = L1.getStateVariables(); + TaikoData.Config memory config = L1.getConfig(); + + TaikoData.HookCall[] memory hookcalls; + + bytes memory paramEncoded = b.numBlocks < config.forkHeight + ? abi.encode(TaikoData.BlockParams(address(0), address(0), 0, 0, hookcalls, eoaSig)) + : abi.encode(TaikoData.BlockParamsV2(address(0), 0, 0, "")); + vm.prank(proposer); if (revertReason != "") vm.expectRevert(revertReason); - (meta,) = L1.proposeBlock{ value: 3 ether }( - abi.encode(TaikoData.BlockParams(assignedProver, address(0), 0, 0, hookcalls, eoaSig)), - txList - ); + meta = L1.proposeBlock{ value: 3 ether }(paramEncoded, txList); } function proveBlock( address prover, - TaikoData.BlockMetadata memory meta, + TaikoData.BlockMetadataV2 memory meta, bytes32 parentHash, bytes32 blockHash, bytes32 stateRoot, @@ -150,7 +139,6 @@ abstract contract TaikoL1TestGroupBase is TaikoL1TestBase { console2.log(" | numBlocks:", b.numBlocks); console2.log(" | timestamp:", block.timestamp); console2.log("---BLOCK#", blk.blockId); - console2.log(" | assignedProver:", blk.assignedProver); console2.log(" | livenessBond:", blk.livenessBond); console2.log(" | proposedAt:", blk.proposedAt); console2.log(" | metaHash:", vm.toString(blk.metaHash)); diff --git a/packages/protocol/test/TaikoTest.sol b/packages/protocol/test/TaikoTest.sol index 025d9666193..dc6188a0879 100644 --- a/packages/protocol/test/TaikoTest.sol +++ b/packages/protocol/test/TaikoTest.sol @@ -18,7 +18,6 @@ import "../contracts/L1/TaikoL1.sol"; import "../contracts/verifiers/SgxVerifier.sol"; import "../contracts/verifiers/RiscZeroVerifier.sol"; import "../test/L1/TestTierProvider.sol"; -import "../contracts/L1/hooks/AssignmentHook.sol"; import "../contracts/L1/provers/GuardianProver.sol"; import "../contracts/bridge/QuotaManager.sol";