diff --git a/l1-contracts/foundry.toml b/l1-contracts/foundry.toml index d0f8e98fd2ed..79512e5d3a54 100644 --- a/l1-contracts/foundry.toml +++ b/l1-contracts/foundry.toml @@ -30,7 +30,7 @@ gas_reports = [ "RollupWithPreheating", "EmpireSlashingProposer", "TallySlashingProposer", - "MultiAdder" + "MultiAdder", ] remappings = [ @@ -39,6 +39,7 @@ remappings = [ "@test/=test", "@zkpassport/=lib/circuits/src/solidity/src/", "@zkpassport-test/=lib/circuits/src/solidity/test", + "@aztec-blob-lib/=src/mock/libraries", ] # See more config options https://github.com/foundry-rs/foundry/tree/master/config @@ -73,7 +74,7 @@ override_spacing = false [lint] ignore = ["./lib/**"] exclude_lints = [ - "unused-import", # Mostly in test code + "unused-import", # Mostly in test code "incorrect-shift", # Throws warnings on construction of bitmasks "asm-keccak256", # https://github.com/AztecProtocol/aztec-packages/issues/16808 @@ -87,3 +88,14 @@ exclude_lints = [ [rpc_endpoints] mainnet_fork = "https://mainnet.infura.io/v3/9928b52099854248b3a096be07a6b23c" + + +[profile.production] +remappings = [ + "@oz/=lib/openzeppelin-contracts/contracts/", + "@aztec/=src", + "@test/=test", + "@zkpassport/=lib/circuits/src/solidity/src/", + "@zkpassport-test/=lib/circuits/src/solidity/test", + "@aztec-blob-lib/=src/core/libraries/rollup/", +] diff --git a/l1-contracts/src/core/libraries/rollup/BlobLib.sol b/l1-contracts/src/core/libraries/rollup/BlobLib.sol index 838e7076ea0f..437074e7f06c 100644 --- a/l1-contracts/src/core/libraries/rollup/BlobLib.sol +++ b/l1-contracts/src/core/libraries/rollup/BlobLib.sol @@ -5,7 +5,6 @@ pragma solidity >=0.8.27; import {Constants} from "@aztec/core/libraries/ConstantsGen.sol"; import {Hash} from "@aztec/core/libraries/crypto/Hash.sol"; import {Errors} from "@aztec/core/libraries/Errors.sol"; -import {Vm} from "forge-std/Vm.sol"; /** * @title BlobLib - Blob Management and Validation Library @@ -35,44 +34,24 @@ import {Vm} from "forge-std/Vm.sol"; * 4. calculateBlobHash() computes versioned hashes from commitments following EIP-4844 specification */ library BlobLib { - address public constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code")))); uint256 internal constant VERSIONED_HASH_VERSION_KZG = 0x0100000000000000000000000000000000000000000000000000000000000000; // 0x01 << 248 to be used in blobHashCheck /** * @notice Get the blob base fee * - * @dev If we are in a foundry test, we use the cheatcode to get the blob base fee. - * Otherwise, we use the `block.blobbasefee` - * * @return uint256 - The blob base fee */ function getBlobBaseFee() internal view returns (uint256) { - if (block.chainid == 31_337 && VM_ADDRESS.code.length > 0) { - return Vm(VM_ADDRESS).getBlobBaseFee(); - } return block.blobbasefee; } /** * @notice Get the blob hash * - * @dev If we are in a foundry test, we use the cheatcode to get the blob hashes - * Otherwise, we use the `blobhash` function in assembly - * * @return blobHash - The blob hash */ function getBlobHash(uint256 _index) internal view returns (bytes32 blobHash) { - if (block.chainid == 31_337 && VM_ADDRESS.code.length > 0) { - // We know that this one is ABHORRENT. But it should not exists, and only will - // be hit in testing. - bytes32[] memory blobHashes = Vm(VM_ADDRESS).getBlobhashes(); - if (_index < blobHashes.length) { - return blobHashes[_index]; - } - return bytes32(0); - } - assembly { blobHash := blobhash(_index) } diff --git a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol index 8bf1fd198268..6e9a492d7c04 100644 --- a/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol +++ b/l1-contracts/src/core/libraries/rollup/EpochProofLib.sol @@ -2,6 +2,7 @@ // Copyright 2024 Aztec Labs. pragma solidity >=0.8.27; +import {BlobLib} from "@aztec-blob-lib/BlobLib.sol"; import {SubmitEpochRootProofArgs, PublicInputArgs, IRollupCore, RollupStore} from "@aztec/core/interfaces/IRollup.sol"; import {CompressedTempBlockLog} from "@aztec/core/libraries/compressed-data/BlockLog.sol"; import {CompressedFeeHeader, FeeHeaderLib} from "@aztec/core/libraries/compressed-data/fees/FeeStructs.sol"; @@ -9,7 +10,6 @@ import {ChainTipsLib, CompressedChainTips} from "@aztec/core/libraries/compresse import {Constants} from "@aztec/core/libraries/ConstantsGen.sol"; import {Errors} from "@aztec/core/libraries/Errors.sol"; import {AttestationLib, CommitteeAttestations} from "@aztec/core/libraries/rollup/AttestationLib.sol"; -import {BlobLib} from "@aztec/core/libraries/rollup/BlobLib.sol"; import {RewardLib} from "@aztec/core/libraries/rollup/RewardLib.sol"; import {STFLib} from "@aztec/core/libraries/rollup/STFLib.sol"; import {ValidatorSelectionLib} from "@aztec/core/libraries/rollup/ValidatorSelectionLib.sol"; diff --git a/l1-contracts/src/core/libraries/rollup/FeeLib.sol b/l1-contracts/src/core/libraries/rollup/FeeLib.sol index 70e8c49b5b82..9ee0360a387e 100644 --- a/l1-contracts/src/core/libraries/rollup/FeeLib.sol +++ b/l1-contracts/src/core/libraries/rollup/FeeLib.sol @@ -2,6 +2,7 @@ // Copyright 2024 Aztec Labs. pragma solidity >=0.8.27; +import {BlobLib} from "@aztec-blob-lib/BlobLib.sol"; import { EthValue, FeeAssetValue, @@ -26,7 +27,6 @@ import {SafeCast} from "@oz/utils/math/SafeCast.sol"; import {SignedMath} from "@oz/utils/math/SignedMath.sol"; import {Errors} from "./../Errors.sol"; import {Slot, Timestamp, TimeLib} from "./../TimeLib.sol"; -import {BlobLib} from "./BlobLib.sol"; import {STFLib} from "./STFLib.sol"; // The lowest number of fee asset per eth is 10 with a precision of 1e9. diff --git a/l1-contracts/src/core/libraries/rollup/ProposeLib.sol b/l1-contracts/src/core/libraries/rollup/ProposeLib.sol index fa4afc6601b1..f2d1d48316e4 100644 --- a/l1-contracts/src/core/libraries/rollup/ProposeLib.sol +++ b/l1-contracts/src/core/libraries/rollup/ProposeLib.sol @@ -2,6 +2,7 @@ // Copyright 2024 Aztec Labs. pragma solidity >=0.8.27; +import {BlobLib} from "@aztec-blob-lib/BlobLib.sol"; import {RollupStore, IRollupCore, BlockHeaderValidationFlags} from "@aztec/core/interfaces/IRollup.sol"; import {TempBlockLog} from "@aztec/core/libraries/compressed-data/BlockLog.sol"; import {FeeHeader} from "@aztec/core/libraries/compressed-data/fees/FeeStructs.sol"; @@ -13,7 +14,6 @@ import {ValidatorSelectionLib} from "@aztec/core/libraries/rollup/ValidatorSelec import {Timestamp, Slot, Epoch, TimeLib} from "@aztec/core/libraries/TimeLib.sol"; import {CompressedSlot, CompressedTimeMath} from "@aztec/shared/libraries/CompressedTimeMath.sol"; import {Signature} from "@aztec/shared/libraries/SignatureLib.sol"; -import {BlobLib} from "./BlobLib.sol"; import {ProposedHeader, ProposedHeaderLib, StateReference} from "./ProposedHeaderLib.sol"; import {STFLib} from "./STFLib.sol"; diff --git a/l1-contracts/src/core/libraries/rollup/RollupOperationsExtLib.sol b/l1-contracts/src/core/libraries/rollup/RollupOperationsExtLib.sol index 9692a00b67db..9b3d7fe1f6c1 100644 --- a/l1-contracts/src/core/libraries/rollup/RollupOperationsExtLib.sol +++ b/l1-contracts/src/core/libraries/rollup/RollupOperationsExtLib.sol @@ -7,7 +7,7 @@ import {Errors} from "@aztec/core/libraries/Errors.sol"; import {SubmitEpochRootProofArgs, PublicInputArgs} from "@aztec/core/interfaces/IRollup.sol"; import {STFLib} from "@aztec/core/libraries/rollup/STFLib.sol"; import {Timestamp, TimeLib, Slot, Epoch} from "@aztec/core/libraries/TimeLib.sol"; -import {BlobLib} from "./BlobLib.sol"; +import {BlobLib} from "@aztec-blob-lib/BlobLib.sol"; import {EpochProofLib} from "./EpochProofLib.sol"; import {AttestationLib} from "@aztec/core/libraries/rollup/AttestationLib.sol"; import { diff --git a/l1-contracts/src/mock/libraries/BlobLib.sol b/l1-contracts/src/mock/libraries/BlobLib.sol new file mode 100644 index 000000000000..90bd087b0916 --- /dev/null +++ b/l1-contracts/src/mock/libraries/BlobLib.sol @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2024 Aztec Labs. +pragma solidity >=0.8.27; + +import {BlobLib as CoreBlobLib} from "@aztec/core/libraries/rollup/BlobLib.sol"; +import {Vm} from "forge-std/Vm.sol"; + +/** + * @title BlobLib - Blob Management and Validation Library + * @author Aztec Labs + * @notice Core library for handling blob operations, validation, and commitment management in the Aztec rollup. + * + * @dev This library provides functionality for managing blobs: + * - Blob hash retrieval and validation against EIP-4844 specifications + * - Blob commitment verification and batched blob proof validation + * - Blob base fee retrieval for transaction cost calculations + * - Accumulated blob commitments hash calculation for epoch proofs + * + * VM_ADDRESS: + * The VM_ADDRESS (0x7109709ECfa91a80626fF3989D68f67F5b1DD12D) is a special address used to detect + * when the contract is running in a Foundry test environment. This address is derived from + * keccak256("hevm cheat code") and corresponds to Foundry's VM contract that provides testing utilities. + * When VM_ADDRESS.code.length > 0, it indicates we' dre in a test environment, allowing the library to: + * - Use Foundry's getBlobBaseFee() cheatcode instead of block.blobbasefee + * - Use Foundry's getBlobhashes() cheatcode instead of the blobhash() opcode + * This enables comprehensive testing of blob functionality without requiring actual blob transactions. + * + * Blob Validation Flow: + * 1. validateBlobs() processes L2 block blob data, extracting commitments and validating against real blobs + * 2. calculateBlobCommitmentsHash() accumulates commitments across an epoch for rollup circuit validation + * 3. validateBatchedBlob() verifies batched blob proofs using the EIP-4844 point evaluation precompile + * 4. calculateBlobHash() computes versioned hashes from commitments following EIP-4844 specification + */ +library BlobLib { + address public constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code")))); + uint256 internal constant VERSIONED_HASH_VERSION_KZG = + 0x0100000000000000000000000000000000000000000000000000000000000000; // 0x01 << 248 to be used in blobHashCheck + + /** + * @notice Get the blob base fee + * + * @dev If we are in a foundry test, we use the cheatcode to get the blob base fee. + * Otherwise, we use the `block.blobbasefee` + * + * @return uint256 - The blob base fee + */ + function getBlobBaseFee() internal view returns (uint256) { + if (VM_ADDRESS.code.length > 0) { + return Vm(VM_ADDRESS).getBlobBaseFee(); + } + return CoreBlobLib.getBlobBaseFee(); + } + + /** + * @notice Get the blob hash + * + * @dev If we are in a foundry test, we use the cheatcode to get the blob hashes + * Otherwise, we use the `blobhash` function in assembly + * + * @return blobHash - The blob hash + */ + function getBlobHash(uint256 _index) internal view returns (bytes32 blobHash) { + if (VM_ADDRESS.code.length > 0) { + // We know that this one is ABHORRENT. But it should not exists, and only will + // be hit in testing. + bytes32[] memory blobHashes = Vm(VM_ADDRESS).getBlobhashes(); + if (_index < blobHashes.length) { + return blobHashes[_index]; + } + return bytes32(0); + } + return CoreBlobLib.getBlobHash(_index); + } + + function validateBlobs(bytes calldata _blobsInput, bool _checkBlob) + internal + view + returns (bytes32[] memory blobHashes, bytes32 blobsHashesCommitment, bytes[] memory blobCommitments) + { + return CoreBlobLib.validateBlobs(_blobsInput, _checkBlob); + } + + function validateBatchedBlob(bytes calldata _blobInput) internal view returns (bool success) { + return CoreBlobLib.validateBatchedBlob(_blobInput); + } + + function calculateBlobCommitmentsHash( + bytes32 _previousBlobCommitmentsHash, + bytes[] memory _blobCommitments, + bool _isFirstBlockOfEpoch + ) internal pure returns (bytes32 currentBlobCommitmentsHash) { + return CoreBlobLib.calculateBlobCommitmentsHash( + _previousBlobCommitmentsHash, _blobCommitments, _isFirstBlockOfEpoch + ); + } + + function calculateBlobHash(bytes memory _blobCommitment) internal pure returns (bytes32) { + return CoreBlobLib.calculateBlobHash(_blobCommitment); + } +} diff --git a/l1-contracts/test/base/RollupBase.sol b/l1-contracts/test/base/RollupBase.sol index 4249cb9cff15..c67fc9dc1a81 100644 --- a/l1-contracts/test/base/RollupBase.sol +++ b/l1-contracts/test/base/RollupBase.sol @@ -13,7 +13,7 @@ import {NaiveMerkle} from "../merkle/Naive.sol"; import {MerkleTestUtil} from "../merkle/TestUtil.sol"; import {Timestamp, Slot, Epoch, TimeLib} from "@aztec/core/libraries/TimeLib.sol"; import {DataStructures} from "@aztec/core/libraries/DataStructures.sol"; -import {BlobLib} from "@aztec/core/libraries/rollup/BlobLib.sol"; +import {BlobLib} from "@aztec-blob-lib/BlobLib.sol"; import {ProposeArgs, OracleInput, ProposeLib} from "@aztec/core/libraries/rollup/ProposeLib.sol"; import { CommitteeAttestation,