Skip to content

Commit

Permalink
Merge pull request #1 from Layr-Labs/epociask--feat-commitment-verifi…
Browse files Browse the repository at this point in the history
…cation

feat(eigenda-plasma): Commitment verification on read
  • Loading branch information
epociask authored May 15, 2024
2 parents fb63a2c + 07de6f3 commit 92cadea
Show file tree
Hide file tree
Showing 19 changed files with 294 additions and 29 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ go.work
/bin

## kzg cache
kzg/SRSTables/
test/resources/SRSTables/
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@

## Introduction

This simple DA server implementation supports ephemeral storage via EigenDA.
This simple DA server implementation supports ephemeral storage via EigenDA.

## EigenDA Configuration
Additional cli args are provided for targeting an EigenDA network backend:
- `--eigenda-rpc`: RPC host of disperser service. (e.g, on holesky this is `disperser-holesky.eigenda.xyz:443`)
- `--eigenda-status-query-timeout`: (default: 25m) Duration for which a client will wait for a blob to finalize after being sent for dispersal.
- `--eigenda-status-query-retry-interval`: (default: 5s) How often a client will attempt a retry when awaiting network blob finalization.
- `--eigenda-use-tls`: (default: true) Whether or not to use TLS for grpc communication with disperser.
- `eigenda-g1-path`: Directory path to g1.point file
- `eigenda-g2-path`: Directory path to g2.point file
- `eigenda-g2-power-of-tau`: Directory path to g2.point.powerOf2 file
- `eigenda-cache-path`: Directory path to dump cached SRS tables

## Running Locally
1. Compile binary: `make da-server`
2. Run binary; e.g: `./bin/da-server --addr 127.0.0.1 --port 6969 --eigenda-rpc disperser-holesky.eigenda.xyz:443 --eigenda-status-query-timeout 45m`
2. Run binary; e.g: `./bin/da-server --addr 127.0.0.1 --port 5050 --eigenda-rpc 127.0.0.1:443 --eigenda-status-query-timeout 45m --eigenda-g1-path test/resources/g1.point --eigenda-g2-path test/resources/g2.point --eigenda-g2-tau-path test/resources/g2.point.powerOf2 --eigenda-use-tls true`

## Breaking changes from existing OP-Stack

Expand Down Expand Up @@ -51,6 +55,10 @@ Some unit tests have been introduced to assert correctness of encoding/decoding
Otherwise E2E tests (`test/e2e_test.go`) exists which asserts that a commitment can be generated when inserting some arbitrary data to the server and can be read using the commitment for a key lookup via the client. These can be ran via `make e2e-test`. Please **note** that this test uses the EigenDA Holesky network which is subject to rate-limiting and slow confirmation times *(i.e, >10 minutes per blob confirmation)*. Please advise EigenDA's [inabox](https://github.com/Layr-Labs/eigenda/tree/master/inabox#readme) if you'd like to spin-up a local DA network for quicker iteration testing.


