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

Abstract block info #105

Merged
merged 8 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
71 changes: 19 additions & 52 deletions contracts/EthStorageContractL2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,62 +28,29 @@ contract EthStorageContractL2 is EthStorageContract2 {
IL1Block internal constant L1_BLOCK = IL1Block(0x4200000000000000000000000000000000000015);

/// @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)
EthStorageContract2(_config, _startTime, _storageCost, _dcfFactor)
{}

/// @notice Get the current block number
function blockNumber() internal view override returns (uint256) {
syntrust marked this conversation as resolved.
Show resolved Hide resolved
return L1_BLOCK.number();
}

/// @notice Get the current block timestamp
function blockTs() internal view override returns (uint256) {
return L1_BLOCK.timestamp();
}

/// @notice Get the randao value from the L1 blockhash.
function _getRandao(uint256 _l1BlockNumber, bytes calldata _headerRlpBytes) internal view returns (bytes32) {
function getRandao(uint256 _l1BlockNumber, bytes calldata _headerRlpBytes)
internal
view
override
returns (bytes32)
{
bytes32 bh = L1_BLOCK.blockHash(_l1BlockNumber);
require(bh != bytes32(0), "EthStorageContractL2: failed to obtain blockhash");

return RandaoLib.verifyHeaderAndGetRandao(bh, _headerRlpBytes);
}

/// @notice We are still using L1 block number, timestamp, and blockhash to mine eventhough we are on L2.
/// @param _blockNumber L1 blocknumber.
/// @param _shardId Shard ID.
/// @param _miner Miner address.
/// @param _nonce Nonce.
/// @param _encodedSamples Encoded samples.
/// @param _masks Sample masks.
/// @param _randaoProof L1 block header RLP bytes.
/// @param _inclusiveProofs Sample inclusive proofs.
/// @param _decodeProof Mask decode proof.
function _mine(
uint256 _blockNumber,
uint256 _shardId,
address _miner,
uint256 _nonce,
bytes32[] memory _encodedSamples,
uint256[] memory _masks,
bytes calldata _randaoProof,
bytes[] calldata _inclusiveProofs,
bytes[] calldata _decodeProof
) internal override {
// Obtain the blockhash of the block number of recent blocks
require(L1_BLOCK.number() - _blockNumber <= MAX_L1_MINING_DRIFT, "EthStorageContractL2: block number too old");
// To avoid stack too deep, we resue the hash0 instead of using randao

bytes32 hash0 = _getRandao(_blockNumber, _randaoProof);
// Estimate block timestamp
uint256 mineTs = L1_BLOCK.timestamp() - (L1_BLOCK.number() - _blockNumber) * 12;

// Given a blockhash and a miner, we only allow sampling up to nonce limit times.
require(_nonce < nonceLimit, "EthStorageContractL2: nonce too big");

// Check if the data matches the hash in metadata and obtain the solution hash.
hash0 = keccak256(abi.encode(_miner, hash0, _nonce));
hash0 = verifySamples(_shardId, hash0, _miner, _encodedSamples, _masks, _inclusiveProofs, _decodeProof);

// Check difficulty
uint256 diff = _calculateDiffAndInitHashSingleShard(_shardId, mineTs);
uint256 required = uint256(2 ** 256 - 1) / diff;
require(uint256(hash0) <= required, "EthStorageContractL2: diff not match");

_rewardMiner(_shardId, _miner, mineTs, diff);
}
}
39 changes: 30 additions & 9 deletions contracts/StorageContract.sol
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ abstract contract StorageContract is DecentralizedKV {
if ((totalEntries % (1 << SHARD_ENTRY_BITS)) == 1 && shardId != 0) {
// Open a new shard if the KV is the first one of the shard
// (TODO): Setup shard difficulty as current difficulty / factor?
return _upfrontPayment(block.timestamp);
return _upfrontPayment(blockTs());
} else {
return _upfrontPayment(infos[shardId].lastMineTime);
}
Expand All @@ -189,7 +189,7 @@ abstract contract StorageContract is DecentralizedKV {
uint256 totalPayment = 0;
if ((totalEntries >> SHARD_ENTRY_BITS) > shardId) {
uint256 kvCountNew = totalEntries % (1 << SHARD_ENTRY_BITS);
totalPayment += _upfrontPayment(block.timestamp) * kvCountNew;
totalPayment += _upfrontPayment(blockTs()) * kvCountNew;
totalPayment += _upfrontPayment(infos[shardId].lastMineTime) * (_batchSize - kvCountNew);
} else {
totalPayment += _upfrontPayment(infos[shardId].lastMineTime) * _batchSize;
Expand All @@ -199,7 +199,7 @@ abstract contract StorageContract is DecentralizedKV {

/// @inheritdoc DecentralizedKV
function _prepareAppend(uint256 _batchSize) internal virtual override {
return _prepareAppendWithTimestamp(block.timestamp, _batchSize);
return _prepareAppendWithTimestamp(blockTs(), _batchSize);
}

/// @notice Verify the samples of the BLOBs by the miner (storage provider) including
Expand Down Expand Up @@ -297,8 +297,8 @@ abstract contract StorageContract is DecentralizedKV {
/// @param _blockNumber The block number.
/// @return The mining reward.
function miningReward(uint256 _shardId, uint256 _blockNumber) public view returns (uint256) {
uint256 minedTs = block.timestamp - (block.number - _blockNumber) * 12;
(, , uint256 minerReward) = _miningReward(_shardId, minedTs);
uint256 minedTs = getMinedTs(_blockNumber);
(,, uint256 minerReward) = _miningReward(_shardId, minedTs);
return minerReward;
}

Expand Down Expand Up @@ -376,12 +376,11 @@ abstract contract StorageContract is DecentralizedKV {
bytes[] calldata _inclusiveProofs,
bytes[] calldata _decodeProof
) internal virtual {
// Obtain the blockhash of the block number of recent blocks
require(block.number - _blockNumber <= MAX_L1_MINING_DRIFT, "StorageContract: block number too old");
require(blockNumber() - _blockNumber <= MAX_L1_MINING_DRIFT, "StorageContract: block number too old");
// To avoid stack too deep, we resue the hash0 instead of using randao
bytes32 hash0 = RandaoLib.verifyHistoricalRandao(_blockNumber, _randaoProof);
bytes32 hash0 = getRandao(_blockNumber, _randaoProof);
// Estimate block timestamp
uint256 mineTs = block.timestamp - (block.number - _blockNumber) * 12;
uint256 mineTs = getMinedTs(_blockNumber);

// Given a blockhash and a miner, we only allow sampling up to nonce limit times.
require(_nonce < nonceLimit, "StorageContract: nonce too big");
Expand All @@ -398,6 +397,28 @@ abstract contract StorageContract is DecentralizedKV {
_rewardMiner(_shardId, _miner, mineTs, diff);
}

/// @notice Get the current block number
function blockNumber() internal view virtual returns (uint256) {
return block.number;
}

/// @notice Get the current block timestamp
function blockTs() internal view virtual returns (uint256) {
return block.timestamp;
}

/// @notice Get the randao value by block number.
function getRandao(uint256 _blockNumber, bytes calldata _headerRlpBytes) internal view virtual returns (bytes32) {
bytes32 bh = blockhash(_blockNumber);
require(bh != bytes32(0), "StorageContract: failed to obtain blockhash");
return RandaoLib.verifyHeaderAndGetRandao(bh, _headerRlpBytes);
}

/// @notice Get the mined timestamp
function getMinedTs(uint256 _blockNumber) internal view returns (uint256) {
return blockTs() - (blockNumber() - _blockNumber) * 12;
}

/// @notice Return the sample size bits.
function sampleSizeBits() public pure returns (uint256) {
return SAMPLE_SIZE_BITS;
Expand Down
13 changes: 0 additions & 13 deletions contracts/libraries/RandaoLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,4 @@ library RandaoLib {
require(_headerHash == item.rlpBytesKeccak256(), "RandaoLib: header hash mismatch");
return getRandaoFromHeader(item);
}

/// @notice Get the historical Randao mixDigest by block number
/// @param _blockNumber The block number
/// @param _headerRlpBytes The RLP data of the header
/// @return The Randao mixDigest
function verifyHistoricalRandao(
uint256 _blockNumber,
bytes memory _headerRlpBytes
) internal view returns (bytes32) {
bytes32 bh = blockhash(_blockNumber);
require(bh != bytes32(0), "RandaoLib: failed to obtain blockhash");
return verifyHeaderAndGetRandao(bh, _headerRlpBytes);
}
}
9 changes: 3 additions & 6 deletions contracts/test/TestEthStorageContract.sol
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,9 @@ contract TestEthStorageContract is EthStorageContract {
bytes[] calldata inclusiveProofs,
bytes[] calldata decodeProof
) internal {
// Obtain the blockhash of the block number of recent blocks
require(block.number - blockNumber <= 64, "block number too old");
// To avoid stack too deep, we resue the hash0 instead of using randao
bytes32 hash0 = RandaoLib.verifyHistoricalRandao(blockNumber, randaoProof);
// Estimate block timestamp
uint256 mineTs = block.timestamp - (block.number - blockNumber) * 12;
require(super.blockNumber() - blockNumber <= MAX_L1_MINING_DRIFT, "block number too old");
syntrust marked this conversation as resolved.
Show resolved Hide resolved
bytes32 hash0 = getRandao(blockNumber, randaoProof);
uint256 mineTs = getMinedTs(blockNumber);

// Given a blockhash and a miner, we only allow sampling up to nonce limit times.
require(nonce < nonceLimit, "nonce too big");
Expand Down
4 changes: 0 additions & 4 deletions contracts/test/TestRandao.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,4 @@ contract TestRandao {
function verifyHeaderAndGetRandao(bytes32 headerHash, bytes memory headerRlpBytes) public pure returns (bytes32) {
return RandaoLib.verifyHeaderAndGetRandao(headerHash, headerRlpBytes);
}

function verifyHistoricalRandao(uint256 blockNumber, bytes memory proof) public view returns (bytes32) {
return RandaoLib.verifyHistoricalRandao(blockNumber, proof);
}
}
4 changes: 2 additions & 2 deletions test/randao-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ describe("Randao Test", function () {
const Randao = await ethers.getContractFactory("TestRandao");
const rd = await Randao.deploy();
await rd.deployed();

let randao = await rd.verifyHistoricalRandao(bn, encodedHeader);
let randao = await rd.verifyHeaderAndGetRandao(hash, encodedHeader);
expect(randao).to.equal(block.mixHash);
});
});
Expand Down
Loading