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(eigen-client-m1): Add dummy bridge #41

Open
wants to merge 8 commits into
base: eigen-client-m1
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 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
23 changes: 23 additions & 0 deletions da-contracts/contracts/da-layers/eigenda/DummyEigenDABridge.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

import {IEigenDABridge} from "./IEigenDABridge.sol";
import {IVectorx} from "./IVectorx.sol";
import {DummyVectorX} from "./DummyVectorX.sol";

contract DummyEigenDABridge is IEigenDABridge {
IVectorx public vectorxContract;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't call it vectorx since it will not use it


constructor() {
vectorxContract = new DummyVectorX();
}

function vectorx() external view returns (IVectorx) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

return vectorxContract;
}

function verifyBlobLeaf(bytes calldata) external view returns (bool) {
return true;
}
}
11 changes: 11 additions & 0 deletions da-contracts/contracts/da-layers/eigenda/DummyVectorX.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

import {IVectorx} from "./IVectorx.sol";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here


contract DummyVectorX is IVectorx {
function rangeStartBlocks(bytes32) external view returns (uint32 startBlock) {
return 1;
}
}
34 changes: 34 additions & 0 deletions da-contracts/contracts/da-layers/eigenda/EigenDAAttestationLib.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.24;

import {IEigenDABridge} from "./IEigenDABridge.sol";
import {IVectorx} from "./IVectorx.sol";

abstract contract EigenDAAttestationLib {
struct AttestationData {
uint32 blockNumber;
uint128 leafIndex;
}

IEigenDABridge public bridge;
IVectorx public vectorx;

/// @dev Mapping from attestation leaf to attestation data.
/// It is necessary for recovery of the state from the onchain data.
mapping(bytes32 => AttestationData) public attestations;

error InvalidAttestationProof();

constructor(IEigenDABridge _bridge) {
bridge = _bridge;
vectorx = bridge.vectorx();
}

function _attest(bytes memory input) internal virtual {
if (!bridge.verifyBlobLeaf(input)) revert InvalidAttestationProof();
/*attestations[input.leaf] = AttestationData(
vectorx.rangeStartBlocks(input.rangeHash) + uint32(input.dataRootIndex) + 1,
uint128(input.leafIndex)
);*/
}
}
40 changes: 40 additions & 0 deletions da-contracts/contracts/da-layers/eigenda/EigenDAL1Validator.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

import {IL1DAValidator, L1DAValidatorOutput} from "../../IL1DAValidator.sol";
import {ValL1DAWrongInputLength} from "../../DAContractsErrors.sol";
import {EigenDAAttestationLib} from "./EigenDAAttestationLib.sol";
import {IEigenDABridge} from "./IEigenDABridge.sol";

contract EigenDAL1Validator is IL1DAValidator, EigenDAAttestationLib {
error InvalidValidatorOutputHash();

constructor(IEigenDABridge _eigendaBridge) EigenDAAttestationLib(_eigendaBridge) {}

function checkDA(
uint256, // _chainId
uint256, // _batchNumber
bytes32 l2DAValidatorOutputHash, // TODO: Maybe we don't need this

Check failure on line 18 in da-contracts/contracts/da-layers/eigenda/EigenDAL1Validator.sol

View workflow job for this annotation

GitHub Actions / lint

Variable "l2DAValidatorOutputHash" is unused

Check failure on line 18 in da-contracts/contracts/da-layers/eigenda/EigenDAL1Validator.sol

View workflow job for this annotation

GitHub Actions / lint

Variable "l2DAValidatorOutputHash" is unused

Check failure on line 18 in da-contracts/contracts/da-layers/eigenda/EigenDAL1Validator.sol

View workflow job for this annotation

GitHub Actions / lint

Variable "l2DAValidatorOutputHash" is unused
bytes calldata operatorDAInput,
uint256 maxBlobsSupported
) external override returns (L1DAValidatorOutput memory output) {
// TODO: Implement real validation logic.
// For Validiums, we expect the operator to just provide the data for us.
// We don't need to do any checks with regard to the l2DAValidatorOutputHash.
if (operatorDAInput.length < 32) {
revert ValL1DAWrongInputLength(operatorDAInput.length, 32);
}
bytes32 stateDiffHash = abi.decode(operatorDAInput[:32], (bytes32));

output.stateDiffHash = stateDiffHash;

/*IEigenDABridge.MerkleProofInput memory input = abi.decode(operatorDAInput[32:], (IEigenDABridge.MerkleProofInput));
if (l2DAValidatorOutputHash != keccak256(abi.encodePacked(output.stateDiffHash, input.leaf)))
revert InvalidValidatorOutputHash();*/ //TODO: Maybe we don't need this
_attest(operatorDAInput[32:]);

output.blobsLinearHashes = new bytes32[](maxBlobsSupported);
output.blobsOpeningCommitments = new bytes32[](maxBlobsSupported);
}
}
46 changes: 46 additions & 0 deletions da-contracts/contracts/da-layers/eigenda/IEigenDABridge.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.24;

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

