Skip to content

Commit

Permalink
V2 Blob Verification (#781)
Browse files Browse the repository at this point in the history
  • Loading branch information
0x0aa0 authored Dec 11, 2024
1 parent 0b90412 commit 3ed9ef6
Show file tree
Hide file tree
Showing 22 changed files with 1,232 additions and 332 deletions.
2 changes: 1 addition & 1 deletion contracts/compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function create_binding {
forge clean
forge build

contracts="PaymentVault SocketRegistry AVSDirectory DelegationManager BitmapUtils OperatorStateRetriever RegistryCoordinator BLSApkRegistry IndexRegistry StakeRegistry BN254 EigenDAServiceManager IEigenDAServiceManager MockRollup EjectionManager IEigenDARelayRegistry"
contracts="PaymentVault SocketRegistry AVSDirectory DelegationManager BitmapUtils OperatorStateRetriever RegistryCoordinator BLSApkRegistry IndexRegistry StakeRegistry BN254 EigenDAServiceManager IEigenDAServiceManager MockRollup EjectionManager EigenDABlobVerifier EigenDAThresholdRegistry EigenDARelayRegistry"
for contract in $contracts; do
create_binding ./ $contract ./bindings
done
Expand Down
64 changes: 58 additions & 6 deletions contracts/script/EigenDADeployer.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,20 @@ import {IServiceManager} from "eigenlayer-middleware/interfaces/IServiceManager.
import {IBLSApkRegistry} from "eigenlayer-middleware/interfaces/IBLSApkRegistry.sol";
import {EigenDAServiceManager, IAVSDirectory, IRewardsCoordinator} from "../src/core/EigenDAServiceManager.sol";
import {EigenDAHasher} from "../src/libraries/EigenDAHasher.sol";
import {ISocketRegistry, SocketRegistry} from "eigenlayer-middleware/SocketRegistry.sol";
import {EigenDAThresholdRegistry} from "../src/core/EigenDAThresholdRegistry.sol";
import {EigenDABlobVerifier} from "../src/core/EigenDABlobVerifier.sol";
import {IEigenDAThresholdRegistry} from "../src/interfaces/IEigenDAThresholdRegistry.sol";
import {IEigenDABatchMetadataStorage} from "../src/interfaces/IEigenDABatchMetadataStorage.sol";
import {IEigenDASignatureVerifier} from "../src/interfaces/IEigenDASignatureVerifier.sol";
import {IEigenDARelayRegistry} from "../src/interfaces/IEigenDARelayRegistry.sol";
import {EigenDARelayRegistry} from "../src/core/EigenDARelayRegistry.sol";
import {ISocketRegistry, SocketRegistry} from "eigenlayer-middleware/SocketRegistry.sol";

import {DeployOpenEigenLayer, ProxyAdmin, ERC20PresetFixedSupply, TransparentUpgradeableProxy, IPauserRegistry} from "./DeployOpenEigenLayer.s.sol";
import "forge-std/Test.sol";
import "forge-std/Script.sol";
import "forge-std/StdJson.sol";
import "../src/interfaces/IEigenDAStructs.sol";

// # To load the variables in the .env file
// source .env
Expand All @@ -36,17 +42,22 @@ contract EigenDADeployer is DeployOpenEigenLayer {

BLSApkRegistry public apkRegistry;
EigenDAServiceManager public eigenDAServiceManager;
EigenDAThresholdRegistry public eigenDAThresholdRegistry;
EigenDABlobVerifier public eigenDABlobVerifier;
RegistryCoordinator public registryCoordinator;
IIndexRegistry public indexRegistry;
IStakeRegistry public stakeRegistry;
ISocketRegistry public socketRegistry;
OperatorStateRetriever public operatorStateRetriever;
EigenDARelayRegistry public eigenDARelayRegistry;

BLSApkRegistry public apkRegistryImplementation;
EigenDAServiceManager public eigenDAServiceManagerImplementation;
IRegistryCoordinator public registryCoordinatorImplementation;
IIndexRegistry public indexRegistryImplementation;
IStakeRegistry public stakeRegistryImplementation;
EigenDAThresholdRegistry public eigenDAThresholdRegistryImplementation;
EigenDARelayRegistry public eigenDARelayRegistryImplementation;
ISocketRegistry public socketRegistryImplementation;

struct AddressConfig {
Expand Down Expand Up @@ -93,16 +104,21 @@ contract EigenDADeployer is DeployOpenEigenLayer {
}

emptyContract = new EmptyContract();

// hard-coded inputs


/**
* First, deploy upgradeable proxy contracts that **will point** to the implementations. Since the implementation contracts are
* not yet deployed, we give these proxies an empty contract as the initial implementation, to act as if they have no code.
*/
eigenDAServiceManager = EigenDAServiceManager(
address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenDAProxyAdmin), ""))
);
eigenDAThresholdRegistry = EigenDAThresholdRegistry(
address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenDAProxyAdmin), ""))
);
eigenDARelayRegistry = EigenDARelayRegistry(
address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenDAProxyAdmin), ""))
);

