Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(protocol): remove the blob-reuse feature #16439

Merged
merged 6 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 3 additions & 19 deletions packages/protocol/contracts/L1/TaikoData.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@ library TaikoData {
uint64 maxBlocksToVerifyPerProposal;
// The maximum gas limit allowed for a block.
uint32 blockMaxGasLimit;
// The maximum allowed bytes for the proposed transaction list calldata.
uint24 blockMaxTxListBytes;
// The max period in seconds that a blob can be reused for DA.
uint24 blobExpiry;
// True if EIP-4844 is enabled for DA
bool blobAllowedForDA;
// True if blob can be reused
bool blobReuseEnabled;
// ---------------------------------------------------------------------
// Group 3: Proof related configs
// ---------------------------------------------------------------------
Expand Down Expand Up @@ -79,10 +71,6 @@ library TaikoData {
address assignedProver;
address coinbase;
bytes32 extraData;
bytes32 blobHash;
uint24 txListByteOffset;
uint24 txListByteSize;
bool cacheBlobForReuse;
bytes32 parentMetaHash;
HookCall[] hookCalls;
}
Expand All @@ -102,8 +90,6 @@ library TaikoData {
uint32 gasLimit;
uint64 timestamp;
uint64 l1Height;
uint24 txListByteOffset;
uint24 txListByteSize;
uint16 minTier;
bool blobUsed;
bytes32 parentMetaHash;
Expand Down Expand Up @@ -189,10 +175,8 @@ library TaikoData {
) transitions;
// Ring buffer for Ether deposits
mapping(uint256 depositId_mod_ethDepositRingBufferSize => uint256 depositAmount) ethDeposits;
// Reusable blobs
mapping(bytes32 blobHash => uint256 since) reusableBlobs;
SlotA slotA; // slot 6
SlotB slotB; // slot 7
uint256[43] __gap;
SlotA slotA; // slot 5
SlotB slotB; // slot 6
uint256[44] __gap;
}
}
5 changes: 1 addition & 4 deletions packages/protocol/contracts/L1/TaikoErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ abstract contract TaikoErrors {
error L1_ALREADY_CONTESTED();
error L1_ALREADY_PROVED();
error L1_ASSIGNED_PROVER_NOT_ALLOWED();
error L1_BLOB_FOR_DA_DISABLED();
error L1_BLOB_NOT_AVAILABLE();
error L1_BLOB_NOT_FOUND();
error L1_BLOB_NOT_REUSABLE();
error L1_BLOB_REUSE_DISABLED();
error L1_BLOCK_MISMATCH();
error L1_INVALID_BLOCK_ID();
error L1_INVALID_CONFIG();
Expand All @@ -36,7 +34,6 @@ abstract contract TaikoErrors {
error L1_TOO_MANY_TIERS();
error L1_TRANSITION_ID_ZERO();
error L1_TRANSITION_NOT_FOUND();
error L1_TXLIST_SIZE();
error L1_UNAUTHORIZED();
error L1_UNEXPECTED_PARENT();
error L1_UNEXPECTED_TRANSITION_ID();
Expand Down
4 changes: 0 additions & 4 deletions packages/protocol/contracts/L1/TaikoEvents.sol
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,6 @@ abstract contract TaikoEvents {
uint16 tier
);

/// @dev Emitted when a blob is cached for reuse.
/// @param blobHash The blobHash cached.
event BlobCached(bytes32 blobHash);

/// @dev Emitted when proving has been paused
/// @param paused True if paused, false if unpaused.
event ProvingPaused(bool paused);
Expand Down
12 changes: 0 additions & 12 deletions packages/protocol/contracts/L1/TaikoL1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,6 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents, TaikoErrors {
return LibDepositing.canDepositEthToL2(state, getConfig(), _amount);
}

/// @notice See {LibProposing-isBlobReusable}.
function isBlobReusable(bytes32 _blobHash) public view returns (bool) {
return LibProposing.isBlobReusable(state, getConfig(), _blobHash);
}

/// @notice Gets the details of a block.
/// @param _blockId Index of the block.
/// @return blk_ The block.
Expand Down Expand Up @@ -197,13 +192,6 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents, TaikoErrors {
// Can be overridden by the tier config.
maxBlocksToVerifyPerProposal: 10,
blockMaxGasLimit: 15_000_000,
// Each go-ethereum transaction has a size limit of 128KB,
// and right now txList is still saved in calldata, so we set it
// to 120KB.
blockMaxTxListBytes: 120_000,
blobExpiry: 24 hours,
blobAllowedForDA: false,
blobReuseEnabled: false,
livenessBond: 250e18, // 250 Taiko token
// ETH deposit related.
ethDepositRingBufferSize: 1024,
Expand Down
89 changes: 9 additions & 80 deletions packages/protocol/contracts/L1/libs/LibProposing.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@ import "./LibDepositing.sol";
library LibProposing {
using LibAddress for address;

/// @notice The maximum number of bytes allowed per blob.
/// @dev According to EIP4844, each blob has up to 4096 field elements, and each
/// field element has 32 bytes.
uint256 public constant MAX_BYTES_PER_BLOB = 4096 * 32;

// 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.
Expand All @@ -36,23 +31,15 @@ library LibProposing {
TaikoData.EthDeposit[] depositsProcessed
);

/// @notice Emitted when a blob is cached.
/// @param blobHash The hash of the cached blob.
event BlobCached(bytes32 blobHash);

// Warning: Any errors defined here must also be defined in TaikoErrors.sol.
error L1_BLOB_FOR_DA_DISABLED();
error L1_BLOB_NOT_AVAILABLE();
error L1_BLOB_NOT_FOUND();
error L1_BLOB_NOT_REUSABLE();
error L1_BLOB_REUSE_DISABLED();
error L1_INVALID_HOOK();
error L1_INVALID_PARAM();
error L1_INVALID_PROVER();
error L1_LIVENESS_BOND_NOT_RECEIVED();
error L1_PROPOSER_NOT_EOA();
error L1_TOO_MANY_BLOCKS();
error L1_TXLIST_OFFSET();
error L1_TXLIST_SIZE();
error L1_UNAUTHORIZED();
error L1_UNEXPECTED_PARENT();

Expand Down Expand Up @@ -129,8 +116,6 @@ library LibProposing {
gasLimit: _config.blockMaxGasLimit,
timestamp: uint64(block.timestamp),
l1Height: uint64(block.number - 1),
txListByteOffset: 0, // to be initialized below
txListByteSize: 0, // to be initialized below
minTier: 0, // to be initialized below
blobUsed: _txList.length == 0,
parentMetaHash: parentMetaHash,
Expand All @@ -140,61 +125,22 @@ library LibProposing {

// Update certain meta fields
if (meta_.blobUsed) {
if (!_config.blobAllowedForDA) revert L1_BLOB_FOR_DA_DISABLED();

if (params.blobHash != 0) {
if (!_config.blobReuseEnabled) revert L1_BLOB_REUSE_DISABLED();

// We try to reuse an old blob
if (!isBlobReusable(_state, _config, params.blobHash)) {
revert L1_BLOB_NOT_REUSABLE();
}
meta_.blobHash = params.blobHash;
} else {
// Always use the first blob in this transaction. If the
// proposeBlock functions are called more than once in the same
// L1 transaction, these multiple L2 blocks will share the same
// blob.
meta_.blobHash = blobhash(0);

if (meta_.blobHash == 0) revert L1_BLOB_NOT_FOUND();

// Depends on the blob data price, it may not make sense to
// cache the blob which costs 20,000 (sstore) + 631 (event)
// extra gas.
if (_config.blobReuseEnabled && params.cacheBlobForReuse) {
_state.reusableBlobs[meta_.blobHash] = block.timestamp;
emit BlobCached(meta_.blobHash);
}
}

// Check that the txList data range is within the max size of a blob
if (uint256(params.txListByteOffset) + params.txListByteSize > MAX_BYTES_PER_BLOB) {
revert L1_TXLIST_OFFSET();
}

meta_.txListByteOffset = params.txListByteOffset;
meta_.txListByteSize = params.txListByteSize;
if (block.chainid != 1) revert L1_BLOB_NOT_AVAILABLE();

// Always use the first blob in this transaction. If the
// proposeBlock functions are called more than once in the same
// L1 transaction, these multiple L2 blocks will share the same
// blob.
meta_.blobHash = blobhash(0);
if (meta_.blobHash == 0) revert L1_BLOB_NOT_FOUND();
} else {
// The proposer must be an Externally Owned Account (EOA) for
// calldata usage. This ensures that the transaction is not an
// internal one, making calldata retrieval more straightforward for
// Taiko node software.
if (!LibAddress.isSenderEOA()) revert L1_PROPOSER_NOT_EOA();

// The txList is the full byte array without any offset
if (params.txListByteOffset != 0) {
revert L1_INVALID_PARAM();
}

meta_.blobHash = keccak256(_txList);
meta_.txListByteOffset = 0;
meta_.txListByteSize = uint24(_txList.length);
}

// Check that the tx length is non-zero and within the supported range
if (meta_.txListByteSize == 0 || meta_.txListByteSize > _config.blockMaxTxListBytes) {
revert L1_TXLIST_SIZE();
}

// Following the Merge, the L1 mixHash incorporates the
Expand Down Expand Up @@ -280,23 +226,6 @@ library LibProposing {
});
}

/// @notice Checks if a blob is reusable.
/// @param _state Current TaikoData.State.
/// @param _config The TaikoData.Config.
/// @param _blobHash The blob hash
/// @return true if the blob is reusable, false otherwise.
function isBlobReusable(
TaikoData.State storage _state,
TaikoData.Config memory _config,
bytes32 _blobHash
)
internal
view
returns (bool)
{
return _state.reusableBlobs[_blobHash] + _config.blobExpiry > block.timestamp;
}

function _isProposerPermitted(
TaikoData.SlotB memory _slotB,
IAddressResolver _resolver
Expand Down
6 changes: 2 additions & 4 deletions packages/protocol/contracts/L1/libs/LibVerifying.sol
Original file line number Diff line number Diff line change
Expand Up @@ -249,10 +249,8 @@ library LibVerifying {
_config.chainId <= 1 || _config.chainId == block.chainid //
|| _config.blockMaxProposals == 1
|| _config.blockRingBufferSize <= _config.blockMaxProposals + 1
|| _config.blockMaxGasLimit == 0 || _config.blockMaxTxListBytes == 0
|| _config.blockMaxTxListBytes > 128 * 1024 // calldata up to 128K
|| _config.livenessBond == 0 || _config.ethDepositRingBufferSize <= 1
|| _config.ethDepositMinCountPerBlock == 0
|| _config.blockMaxGasLimit == 0 || _config.livenessBond == 0
|| _config.ethDepositRingBufferSize <= 1 || _config.ethDepositMinCountPerBlock == 0
// Audit recommendation, and gas tested. Processing 32 deposits (as initially set in
// TaikoL1.sol) costs 72_502 gas.
|| _config.ethDepositMaxCountPerBlock > 32
Expand Down
2 changes: 1 addition & 1 deletion packages/protocol/test/L1/TaikoL1TestBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ abstract contract TaikoL1TestBase is TaikoTest {

vm.prank(proposer, proposer);
(meta, depositsProcessed) = L1.proposeBlock{ value: msgValue }(
abi.encode(TaikoData.BlockParams(prover, address(0), 0, 0, 0, 0, false, 0, hookcalls)),
abi.encode(TaikoData.BlockParams(prover, address(0), 0, 0, hookcalls)),
new bytes(txListSize)
);
}
Expand Down
Loading