interface IEigenDABridge {
// solhint-disable-next-line gas-struct-packing
struct Message {
// single-byte prefix representing the message type
bytes1 messageType;
// address of message sender
bytes32 from;
// address of message receiver
bytes32 to;
// origin chain code
uint32 originDomain;
// destination chain code
uint32 destinationDomain;
// data being sent
bytes data;
// nonce
uint64 messageId;
}

struct MerkleProofInput {
// proof of inclusion for the data root
bytes32[] dataRootProof;
// proof of inclusion of leaf within blob/bridge root
bytes32[] leafProof;
// abi.encodePacked(startBlock, endBlock) of header range commitment on vectorx
bytes32 rangeHash;
// index of the data root in the commitment tree
uint256 dataRootIndex;
// blob root to check proof against, or reconstruct the data root
bytes32 blobRoot;
// bridge root to check proof against, or reconstruct the data root
bytes32 bridgeRoot;
// leaf being proven
bytes32 leaf;
// index of the leaf in the blob/bridge root tree
uint256 leafIndex;
}

function vectorx() external view returns (IVectorx vectorx);
function verifyBlobLeaf(bytes calldata input) external view returns (bool);
}
6 changes: 6 additions & 0 deletions da-contracts/contracts/da-layers/eigenda/IVectorx.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.24;

interface IVectorx {
function rangeStartBlocks(bytes32 rangeHash) external view returns (uint32 startBlock);
}
26 changes: 26 additions & 0 deletions l1-contracts/deploy-scripts/DeployL1.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,15 @@ contract DeployL1Script is Script, DeployUtils {
);
}

function getEigenDAL2ValidatorAddress() internal returns (address) {
return
Utils.getL2AddressViaCreate2Factory(
bytes32(0),
L2ContractHelper.hashL2Bytecode(L2ContractsBytecodesLib.readEigenDAL2ValidatorBytecode()),
hex""
);
}