## Downloading SRS
KZG commitment verification requires constructing the SRS string from the proper trusted setup values (g1, g2, g2.power_of_tau). These values can be downloaded locally using the [srs_setup](https://github.com/Layr-Labs/eigenda-operator-setup/blob/master/srs_setup.sh) script in the operator setup repo.


## Resources
- [op-stack](https://github.com/ethereum-optimism/optimism)
- [plasma spec](https://specs.optimism.io/experimental/plasma.html)
Expand Down
1 change: 0 additions & 1 deletion cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ func CLIFlags(envPrefix string, category string) []cli.Flag {
EnvVars: plasmaEnv(envPrefix, "DA_SERVER"),
Category: category,
},
// This is currently unsupported
&cli.BoolFlag{
Name: VerifyOnReadFlagName,
Usage: "Verify input data matches the commitments from the DA storage service",
Expand Down
14 changes: 11 additions & 3 deletions cmd/daserver/entrypoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
plasma "github.com/Layr-Labs/op-plasma-eigenda"
"github.com/Layr-Labs/op-plasma-eigenda/eigenda"
plasma_store "github.com/Layr-Labs/op-plasma-eigenda/store"
"github.com/Layr-Labs/op-plasma-eigenda/verify"
oplog "github.com/ethereum-optimism/optimism/op-service/log"
"github.com/ethereum-optimism/optimism/op-service/opio"
)
Expand All @@ -25,7 +26,7 @@ func StartDAServer(cliCtx *cli.Context) error {
log := oplog.NewLogger(oplog.AppOut(cliCtx), oplog.ReadCLIConfig(cliCtx)).New("role", "eigenda_plasma_server")
oplog.SetGlobalLogHandler(log.Handler())

log.Info("Initializing EigenDA Plasma DA server...")
log.Info("Initializing EigenDA Plasma DA server with config ...")

var store plasma.PlasmaStore

Expand All @@ -40,13 +41,20 @@ func StartDAServer(cliCtx *cli.Context) error {
}
store = s3
} else if cfg.EigenDAEnabled() {
log.Info("Using EigenDA storage", "RPC", cfg.EigenDAConfig.RPC)
daCfg := cfg.EigenDAConfig

v, err := verify.NewVerifier(daCfg.KzgConfig())
if err != nil {
return err
}

eigenda, err := plasma_store.NewEigenDAStore(
cliCtx.Context,
eigenda.NewEigenDAClient(
log,
cfg.EigenDAConfig,
daCfg,
),
v,
)
if err != nil {
return fmt.Errorf("failed to create EigenDA store: %w", err)
Expand Down
6 changes: 0 additions & 6 deletions commitment.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,6 @@ func (c EigenDACommitment) TxData() []byte {
return append([]byte{TxDataVersion1}, c.Encode()...)
}

// TODO - verify the commitment against the input blob by evaluating its polynomial representation at an arbitrary point
// and asserting that the generated output proof can be successfully verified against the commitment.
func (c EigenDACommitment) Verify(input []byte) error {
return nil
}

func DecodeEigenDACommitment(commitment []byte) (EigenDACommitment, error) {
if len(commitment) <= 3 {
return nil, ErrInvalidCommitment
Expand Down
6 changes: 0 additions & 6 deletions daclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,7 @@ func (c *DAClient) GetInput(ctx context.Context, comm EigenDACommitment) ([]byte
if err != nil {
return nil, err
}
// TODO: Implement verification
if c.verify {
if err := comm.Verify(input); err != nil {
return nil, err
}

}
return input, nil
}

Expand Down
16 changes: 15 additions & 1 deletion eigenda/cert.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package eigenda

import "github.com/Layr-Labs/eigenda/api/grpc/common"
import (
"github.com/Layr-Labs/eigenda/api/grpc/common"
"github.com/consensys/gnark-crypto/ecc/bn254/fp"
)

// EigenDA finalized blob certificate
type Cert struct {
Expand All @@ -11,3 +14,14 @@ type Cert struct {
// Used for kzg verification when reading blob data from DA
BlobCommitment *common.G1Commitment
}

// BlobCommitmentFields transforms commitment byte arrays to bn254 field elements
func (c *Cert) BlobCommitmentFields() (*fp.Element, *fp.Element) {
xBytes, yBytes := c.BlobCommitment.X, c.BlobCommitment.Y
xElement, yElement := &fp.Element{}, &fp.Element{}

xElement.Unmarshal(xBytes)
yElement.Unmarshal(yBytes)

return xElement, yElement
}
20 changes: 20 additions & 0 deletions eigenda/cert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,23 @@ func TestCertEncodingDecoding(t *testing.T) {

assert.True(t, equal(), "values shouldn't change")
}

func TestCommitmentToFieldElement(t *testing.T) {
xBytes, yBytes := []byte{0x69}, []byte{0x42}

c := Cert{
BatchHeaderHash: []byte{0x42, 0x69},
BlobIndex: 420,
ReferenceBlockNumber: 80085,
QuorumIDs: []uint32{666},
BlobCommitment: &eigen_da_common.G1Commitment{
X: xBytes,
Y: yBytes,
},
}

x, y := c.BlobCommitmentFields()

assert.Equal(t, uint64(0x69), x.Uint64())
assert.Equal(t, uint64(0x42), y.Uint64())
}
5 changes: 3 additions & 2 deletions eigenda/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,14 @@ func (m *EigenDAClient) DisperseBlob(ctx context.Context, data []byte) (*Cert, e
quorumIDs[i] = blobInfo.BlobHeader.BlobQuorumParams[i].QuorumNumber
}

return &Cert{
c := &Cert{
BatchHeaderHash: blobInfo.BlobVerificationProof.BatchMetadata.BatchHeaderHash,
BlobIndex: blobInfo.BlobVerificationProof.BlobIndex,
ReferenceBlockNumber: blobInfo.BlobVerificationProof.BatchMetadata.BatchHeader.ReferenceBlockNumber,
QuorumIDs: quorumIDs,
BlobCommitment: blobInfo.BlobHeader.Commitment,
}, nil
}
return c, nil
default:
return nil, fmt.Errorf("EigenDA blob dispersal failed in processing with reply status %d", statusRes.Status)
}
Expand Down
57 changes: 55 additions & 2 deletions eigenda/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package eigenda

import (
"errors"
"runtime"
"time"

"github.com/Layr-Labs/eigenda/encoding/kzg"
opservice "github.com/ethereum-optimism/optimism/op-service"
"github.com/urfave/cli/v2"
)
Expand All @@ -13,11 +15,16 @@ const (
StatusQueryRetryIntervalFlagName = "eigenda-status-query-retry-interval"
StatusQueryTimeoutFlagName = "eigenda-status-query-timeout"
UseTlsFlagName = "eigenda-use-tls"
// Kzg flags
G1PathFlagName = "eigenda-g1-path"
G2PathFlagName = "eigenda-g2-path"
G2TauFlagName = "eigenda-g2-tau-path"
CachePathFlagName = "eigenda-cache-path"
)

type Config struct {
// TODO(eigenlayer): Update quorum ID command-line parameters to support passing
// and arbitrary number of quorum IDs.
// an arbitrary number of quorum IDs.

// RPC is the HTTP provider URL for the Data Availability node.
RPC string
Expand All @@ -30,16 +37,42 @@ type Config struct {

// UseTLS specifies whether the client should use TLS as a transport layer when connecting to disperser.
UseTLS bool

// KZG vars
CacheDir string

G1Path string
G2Path string

G2PowerOfTauPath string
}

func (c *Config) KzgConfig() *kzg.KzgConfig {
return &kzg.KzgConfig{
G1Path: c.G1Path,
G2Path: c.G2Path,
G2PowerOf2Path: c.G2PowerOfTauPath,
CacheDir: c.CacheDir,
SRSOrder: 3000,
SRSNumberToLoad: 3000,
NumWorker: uint64(runtime.GOMAXPROCS(0)),
}
}

// NewConfig parses the Config from the provided flags or environment variables.
func ReadConfig(ctx *cli.Context) Config {
return Config{
cfg := Config{
/* Required Flags */
RPC: ctx.String(RPCFlagName),
StatusQueryRetryInterval: ctx.Duration(StatusQueryRetryIntervalFlagName),
StatusQueryTimeout: ctx.Duration(StatusQueryTimeoutFlagName),
UseTLS: ctx.Bool(UseTlsFlagName),
G1Path: ctx.String(G1PathFlagName),
G2Path: ctx.String(G2PathFlagName),
G2PowerOfTauPath: ctx.String(G2TauFlagName),
CacheDir: ctx.String(CachePathFlagName),
}
return cfg
}

func (m Config) Check() error {
Expand Down Expand Up @@ -80,5 +113,25 @@ func CLIFlags(envPrefix string) []cli.Flag {
Value: true,
EnvVars: prefixEnvVars("EIGENDA_GRPC_USE_TLS"),
},
&cli.StringFlag{
Name: G1PathFlagName,
Usage: "Directory path to g1.point file",
EnvVars: prefixEnvVars("EIGENDA_KZG_G1_PATH"),
},
&cli.StringFlag{
Name: G2PathFlagName,
Usage: "Directory path to g2.point file",
EnvVars: prefixEnvVars("EIGENDA_KZG_G2_PATH"),
},
&cli.StringFlag{
Name: G2TauFlagName,
Usage: "Directory path to g2.point.powerOf2 file",
EnvVars: prefixEnvVars("EIGENDA_G2_TAU_PATH"),
},
&cli.StringFlag{
Name: CachePathFlagName,
Usage: "Directory path to SRS tables",
EnvVars: prefixEnvVars("EIGENDA_CACHE_PATH"),
},
}
}
9 changes: 9 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ require (
github.com/CloudyKit/jet/v6 v6.2.0 // indirect
github.com/DataDog/zstd v1.5.2 // indirect
github.com/Joker/jade v1.1.3 // indirect
github.com/Layr-Labs/eigensdk-go v0.1.6-0.20240414172936-84d5bc10f72f // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 // indirect
github.com/VictoriaMetrics/fastcache v1.12.1 // indirect
Expand All @@ -38,6 +39,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.7 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.5 // indirect
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.5 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.20.5 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.4 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.28.6 // indirect
Expand Down Expand Up @@ -70,12 +72,14 @@ require (
github.com/fjl/memsize v0.0.2 // indirect
github.com/flosch/pongo2/v4 v4.0.2 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.5.0 // indirect
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect
github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect
github.com/getsentry/sentry-go v0.18.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
Expand Down Expand Up @@ -153,12 +157,17 @@ require (
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/urfave/cli v1.22.14 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/yosssi/ace v0.0.5 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
go.uber.org/automaxprocs v1.5.2 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
golang.org/x/mod v0.16.0 // indirect
Expand Down
Loading

0 comments on commit 92cadea

Please sign in to comment.