Skip to content
Merged
Show file tree
Hide file tree
Changes from 81 commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
d93e21e
Refactor: Consolidate struct types into versioned libraries
pakim249CAL Apr 30, 2025
7ce68c3
fix: fmt
pakim249CAL Apr 30, 2025
4d17389
feat: cert verifier v3
pakim249CAL Apr 30, 2025
7757b99
fix: ci
pakim249CAL May 1, 2025
b3fe8c1
fix: ci
pakim249CAL May 1, 2025
52d12dc
fix: remove certverifier binding
pakim249CAL May 1, 2025
0985b47
fix: ci
pakim249CAL May 1, 2025
5be5313
fix: ci
pakim249CAL May 1, 2025
2957935
feat: new file structure
pakim249CAL May 1, 2025
f451cb7
fix: ci
pakim249CAL May 1, 2025
0dd14a2
fix: ci
pakim249CAL May 1, 2025
5ef491b
Merge branch 'refactor/version-contract-types' into feat/cert-verifie…
pakim249CAL May 2, 2025
b964301
Merge remote-tracking branch 'origin/master' into refactor/version-co…
pakim249CAL May 2, 2025
f597d07
fix: bindings
pakim249CAL May 2, 2025
8f59b00
Merge branch 'refactor/version-contract-types' into feat/cert-verifie…
pakim249CAL May 2, 2025
7e26828
feat: add dummy interface
pakim249CAL May 2, 2025
c1b9fdb
chore: address comments
pakim249CAL May 2, 2025
c2db1b4
Merge branch 'refactor/version-contract-types' into feat/cert-verifie…
pakim249CAL May 2, 2025
d4d304f
chore: address comments
pakim249CAL May 2, 2025
c9a5699
chore: add comment explaining ordering of fields, fix rbn position
pakim249CAL May 2, 2025
35cd63f
fix: field position
pakim249CAL May 2, 2025
887ffae
fix: encoding
pakim249CAL May 2, 2025
6cbf4be
Update contracts/src/periphery/cert/router/EigenDACertVerifierRouter.sol
pakim249CAL May 2, 2025
515ef68
chore: address comment
pakim249CAL May 5, 2025
b72abad
Merge remote-tracking branch 'origin/master' into feat/cert-verifier-v3
pakim249CAL May 7, 2025
191ed61
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 7, 2025
cfba65a
feat: purge other versions, maintain canonical cert verifier
pakim249CAL May 7, 2025
4e394f9
fix: bindings
pakim249CAL May 7, 2025
1058ea0
doc: add some docs, addres some comments
pakim249CAL May 7, 2025
b9745fc
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 8, 2025
d7dc0e1
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 8, 2025
f6384f3
chore: address comments
pakim249CAL May 8, 2025
9fed5c6
chore: address some comments
pakim249CAL May 8, 2025
b4ede42
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 9, 2025
79dd5e8
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 9, 2025
cd33eb8
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 12, 2025
84b2bed
doc: add cert bytes comment
pakim249CAL May 12, 2025
a4374d6
refactor: remove use of public, add docs, add missing interface fns
pakim249CAL May 12, 2025
f0d58d9
doc: elaborate on quorum
pakim249CAL May 12, 2025
072c3ad
fix: address comments. add dummies, fix unused error, remove duplicat…
pakim249CAL May 12, 2025
8dcadff
fix: wrong check, update binding
pakim249CAL May 12, 2025
a4369fe
refactor: change bytes name
pakim249CAL May 12, 2025
b60dcff
Merge remote-tracking branch 'origin/master' into feat/cert-verifier-v3
pakim249CAL May 12, 2025
3982d5f
feat: add eigenDA state retriever to replace removed getter from cert…
pakim249CAL May 12, 2025
159c8d0
fix: add more bindings
pakim249CAL May 13, 2025
03050a0
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 13, 2025
8a2956e
chore: address comments, add legacy cert verifier
pakim249CAL May 13, 2025
69b8a00
chore: readd all old stuff
pakim249CAL May 13, 2025
f1ee309
chore: readd old interface
pakim249CAL May 13, 2025
3419421
chore: remove comment
pakim249CAL May 13, 2025
ce6fd1c
fix: cert verifier deployer for integration test
pakim249CAL May 13, 2025
4635dba
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 13, 2025
ca824be
chore: address comments
pakim249CAL May 13, 2025
463e78a
fix: ci
pakim249CAL May 13, 2025
6fda146
fix: ci, formatting of script
pakim249CAL May 13, 2025
b14769f
Merge branch 'feat/cert-verifier-v3' of github.com:Layr-Labs/eigenda …
ethenotethan May 14, 2025
fdcc4a9
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 14, 2025
e3fac51
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 14, 2025
1980319
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 14, 2025
4b046f2
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 14, 2025
f989da6
Merge remote-tracking branch 'origin/master' into feat/cert-verifier-v3
pakim249CAL May 15, 2025
3e39303
test: update cert verifier test
pakim249CAL May 15, 2025
59db366
Merge remote-tracking branch 'origin/master' into feat/cert-verifier-v3
pakim249CAL May 15, 2025
8bf0a01
fix: ci
pakim249CAL May 15, 2025
0d0f7bb
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 16, 2025
0a0588a
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 16, 2025
08b6343
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 16, 2025
31177e6
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 16, 2025
4afbd8d
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 16, 2025
61ce636
chore: address comments, add test
pakim249CAL May 16, 2025
296f23c
fix: remove mistakenly added file
pakim249CAL May 16, 2025
92ab00c
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 19, 2025
41a28c4
fix: enforce abn in future when adding cert verifier
pakim249CAL May 19, 2025
e3aa022
feat: add eigenda cert verifier interface
pakim249CAL May 19, 2025
88c2cc5
Merge branch 'feat/cert-verifier-v3' of github.com:Layr-Labs/eigenda …
ethenotethan May 19, 2025
13d650c
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 19, 2025
2a23dcb
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 19, 2025
8357550
Merge branch 'master' of github.com:Layr-Labs/eigenda into epociask--…
ethenotethan May 21, 2025
037a5f4
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 21, 2025
d3ab9f6
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 21, 2025
ca29316
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 22, 2025
611662c
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 22, 2025
0129bfe
feat: Sepolia Network Support - bring back v2 certr
ethenotethan May 23, 2025
01be9bb
Merge branch 'master' of github.com:Layr-Labs/eigenda into epociask--…
ethenotethan May 27, 2025
941c350
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 27, 2025
276fafc
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 27, 2025
407bb0d
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 27, 2025
e4f2697
feat(api/clients/v2): Support V3 cert type for compatibility with new…
ethenotethan May 27, 2025
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
174 changes: 174 additions & 0 deletions api/clients/v2/cert_builder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
package clients