function deployDAValidators() internal {
vm.broadcast(msg.sender);
address rollupDAManager = address(new RollupDAManager());
Expand All @@ -202,6 +211,17 @@ contract DeployL1Script is Script, DeployUtils {
addresses.daAddresses.availL1DAValidator = config.contracts.availL1DAValidator;
}

if (config.contracts.eigenDAL1Validator == address(0)) {
address eigendaBridge = deployViaCreate2(Utils.readDummyEigenDABridgeBytecode(), "");
addresses.daAddresses.eigenDAL1Validator = deployViaCreate2(
Utils.readEigenDAL1ValidatorBytecode(),
abi.encode(eigendaBridge)
);
console.log("EigenDAL1Validator deployed at:", addresses.daAddresses.eigenDAL1Validator);
} else {
addresses.daAddresses.eigenDAL1Validator = config.contracts.eigenDAL1Validator;
}

vm.startBroadcast(msg.sender);
RollupDAManager(rollupDAManager).updateDAPair(address(rollupDAValidator), getRollupL2ValidatorAddress(), true);
vm.stopBroadcast();
Expand Down Expand Up @@ -707,6 +727,11 @@ contract DeployL1Script is Script, DeployUtils {
"avail_l1_da_validator_addr",
addresses.daAddresses.availL1DAValidator
);
vm.serializeAddress(
"deployed_addresses",
"eigenda_l1_validator_addr",
addresses.daAddresses.eigenDAL1Validator
);

string memory deployedAddresses = vm.serializeAddress(
"deployed_addresses",
Expand All @@ -725,6 +750,7 @@ contract DeployL1Script is Script, DeployUtils {
vm.serializeAddress("root", "expected_rollup_l2_da_validator_addr", getRollupL2ValidatorAddress());
vm.serializeAddress("root", "expected_no_da_validium_l2_validator_addr", getNoDAValidiumL2ValidatorAddress());
vm.serializeAddress("root", "expected_avail_l2_da_validator_addr", getAvailL2ValidatorAddress());
vm.serializeAddress("root", "expected_eigenda_l2_validator_addr", getEigenDAL2ValidatorAddress());
string memory toml = vm.serializeAddress("root", "owner_address", config.ownerAddress);

vm.writeToml(toml, outputPath);
Expand Down
2 changes: 1 addition & 1 deletion l1-contracts/deploy-scripts/DeployL2Contracts.sol
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ contract DeployL2Script is Script {
} else if (config.validatorType == DAValidatorType.Avail) {
bytecode = L2ContractsBytecodesLib.readAvailL2DAValidatorBytecode();
} else if (config.validatorType == DAValidatorType.EigenDA) {
bytecode = L2ContractsBytecodesLib.readNoDAL2DAValidatorBytecode(); // TODO: update to EigenDA
bytecode = L2ContractsBytecodesLib.readEigenDAL2ValidatorBytecode();
} else {
revert("Invalid DA validator type");
}
Expand Down
6 changes: 6 additions & 0 deletions l1-contracts/deploy-scripts/DeployUtils.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ struct DataAvailabilityDeployedAddresses {
address l1RollupDAValidator;
address noDAValidiumL1DAValidator;
address availL1DAValidator;
address eigenDAL1Validator;
}

// solhint-disable-next-line gas-struct-packing
Expand Down Expand Up @@ -165,6 +166,7 @@ struct ContractsConfig {
bytes32 bootloaderHash;
bytes32 defaultAAHash;
address availL1DAValidator;
address eigenDAL1Validator;
}

struct TokensConfig {
Expand Down Expand Up @@ -240,6 +242,10 @@ contract DeployUtils is Script {
config.contracts.availL1DAValidator = toml.readAddress("$.contracts.avail_l1_da_validator");
}

if (vm.keyExistsToml(toml, "$.contracts.eigenda_l1_validator")) {
config.contracts.eigenDAL1Validator = toml.readAddress("$.contracts.eigenda_l1_validator");
}

config.tokens.tokenWethAddress = toml.readAddress("$.tokens.token_weth_address");
}

Expand Down
6 changes: 6 additions & 0 deletions l1-contracts/deploy-scripts/L2ContractsBytecodesLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ library L2ContractsBytecodesLib {
return Utils.readZKFoundryBytecodeL2("AvailL2DAValidator.sol", "AvailL2DAValidator");
}

/// @notice Reads the bytecode of the ValidiumL2DAValidator contract for EigenDA.
/// @return The bytecode of the ValidiumL2DAValidator contract.
function readEigenDAL2ValidatorBytecode() internal view returns (bytes memory) {
return Utils.readZKFoundryBytecodeL2("EigenDAL2Validator.sol", "EigenDAL2Validator");
}

/// @notice Reads the bytecode of the ValidiumL2DAValidator contract for NoDA validium.
/// @return The bytecode of the ValidiumL2DAValidator contract.
function readNoDAL2DAValidatorBytecode() internal view returns (bytes memory) {
Expand Down
8 changes: 8 additions & 0 deletions l1-contracts/deploy-scripts/Utils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,14 @@ library Utils {
bytecode = readFoundryBytecode("/../da-contracts/out/DummyAvailBridge.sol/DummyAvailBridge.json");
}

function readDummyEigenDABridgeBytecode() internal view returns (bytes memory bytecode) {
bytecode = readFoundryBytecode("/../da-contracts/out/DummyEigenDABridge.sol/DummyEigenDABridge.json");
}

function readEigenDAL1ValidatorBytecode() internal view returns (bytes memory bytecode) {
bytecode = readFoundryBytecode("/../da-contracts/out/EigenDAL1Validator.sol/EigenDAL1Validator.json");
}

// add this to be excluded from coverage report
function test() internal {}
}
31 changes: 31 additions & 0 deletions l2-contracts/contracts/data-availability/EigenDAL2Validator.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.24;

import {IL2DAValidator} from "../interfaces/IL2DAValidator.sol";
import {StateDiffL2DAValidator} from "./StateDiffL2DAValidator.sol";

/// Rollup DA validator. It will publish data that would allow to use either calldata or blobs.
contract EigenDAL2Validator is IL2DAValidator, StateDiffL2DAValidator {
function validatePubdata(
// The rolling hash of the user L2->L1 logs.
bytes32,
// The root hash of the user L2->L1 logs.
bytes32,
// The chained hash of the L2->L1 messages
bytes32 _chainedMessagesHash,
// The chained hash of uncompressed bytecodes sent to L1
bytes32 _chainedBytecodesHash,
// Operator data, that is related to the DA itself
bytes calldata _totalL2ToL1PubdataAndStateDiffs
) external returns (bytes32 outputHash) {
(bytes32 stateDiffHash, bytes calldata _totalPubdata, ) = _produceStateDiffPubdata(
_chainedMessagesHash,
_chainedBytecodesHash,
_totalL2ToL1PubdataAndStateDiffs
);

bytes32 fullPubdataHash = keccak256(_totalPubdata);
outputHash = keccak256(abi.encodePacked(stateDiffHash, fullPubdataHash));
}
}
Loading