registryCoordinator = RegistryCoordinator(
address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenDAProxyAdmin), ""))
);
Expand Down Expand Up @@ -205,8 +221,8 @@ contract EigenDADeployer is DeployOpenEigenLayer {
rewardsCoordinator,
registryCoordinator,
stakeRegistry,
IEigenDAThresholdRegistry(address(0)),
IEigenDARelayRegistry(address(0))
eigenDAThresholdRegistry,
eigenDARelayRegistry
);

address[] memory confirmers = new address[](1);
Expand All @@ -226,6 +242,42 @@ contract EigenDADeployer is DeployOpenEigenLayer {
)
);

eigenDAThresholdRegistryImplementation = new EigenDAThresholdRegistry();

VersionedBlobParams[] memory versionedBlobParams = new VersionedBlobParams[](0);
SecurityThresholds memory defaultSecurityThresholds = SecurityThresholds(33, 55);

eigenDAProxyAdmin.upgradeAndCall(
TransparentUpgradeableProxy(payable(address(eigenDAThresholdRegistry))),
address(eigenDAThresholdRegistryImplementation),
abi.encodeWithSelector(
EigenDAThresholdRegistry.initialize.selector,
addressConfig.eigenDACommunityMultisig,
hex"212121",
hex"373737",
hex"0001",
versionedBlobParams,
defaultSecurityThresholds
)
);

operatorStateRetriever = new OperatorStateRetriever();

eigenDABlobVerifier = new EigenDABlobVerifier(
IEigenDAThresholdRegistry(address(eigenDAThresholdRegistry)),
IEigenDABatchMetadataStorage(address(eigenDAServiceManager)),
IEigenDASignatureVerifier(address(eigenDAServiceManager)),
IEigenDARelayRegistry(address(eigenDARelayRegistry)),
OperatorStateRetriever(address(operatorStateRetriever)),
IRegistryCoordinator(address(registryCoordinator))
);

eigenDARelayRegistryImplementation = new EigenDARelayRegistry();

eigenDAProxyAdmin.upgradeAndCall(
TransparentUpgradeableProxy(payable(address(eigenDARelayRegistry))),
address(eigenDARelayRegistryImplementation),
abi.encodeWithSelector(EigenDARelayRegistry.initialize.selector, addressConfig.eigenDACommunityMultisig)
);
}
}
2 changes: 1 addition & 1 deletion contracts/script/MockRollupDeployer.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
pragma solidity ^0.8.9;

import "forge-std/Script.sol";
import "../src/rollup/MockRollup.sol";
import "../test/rollup/MockRollup.sol";
import {IEigenDAServiceManager} from "../src/interfaces/IEigenDAServiceManager.sol";

