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

feat: sync layer cleaned up contracts #463

Open
wants to merge 152 commits into
base: kl/custom-asset-bridging
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
152 commits
Select commit Hold shift + click to select a range
33a5b97
Merge branch 'release-v23' of ssh://github.com/matter-labs/era-contra…
kelemeno May 20, 2024
db4c066
zk fmt && zk lint
kelemeno May 20, 2024
a033b6a
basic tx relay
StanislavBreadless May 21, 2024
ef22282
Merge pull request #482 from matter-labs/kl/sb-sync-layer-merge-relea…
StanislavBreadless May 21, 2024
4995c5d
Merge branch 'sb-sync-layer-migration' into sb-basic-relay-txs
StanislavBreadless May 21, 2024
77bcc0e
txs
StanislavBreadless May 21, 2024
ae5e5a5
more fixes
kelemeno May 22, 2024
5b38c69
remove remoteGovernance
kelemeno May 22, 2024
5ea7cc4
naming error
kelemeno May 22, 2024
39d1b73
fix tests
kelemeno May 22, 2024
c9fd7ec
Merge branch 'sb-sync-layer-migration' of ssh://github.com/matter-lab…
kelemeno May 22, 2024
bf75057
fix linting (#486)
Raid5594 May 22, 2024
9bf17e0
small fixes
kelemeno May 22, 2024
a736e56
sl deployment start ( unfinished)
kelemeno May 22, 2024
08b69e7
zk fmt
kelemeno May 22, 2024
584d405
small fixes, getting foundry to compile
kelemeno May 27, 2024
9432bbd
Merge branch 'sb-basic-relay-txs' of ssh://github.com/matter-labs/era…
kelemeno May 27, 2024
3a32079
l1->L3 messaging
kelemeno May 28, 2024
aac0a4e
smaller fixes
kelemeno May 28, 2024
2f75ae3
fmt
kelemeno May 28, 2024
8514a3d
input error
kelemeno May 29, 2024
0da7d23
typos
kelemeno May 29, 2024
a3f8cf4
linting
kelemeno May 29, 2024
adf5012
slither checks
kelemeno May 29, 2024
71991ff
slither checks
kelemeno May 29, 2024
642eeb8
config fix
kelemeno May 29, 2024
0b4ed87
small tx vs receipt error
kelemeno May 29, 2024
cbf4dab
second attempt
kelemeno May 29, 2024
129684c
added new merkle trees, modified OZ,
kelemeno May 30, 2024
61d1a35
fixes
kelemeno May 30, 2024
e11ac53
further cleanup
kelemeno May 31, 2024
51edbd1
more clean, full merkle tests etc
kelemeno Jun 1, 2024
01f033b
Add script for system contracts block explorer verification (#510)
vladbochok Jun 11, 2024
1f12bbd
sync with dev
StanislavBreadless Jun 12, 2024
29f9ff4
Finalize gas bound caller (#526)
StanislavBreadless Jun 12, 2024
f07b199
sync with main
StanislavBreadless Jun 13, 2024
103dd39
fix script
StanislavBreadless Jun 13, 2024
026f19f
make sl stable work
StanislavBreadless Jun 13, 2024
f3543cd
fmt
StanislavBreadless Jun 13, 2024
594bac2
Update README.md (#532)
StanislavBreadless Jun 14, 2024
89d3487
starting genesis upgrade
kelemeno Jun 17, 2024
7704660
Merge branch 'kl/custom-asset-bridging' of ssh://github.com/matter-la…
kelemeno Jun 17, 2024
0adbabb
getting hardhat tests to start
kelemeno Jun 17, 2024
e77ac03
more fixes
kelemeno Jun 17, 2024
f93e4f1
more system contract changes
kelemeno Jun 17, 2024
3e6dac2
linting
kelemeno Jun 17, 2024
b6d809e
slither
kelemeno Jun 17, 2024
490b52c
Merge branch 'sync-layer-stable' of ssh://github.com/matter-labs/era-…
kelemeno Jun 17, 2024
58743b3
typo
kelemeno Jun 17, 2024
b37151e
more linting
kelemeno Jun 17, 2024
ffa0427
Merge branch 'main' of ssh://github.com/matter-labs/era-contracts int…
kelemeno Jun 17, 2024
2b65624
linting
kelemeno Jun 17, 2024
8a44dfc
copied system contracts from kl/sync-layer-reorg
kelemeno Jun 17, 2024
1fec1e5
Merge branch 'kl/more-system-contracts' of ssh://github.com/matter-la…
kelemeno Jun 17, 2024
3d01cbc
l1 da handling basic integration
StanislavBreadless Jun 17, 2024
41866cb
remove some unneeded changes
StanislavBreadless Jun 17, 2024
0cd4bc8
genesis upgrade fix
kelemeno Jun 17, 2024
f541472
system contract hashes
kelemeno Jun 17, 2024
28c397f
outdated import
kelemeno Jun 17, 2024
ab4a99b
feat: custom DA support
dimazhornyk Jun 17, 2024
a3da6e0
add message from the bootloader
dimazhornyk Jun 17, 2024
c9eb562
Merge remote-tracking branch 'origin/feat-custom-da' into sb-l1-l2-cu…
StanislavBreadless Jun 18, 2024
d39defa
fixing migration
kelemeno Jun 18, 2024
9ebafce
lint
kelemeno Jun 18, 2024
e80d5d6
write contracts for l2 da
StanislavBreadless Jun 18, 2024
7843ffb
Merge branch 'dev' into sb-l1-l2-custom-da
StanislavBreadless Jun 18, 2024
3d3e211
small fixes
kelemeno Jun 18, 2024
90dc77f
linting
kelemeno Jun 18, 2024
9582a30
remove empty pq condition
kelemeno Jun 18, 2024
07e02aa
rm unneeded changes
StanislavBreadless Jun 18, 2024
fe4bdac
remove some more unneeded changes
StanislavBreadless Jun 18, 2024
bc0c169
nonce error
kelemeno Jun 18, 2024
50f713c
lint
kelemeno Jun 18, 2024
d88edb7
first working version
StanislavBreadless Jun 18, 2024
92dcd02
actually use the variable
StanislavBreadless Jun 18, 2024
c08bba8
fmt
StanislavBreadless Jun 18, 2024
a5718f7
easier compatible logs
StanislavBreadless Jun 18, 2024
40129c7
fmt
StanislavBreadless Jun 18, 2024
8f639db
working versiojn
StanislavBreadless Jun 19, 2024
5826f4a
fix compile
StanislavBreadless Jun 19, 2024
b597088
fmt
StanislavBreadless Jun 19, 2024
8b8ed44
fix review
StanislavBreadless Jun 19, 2024
d6b2ed0
sync with kl-reorg-sl
StanislavBreadless Jun 20, 2024
8dc1337
sl relayed da
StanislavBreadless Jun 20, 2024
6dedc39
make it work on server side also
StanislavBreadless Jun 21, 2024
b4d5b1d
fmt
StanislavBreadless Jun 21, 2024
fb6fe9a
foundry tests comment out, slither
kelemeno Jun 21, 2024
ab75b0f
lint
kelemeno Jun 21, 2024
fea20b6
fix script
StanislavBreadless Jun 21, 2024
01fe5fc
partially fix lint
StanislavBreadless Jun 21, 2024
bd894bb
fix lint
StanislavBreadless Jun 21, 2024
d050483
fix codespell
StanislavBreadless Jun 22, 2024
66643e5
lint
StanislavBreadless Jun 22, 2024
7801bf3
partially fix hardhat tests
StanislavBreadless Jun 22, 2024
a602588
fix hardhat l1 tests
StanislavBreadless Jun 22, 2024
7020bdd
additional fixes
StanislavBreadless Jun 22, 2024
52e85ab
delete no more relevant tests + temporarily turn off l1 messenger tests
StanislavBreadless Jun 23, 2024
d87f0f6
fix bootloader tests
StanislavBreadless Jun 23, 2024
6bd78ca
calculate fixed hashes
StanislavBreadless Jun 24, 2024
b5e9285
calculate hashes fix
StanislavBreadless Jun 24, 2024
d05ff61
Some clarification (#541)
StanislavBreadless Jun 24, 2024
7cf844d
Merge branch 'kl/sync-layer-reorg' into sb-l1-l2-cutom-da-with-sl
StanislavBreadless Jun 24, 2024
42be7e5
fix codespell
StanislavBreadless Jun 24, 2024
23c6c20
Merge branch 'kl/custom-asset-bridging' of ssh://github.com/matter-la…
kelemeno Jun 25, 2024
426d818
typo
kelemeno Jun 25, 2024
fcfbb59
small fix
kelemeno Jun 25, 2024
43f7232
Merge pull request #542 from matter-labs/sb-l1-l2-cutom-da-with-sl
StanislavBreadless Jun 25, 2024
4aa6f14
feat: new system contracts (#537)
kelemeno Jun 26, 2024
17e4d1c
legacy for L2Shared Bridge
kelemeno Jun 26, 2024
7b7f322
linting
kelemeno Jun 26, 2024
947efb5
chore: merge CAB (#554)
kelemeno Jun 26, 2024
66721c5
Merge branch 'kl/custom-asset-bridging' of ssh://github.com/matter-la…
kelemeno Jun 26, 2024
1cefe28
feat: move da-contracts to their own folder (#556)
kelemeno Jun 27, 2024
4a52da2
fixing small tests start
kelemeno Jun 27, 2024
3eb60a9
system contract hashes
kelemeno Jun 27, 2024
88cc446
commenting and fixing some tests
kelemeno Jun 27, 2024
3f6d26d
Merge branch 'kl/custom-asset-bridging' of ssh://github.com/matter-la…
kelemeno Jun 27, 2024
4279113
test fixes
kelemeno Jun 27, 2024
9f9c5c5
(fix): L2 tests
Jun 28, 2024
4587cd4
Merge branch 'kl/custom-asset-bridging' into kl/sync-layer-reorg
Jun 28, 2024
e44c682
(fix): copy typechain file from system contracts to l2 contracts
Jun 28, 2024
88da22e
(fix): update the script to copy typechain
Jun 28, 2024
b066688
(fix): test with updating ci flow
Jun 28, 2024
e6a100e
(fix): fmt
Jun 28, 2024
f2ccc49
(fix): test fixing ci
Jun 28, 2024
ad522d1
(fix): test fixing ci
Jun 28, 2024
8c0b80c
feat: priority tree on sync layer (#562)
kelemeno Jun 29, 2024
1c4dce4
test: FullMerkle tests (#553)
benceharomi Jun 29, 2024
529a1f9
docs and small fixes
kelemeno Jun 30, 2024
410143f
small fixes
kelemeno Jul 1, 2024
ee15a99
delete extra files
kelemeno Jul 1, 2024
c0a479d
added picture
kelemeno Jul 1, 2024
2dd22cb
custom da doc
kelemeno Jul 1, 2024
4a7359d
linting
kelemeno Jul 1, 2024
206ccd5
lint
kelemeno Jul 1, 2024
a09835e
fix: tests for custom DA (#563)
dimazhornyk Jul 1, 2024
ffa6e14
update todos fix efficient calls (#549)
koloz193 Jul 1, 2024
59fe36c
explicit interface path
koloz193 Jul 1, 2024
7537c3e
update system log key
koloz193 Jul 1, 2024
7cb54b5
fmt
koloz193 Jul 1, 2024
496652b
update bootloader test with correct key value
koloz193 Jul 1, 2024
46955b3
(feat): separate out nullifier from asset router
Jul 2, 2024
57b5a65
(feat): refactoring logic
Jul 3, 2024
d727b8a
Revert "(feat): refactoring logic"
Jul 3, 2024
2a81839
Revert "(feat): separate out nullifier from asset router"
Jul 3, 2024
f992e1b
L3 L1 comms integration (#557)
StanislavBreadless Jul 5, 2024
c8a7d70
Pin hardhat-zksolc version
ly0va Jul 8, 2024
45fa02a
updated docs
kelemeno Jul 8, 2024
11d38fa
chore: pull visisoft tests for more coverage (#600)
kelemeno Jul 9, 2024
fc862ad
later scope update
kelemeno Jul 9, 2024
c500ce8
add tests for da contracts (#603)
koloz193 Jul 9, 2024
2aab26a
add pubdata size check (#604)
koloz193 Jul 10, 2024
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
3 changes: 3 additions & 0 deletions .github/workflows/l2-contracts-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,8 @@ jobs:
- name: Run Era test node
uses: dutterbutter/era-test-node-action@v0.1.3

- name: Copy typechain from System Contracts
run: yarn sc build && yarn sc copy:typechain

- name: Run tests
run: yarn l2 test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ l1-contracts/out/*
l1-contracts/broadcast/*
l1-contracts/script-config/*
l1-contracts/script-out/*
l1-contracts/test/foundry/integration/deploy-scripts/script-out/*.toml
!l1-contracts/script-out/.gitkeep
*.timestamp
2 changes: 2 additions & 0 deletions da-contracts/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CHAIN_ETH_NETWORK=hardhat
ETH_CLIENT_WEB3_URL=http://127.0.0.1:8545
91 changes: 91 additions & 0 deletions da-contracts/contracts/CalldataDA.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

// solhint-disable gas-custom-errors, reason-string

import {BLOB_SIZE_BYTES} from "./DAUtils.sol";

uint256 constant BLOBS_SUPPORTED = 6;

/// @notice Contract that contains the functionality for process the calldata DA.
/// @dev The expected l2DAValidator that should be used with it `RollupL2DAValidator`.
abstract contract CalldataDA {
/// @notice Parses the input that the l2 Da validator has provided to the contract.
/// @param _l2DAValidatorOutputHash The hash of the output of the L2 DA validator.
/// @param _maxBlobsSupported The maximal number of blobs supported by the chain.
/// @param _operatorDAInput The DA input by the operator provided on L1.
function _processL2RollupDAValidatorOutputHash(
bytes32 _l2DAValidatorOutputHash,
uint256 _maxBlobsSupported,
bytes calldata _operatorDAInput
)
internal
pure
returns (
bytes32 stateDiffHash,
bytes32 fullPubdataHash,
bytes32[] memory blobsLinearHashes,
uint256 blobsProvided,
bytes calldata l1DaInput
)
{
// The preimage under the hash `l2DAValidatorOutputHash` is expected to be in the following format:
// - First 32 bytes are the hash of the uncompressed state diff.
// - Then, there is a 32-byte hash of the full pubdata.
// - Then, there is the 1-byte number of blobs published.
// - Then, there are linear hashes of the published blobs, 32 bytes each.

// Check that it accommodates enough pubdata for the state diff hash, hash of pubdata + the number of blobs.
require(_operatorDAInput.length >= 32 + 32 + 1, "too small");

stateDiffHash = bytes32(_operatorDAInput[:32]);
fullPubdataHash = bytes32(_operatorDAInput[32:64]);
blobsProvided = uint256(uint8(_operatorDAInput[64]));

require(blobsProvided <= _maxBlobsSupported, "invalid number of blobs");

// Note that the API of the contract requires that the returned blobs linear hashes have length of
// the `_maxBlobsSupported`
blobsLinearHashes = new bytes32[](_maxBlobsSupported);

require(_operatorDAInput.length >= 65 + 32 * blobsProvided, "invalid blobs hashes");

uint256 ptr = 65;

for (uint256 i = 0; i < blobsProvided; ++i) {
// Take the 32 bytes of the blob linear hash
blobsLinearHashes[i] = bytes32(_operatorDAInput[ptr:ptr + 32]);
ptr += 32;
}

// Now, we need to double check that the provided input was indeed retutned by the L2 DA validator.
require(keccak256(_operatorDAInput[:ptr]) == _l2DAValidatorOutputHash, "invalid l2 DA output hash");

// The rest of the output were provided specifically by the operator
l1DaInput = _operatorDAInput[ptr:];
}

/// @notice Verify that the calldata DA was correctly provided.
/// todo: better doc comments
function _processCalldataDA(
uint256 _blobsProvided,
bytes32 _fullPubdataHash,
uint256 _maxBlobsSupported,
bytes calldata _pubdataInput
) internal pure returns (bytes32[] memory blobCommitments, bytes calldata _pubdata) {
// We typically do not know whether we'll use calldata or blobs at the time when
// we start proving the batch. That's why the blob commitment for a single blob is still present in the case of calldata.

blobCommitments = new bytes32[](_maxBlobsSupported);

require(_blobsProvided == 1, "one one blob with calldata");

_pubdata = _pubdataInput[:_pubdataInput.length - 32];

// FIXME: allow larger lengths for SyncLayer-based chains.
require(_pubdata.length <= BLOB_SIZE_BYTES, "cz");
require(_fullPubdataHash == keccak256(_pubdata), "wp");
blobCommitments[0] = bytes32(_pubdataInput[_pubdataInput.length - 32:_pubdataInput.length]);
}
}
37 changes: 37 additions & 0 deletions da-contracts/contracts/DAUtils.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

/// @dev Total number of bytes in a blob. Blob = 4096 field elements * 31 bytes per field element
/// @dev EIP-4844 defines it as 131_072 but we use 4096 * 31 within our circuits to always fit within a field element
/// @dev Our circuits will prove that a EIP-4844 blob and our internal blob are the same.
uint256 constant BLOB_SIZE_BYTES = 126_976;

/// @dev Enum used to determine the source of pubdata. At first we will support calldata and blobs but this can be extended.
enum PubdataSource {
Calldata,
Blob
}

/// @dev BLS Modulus value defined in EIP-4844 and the magic value returned from a successful call to the
/// point evaluation precompile
uint256 constant BLS_MODULUS = 52435875175126190479447740508185965837690552500527637822603658699938581184513;

/// @dev Packed pubdata commitments.
/// @dev Format: list of: opening point (16 bytes) || claimed value (32 bytes) || commitment (48 bytes) || proof (48 bytes)) = 144 bytes
uint256 constant PUBDATA_COMMITMENT_SIZE = 144;

/// @dev Offset in pubdata commitment of blobs for claimed value
uint256 constant PUBDATA_COMMITMENT_CLAIMED_VALUE_OFFSET = 16;

/// @dev Offset in pubdata commitment of blobs for kzg commitment
uint256 constant PUBDATA_COMMITMENT_COMMITMENT_OFFSET = 48;

/// @dev For each blob we expect that the commitment is provided as well as the marker whether a blob with such commitment has been published before.
uint256 constant BLOB_DA_INPUT_SIZE = PUBDATA_COMMITMENT_SIZE + 32;

/// @dev Address of the point evaluation precompile used for EIP-4844 blob verification.
address constant POINT_EVALUATION_PRECOMPILE_ADDR = address(0x0A);

/// @dev The address of the special smart contract that can send arbitrary length message as an L2 log
address constant L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR = address(0x8008);
34 changes: 34 additions & 0 deletions da-contracts/contracts/IL1DAValidator.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

struct L1DAValidatorOutput {
/// @dev The hash of the uncompressed state diff.
bytes32 stateDiffHash;
/// @dev The hashes of the blobs on L1. The array is dynamic to account for forward compatibility.
/// The length of it must be equal to `maxBlobsSupported`.
bytes32[] blobsLinearHashes;
/// @dev The commitments to the blobs on L1. The array is dynamic to account for forward compatibility.
/// Its length must be equal to the length of blobsLinearHashes.
/// @dev If the system supports more blobs than returned, the rest of the array should be filled with zeros.
bytes32[] blobsOpeningCommitments;
}

// TODO: require EIP165 support as this will allow changes for future compatibility.
interface IL1DAValidator {
/// @notice The function that checks the data availability for the given batch input.
/// @param chainId The chain id of the chain that is being committed.
/// @param l2DAValidatorOutputHash The hash of that was returned by the l2DAValidator.
/// @param operatorDAInput The DA input by the operator provided on L1.
/// @param maxBlobsSupported The maximal number of blobs supported by the chain.
/// We provide this value for future compatibility.
/// This is needed because the corresponding `blobsLinearHashes`/`blobsOpeningCommitments`
/// in the `L1DAValidatorOutput` struct will have to have this length as it is required
/// to be static by the circuits.
function checkDA(
uint256 chainId,
bytes32 l2DAValidatorOutputHash,
bytes calldata operatorDAInput,
uint256 maxBlobsSupported
) external returns (L1DAValidatorOutput memory output);
}
11 changes: 11 additions & 0 deletions da-contracts/contracts/IL1Messenger.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;
/**
* @author Matter Labs
* @custom:security-contact security@matterlabs.dev
* @notice The interface of the L1 Messenger contract, responsible for sending messages to L1.
*/
interface IL1Messenger {
function sendToL1(bytes memory _message) external returns (bytes32);
}
179 changes: 179 additions & 0 deletions da-contracts/contracts/RollupL1DAValidator.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

// solhint-disable gas-custom-errors, reason-string

import {IL1DAValidator, L1DAValidatorOutput} from "./IL1DAValidator.sol";

import {CalldataDA} from "./CalldataDA.sol";

import {PubdataSource, BLS_MODULUS, PUBDATA_COMMITMENT_SIZE, PUBDATA_COMMITMENT_CLAIMED_VALUE_OFFSET, PUBDATA_COMMITMENT_COMMITMENT_OFFSET, BLOB_DA_INPUT_SIZE, POINT_EVALUATION_PRECOMPILE_ADDR} from "./DAUtils.sol";

uint256 constant BLOBS_SUPPORTED = 6;

contract RollupL1DAValidator is IL1DAValidator, CalldataDA {
/// @dev The published blob commitments. Note, that the correctness of blob commitment with relation to the linear hash
/// is *not* checked in this contract, but is expected to be checked at the veriifcation stage of the ZK contract.
mapping(bytes32 blobCommitment => bool isPublished) public publishedBlobCommitments;

/// @notice Publishes certain blobs, marking commitments to them as published.
/// @param _pubdataCommitments The commitments to the blobs to be published.
/// `_pubdataCommitments` is a packed list of commitments of the following format:
/// opening point (16 bytes) || claimed value (32 bytes) || commitment (48 bytes) || proof (48 bytes)
function publishBlobs(bytes calldata _pubdataCommitments) external {
require(_pubdataCommitments.length > 0, "zln");
require(_pubdataCommitments.length % PUBDATA_COMMITMENT_SIZE == 0, "bd");

uint256 versionedHashIndex = 0;
// solhint-disable-next-line gas-length-in-loops
for (uint256 i = 0; i < _pubdataCommitments.length; i += PUBDATA_COMMITMENT_SIZE) {
bytes32 blobCommitment = _getPublishedBlobCommitment(
versionedHashIndex,
_pubdataCommitments[i:i + PUBDATA_COMMITMENT_SIZE]
);
publishedBlobCommitments[blobCommitment] = true;
++versionedHashIndex;
}
}

/// @notice Generated the blob commitemnt to be used in the cryptographic proof by calling the point evaluation precompile.
/// @param _index The index of the blob in this transaction.
/// @param _commitment The packed: opening point (16 bytes) || claimed value (32 bytes) || commitment (48 bytes) || proof (48 bytes)) = 144 bytes
/// @return The commitment to be used in the cryptographic proof.
function _getPublishedBlobCommitment(uint256 _index, bytes calldata _commitment) internal view returns (bytes32) {
bytes32 blobVersionedHash = _getBlobVersionedHash(_index);

require(blobVersionedHash != bytes32(0), "vh");

// First 16 bytes is the opening point. While we get the point as 16 bytes, the point evaluation precompile
// requires it to be 32 bytes. The blob commitment must use the opening point as 16 bytes though.
bytes32 openingPoint = bytes32(
uint256(uint128(bytes16(_commitment[:PUBDATA_COMMITMENT_CLAIMED_VALUE_OFFSET])))
);

_pointEvaluationPrecompile(
blobVersionedHash,
openingPoint,
_commitment[PUBDATA_COMMITMENT_CLAIMED_VALUE_OFFSET:PUBDATA_COMMITMENT_SIZE]
);

// Take the hash of the versioned hash || opening point || claimed value
return keccak256(abi.encodePacked(blobVersionedHash, _commitment[:PUBDATA_COMMITMENT_COMMITMENT_OFFSET]));
}

/// @notice Verify that the blob DA was correctly provided.
/// @param _blobsProvided The number of blobs provided.
/// @param _maxBlobsSupported Maximum number of blobs supported.
/// @param _operatorDAInput Input used to verify that the blobs contain the data we expect.
function _processBlobDA(
uint256 _blobsProvided,
uint256 _maxBlobsSupported,
bytes calldata _operatorDAInput
) internal view returns (bytes32[] memory blobsCommitments) {
blobsCommitments = new bytes32[](_maxBlobsSupported);

// For blobs we expect to receive the commitments in the following format:
// 144 bytes for commitment data
// 32 bytes for the prepublished commitment. If it is non-zero, it means that it is expected that
// such commitment was published before. Otherwise, it is expected that it is published in this transaction
require(_operatorDAInput.length == _blobsProvided * BLOB_DA_INPUT_SIZE, "bd");

uint256 versionedHashIndex = 0;

// we iterate over the `_operatorDAInput`, while advacning the pointer by `BLOB_DA_INPUT_SIZE` each time
for (uint256 i = 0; i < _blobsProvided; ++i) {
bytes calldata commitmentData = _operatorDAInput[:PUBDATA_COMMITMENT_SIZE];
bytes32 prepublishedCommitment = bytes32(
_operatorDAInput[PUBDATA_COMMITMENT_SIZE:PUBDATA_COMMITMENT_SIZE + 32]
);

if (prepublishedCommitment != bytes32(0)) {
// We double check that this commitment has indeed been published.
// If that is the case, we do not care about the actual underlying data.
require(publishedBlobCommitments[prepublishedCommitment], "not published");

blobsCommitments[i] = prepublishedCommitment;
} else {
blobsCommitments[i] = _getPublishedBlobCommitment(versionedHashIndex, commitmentData);
++versionedHashIndex;
}

// Advance the pointer
_operatorDAInput = _operatorDAInput[BLOB_DA_INPUT_SIZE:];
}

// This check is required because we want to ensure that there aren't any extra blobs trying to be published.
// Calling the BLOBHASH opcode with an index > # blobs - 1 yields bytes32(0)
bytes32 versionedHash = _getBlobVersionedHash(versionedHashIndex);
require(versionedHash == bytes32(0), "lh");
}

/// @inheritdoc IL1DAValidator
function checkDA(
uint256, // _chainId
bytes32 _l2DAValidatorOutputHash,
bytes calldata _operatorDAInput,
uint256 _maxBlobsSupported
) external returns (L1DAValidatorOutput memory output) {
(
bytes32 stateDiffHash,
bytes32 fullPubdataHash,
bytes32[] memory blobsLinearHashes,
uint256 blobsProvided,
bytes calldata l1DaInput
) = _processL2RollupDAValidatorOutputHash(_l2DAValidatorOutputHash, _maxBlobsSupported, _operatorDAInput);

uint8 pubdataSource = uint8(l1DaInput[0]);
bytes32[] memory blobCommitments;

if (pubdataSource == uint8(PubdataSource.Blob)) {
blobCommitments = _processBlobDA(blobsProvided, _maxBlobsSupported, l1DaInput[1:]);
} else if (pubdataSource == uint8(PubdataSource.Calldata)) {
(blobCommitments, ) = _processCalldataDA(blobsProvided, fullPubdataHash, _maxBlobsSupported, l1DaInput[1:]);
} else {
revert("l1-da-validator/invalid-pubdata-source");
}

// We verify that for each set of blobHash/blobCommitment are either both empty
// or there are values for both.
// This is mostly a sanity check and it is not strictly required.
for (uint256 i = 0; i < _maxBlobsSupported; ++i) {
require(
(blobsLinearHashes[i] == bytes32(0) && blobCommitments[i] == bytes32(0)) ||
(blobsLinearHashes[i] != bytes32(0) && blobCommitments[i] != bytes32(0)),
"bh"
);
}

output.stateDiffHash = stateDiffHash;
output.blobsLinearHashes = blobsLinearHashes;
output.blobsOpeningCommitments = blobCommitments;
}

/// @notice Calls the point evaluation precompile and verifies the output
/// Verify p(z) = y given commitment that corresponds to the polynomial p(x) and a KZG proof.
/// Also verify that the provided commitment matches the provided versioned_hash.
///
function _pointEvaluationPrecompile(
bytes32 _versionedHash,
bytes32 _openingPoint,
bytes calldata _openingValueCommitmentProof
) internal view {
bytes memory precompileInput = abi.encodePacked(_versionedHash, _openingPoint, _openingValueCommitmentProof);

(bool success, bytes memory data) = POINT_EVALUATION_PRECOMPILE_ADDR.staticcall(precompileInput);

// We verify that the point evaluation precompile call was successful by testing the latter 32 bytes of the
// response is equal to BLS_MODULUS as defined in https://eips.ethereum.org/EIPS/eip-4844#point-evaluation-precompile
require(success, "failed to call point evaluation precompile");
(, uint256 result) = abi.decode(data, (uint256, uint256));
require(result == BLS_MODULUS, "precompile unexpected output");
}

function _getBlobVersionedHash(uint256 _index) internal view virtual returns (bytes32 versionedHash) {
assembly {
versionedHash := blobhash(_index)
}
}
}
Loading
Loading