import (
"context"
"fmt"
"math/big"
"time"

"github.com/Layr-Labs/eigenda/api/clients/v2/coretypes"
coreEth "github.com/Layr-Labs/eigenda/core/eth"

disperser "github.com/Layr-Labs/eigenda/api/grpc/disperser/v2"
"github.com/Layr-Labs/eigenda/common"
certTypesBinding "github.com/Layr-Labs/eigenda/contracts/bindings/IEigenDACertTypeBindings"
opsrbinding "github.com/Layr-Labs/eigenda/contracts/bindings/OperatorStateRetriever"
"github.com/Layr-Labs/eigenda/core"
coreV2 "github.com/Layr-Labs/eigenda/core/v2"
"github.com/Layr-Labs/eigensdk-go/logging"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
gethcommon "github.com/ethereum/go-ethereum/common"
)


type CertBuilder struct {
logger logging.Logger
opsrCaller *opsrbinding.ContractOperatorStateRetrieverCaller
registryCoordinatorAddr gethcommon.Address
}

// NewCertBuilder constructs a new CertBuilder instance used to build EigenDA certificates
// across different versions.
func NewCertBuilder(
logger logging.Logger,
opsrAddr gethcommon.Address,
registryCoordinatorAddr gethcommon.Address,
ethClient common.EthClient,
) (*CertBuilder, error) {
if logger == nil {
return nil, fmt.Errorf("logger cannot be nil")
}
// Create the Operator State Retriever caller
opsrCaller, err := opsrbinding.NewContractOperatorStateRetrieverCaller(opsrAddr, ethClient)
if err != nil {
return nil, fmt.Errorf("create operator state retriever caller: %w", err)
}


return &CertBuilder{
logger: logger,
opsrCaller: opsrCaller,
registryCoordinatorAddr: registryCoordinatorAddr,
}, nil
}