contract MockRollupDeployer is Script {
Expand Down
209 changes: 209 additions & 0 deletions contracts/src/core/EigenDABlobVerifier.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import {IEigenDABlobVerifier} from "../interfaces/IEigenDABlobVerifier.sol";
import {IEigenDAThresholdRegistry} from "../interfaces/IEigenDAThresholdRegistry.sol";
import {IEigenDABatchMetadataStorage} from "../interfaces/IEigenDABatchMetadataStorage.sol";
import {IEigenDASignatureVerifier} from "../interfaces/IEigenDASignatureVerifier.sol";
import {EigenDABlobVerificationUtils} from "../libraries/EigenDABlobVerificationUtils.sol";
import {OperatorStateRetriever} from "lib/eigenlayer-middleware/src/OperatorStateRetriever.sol";
import {IRegistryCoordinator} from "lib/eigenlayer-middleware/src/RegistryCoordinator.sol";
import {IEigenDARelayRegistry} from "../interfaces/IEigenDARelayRegistry.sol";
import "../interfaces/IEigenDAStructs.sol";

contract EigenDABlobVerifier is IEigenDABlobVerifier {

IEigenDAThresholdRegistry public immutable eigenDAThresholdRegistry;
IEigenDABatchMetadataStorage public immutable eigenDABatchMetadataStorage;
IEigenDASignatureVerifier public immutable eigenDASignatureVerifier;
IEigenDARelayRegistry public immutable eigenDARelayRegistry;

OperatorStateRetriever public immutable operatorStateRetriever;
IRegistryCoordinator public immutable registryCoordinator;

constructor(
IEigenDAThresholdRegistry _eigenDAThresholdRegistry,
IEigenDABatchMetadataStorage _eigenDABatchMetadataStorage,
IEigenDASignatureVerifier _eigenDASignatureVerifier,
IEigenDARelayRegistry _eigenDARelayRegistry,
OperatorStateRetriever _operatorStateRetriever,
IRegistryCoordinator _registryCoordinator
) {
eigenDAThresholdRegistry = _eigenDAThresholdRegistry;
eigenDABatchMetadataStorage = _eigenDABatchMetadataStorage;
eigenDASignatureVerifier = _eigenDASignatureVerifier;
eigenDARelayRegistry = _eigenDARelayRegistry;
operatorStateRetriever = _operatorStateRetriever;
registryCoordinator = _registryCoordinator;
}

///////////////////////// V1 ///////////////////////////////

/**
* @notice Verifies a the blob is valid for the required quorums
* @param blobHeader The blob header to verify
* @param blobVerificationProof The blob verification proof to verify the blob against
*/
function verifyBlobV1(
BlobHeader calldata blobHeader,
BlobVerificationProof calldata blobVerificationProof
) external view {
EigenDABlobVerificationUtils._verifyBlobV1ForQuorums(
eigenDAThresholdRegistry,
eigenDABatchMetadataStorage,
blobHeader,
blobVerificationProof,
quorumNumbersRequired()
);
}

/**
* @notice Verifies a batch of blobs for the required quorums
* @param blobHeaders The blob headers to verify
* @param blobVerificationProofs The blob verification proofs to verify the blobs against
*/
function verifyBlobsV1(
BlobHeader[] calldata blobHeaders,
BlobVerificationProof[] calldata blobVerificationProofs
) external view {
EigenDABlobVerificationUtils._verifyBlobsV1ForQuorums(
eigenDAThresholdRegistry,
eigenDABatchMetadataStorage,
blobHeaders,
blobVerificationProofs,
quorumNumbersRequired()
);
}

///////////////////////// V2 ///////////////////////////////

/**
* @notice Verifies a blob for the base required quorums and the default security thresholds
* @param batchHeader The batch header of the blob
* @param blobVerificationProof The blob verification proof for the blob
* @param nonSignerStakesAndSignature The nonSignerStakesAndSignature for the blob
*/
function verifyBlobV2(
BatchHeaderV2 calldata batchHeader,
BlobVerificationProofV2 calldata blobVerificationProof,
NonSignerStakesAndSignature calldata nonSignerStakesAndSignature
) external view {
EigenDABlobVerificationUtils._verifyBlobV2ForQuorums(
eigenDAThresholdRegistry,
eigenDASignatureVerifier,
eigenDARelayRegistry,
batchHeader,
blobVerificationProof,
nonSignerStakesAndSignature,
getDefaultSecurityThresholdsV2(),
quorumNumbersRequired()
);
}

/**
* @notice Verifies a blob for the base required quorums and the default security thresholds
* @param signedBatch The signed batch to verify the blob against
* @param blobVerificationProof The blob verification proof for the blob
*/
function verifyBlobV2FromSignedBatch(
SignedBatch calldata signedBatch,
BlobVerificationProofV2 calldata blobVerificationProof
) external view {
EigenDABlobVerificationUtils._verifyBlobV2ForQuorumsFromSignedBatch(
eigenDAThresholdRegistry,
eigenDASignatureVerifier,
eigenDARelayRegistry,
operatorStateRetriever,
registryCoordinator,
signedBatch,
blobVerificationProof,
getDefaultSecurityThresholdsV2(),
quorumNumbersRequired()
);
}

///////////////////////// HELPER FUNCTIONS ///////////////////////////////

/**
* @notice Returns the nonSignerStakesAndSignature for a given blob and signed batch
* @param signedBatch The signed batch to get the nonSignerStakesAndSignature for
*/
function getNonSignerStakesAndSignature(
SignedBatch calldata signedBatch
) external view returns (NonSignerStakesAndSignature memory) {
return EigenDABlobVerificationUtils._getNonSignerStakesAndSignature(
operatorStateRetriever,
registryCoordinator,
signedBatch.attestation
);
}

/**
* @notice Verifies the security parameters for a blob
* @param blobParams The blob params to verify
* @param securityThresholds The security thresholds to verify against
*/
function verifyBlobSecurityParams(
VersionedBlobParams memory blobParams,
SecurityThresholds memory securityThresholds
) external view {
EigenDABlobVerificationUtils._verifyBlobSecurityParams(blobParams, securityThresholds);
}

/**
* @notice Verifies the security parameters for a blob
* @param version The version of the blob to verify
* @param securityThresholds The security thresholds to verify against
*/
function verifyBlobSecurityParams(
uint16 version,
SecurityThresholds memory securityThresholds
) external view {
EigenDABlobVerificationUtils._verifyBlobSecurityParams(getBlobParams(version), securityThresholds);
}

/// @notice Returns an array of bytes where each byte represents the adversary threshold percentage of the quorum at that index
function quorumAdversaryThresholdPercentages() external view returns (bytes memory) {
return eigenDAThresholdRegistry.quorumAdversaryThresholdPercentages();
}

/// @notice Returns an array of bytes where each byte represents the confirmation threshold percentage of the quorum at that index
function quorumConfirmationThresholdPercentages() external view returns (bytes memory) {
return eigenDAThresholdRegistry.quorumConfirmationThresholdPercentages();
}

/// @notice Returns an array of bytes where each byte represents the number of a required quorum
function quorumNumbersRequired() public view returns (bytes memory) {
return eigenDAThresholdRegistry.quorumNumbersRequired();
}

function getQuorumAdversaryThresholdPercentage(
uint8 quorumNumber
) external view returns (uint8){
return eigenDAThresholdRegistry.getQuorumAdversaryThresholdPercentage(quorumNumber);
}

/// @notice Gets the confirmation threshold percentage for a quorum
function getQuorumConfirmationThresholdPercentage(
uint8 quorumNumber
) external view returns (uint8){
return eigenDAThresholdRegistry.getQuorumConfirmationThresholdPercentage(quorumNumber);
}

/// @notice Checks if a quorum is required
function getIsQuorumRequired(
uint8 quorumNumber
) external view returns (bool){
return eigenDAThresholdRegistry.getIsQuorumRequired(quorumNumber);
}

/// @notice Returns the blob params for a given blob version
function getBlobParams(uint16 version) public view returns (VersionedBlobParams memory) {
return eigenDAThresholdRegistry.getBlobParams(version);
}

/// @notice Gets the default security thresholds for V2
function getDefaultSecurityThresholdsV2() public view returns (SecurityThresholds memory) {
return eigenDAThresholdRegistry.getDefaultSecurityThresholdsV2();
}
}
38 changes: 38 additions & 0 deletions contracts/src/core/EigenDARelayRegistry.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import {OwnableUpgradeable} from "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol";
import {EigenDARelayRegistryStorage} from "./EigenDARelayRegistryStorage.sol";
import {IEigenDARelayRegistry} from "../interfaces/IEigenDARelayRegistry.sol";
import "../interfaces/IEigenDAStructs.sol";

/**
* @title Registry for EigenDA relay keys
* @author Layr Labs, Inc.
*/
contract EigenDARelayRegistry is OwnableUpgradeable, EigenDARelayRegistryStorage, IEigenDARelayRegistry {

constructor() {
_disableInitializers();
}

function initialize(
address _initialOwner
) external initializer {
_transferOwnership(_initialOwner);
}

function addRelayInfo(RelayInfo memory relayInfo) external onlyOwner returns (uint32) {
relayKeyToInfo[nextRelayKey] = relayInfo;
emit RelayAdded(relayInfo.relayAddress, nextRelayKey, relayInfo.relayURL);
return nextRelayKey++;
}

function relayKeyToAddress(uint32 key) external view returns (address) {
return relayKeyToInfo[key].relayAddress;
}

function relayKeyToUrl(uint32 key) external view returns (string memory) {
return relayKeyToInfo[key].relayURL;
}
}
Loading

0 comments on commit 3ed9ef6

Please sign in to comment.