Skip to content

Commit

Permalink
inabox v2 verifyblob
Browse files Browse the repository at this point in the history
  • Loading branch information
ian-shim committed Dec 19, 2024
1 parent 1345e77 commit a8c0502
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 11 deletions.
1 change: 1 addition & 0 deletions contracts/script/SetUpEigenDA.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ contract SetupEigenDA is EigenDADeployer, EigenLayerUtils {
vm.serializeAddress(output, "operatorStateRetriever", address(operatorStateRetriever));
vm.serializeAddress(output, "blsApkRegistry" , address(apkRegistry));
vm.serializeAddress(output, "registryCoordinator", address(registryCoordinator));
vm.serializeAddress(output, "blobVerifier", address(eigenDABlobVerifier));

string memory finalJson = vm.serializeString(output, "object", output);

Expand Down
1 change: 1 addition & 0 deletions inabox/deploy/config_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ type EigenDAContract struct {
OperatorStateRetreiver string `json:"operatorStateRetriever"`
BlsApkRegistry string `json:"blsApkRegistry"`
RegistryCoordinator string `json:"registryCoordinator"`
BlobVerifier string `json:"blobVerifier"`
}

type Stakes struct {
Expand Down
4 changes: 4 additions & 0 deletions inabox/tests/integration_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
clientsv2 "github.com/Layr-Labs/eigenda/api/clients/v2"
"github.com/Layr-Labs/eigenda/common"
"github.com/Layr-Labs/eigenda/common/geth"
verifierbindings "github.com/Layr-Labs/eigenda/contracts/bindings/EigenDABlobVerifier"
rollupbindings "github.com/Layr-Labs/eigenda/contracts/bindings/MockRollup"
"github.com/Layr-Labs/eigenda/core"
"github.com/Layr-Labs/eigenda/core/eth"
Expand Down Expand Up @@ -47,6 +48,7 @@ var (
ethClient common.EthClient
rpcClient common.RPCEthClient
mockRollup *rollupbindings.ContractMockRollup
verifierContract *verifierbindings.ContractEigenDABlobVerifier
retrievalClient clients.RetrievalClient
retrievalClientV2 clientsv2.RetrievalClient
numConfirmations int = 3
Expand Down Expand Up @@ -137,6 +139,8 @@ var _ = BeforeSuite(func() {

mockRollup, err = rollupbindings.NewContractMockRollup(gcommon.HexToAddress(testConfig.MockRollup), ethClient)
Expect(err).To(BeNil())
verifierContract, err = verifierbindings.NewContractEigenDABlobVerifier(gcommon.HexToAddress(testConfig.EigenDA.BlobVerifier), ethClient)
Expect(err).To(BeNil())
err = setupRetrievalClient(testConfig)
Expect(err).To(BeNil())
}
Expand Down
225 changes: 214 additions & 11 deletions inabox/tests/integration_v2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@ import (
"bytes"
"context"
"crypto/rand"
"fmt"
"math/big"
"time"

"github.com/Layr-Labs/eigenda/api/clients/v2"
commonpb "github.com/Layr-Labs/eigenda/api/grpc/common/v2"
disperserpb "github.com/Layr-Labs/eigenda/api/grpc/disperser/v2"
verifierbindings "github.com/Layr-Labs/eigenda/contracts/bindings/EigenDABlobVerifier"
"github.com/Layr-Labs/eigenda/core"
auth "github.com/Layr-Labs/eigenda/core/auth/v2"
corev2 "github.com/Layr-Labs/eigenda/core/v2"
dispv2 "github.com/Layr-Labs/eigenda/disperser/common/v2"
"github.com/Layr-Labs/eigenda/encoding/utils/codec"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/wealdtech/go-merkletree/v2"
Expand Down Expand Up @@ -64,8 +67,10 @@ var _ = Describe("Inabox v2 Integration", func() {
var reply2 *disperserpb.BlobStatusReply
var blobCert1 *corev2.BlobCertificate
var blobCert2 *corev2.BlobCertificate
var batchHeader1 *commonpb.BatchHeader
var batchHeader2 *commonpb.BatchHeader
var signedBatch1 *disperserpb.SignedBatch
var signedBatch2 *disperserpb.SignedBatch
var blobVerification1 *disperserpb.BlobVerificationInfo
var blobVerification2 *disperserpb.BlobVerificationInfo
for loop := true; loop; {
select {
case <-ctx.Done():
Expand All @@ -87,7 +92,8 @@ var _ = Describe("Inabox v2 Integration", func() {
continue
}

batchHeader1 = reply1.GetSignedBatch().GetHeader()
signedBatch1 = reply1.GetSignedBatch()
batchHeader1 := signedBatch1.GetHeader()
Expect(batchHeader1).To(Not(BeNil()))
Expect(batchHeader1.GetBatchRoot()).To(Not(BeNil()))
Expect(batchHeader1.GetReferenceBlockNumber()).To(BeNumerically(">", 0))
Expand All @@ -103,8 +109,8 @@ var _ = Describe("Inabox v2 Integration", func() {
Expect(blobVerification.GetBlobCertificate()).To(Not(BeNil()))
blobCert1, err = corev2.BlobCertificateFromProtobuf(blobVerification.GetBlobCertificate())
Expect(err).To(BeNil())
inclusionProofBytes := blobVerification.GetInclusionProof()
blobIndex := blobVerification.GetBlobIndex()
inclusionProofBytes := blobVerification1.GetInclusionProof()
blobIndex := blobVerification1.GetBlobIndex()
proof, err := core.DeserializeMerkleProof(inclusionProofBytes, uint64(blobIndex))
Expect(err).To(BeNil())
certHash, err := blobCert1.Hash()
Expand All @@ -115,7 +121,8 @@ var _ = Describe("Inabox v2 Integration", func() {
Expect(err).To(BeNil())
Expect(verified).To(BeTrue())

batchHeader2 = reply2.GetSignedBatch().GetHeader()
signedBatch2 = reply2.GetSignedBatch()
batchHeader2 := signedBatch2.GetHeader()
Expect(batchHeader2).To(Not(BeNil()))
Expect(batchHeader2.GetBatchRoot()).To(Not(BeNil()))
Expect(batchHeader2.GetReferenceBlockNumber()).To(BeNumerically(">", 0))
Expand All @@ -131,21 +138,71 @@ var _ = Describe("Inabox v2 Integration", func() {
Expect(blobVerification.GetBlobCertificate()).To(Not(BeNil()))
blobCert2, err = corev2.BlobCertificateFromProtobuf(blobVerification.GetBlobCertificate())
Expect(err).To(BeNil())
inclusionProofBytes = blobVerification.GetInclusionProof()
blobIndex = blobVerification.GetBlobIndex()
inclusionProofBytes = blobVerification2.GetInclusionProof()
blobIndex = blobVerification2.GetBlobIndex()
proof, err = core.DeserializeMerkleProof(inclusionProofBytes, uint64(blobIndex))
Expect(err).To(BeNil())
certHash, err = blobCert2.Hash()
Expect(err).To(BeNil())
verified, err = merkletree.VerifyProofUsing(certHash[:], false, proof, [][]byte{batchHeader2.BatchRoot}, keccak256.New())
Expect(err).To(BeNil())
Expect(verified).To(BeTrue())
// TODO(ian-shim): verify the blob onchain using a mock rollup contract
loop = false
}
}

// Test retrieval from relay
// necessary to ensure that reference block number < current block number
mineAnvilBlocks(1)

// test onchain verification
batchHeader1 := signedBatch1.GetHeader()
attestation, err := convertAttestation(signedBatch1.GetAttestation())
Expect(err).To(BeNil())
proof, err := convertBlobVerificationInfo(blobVerification1)
Expect(err).To(BeNil())
deserializedProof, err := core.DeserializeMerkleProof(proof.InclusionProof, uint64(proof.BlobIndex))
Expect(err).To(BeNil())
certHash, err := blobCert1.Hash()
Expect(err).To(BeNil())
verified, err := merkletree.VerifyProofUsing(certHash[:], false, deserializedProof, [][]byte{batchHeader1.BatchRoot}, keccak256.New())
Expect(err).To(BeNil())
Expect(verified).To(BeTrue())

var batchRoot [32]byte
copy(batchRoot[:], batchHeader1.BatchRoot)
err = verifierContract.VerifyBlobV2FromSignedBatch(
&bind.CallOpts{},
verifierbindings.SignedBatch{
BatchHeader: verifierbindings.BatchHeaderV2{
BatchRoot: batchRoot,
ReferenceBlockNumber: uint32(batchHeader1.ReferenceBlockNumber),
},
Attestation: *attestation,
},
*proof,
)
Expect(err).To(BeNil())

batchHeader2 := signedBatch2.GetHeader()
attestation, err = convertAttestation(signedBatch2.GetAttestation())
Expect(err).To(BeNil())
proof, err = convertBlobVerificationInfo(blobVerification2)
Expect(err).To(BeNil())
copy(batchRoot[:], batchHeader2.BatchRoot)
err = verifierContract.VerifyBlobV2FromSignedBatch(
&bind.CallOpts{},
verifierbindings.SignedBatch{
BatchHeader: verifierbindings.BatchHeaderV2{
BatchRoot: batchRoot,
ReferenceBlockNumber: uint32(batchHeader2.ReferenceBlockNumber),
},
Attestation: *attestation,
},
*proof,
)
Expect(err).To(BeNil())

// test retrieval from relay
relayClient, err := clients.NewRelayClient(&clients.RelayClientConfig{
Sockets: relays,
}, logger)
Expand Down Expand Up @@ -177,6 +234,7 @@ var _ = Describe("Inabox v2 Integration", func() {
}
}

// Test retrieval from DA network
b, err := retrievalClientV2.GetBlob(ctx, blobCert1.BlobHeader, batchHeader1.ReferenceBlockNumber, 0)
Expect(err).To(BeNil())
restored := bytes.TrimRight(b, "\x00")
Expand All @@ -195,3 +253,148 @@ var _ = Describe("Inabox v2 Integration", func() {
Expect(restored).To(BeNil())
})
})

func convertBlobVerificationInfo(verificationInfo *disperserpb.BlobVerificationInfo) (*verifierbindings.BlobVerificationProofV2, error) {
blobCertificate, err := corev2.BlobCertificateFromProtobuf(verificationInfo.GetBlobCertificate())
if err != nil {
return nil, err
}
paymentHeaderHash, err := blobCertificate.BlobHeader.PaymentMetadata.Hash()
if err != nil {
return nil, err
}

inclusionProof := verificationInfo.GetInclusionProof()
blobIndex := verificationInfo.GetBlobIndex()

commitX := big.NewInt(0)
blobCertificate.BlobHeader.BlobCommitments.Commitment.X.BigInt(commitX)
commitY := big.NewInt(0)
blobCertificate.BlobHeader.BlobCommitments.Commitment.Y.BigInt(commitY)
lengthCommitX0 := big.NewInt(0)
blobCertificate.BlobHeader.BlobCommitments.LengthCommitment.X.A0.BigInt(lengthCommitX0)
lengthCommitX1 := big.NewInt(0)
blobCertificate.BlobHeader.BlobCommitments.LengthCommitment.X.A1.BigInt(lengthCommitX1)
lengthCommitY0 := big.NewInt(0)
blobCertificate.BlobHeader.BlobCommitments.LengthCommitment.Y.A0.BigInt(lengthCommitY0)
lengthCommitY1 := big.NewInt(0)
blobCertificate.BlobHeader.BlobCommitments.LengthCommitment.Y.A1.BigInt(lengthCommitY1)
lengthProofX0 := big.NewInt(0)
blobCertificate.BlobHeader.BlobCommitments.LengthProof.X.A0.BigInt(lengthProofX0)
lengthProofX1 := big.NewInt(0)
blobCertificate.BlobHeader.BlobCommitments.LengthProof.X.A1.BigInt(lengthProofX1)
lengthProofY0 := big.NewInt(0)
blobCertificate.BlobHeader.BlobCommitments.LengthProof.Y.A0.BigInt(lengthProofY0)
lengthProofY1 := big.NewInt(0)
blobCertificate.BlobHeader.BlobCommitments.LengthProof.Y.A1.BigInt(lengthProofY1)
return &verifierbindings.BlobVerificationProofV2{
BlobCertificate: verifierbindings.BlobCertificate{
BlobHeader: verifierbindings.BlobHeaderV2{
Version: uint16(blobCertificate.BlobHeader.BlobVersion),
QuorumNumbers: blobCertificate.BlobHeader.QuorumNumbers,
Commitment: verifierbindings.BlobCommitment{
Commitment: verifierbindings.BN254G1Point{
X: commitX,
Y: commitY,
},
LengthCommitment: verifierbindings.BN254G2Point{
X: [2]*big.Int{lengthCommitX0, lengthCommitX1},
Y: [2]*big.Int{lengthCommitY0, lengthCommitY1},
},
LengthProof: verifierbindings.BN254G2Point{
X: [2]*big.Int{lengthProofX0, lengthProofX1},
Y: [2]*big.Int{lengthProofY0, lengthProofY1},
},
DataLength: uint32(blobCertificate.BlobHeader.BlobCommitments.Length),
},
PaymentHeaderHash: paymentHeaderHash,
},
RelayKeys: blobCertificate.RelayKeys,
},
InclusionProof: inclusionProof,
BlobIndex: blobIndex,
}, nil
}

func convertAttestation(attestation *disperserpb.Attestation) (*verifierbindings.Attestation, error) {
if attestation == nil {
return nil, fmt.Errorf("attestation is nil")
}
nonSignerPubkeys := make([]verifierbindings.BN254G1Point, 0)
for _, pubkey := range attestation.GetNonSignerPubkeys() {
pk, err := convertG1Point(pubkey)
if err != nil {
return nil, err
}
nonSignerPubkeys = append(nonSignerPubkeys, *pk)
}

quorumApks := make([]verifierbindings.BN254G1Point, 0)
for _, apk := range attestation.GetQuorumApks() {
apk, err := convertG1Point(apk)
if err != nil {
return nil, err
}
quorumApks = append(quorumApks, *apk)
}

if attestation.GetSigma() == nil {
return nil, fmt.Errorf("attestation sigma is nil")
}
sigma, err := convertG1Point(attestation.GetSigma())
if err != nil {
return nil, err
}

if attestation.GetApkG2() == nil {
return nil, fmt.Errorf("attestation apkG2 is nil")
}
apkg2, err := convertG2Point(attestation.GetApkG2())
if err != nil {
return nil, err
}

return &verifierbindings.Attestation{
NonSignerPubkeys: nonSignerPubkeys,
QuorumApks: quorumApks,
Sigma: *sigma,
ApkG2: *apkg2,
QuorumNumbers: attestation.GetQuorumNumbers(),
}, nil
}

func convertG1Point(data []byte) (*verifierbindings.BN254G1Point, error) {
point, err := new(core.G1Point).Deserialize(data)
if err != nil {
return nil, err
}
x := big.NewInt(0)
y := big.NewInt(0)

point.X.BigInt(x)
point.Y.BigInt(y)
return &verifierbindings.BN254G1Point{
X: x,
Y: y,
}, nil
}

func convertG2Point(data []byte) (*verifierbindings.BN254G2Point, error) {
point, err := new(core.G2Point).Deserialize(data)
if err != nil {
return nil, err
}
x0 := big.NewInt(0)
x1 := big.NewInt(0)
y0 := big.NewInt(0)
y1 := big.NewInt(0)

point.X.A0.BigInt(x0)
point.X.A1.BigInt(x1)
point.Y.A0.BigInt(y0)
point.Y.A1.BigInt(y1)
return &verifierbindings.BN254G2Point{
X: [2]*big.Int{x0, x1},
Y: [2]*big.Int{y0, y1},
}, nil
}

0 comments on commit a8c0502

Please sign in to comment.