Skip to content

Commit

Permalink
use bitmap
Browse files Browse the repository at this point in the history
  • Loading branch information
syntrust committed Sep 30, 2024
1 parent 44da2b7 commit 4a3d006
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 14 deletions.
21 changes: 12 additions & 9 deletions contracts/EthStorageContractL2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@ contract EthStorageContractL2 is EthStorageContract2 {
IL1Block internal constant L1_BLOCK = IL1Block(0x4200000000000000000000000000000000000015);
/// @notice The rate limit to update blobs per block
uint256 internal immutable UPDATE_LIMIT;
/// @notice The blobs updated within current block
uint256 internal blobsUpdated;
/// @notice The block last update happens
uint256 internal blockLastUpdate;

/// @notice Bitmap to store blobsUpdated and blockLastUpdate
uint256 internal updateStateBitmap;

/// @notice Constructs the EthStorageContractL2 contract.
constructor(
Expand Down Expand Up @@ -68,13 +67,17 @@ contract EthStorageContractL2 is EthStorageContract2 {

/// @notice Check the update rate limit of blobs put.
function _checkUpdateLimit(uint256 _blobs) internal override {
if (blockLastUpdate == _blockNumber()) {
blobsUpdated = blobsUpdated + _blobs;
uint256 currentBlock = _blockNumber();
uint256 blockLastUpdate = updateStateBitmap & type(uint128).max;
if (blockLastUpdate == currentBlock) {
uint256 blobsUpdated = updateStateBitmap >> 128;
blobsUpdated += _blobs;
require(blobsUpdated <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit");
updateStateBitmap = (blobsUpdated << 128) | currentBlock;
} else {
blockLastUpdate = _blockNumber();
blobsUpdated = _blobs;
require(_blobs <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit");
updateStateBitmap = (_blobs << 128) | currentBlock;
}
require(blobsUpdated <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit");
}

/// @notice Getter for UPDATE_LIMIT
Expand Down
22 changes: 19 additions & 3 deletions contracts/test/EthStorageContractL2Test.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ contract EthStorageContractL2Test is Test {
uint256 constant SHARD_SIZE_BITS = 19;
uint256 constant MAX_KV_SIZE = 17;
uint256 constant PREPAID_AMOUNT = 0;
uint256 constant UPDATE_LIMIT = 12;
uint256 constant UPDATE_LIMIT = 16;

TestEthStorageContractL2 storageContract;
address owner = address(0x1);
Expand All @@ -27,7 +27,7 @@ contract EthStorageContractL2Test is Test {
storageContract = TestEthStorageContractL2(address(proxy));
}

function testCheckUpdateLimitWithinSameBlock() public {
function testUpdateLimit() public {
uint256 size = 6;
bytes32[] memory hashes = new bytes32[](size);
bytes32[] memory keys = new bytes32[](size);
Expand All @@ -52,12 +52,28 @@ contract EthStorageContractL2Test is Test {
storageContract.putBlobs(keys, blobIdxs, lengths);
assertEq(storageContract.getBlobsUpdated(), 5);
assertEq(storageContract.getBlockLastUpdate(), 10000);

// Update all 6
storageContract.putBlobs(keys, blobIdxs, lengths);
assertEq(storageContract.getBlobsUpdated(), 11);
// Update all 6 again, exceeds 12

// Update all 6 again, exceeds UPDATE_LIMIT = 16
vm.expectRevert("EthStorageContractL2: exceeds update rate limit");
storageContract.putBlobs(keys, blobIdxs, lengths);
assertEq(storageContract.getBlockLastUpdate(), 10000);

vm.roll(block.number + 1);

// Update all 6
storageContract.putBlobs(keys, blobIdxs, lengths);
assertEq(storageContract.getBlobsUpdated(), 6);
assertEq(storageContract.getBlockLastUpdate(), 10001);

// Update till exceeds UPDATE_LIMIT = 16
storageContract.putBlobs(keys, blobIdxs, lengths);
assertEq(storageContract.getBlobsUpdated(), 12);
assertEq(storageContract.getBlockLastUpdate(), 10001);
vm.expectRevert("EthStorageContractL2: exceeds update rate limit");
storageContract.putBlobs(keys, blobIdxs, lengths);
}
}
6 changes: 4 additions & 2 deletions contracts/test/TestEthStorageContractL2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ contract TestEthStorageContractL2 is EthStorageContractL2 {
uint256 _updateLimit
) EthStorageContractL2(_config, _startTime, _storageCost, _dcfFactor, _updateLimit) {}

/// @notice Get the number of blobs updated within the current block.
function getBlobsUpdated() public view returns (uint256) {
return blobsUpdated;
return updateStateBitmap >> 128;
}

/// @notice Get the block number of the last update.
function getBlockLastUpdate() public view returns (uint256) {
return blockLastUpdate;
return updateStateBitmap & type(uint128).max;
}

function _blockNumber() internal view virtual override returns (uint256) {
Expand Down

0 comments on commit 4a3d006

Please sign in to comment.