From 3fbacb2e5f7ffecb7cac2327b01b10c8ece6ba7d Mon Sep 17 00:00:00 2001 From: syntrust Date: Mon, 30 Sep 2024 13:47:14 +0800 Subject: [PATCH 01/15] update ratelimit --- contracts/DecentralizedKV.sol | 4 ++ contracts/EthStorageContractL2.sol | 21 ++++++- contracts/test/EthStorageContractL2Test.t.sol | 56 +++++++++++++++++++ contracts/test/EthStorageContractTest.t.sol | 2 +- contracts/test/TestEthStorageContractL2.sol | 27 +++++++++ contracts/test/TestStorageContract.sol | 2 +- 6 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 contracts/test/EthStorageContractL2Test.t.sol create mode 100644 contracts/test/TestEthStorageContractL2.sol diff --git a/contracts/DecentralizedKV.sol b/contracts/DecentralizedKV.sol index bb1ff26..0e08bc0 100644 --- a/contracts/DecentralizedKV.sol +++ b/contracts/DecentralizedKV.sol @@ -119,6 +119,9 @@ contract DecentralizedKV is OwnableUpgradeable { require(msg.value >= upfrontPayment() * _batchSize, "DecentralizedKV: not enough batch payment"); } + /// @notice Check the update rate limit of blobs put (L2 only). + function _checkUpdateLimit(uint256 _blobs) internal virtual {} + /// @notice Called by public putBlob and putBlobs methods. /// @param _keys Keys of the data. /// @param _dataHashes Hashes of the data. @@ -153,6 +156,7 @@ contract DecentralizedKV is OwnableUpgradeable { } _checkAppend(batchPaymentSize); + _checkUpdateLimit(_keys.length - batchPaymentSize); return res; } diff --git a/contracts/EthStorageContractL2.sol b/contracts/EthStorageContractL2.sol index 9ec0c44..510af30 100644 --- a/contracts/EthStorageContractL2.sol +++ b/contracts/EthStorageContractL2.sol @@ -26,6 +26,12 @@ interface IL1Block { contract EthStorageContractL2 is EthStorageContract2 { /// @notice The precompile contract address for L1Block. IL1Block internal constant L1_BLOCK = IL1Block(0x4200000000000000000000000000000000000015); + /// @notice The rate limit to update blobs per block + uint256 internal constant UPDATE_LIMIT = 512; + /// @notice The blobs updated within current block + uint256 internal blobsUpdated; + /// @notice The block last update happens + uint256 internal blockLastUpdate; /// @notice Constructs the EthStorageContractL2 contract. constructor(Config memory _config, uint256 _startTime, uint256 _storageCost, uint256 _dcfFactor) @@ -33,12 +39,12 @@ contract EthStorageContractL2 is EthStorageContract2 { {} /// @notice Get the current block number - function _blockNumber() internal view override returns (uint256) { + function _blockNumber() internal view virtual override returns (uint256) { return L1_BLOCK.number(); } /// @notice Get the current block timestamp - function _blockTs() internal view override returns (uint256) { + function _blockTs() internal view virtual override returns (uint256) { return L1_BLOCK.timestamp(); } @@ -53,4 +59,15 @@ contract EthStorageContractL2 is EthStorageContract2 { require(bh != bytes32(0), "EthStorageContractL2: failed to obtain blockhash"); return RandaoLib.verifyHeaderAndGetRandao(bh, _headerRlpBytes); } + + /// @notice Check the update rate limit of blobs put. + function _checkUpdateLimit(uint256 _blobs) internal override { + if (blockLastUpdate == _blockNumber()) { + blobsUpdated = blobsUpdated + _blobs; + } else { + blockLastUpdate = _blockNumber(); + blobsUpdated = _blobs; + } + require(blobsUpdated <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit"); + } } diff --git a/contracts/test/EthStorageContractL2Test.t.sol b/contracts/test/EthStorageContractL2Test.t.sol new file mode 100644 index 0000000..2ed2641 --- /dev/null +++ b/contracts/test/EthStorageContractL2Test.t.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "forge-std/Test.sol"; +import "./TestEthStorageContractL2.sol"; +import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; + +contract EthStorageContractL2Test is Test { + uint256 constant STORAGE_COST = 0; + uint256 constant SHARD_SIZE_BITS = 19; + uint256 constant MAX_KV_SIZE = 17; + uint256 constant PREPAID_AMOUNT = 0; + + TestEthStorageContractL2 storageContract; + address owner = address(0x1); + + function setUp() public { + TestEthStorageContractL2 imp = new TestEthStorageContractL2( + StorageContract.Config(MAX_KV_SIZE, SHARD_SIZE_BITS, 2, 0, 0, 0), 0, STORAGE_COST, 0 + ); + bytes memory data = abi.encodeWithSelector( + storageContract.initialize.selector, 0, PREPAID_AMOUNT, 0, address(0x1), address(0x1) + ); + TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(address(imp), owner, data); + + storageContract = TestEthStorageContractL2(address(proxy)); + } + + function testCheckUpdateLimitWithinSameBlock() public { + uint256 size = 6; + bytes32[] memory hashes = new bytes32[](size); + bytes32[] memory keys = new bytes32[](size); + uint256[] memory blobIdxs = new uint256[](size); + uint256[] memory lengths = new uint256[](size); + for (uint256 i = 0; i < size; i++) { + keys[i] = bytes32(uint256(i)); + hashes[i] = bytes32(uint256((i + 1) << 64)); + blobIdxs[i] = i; + lengths[i] = 10 + i * 10; + } + vm.blobhashes(hashes); + vm.roll(10000); + + // No updates + storageContract.putBlobs(keys, blobIdxs, lengths); + assertEq(storageContract.getBlobsUpdated(), 0); + assertEq(storageContract.getBlockLastUpdate(), 10000); + + // Append 2 new key-values, leaving 4 as updating + keys[0] = bytes32(uint256(10)); + keys[1] = bytes32(uint256(11)); + storageContract.putBlobs(keys, blobIdxs, lengths); + assertEq(storageContract.getBlobsUpdated(), 4); + assertEq(storageContract.getBlockLastUpdate(), 10000); + } +} diff --git a/contracts/test/EthStorageContractTest.t.sol b/contracts/test/EthStorageContractTest.t.sol index 0e2564b..de7982d 100644 --- a/contracts/test/EthStorageContractTest.t.sol +++ b/contracts/test/EthStorageContractTest.t.sol @@ -63,7 +63,7 @@ contract EthStorageContractTest is Test { keys[1] = bytes32(uint256(1)); uint256[] memory blobIdxs = new uint256[](2); blobIdxs[0] = 0; - blobIdxs[1] = 0; + blobIdxs[1] = 1; uint256[] memory lengths = new uint256[](2); lengths[0] = 10; lengths[1] = 20; diff --git a/contracts/test/TestEthStorageContractL2.sol b/contracts/test/TestEthStorageContractL2.sol new file mode 100644 index 0000000..4cb3a53 --- /dev/null +++ b/contracts/test/TestEthStorageContractL2.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "../EthStorageContractL2.sol"; + +contract TestEthStorageContractL2 is EthStorageContractL2 { + constructor(Config memory _config, uint256 _startTime, uint256 _storageCost, uint256 _dcfFactor) + EthStorageContractL2(_config, _startTime, _storageCost, _dcfFactor) + {} + + function getBlobsUpdated() public view returns (uint256) { + return blobsUpdated; + } + + function getBlockLastUpdate() public view returns (uint256) { + return blockLastUpdate; + } + + function _blockNumber() internal view virtual override returns (uint256) { + return block.number; + } + + /// @notice Get the current block timestamp + function _blockTs() internal view virtual override returns (uint256) { + return block.timestamp; + } +} diff --git a/contracts/test/TestStorageContract.sol b/contracts/test/TestStorageContract.sol index 82810a3..ece1996 100644 --- a/contracts/test/TestStorageContract.sol +++ b/contracts/test/TestStorageContract.sol @@ -1,4 +1,4 @@ -// SPDX License Identifier: MIT +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../StorageContract.sol"; From 44da2b71b021f498e4e2e55974f7eec51197f35e Mon Sep 17 00:00:00 2001 From: syntrust Date: Mon, 30 Sep 2024 14:26:28 +0800 Subject: [PATCH 02/15] make immutable --- contracts/EthStorageContractL2.sol | 19 +++++++++++++++---- contracts/test/EthStorageContractL2Test.t.sol | 15 +++++++++++---- contracts/test/TestEthStorageContractL2.sol | 10 +++++++--- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/contracts/EthStorageContractL2.sol b/contracts/EthStorageContractL2.sol index 510af30..1d1e1dd 100644 --- a/contracts/EthStorageContractL2.sol +++ b/contracts/EthStorageContractL2.sol @@ -27,16 +27,22 @@ contract EthStorageContractL2 is EthStorageContract2 { /// @notice The precompile contract address for L1Block. IL1Block internal constant L1_BLOCK = IL1Block(0x4200000000000000000000000000000000000015); /// @notice The rate limit to update blobs per block - uint256 internal constant UPDATE_LIMIT = 512; + 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 Constructs the EthStorageContractL2 contract. - constructor(Config memory _config, uint256 _startTime, uint256 _storageCost, uint256 _dcfFactor) - EthStorageContract2(_config, _startTime, _storageCost, _dcfFactor) - {} + constructor( + Config memory _config, + uint256 _startTime, + uint256 _storageCost, + uint256 _dcfFactor, + uint256 _updateLimit + ) EthStorageContract2(_config, _startTime, _storageCost, _dcfFactor) { + UPDATE_LIMIT = _updateLimit; + } /// @notice Get the current block number function _blockNumber() internal view virtual override returns (uint256) { @@ -70,4 +76,9 @@ contract EthStorageContractL2 is EthStorageContract2 { } require(blobsUpdated <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit"); } + + /// @notice Getter for UPDATE_LIMIT + function getUpdateLimit() public view returns (uint256) { + return UPDATE_LIMIT; + } } diff --git a/contracts/test/EthStorageContractL2Test.t.sol b/contracts/test/EthStorageContractL2Test.t.sol index 2ed2641..d50932b 100644 --- a/contracts/test/EthStorageContractL2Test.t.sol +++ b/contracts/test/EthStorageContractL2Test.t.sol @@ -10,13 +10,14 @@ 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; TestEthStorageContractL2 storageContract; address owner = address(0x1); function setUp() public { TestEthStorageContractL2 imp = new TestEthStorageContractL2( - StorageContract.Config(MAX_KV_SIZE, SHARD_SIZE_BITS, 2, 0, 0, 0), 0, STORAGE_COST, 0 + StorageContract.Config(MAX_KV_SIZE, SHARD_SIZE_BITS, 2, 0, 0, 0), 0, STORAGE_COST, 0, UPDATE_LIMIT ); bytes memory data = abi.encodeWithSelector( storageContract.initialize.selector, 0, PREPAID_AMOUNT, 0, address(0x1), address(0x1) @@ -46,11 +47,17 @@ contract EthStorageContractL2Test is Test { assertEq(storageContract.getBlobsUpdated(), 0); assertEq(storageContract.getBlockLastUpdate(), 10000); - // Append 2 new key-values, leaving 4 as updating + // Append 1 new key-values, leaving 5 as updating keys[0] = bytes32(uint256(10)); - keys[1] = bytes32(uint256(11)); storageContract.putBlobs(keys, blobIdxs, lengths); - assertEq(storageContract.getBlobsUpdated(), 4); + 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 + vm.expectRevert("EthStorageContractL2: exceeds update rate limit"); + storageContract.putBlobs(keys, blobIdxs, lengths); assertEq(storageContract.getBlockLastUpdate(), 10000); } } diff --git a/contracts/test/TestEthStorageContractL2.sol b/contracts/test/TestEthStorageContractL2.sol index 4cb3a53..c5c54c1 100644 --- a/contracts/test/TestEthStorageContractL2.sol +++ b/contracts/test/TestEthStorageContractL2.sol @@ -4,9 +4,13 @@ pragma solidity ^0.8.0; import "../EthStorageContractL2.sol"; contract TestEthStorageContractL2 is EthStorageContractL2 { - constructor(Config memory _config, uint256 _startTime, uint256 _storageCost, uint256 _dcfFactor) - EthStorageContractL2(_config, _startTime, _storageCost, _dcfFactor) - {} + constructor( + Config memory _config, + uint256 _startTime, + uint256 _storageCost, + uint256 _dcfFactor, + uint256 _updateLimit + ) EthStorageContractL2(_config, _startTime, _storageCost, _dcfFactor, _updateLimit) {} function getBlobsUpdated() public view returns (uint256) { return blobsUpdated; From 4a3d006f37441c1dd305398b498f0139c616d447 Mon Sep 17 00:00:00 2001 From: syntrust Date: Mon, 30 Sep 2024 15:44:12 +0800 Subject: [PATCH 03/15] use bitmap --- contracts/EthStorageContractL2.sol | 21 ++++++++++-------- contracts/test/EthStorageContractL2Test.t.sol | 22 ++++++++++++++++--- contracts/test/TestEthStorageContractL2.sol | 6 +++-- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/contracts/EthStorageContractL2.sol b/contracts/EthStorageContractL2.sol index 1d1e1dd..ec45ef3 100644 --- a/contracts/EthStorageContractL2.sol +++ b/contracts/EthStorageContractL2.sol @@ -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( @@ -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 diff --git a/contracts/test/EthStorageContractL2Test.t.sol b/contracts/test/EthStorageContractL2Test.t.sol index d50932b..ad621a9 100644 --- a/contracts/test/EthStorageContractL2Test.t.sol +++ b/contracts/test/EthStorageContractL2Test.t.sol @@ -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); @@ -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); @@ -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); } } diff --git a/contracts/test/TestEthStorageContractL2.sol b/contracts/test/TestEthStorageContractL2.sol index c5c54c1..943704e 100644 --- a/contracts/test/TestEthStorageContractL2.sol +++ b/contracts/test/TestEthStorageContractL2.sol @@ -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) { From d997e08d9b27addfd96cddd578a53b36f672c768 Mon Sep 17 00:00:00 2001 From: syntrust Date: Mon, 30 Sep 2024 16:01:57 +0800 Subject: [PATCH 04/15] script --- scripts/deployL2.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/deployL2.js b/scripts/deployL2.js index 5398f06..984850c 100644 --- a/scripts/deployL2.js +++ b/scripts/deployL2.js @@ -19,6 +19,7 @@ const config = [ ]; const storageCost = 1500000000000000; // storageCost - 1,500,000Gwei forever per blob - https://ethresear.ch/t/ethstorage-scaling-ethereum-storage-via-l2-and-da/14223/6#incentivization-for-storing-m-physical-replicas-1 const dcfFactor = 340282366367469178095360967382638002176n; // dcfFactor, it mean 0.95 for yearly discount +const updateLimit = 512; async function verifyContract(contract, args) { // if (!process.env.ETHERSCAN_API_KEY) { @@ -44,6 +45,7 @@ async function deployContract() { startTime, // startTime storageCost, dcfFactor, + updateLimit, { gasPrice: gasPrice } ); await implContract.deployed(); @@ -75,7 +77,7 @@ async function deployContract() { // fund 50 qkc into the storage contract to give reward for empty mining const ethStorage = StorageContract.attach(ethStorageProxy.address); - const tx = await ethStorage.sendValue({ value: hre.ethers.utils.parseEther("50") }); + const tx = await ethStorage.sendValue({ value: hre.ethers.utils.parseEther("1") }); await tx.wait(); console.log("balance of " + ethStorage.address, await hre.ethers.provider.getBalance(ethStorage.address)); From 96d0d6ac4f3730952029c40ac9c3b0c42e18f3ad Mon Sep 17 00:00:00 2001 From: syntrust Date: Mon, 30 Sep 2024 16:03:33 +0800 Subject: [PATCH 05/15] revert --- scripts/deployL2.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/deployL2.js b/scripts/deployL2.js index 984850c..0971190 100644 --- a/scripts/deployL2.js +++ b/scripts/deployL2.js @@ -77,7 +77,7 @@ async function deployContract() { // fund 50 qkc into the storage contract to give reward for empty mining const ethStorage = StorageContract.attach(ethStorageProxy.address); - const tx = await ethStorage.sendValue({ value: hre.ethers.utils.parseEther("1") }); + const tx = await ethStorage.sendValue({ value: hre.ethers.utils.parseEther("50") }); await tx.wait(); console.log("balance of " + ethStorage.address, await hre.ethers.provider.getBalance(ethStorage.address)); From 53f3ce8d7450c8cb9883c07e14e815370335902c Mon Sep 17 00:00:00 2001 From: syntrust Date: Tue, 8 Oct 2024 11:27:25 +0800 Subject: [PATCH 06/15] optimize --- contracts/EthStorageContractL2.sol | 10 +++++----- contracts/test/TestEthStorageContractL2.sol | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contracts/EthStorageContractL2.sol b/contracts/EthStorageContractL2.sol index ec45ef3..cfa67a9 100644 --- a/contracts/EthStorageContractL2.sol +++ b/contracts/EthStorageContractL2.sol @@ -29,7 +29,7 @@ contract EthStorageContractL2 is EthStorageContract2 { /// @notice The rate limit to update blobs per block uint256 internal immutable UPDATE_LIMIT; - /// @notice Bitmap to store blobsUpdated and blockLastUpdate + /// @notice Bitmap to store blobsUpdated (left 32) and blockLastUpdate (right 224) uint256 internal updateStateBitmap; /// @notice Constructs the EthStorageContractL2 contract. @@ -68,15 +68,15 @@ contract EthStorageContractL2 is EthStorageContract2 { /// @notice Check the update rate limit of blobs put. function _checkUpdateLimit(uint256 _blobs) internal override { uint256 currentBlock = _blockNumber(); - uint256 blockLastUpdate = updateStateBitmap & type(uint128).max; + uint256 blockLastUpdate = updateStateBitmap & type(uint224).max; if (blockLastUpdate == currentBlock) { - uint256 blobsUpdated = updateStateBitmap >> 128; + uint256 blobsUpdated = updateStateBitmap >> 224; blobsUpdated += _blobs; require(blobsUpdated <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit"); - updateStateBitmap = (blobsUpdated << 128) | currentBlock; + updateStateBitmap = (blobsUpdated << 224) | currentBlock; } else { require(_blobs <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit"); - updateStateBitmap = (_blobs << 128) | currentBlock; + updateStateBitmap = (_blobs << 224) | currentBlock; } } diff --git a/contracts/test/TestEthStorageContractL2.sol b/contracts/test/TestEthStorageContractL2.sol index 943704e..4dd0e8b 100644 --- a/contracts/test/TestEthStorageContractL2.sol +++ b/contracts/test/TestEthStorageContractL2.sol @@ -14,12 +14,12 @@ contract TestEthStorageContractL2 is EthStorageContractL2 { /// @notice Get the number of blobs updated within the current block. function getBlobsUpdated() public view returns (uint256) { - return updateStateBitmap >> 128; + return updateStateBitmap >> 224; } /// @notice Get the block number of the last update. function getBlockLastUpdate() public view returns (uint256) { - return updateStateBitmap & type(uint128).max; + return updateStateBitmap & type(uint224).max; } function _blockNumber() internal view virtual override returns (uint256) { From 4888f95aeba99d739edef36790dc0d16fcdcc4d7 Mon Sep 17 00:00:00 2001 From: syntrust Date: Tue, 8 Oct 2024 14:28:54 +0800 Subject: [PATCH 07/15] rename --- contracts/EthStorageContractL2.sol | 12 ++++++------ contracts/test/TestEthStorageContractL2.sol | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/contracts/EthStorageContractL2.sol b/contracts/EthStorageContractL2.sol index cfa67a9..0b2849e 100644 --- a/contracts/EthStorageContractL2.sol +++ b/contracts/EthStorageContractL2.sol @@ -29,8 +29,8 @@ contract EthStorageContractL2 is EthStorageContract2 { /// @notice The rate limit to update blobs per block uint256 internal immutable UPDATE_LIMIT; - /// @notice Bitmap to store blobsUpdated (left 32) and blockLastUpdate (right 224) - uint256 internal updateStateBitmap; + /// @notice A slot to store both `blobsUpdated` (left 32) and `blockLastUpdate` (right 224) + uint256 internal updateState; /// @notice Constructs the EthStorageContractL2 contract. constructor( @@ -68,15 +68,15 @@ contract EthStorageContractL2 is EthStorageContract2 { /// @notice Check the update rate limit of blobs put. function _checkUpdateLimit(uint256 _blobs) internal override { uint256 currentBlock = _blockNumber(); - uint256 blockLastUpdate = updateStateBitmap & type(uint224).max; + uint256 blockLastUpdate = updateState & type(uint224).max; if (blockLastUpdate == currentBlock) { - uint256 blobsUpdated = updateStateBitmap >> 224; + uint256 blobsUpdated = updateState >> 224; blobsUpdated += _blobs; require(blobsUpdated <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit"); - updateStateBitmap = (blobsUpdated << 224) | currentBlock; + updateState = (blobsUpdated << 224) | currentBlock; } else { require(_blobs <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit"); - updateStateBitmap = (_blobs << 224) | currentBlock; + updateState = (_blobs << 224) | currentBlock; } } diff --git a/contracts/test/TestEthStorageContractL2.sol b/contracts/test/TestEthStorageContractL2.sol index 4dd0e8b..6c08b04 100644 --- a/contracts/test/TestEthStorageContractL2.sol +++ b/contracts/test/TestEthStorageContractL2.sol @@ -14,12 +14,12 @@ contract TestEthStorageContractL2 is EthStorageContractL2 { /// @notice Get the number of blobs updated within the current block. function getBlobsUpdated() public view returns (uint256) { - return updateStateBitmap >> 224; + return updateState >> 224; } /// @notice Get the block number of the last update. function getBlockLastUpdate() public view returns (uint256) { - return updateStateBitmap & type(uint224).max; + return updateState & type(uint224).max; } function _blockNumber() internal view virtual override returns (uint256) { From b16fd55b7e1d6b8a215b320d397ac85918024621 Mon Sep 17 00:00:00 2001 From: syntrust Date: Tue, 8 Oct 2024 15:00:40 +0800 Subject: [PATCH 08/15] use 2 sec --- contracts/EthStorageContractL2.sol | 7 +++---- scripts/deployL2-it.js | 8 +++++--- scripts/deployL2.js | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/contracts/EthStorageContractL2.sol b/contracts/EthStorageContractL2.sol index 0b2849e..fe61e96 100644 --- a/contracts/EthStorageContractL2.sol +++ b/contracts/EthStorageContractL2.sol @@ -67,16 +67,15 @@ contract EthStorageContractL2 is EthStorageContract2 { /// @notice Check the update rate limit of blobs put. function _checkUpdateLimit(uint256 _blobs) internal override { - uint256 currentBlock = _blockNumber(); uint256 blockLastUpdate = updateState & type(uint224).max; - if (blockLastUpdate == currentBlock) { + if (blockLastUpdate == block.number) { uint256 blobsUpdated = updateState >> 224; blobsUpdated += _blobs; require(blobsUpdated <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit"); - updateState = (blobsUpdated << 224) | currentBlock; + updateState = (blobsUpdated << 224) | block.number; } else { require(_blobs <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit"); - updateState = (_blobs << 224) | currentBlock; + updateState = (_blobs << 224) | block.number; } } diff --git a/scripts/deployL2-it.js b/scripts/deployL2-it.js index 4135eca..b71545a 100644 --- a/scripts/deployL2-it.js +++ b/scripts/deployL2-it.js @@ -20,6 +20,7 @@ const config = [ ]; const storageCost = 1500000000000000; // storageCost - 1,500,000Gwei forever per blob - https://ethresear.ch/t/ethstorage-scaling-ethereum-storage-via-l2-and-da/14223/6#incentivization-for-storing-m-physical-replicas-1 const dcfFactor = 340282366367469178095360967382638002176n; // dcfFactor, it mean 0.95 for yearly discount +const updateLimit = 90; // 45 blobs/s according to sync/encoding test, times block interval of L2 async function verifyContract(contract, args) { // if (!process.env.ETHERSCAN_API_KEY) { @@ -45,6 +46,7 @@ async function deployContract() { startTime, // startTime storageCost, dcfFactor, + updateLimit, { gasPrice: gasPrice } ); await implContract.deployed(); @@ -85,7 +87,7 @@ async function deployContract() { await verifyContract(impl, [config, startTime, storageCost, dcfFactor]); // wait for contract finalized - var intervalId = setInterval(async function (){ + var intervalId = setInterval(async function () { try { const block = await hre.ethers.provider.getBlock("finalized"); console.log( @@ -93,13 +95,13 @@ async function deployContract() { block.number, "at", new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" }) - ); + ); if (receipt.blockNumber < block.number) { fs.writeFileSync(".caddr", ethStorageProxy.address); clearInterval(intervalId); } } catch (e) { - console.error(`EthStorage: get finalized block failed!`, e.message);g + console.error(`EthStorage: get finalized block failed!`, e.message); } }, 60000); } diff --git a/scripts/deployL2.js b/scripts/deployL2.js index 0971190..50fa5c3 100644 --- a/scripts/deployL2.js +++ b/scripts/deployL2.js @@ -19,7 +19,7 @@ const config = [ ]; const storageCost = 1500000000000000; // storageCost - 1,500,000Gwei forever per blob - https://ethresear.ch/t/ethstorage-scaling-ethereum-storage-via-l2-and-da/14223/6#incentivization-for-storing-m-physical-replicas-1 const dcfFactor = 340282366367469178095360967382638002176n; // dcfFactor, it mean 0.95 for yearly discount -const updateLimit = 512; +const updateLimit = 90; // 45 blobs/s according to sync/encoding test, times block interval of L2 async function verifyContract(contract, args) { // if (!process.env.ETHERSCAN_API_KEY) { From 6fc3ef3e2d7e2039693efaf60800430237194994 Mon Sep 17 00:00:00 2001 From: syntrust Date: Tue, 8 Oct 2024 16:33:03 +0800 Subject: [PATCH 09/15] simplify --- contracts/EthStorageContractL2.sol | 10 +++++----- contracts/test/TestEthStorageContractL2.sol | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contracts/EthStorageContractL2.sol b/contracts/EthStorageContractL2.sol index fe61e96..ac70e0f 100644 --- a/contracts/EthStorageContractL2.sol +++ b/contracts/EthStorageContractL2.sol @@ -29,7 +29,7 @@ contract EthStorageContractL2 is EthStorageContract2 { /// @notice The rate limit to update blobs per block uint256 internal immutable UPDATE_LIMIT; - /// @notice A slot to store both `blobsUpdated` (left 32) and `blockLastUpdate` (right 224) + /// @notice A slot to store both `blockLastUpdate` (left 224) and `blobsUpdated` (right 32) uint256 internal updateState; /// @notice Constructs the EthStorageContractL2 contract. @@ -67,15 +67,15 @@ contract EthStorageContractL2 is EthStorageContract2 { /// @notice Check the update rate limit of blobs put. function _checkUpdateLimit(uint256 _blobs) internal override { - uint256 blockLastUpdate = updateState & type(uint224).max; + uint256 blockLastUpdate = updateState >> 32; if (blockLastUpdate == block.number) { - uint256 blobsUpdated = updateState >> 224; + uint256 blobsUpdated = updateState & type(uint32).max; blobsUpdated += _blobs; require(blobsUpdated <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit"); - updateState = (blobsUpdated << 224) | block.number; + updateState = block.number << 32 | blobsUpdated; } else { require(_blobs <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit"); - updateState = (_blobs << 224) | block.number; + updateState = block.number << 32 | _blobs; } } diff --git a/contracts/test/TestEthStorageContractL2.sol b/contracts/test/TestEthStorageContractL2.sol index 6c08b04..d9589cf 100644 --- a/contracts/test/TestEthStorageContractL2.sol +++ b/contracts/test/TestEthStorageContractL2.sol @@ -14,12 +14,12 @@ contract TestEthStorageContractL2 is EthStorageContractL2 { /// @notice Get the number of blobs updated within the current block. function getBlobsUpdated() public view returns (uint256) { - return updateState >> 224; + return updateState & type(uint32).max; } /// @notice Get the block number of the last update. function getBlockLastUpdate() public view returns (uint256) { - return updateState & type(uint224).max; + return updateState >> 32; } function _blockNumber() internal view virtual override returns (uint256) { From 1200a5aaaa321f0f510a6d050bc74fa768334bde Mon Sep 17 00:00:00 2001 From: syntrust Date: Tue, 8 Oct 2024 16:40:52 +0800 Subject: [PATCH 10/15] simplify --- contracts/EthStorageContractL2.sol | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/contracts/EthStorageContractL2.sol b/contracts/EthStorageContractL2.sol index ac70e0f..357654c 100644 --- a/contracts/EthStorageContractL2.sol +++ b/contracts/EthStorageContractL2.sol @@ -68,15 +68,9 @@ contract EthStorageContractL2 is EthStorageContract2 { /// @notice Check the update rate limit of blobs put. function _checkUpdateLimit(uint256 _blobs) internal override { uint256 blockLastUpdate = updateState >> 32; - if (blockLastUpdate == block.number) { - uint256 blobsUpdated = updateState & type(uint32).max; - blobsUpdated += _blobs; - require(blobsUpdated <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit"); - updateState = block.number << 32 | blobsUpdated; - } else { - require(_blobs <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit"); - updateState = block.number << 32 | _blobs; - } + uint256 blobsUpdated = blockLastUpdate == block.number ? updateState & type(uint32).max : 0; + require(blobsUpdated + _blobs <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit"); + updateState = block.number << 32 | (blobsUpdated + _blobs); } /// @notice Getter for UPDATE_LIMIT From 6322c9661f90c8c5e96caba20bdf1903f6f4fe87 Mon Sep 17 00:00:00 2001 From: syntrust Date: Wed, 9 Oct 2024 12:42:30 +0800 Subject: [PATCH 11/15] fix comments --- contracts/DecentralizedKV.sol | 4 +++- contracts/EthStorageContractL2.sol | 7 +++++-- contracts/test/EthStorageContractL2Test.t.sol | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/contracts/DecentralizedKV.sol b/contracts/DecentralizedKV.sol index 0e08bc0..2b05e9c 100644 --- a/contracts/DecentralizedKV.sol +++ b/contracts/DecentralizedKV.sol @@ -156,7 +156,9 @@ contract DecentralizedKV is OwnableUpgradeable { } _checkAppend(batchPaymentSize); - _checkUpdateLimit(_keys.length - batchPaymentSize); + if (_keys.length > batchPaymentSize) { + _checkUpdateLimit(_keys.length - batchPaymentSize); + } return res; } diff --git a/contracts/EthStorageContractL2.sol b/contracts/EthStorageContractL2.sol index 357654c..1788428 100644 --- a/contracts/EthStorageContractL2.sol +++ b/contracts/EthStorageContractL2.sol @@ -26,6 +26,10 @@ interface IL1Block { contract EthStorageContractL2 is EthStorageContract2 { /// @notice The precompile contract address for L1Block. IL1Block internal constant L1_BLOCK = IL1Block(0x4200000000000000000000000000000000000015); + + /// @notice The mask to extract `blockLastUpdate` + uint256 internal constant MASK = ~uint256(0) ^ type(uint32).max; + /// @notice The rate limit to update blobs per block uint256 internal immutable UPDATE_LIMIT; @@ -67,8 +71,7 @@ contract EthStorageContractL2 is EthStorageContract2 { /// @notice Check the update rate limit of blobs put. function _checkUpdateLimit(uint256 _blobs) internal override { - uint256 blockLastUpdate = updateState >> 32; - uint256 blobsUpdated = blockLastUpdate == block.number ? updateState & type(uint32).max : 0; + uint256 blobsUpdated = updateState & MASK == block.number << 32 ? updateState & type(uint32).max : 0; require(blobsUpdated + _blobs <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit"); updateState = block.number << 32 | (blobsUpdated + _blobs); } diff --git a/contracts/test/EthStorageContractL2Test.t.sol b/contracts/test/EthStorageContractL2Test.t.sol index ad621a9..5e1b58f 100644 --- a/contracts/test/EthStorageContractL2Test.t.sol +++ b/contracts/test/EthStorageContractL2Test.t.sol @@ -45,7 +45,7 @@ contract EthStorageContractL2Test is Test { // No updates storageContract.putBlobs(keys, blobIdxs, lengths); assertEq(storageContract.getBlobsUpdated(), 0); - assertEq(storageContract.getBlockLastUpdate(), 10000); + assertEq(storageContract.getBlockLastUpdate(), 0); // Append 1 new key-values, leaving 5 as updating keys[0] = bytes32(uint256(10)); From 740ff613eb9fa9d0ee2f5daa525b8c53b79395cb Mon Sep 17 00:00:00 2001 From: syntrust Date: Thu, 10 Oct 2024 14:10:15 +0800 Subject: [PATCH 12/15] fix comments --- contracts/DecentralizedKV.sol | 4 ++-- contracts/EthStorageContractL2.sol | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/DecentralizedKV.sol b/contracts/DecentralizedKV.sol index 2b05e9c..2190784 100644 --- a/contracts/DecentralizedKV.sol +++ b/contracts/DecentralizedKV.sol @@ -119,8 +119,8 @@ contract DecentralizedKV is OwnableUpgradeable { require(msg.value >= upfrontPayment() * _batchSize, "DecentralizedKV: not enough batch payment"); } - /// @notice Check the update rate limit of blobs put (L2 only). - function _checkUpdateLimit(uint256 _blobs) internal virtual {} + /// @notice Check if the key-values being updated exceed the limit per block (L2 only). + function _checkUpdateLimit(uint256 _updateSize) internal virtual {} /// @notice Called by public putBlob and putBlobs methods. /// @param _keys Keys of the data. diff --git a/contracts/EthStorageContractL2.sol b/contracts/EthStorageContractL2.sol index 1788428..125f5da 100644 --- a/contracts/EthStorageContractL2.sol +++ b/contracts/EthStorageContractL2.sol @@ -69,11 +69,11 @@ contract EthStorageContractL2 is EthStorageContract2 { return RandaoLib.verifyHeaderAndGetRandao(bh, _headerRlpBytes); } - /// @notice Check the update rate limit of blobs put. - function _checkUpdateLimit(uint256 _blobs) internal override { + /// @notice Check if the key-values being updated exceed the limit per block. + function _checkUpdateLimit(uint256 _updateSize) internal override { uint256 blobsUpdated = updateState & MASK == block.number << 32 ? updateState & type(uint32).max : 0; - require(blobsUpdated + _blobs <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit"); - updateState = block.number << 32 | (blobsUpdated + _blobs); + require(blobsUpdated + _updateSize <= UPDATE_LIMIT, "EthStorageContractL2: exceeds update rate limit"); + updateState = block.number << 32 | (blobsUpdated + _updateSize); } /// @notice Getter for UPDATE_LIMIT From e0b2cf3f57cb068f229a001b4b921368beb8c2d9 Mon Sep 17 00:00:00 2001 From: syntrust Date: Thu, 10 Oct 2024 15:58:12 +0800 Subject: [PATCH 13/15] kill warns --- contracts/test/EthStorageContractTest.t.sol | 2 -- contracts/test/StorageContractTest.t.sol | 4 +--- contracts/test/TestDecentralizedKV.sol | 2 +- contracts/test/TestEthStorageContract.sol | 4 ++-- contracts/test/TestStorageContract.sol | 26 ++++++++++----------- 5 files changed, 17 insertions(+), 21 deletions(-) diff --git a/contracts/test/EthStorageContractTest.t.sol b/contracts/test/EthStorageContractTest.t.sol index de7982d..59df16d 100644 --- a/contracts/test/EthStorageContractTest.t.sol +++ b/contracts/test/EthStorageContractTest.t.sol @@ -3,8 +3,6 @@ pragma solidity ^0.8.19; import "./TestEthStorageContract.sol"; import "forge-std/Test.sol"; -import "forge-std/Vm.sol"; -import "forge-std/console.sol"; import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; contract EthStorageContractTest is Test { diff --git a/contracts/test/StorageContractTest.t.sol b/contracts/test/StorageContractTest.t.sol index 4763a2d..cd20b36 100644 --- a/contracts/test/StorageContractTest.t.sol +++ b/contracts/test/StorageContractTest.t.sol @@ -1,11 +1,9 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.19; -import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "./TestStorageContract.sol"; import "../StorageContract.sol"; import "forge-std/Test.sol"; -import "forge-std/Vm.sol"; contract StorageContractTest is Test { uint256 constant STORAGE_COST = 10000000; @@ -172,7 +170,7 @@ contract Attacker is Test { storageContract = _storageContract; } - fallback() external payable { + receive() external payable { uint256 _shardId = 0; uint256 _nonce = 0; bytes32[] memory _encodedSamples = new bytes32[](0); diff --git a/contracts/test/TestDecentralizedKV.sol b/contracts/test/TestDecentralizedKV.sol index 6359ffe..9a76300 100644 --- a/contracts/test/TestDecentralizedKV.sol +++ b/contracts/test/TestDecentralizedKV.sol @@ -39,7 +39,7 @@ contract TestDecentralizedKV is DecentralizedKV { dataMap[kvIndices[0]] = data; } - function get(bytes32 key, DecodeType decodeType, uint256 off, uint256 len) + function get(bytes32 key, DecodeType, /* decodeType */ uint256 off, uint256 len) public view override diff --git a/contracts/test/TestEthStorageContract.sol b/contracts/test/TestEthStorageContract.sol index fecae4e..6a6c804 100644 --- a/contracts/test/TestEthStorageContract.sol +++ b/contracts/test/TestEthStorageContract.sol @@ -36,7 +36,7 @@ contract TestEthStorageContract is EthStorageContract { _putBatchInternal(keys, dataHashes, lengths); } - function putBlob(bytes32 _key, uint256 _blobIdx, uint256 _length) public payable override { + function putBlob(bytes32 _key, uint256, /* _blobIdx */ uint256 _length) public payable override { bytes32 dataHash = bytes32(uint256(1 << 8 * 8)); require(dataHash != 0, "EthStorageContract: failed to get blob hash"); @@ -194,7 +194,7 @@ contract TestEthStorageContract is EthStorageContract { require(nonce < nonceLimit, "nonce too big"); // Check if the data matches the hash in metadata and obtain the solution hash. - bytes32 hash0 = verifySamples(shardId, initHash0, miner, encodedSamples, masks, inclusiveProofs, decodeProof); + verifySamples(shardId, initHash0, miner, encodedSamples, masks, inclusiveProofs, decodeProof); uint256 diff = _calculateDiffAndInitHashSingleShard(shardId, mineTs); diff --git a/contracts/test/TestStorageContract.sol b/contracts/test/TestStorageContract.sol index ece1996..22960d5 100644 --- a/contracts/test/TestStorageContract.sol +++ b/contracts/test/TestStorageContract.sol @@ -19,13 +19,13 @@ contract TestStorageContract is StorageContract { } function verifySamples( - uint256 _startShardId, - bytes32 _hash0, - address _miner, - bytes32[] memory _encodedSamples, - uint256[] memory _masks, - bytes[] calldata _inclusiveProofs, - bytes[] calldata _decodeProof + uint256, /* _startShardId */ + bytes32, /* _hash0 */ + address, /* _miner */ + bytes32[] memory, /* _encodedSamples */ + uint256[] memory, /* _masks */ + bytes[] calldata, /* _inclusiveProofs */ + bytes[] calldata /* _decodeProof */ ) public pure override returns (bytes32) { return bytes32(0); } @@ -50,12 +50,12 @@ contract TestStorageContract is StorageContract { uint256 _blockNum, uint256 _shardId, address _miner, - uint256 _nonce, - bytes32[] memory _encodedSamples, - uint256[] memory _masks, - bytes calldata _randaoProof, - bytes[] calldata _inclusiveProofs, - bytes[] calldata _decodeProof + uint256, /* _nonce */ + bytes32[] memory, /* _encodedSamples */ + uint256[] memory, /* _masks */ + bytes calldata, /* _randaoProof */ + bytes[] calldata, /* _inclusiveProofs */ + bytes[] calldata /* å */ ) internal override { uint256 mineTs = _getMinedTs(_blockNum); _rewardMiner(_shardId, _miner, mineTs, 1); From bb89625469e5cf473d06fe78d735de44733e3950 Mon Sep 17 00:00:00 2001 From: syntrust Date: Thu, 10 Oct 2024 16:39:05 +0800 Subject: [PATCH 14/15] make pure --- contracts/test/TestMerkleLib.sol | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/contracts/test/TestMerkleLib.sol b/contracts/test/TestMerkleLib.sol index e2b5fec..7293bb9 100644 --- a/contracts/test/TestMerkleLib.sol +++ b/contracts/test/TestMerkleLib.sol @@ -12,29 +12,27 @@ contract TestMerkleLib { return MerkleLib.merkleRootWithMinTree(data, chunkSize); } - function merkleRootNoView(bytes memory data, uint256 chunkSize, uint256 nChunkBits) public returns (bytes32) { + function merkleRootNoView(bytes memory data, uint256 chunkSize, uint256 nChunkBits) public pure returns (bytes32) { return MerkleLib.merkleRoot(data, chunkSize, nChunkBits); } - function keccak256NoView(bytes memory data) public returns (bytes32) { + function keccak256NoView(bytes memory data) public pure returns (bytes32) { return keccak256(data); } - function verify( - bytes memory chunkData, - uint256 chunkIdx, - bytes32 root, - bytes32[] memory proofs - ) public pure returns (bool) { + function verify(bytes memory chunkData, uint256 chunkIdx, bytes32 root, bytes32[] memory proofs) + public + pure + returns (bool) + { return MerkleLib.verify(keccak256(chunkData), chunkIdx, root, proofs); } - function getProof( - bytes memory data, - uint256 chunkSize, - uint256 nChunkBits, - uint256 chunkIdx - ) public pure returns (bytes32[] memory) { + function getProof(bytes memory data, uint256 chunkSize, uint256 nChunkBits, uint256 chunkIdx) + public + pure + returns (bytes32[] memory) + { return MerkleLib.getProof(data, chunkSize, nChunkBits, chunkIdx); } From e62ce725fb51441883d9fa7f4641a4f103afa014 Mon Sep 17 00:00:00 2001 From: syntrust Date: Fri, 11 Oct 2024 18:02:30 +0800 Subject: [PATCH 15/15] fix typo --- contracts/test/TestStorageContract.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/test/TestStorageContract.sol b/contracts/test/TestStorageContract.sol index 22960d5..e8216df 100644 --- a/contracts/test/TestStorageContract.sol +++ b/contracts/test/TestStorageContract.sol @@ -55,7 +55,7 @@ contract TestStorageContract is StorageContract { uint256[] memory, /* _masks */ bytes calldata, /* _randaoProof */ bytes[] calldata, /* _inclusiveProofs */ - bytes[] calldata /* å */ + bytes[] calldata /* _decodeProof */ ) internal override { uint256 mineTs = _getMinedTs(_blockNum); _rewardMiner(_shardId, _miner, mineTs, 1);