// BuildCert builds an EigenDA certificate of the specified version using the provided blob key and blob status reply.
func (cb *CertBuilder) BuildCert(
ctx context.Context,
certVersion coretypes.CertificateVersion,
blobKey coreV2.BlobKey,
blobStatusReply *disperser.BlobStatusReply,
) (coretypes.EigenDACert, error) {
switch certVersion {
case coretypes.VersionThreeCert:
return cb.buildEigenDAV3Cert(ctx, blobKey, blobStatusReply)
default:
return nil, fmt.Errorf("unsupported EigenDA cert version: %d", certVersion)
}
}

// buildEigenDAV3Cert builds an EigenDA certificate of version 3 using the provided blob key and blob status reply.
func (cb *CertBuilder) buildEigenDAV3Cert(
ctx context.Context,
blobKey coreV2.BlobKey,
blobStatusReply *disperser.BlobStatusReply,
) (*coretypes.EigenDACertV3, error) {
// TODO: configurable timeout
timeoutCtx, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()
nonSignerStakesAndSignature, err := cb.getNonSignerStakesAndSignature(
timeoutCtx, blobStatusReply.GetSignedBatch())
if err != nil {
return nil, fmt.Errorf("get non signer stake and signature: %w", err)
}
cb.logger.Debug("Retrieved NonSignerStakesAndSignature", "blobKey", blobKey.Hex())

eigenDACert, err := coretypes.BuildEigenDACertV3(blobStatusReply, nonSignerStakesAndSignature)
Copy link
Collaborator

@samlaf samlaf May 16, 2025

Choose a reason for hiding this comment

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

why do we need buildEigenDAV3Cert and BuildEigenDACertV3? Its late and I'm super tired so prob missing something but seems like a lot of layers. Also shouldnt they be called the same thing (v3 in different positions right now)?

Copy link
Collaborator

Choose a reason for hiding this comment

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

still think the name warrants changing to make them both have the same name. Actually maybe make the coretype use NewEigenDACertV3.

I like the separation between New and Build, and imo Build should be the external layer doing IO that can return errors, and the New constructors should be purely stateless with dependency injection and are just doing stateless data manipulation (which I think is what's happening here..)

if err != nil {
return nil, fmt.Errorf("build eigenda v3 cert: %w", err)
}
cb.logger.Debug("Constructed EigenDACertV3", "blobKey", blobKey.Hex())

return eigenDACert, nil
}

// GetNonSignerStakesAndSignature constructs a NonSignerStakesAndSignature object by calling an
// onchain OperatorStateRetriever retriever to fetch necessary non-signer metadata
func (cb *CertBuilder) getNonSignerStakesAndSignature(
ctx context.Context,
signedBatch *disperser.SignedBatch,
) (*certTypesBinding.EigenDATypesV1NonSignerStakesAndSignature, error) {
// 1 - Pre-process inputs for operator state retriever call
signedBatchBinding, err := coretypes.SignedBatchProtoToV2CertBinding(signedBatch)
if err != nil {
return nil, fmt.Errorf("convert signed batch: %w", err)
}

nonSignerPubKeys := signedBatchBinding.Attestation.NonSignerPubkeys

// 2a - create operator IDs by hashing non-signer public keys
nonSignerOperatorIDs := make([][32]byte, len(nonSignerPubKeys))
for i, pubKeySet := range nonSignerPubKeys {
g1Point := core.NewG1Point(pubKeySet.X, pubKeySet.Y)
nonSignerOperatorIDs[i] = coreEth.HashPubKeyG1(g1Point)
}

// 2b - cast []uint32 to []byte for quorum numbers
quorumNumbers := make([]byte, len(signedBatch.GetAttestation().GetQuorumNumbers()))
for i, qn := range signedBatch.GetAttestation().GetQuorumNumbers() {
quorumNumbers[i] = byte(qn)
}

// use the reference block # from the disperser generated signed batch header
// for referencing operator states at a specific block checkpoint
rbn := signedBatch.GetHeader().GetReferenceBlockNumber()

// 3 - call operator state retriever to fetch signature indices
checkSigIndices, err := cb.opsrCaller.GetCheckSignaturesIndices(&bind.CallOpts{Context: ctx, BlockNumber: big.NewInt(int64(rbn))},
cb.registryCoordinatorAddr, uint32(rbn), quorumNumbers, nonSignerOperatorIDs)

if err != nil {
return nil, fmt.Errorf("check sig indices call: %w", err)
}

// 4 - translate from CertVerifier binding types to cert type
// TODO: Should probably put SignedBatch into the types directly to avoid this downstream conversion
nonSignerPubKeysBN254 := make([]certTypesBinding.BN254G1Point, len(signedBatchBinding.Attestation.NonSignerPubkeys))
for i, pubKeySet := range signedBatchBinding.Attestation.NonSignerPubkeys {
nonSignerPubKeysBN254[i] = certTypesBinding.BN254G1Point{
X: pubKeySet.X,
Y: pubKeySet.Y,
}
}

quorumApksBN254 := make([]certTypesBinding.BN254G1Point, len(signedBatchBinding.Attestation.QuorumApks))
for i, apkSet := range signedBatchBinding.Attestation.QuorumApks {
quorumApksBN254[i] = certTypesBinding.BN254G1Point{
X: apkSet.X,
Y: apkSet.Y,
}
}

apkG2BN254 := certTypesBinding.BN254G2Point{
X: signedBatchBinding.Attestation.ApkG2.X,
Y: signedBatchBinding.Attestation.ApkG2.Y,
}

sigmaBN254 := certTypesBinding.BN254G1Point{
X: signedBatchBinding.Attestation.Sigma.X,
Y: signedBatchBinding.Attestation.Sigma.Y,
}


// 5 - construct non signer stakes and signature
return &certTypesBinding.EigenDATypesV1NonSignerStakesAndSignature{
NonSignerQuorumBitmapIndices: checkSigIndices.NonSignerQuorumBitmapIndices,
NonSignerPubkeys: nonSignerPubKeysBN254,
QuorumApks: quorumApksBN254,
ApkG2: apkG2BN254,
Sigma: sigmaBN254,
QuorumApkIndices: checkSigIndices.QuorumApkIndices,
TotalStakeIndices: checkSigIndices.TotalStakeIndices,
NonSignerStakeIndices: checkSigIndices.NonSignerStakeIndices,
}, nil
}
34 changes: 0 additions & 34 deletions api/clients/v2/cert_verifier.go

This file was deleted.

58 changes: 54 additions & 4 deletions api/clients/v2/coretypes/conversion_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,22 @@ import (
commonv2 "github.com/Layr-Labs/eigenda/api/grpc/common/v2"
disperserv2 "github.com/Layr-Labs/eigenda/api/grpc/disperser/v2"
contractEigenDACertVerifier "github.com/Layr-Labs/eigenda/contracts/bindings/EigenDACertVerifierV2"
certTypesBinding "github.com/Layr-Labs/eigenda/contracts/bindings/IEigenDACertTypeBindings"
"github.com/Layr-Labs/eigenda/core"
"github.com/Layr-Labs/eigenda/encoding"
"github.com/consensys/gnark-crypto/ecc/bn254"
"github.com/consensys/gnark-crypto/ecc/bn254/fp"
"golang.org/x/exp/slices"
)

func SignedBatchProtoToBinding(inputBatch *disperserv2.SignedBatch) (*contractEigenDACertVerifier.EigenDATypesV2SignedBatch, error) {
convertedBatchHeader, err := BatchHeaderProtoToBinding(inputBatch.GetHeader())
/*
NOTE: Two binding types are used here to represent the same data since legacy EigenDACertVerifierV2
binding and IEigenDACertTypeBindings leverage the same structs but are not currently interchangeable.
This can be changed in the future to use a single binding type once the legacy contract is deprecated.
*/

func SignedBatchProtoToV2CertBinding(inputBatch *disperserv2.SignedBatch) (*contractEigenDACertVerifier.EigenDATypesV2SignedBatch, error) {
convertedBatchHeader, err := BatchHeaderProtoToV2CertVerifierBinding(inputBatch.GetHeader())
if err != nil {
return nil, fmt.Errorf("convert batch header: %s", err)
}
Expand All @@ -35,7 +42,7 @@ func SignedBatchProtoToBinding(inputBatch *disperserv2.SignedBatch) (*contractEi
return outputSignedBatch, nil
}

func BatchHeaderProtoToBinding(inputHeader *commonv2.BatchHeader) (*contractEigenDACertVerifier.EigenDATypesV2BatchHeaderV2, error) {
func BatchHeaderProtoToV2CertVerifierBinding(inputHeader *commonv2.BatchHeader) (*contractEigenDACertVerifier.EigenDATypesV2BatchHeaderV2, error) {
var outputBatchRoot [32]byte

inputBatchRoot := inputHeader.GetBatchRoot()
Expand All @@ -59,6 +66,19 @@ func BatchHeaderProtoToBinding(inputHeader *commonv2.BatchHeader) (*contractEige

return convertedHeader, nil
}
func BatchHeaderProtoToIEigenDATypesBinding(inputHeader *commonv2.BatchHeader) (*certTypesBinding.EigenDATypesV2BatchHeaderV2, error) {
verifierBatchHeaderBinding, err := BatchHeaderProtoToV2CertVerifierBinding(inputHeader)
if err != nil {
return nil, err
}

convertedHeader := &certTypesBinding.EigenDATypesV2BatchHeaderV2{
BatchRoot: verifierBatchHeaderBinding.BatchRoot,
ReferenceBlockNumber: verifierBatchHeaderBinding.ReferenceBlockNumber,
}

return convertedHeader, nil
}

func attestationProtoToBinding(inputAttestation *disperserv2.Attestation) (*contractEigenDACertVerifier.EigenDATypesV2Attestation, error) {
if len(inputAttestation.QuorumApks) != len(inputAttestation.QuorumNumbers) {
Expand Down Expand Up @@ -111,7 +131,37 @@ func attestationProtoToBinding(inputAttestation *disperserv2.Attestation) (*cont
return convertedAttestation, nil
}

func InclusionInfoProtoToBinding(inputInclusionInfo *disperserv2.BlobInclusionInfo) (*contractEigenDACertVerifier.EigenDATypesV2BlobInclusionInfo, error) {
func InclusionInfoProtoToIEigenDATypesBinding(inputInclusionInfo *disperserv2.BlobInclusionInfo) (*certTypesBinding.EigenDATypesV2BlobInclusionInfo, error) {
convertedBlobCertificate, err := blobCertificateProtoToBinding(inputInclusionInfo.GetBlobCertificate())
if err != nil {
return nil, fmt.Errorf("convert blob certificate: %s", err)
}

blobCertificateTypesBinding := &certTypesBinding.EigenDATypesV2BlobCertificate{
BlobHeader: certTypesBinding.EigenDATypesV2BlobHeaderV2{
Version: convertedBlobCertificate.BlobHeader.Version,
QuorumNumbers: convertedBlobCertificate.BlobHeader.QuorumNumbers,
Commitment: certTypesBinding.EigenDATypesV2BlobCommitment{
Commitment: certTypesBinding.BN254G1Point(convertedBlobCertificate.BlobHeader.Commitment.Commitment),
LengthCommitment: certTypesBinding.BN254G2Point(convertedBlobCertificate.BlobHeader.Commitment.LengthCommitment),
LengthProof: certTypesBinding.BN254G2Point(convertedBlobCertificate.BlobHeader.Commitment.LengthProof),
Length: convertedBlobCertificate.BlobHeader.Commitment.Length,
},
PaymentHeaderHash: convertedBlobCertificate.BlobHeader.PaymentHeaderHash,
},
Signature: convertedBlobCertificate.Signature,
RelayKeys: convertedBlobCertificate.RelayKeys,
}


return &certTypesBinding.EigenDATypesV2BlobInclusionInfo{
BlobCertificate: *blobCertificateTypesBinding,
BlobIndex: inputInclusionInfo.GetBlobIndex(),
InclusionProof: inputInclusionInfo.GetInclusionProof(),
}, nil
}

func InclusionInfoProtoToV2CertVerifierBinding(inputInclusionInfo *disperserv2.BlobInclusionInfo) (*contractEigenDACertVerifier.EigenDATypesV2BlobInclusionInfo, error) {
convertedBlobCertificate, err := blobCertificateProtoToBinding(inputInclusionInfo.GetBlobCertificate())

if err != nil {
Expand Down
Loading
Loading