diff --git a/.env.example b/.env.example deleted file mode 100644 index 9b32d2b..0000000 --- a/.env.example +++ /dev/null @@ -1,51 +0,0 @@ -# Server listening address -EIGENDA_PROXY_ADDR=127.0.0.1 - -# Server listening port (default: 3100) -EIGENDA_PROXY_PORT=3100 - -# Directory path to SRS tables -EIGENDA_PROXY_TARGET_CACHE_PATH=resources/SRSTables - -# Directory path to g1.point file -EIGENDA_PROXY_TARGET_KZG_G1_PATH=resources/g1.point - -# Directory path to g2.point.powerOf2 file -EIGENDA_PROXY_TARGET_G2_TAU_PATH=resources/g2.point.powerOf2 - -# RPC endpoint of the EigenDA disperser -EIGENDA_PROXY_EIGENDA_DISPERSER_RPC= - -# Wait time between retries of EigenDA blob status queries (default: 5s) -EIGENDA_PROXY_STATUS_QUERY_INTERVAL=5s - -# Maximum size in string representation (e.g. "10mb", "4 KiB") of blobs to be dispersed and verified using this proxy (default: 2MiB) -EIGENDA_PROXY_MAX_BLOB_LENGTH=2MiB - -# Timeout for aborting an EigenDA blob dispersal (default: 25m0s) -EIGENDA_PROXY_STATUS_QUERY_TIMEOUT=25m0s - -# Use TLS when connecting to the EigenDA disperser (default: true) -EIGENDA_PROXY_GRPC_USE_TLS=true - -# Color the log output if in terminal mode (default: false) -EIGENDA_PROXY_LOG_COLOR=false - -# Format the log output (default: text) -# Supported formats: 'text', 'terminal', 'logfmt', 'json', 'json-pretty' -EIGENDA_PROXY_LOG_FORMAT=text - -# The lowest log level that will be output (default: INFO) -EIGENDA_PROXY_LOG_LEVEL=INFO - -# Metrics listening address (default: 0.0.0.0) -EIGENDA_PROXY_METRICS_ADDR=0.0.0.0 - -# Enable the metrics server (default: false) -EIGENDA_PROXY_METRICS_ENABLED=false - -# Metrics listening port (default: 7300) -EIGENDA_PROXY_METRICS_PORT=7300 - -# Private key for signing EigenDA blobs -EIGENDA_PROXY_SIGNER_PRIVATE_KEY_HEX= \ No newline at end of file diff --git a/.env.example.holesky b/.env.example.holesky new file mode 100644 index 0000000..55706ed --- /dev/null +++ b/.env.example.holesky @@ -0,0 +1,73 @@ +# An example holesky testnet configuration + +# Hex-encoded signer private key. This key should not be associated with an Ethereum address holding any funds. +EIGENDA_PROXY_SIGNER_PRIVATE_KEY_HEX= + +# JSON RPC node endpoint for the Ethereum network used for finalizing DA blobs. See available list here: https://docs.eigenlayer.xyz/eigenda/networks/ +EIGENDA_PROXY_ETH_RPC=https://ethereum-holesky-rpc.publicnode.com + +# RPC host of the EigenDA disperser service (e.g., on Holesky this is `disperser-holesky.eigenda.xyz:443`). Full network list available in the documentation. +EIGENDA_PROXY_EIGENDA_DISPERSER_RPC=disperser-holesky.eigenda.xyz:443 + +# The deployed EigenDA service manager address. The list can be found here: https://github.com/Layr-Labs/eigenlayer-middleware/?tab=readme-ov-file#current-mainnet-deployment +EIGENDA_PROXY_SERVICE_MANAGER_ADDR=0xD4A7E1Bd8015057293f0D0A557088c286942e84b + +# Custom quorum IDs for writing blobs. Should not include default quorums 0 or 1. +# EIGENDA_PROXY_CUSTOM_QUORUM_IDS= + +# Directory path to SRS tables +# EIGENDA_PROXY_TARGET_CACHE_PATH=resources/SRSTables + +# Directory path to g1.point file +# EIGENDA_PROXY_TARGET_KZG_G1_PATH=resources/g1.point + +# Directory path to g2.point.powerOf2 file +# EIGENDA_PROXY_TARGET_G2_TAU_PATH=resources/g2.point.powerOf2 + +# Disable point verification mode. This mode performs IFFT on data before writing and FFT on data after reading. Disabling requires supplying the entire blob for verification against the KZG commitment. +# EIGENDA_PROXY_DISABLE_POINT_VERIFICATION_MODE=false + +# Disable TLS for gRPC communication with the EigenDA disperser +# EIGENDA_PROXY_GRPC_DISABLE_TLS=false + +# Maximum blob length to be written or read from EigenDA. Determines the number of SRS points loaded into memory for KZG commitments. Example units: '30MiB', '4Kb', '30MB'. Maximum size slightly exceeds 1GB. +# EIGENDA_PROXY_MAX_BLOB_LENGTH=2MiB + +# Blob encoding version to use when writing blobs from the high-level interface +# EIGENDA_PROXY_PUT_BLOB_ENCODING_VERSION=0 + +# Total time to wait for a response from the EigenDA disperser +# EIGENDA_PROXY_RESPONSE_TIMEOUT=10s + +# Interval between retries when awaiting network blob finalization +# EIGENDA_PROXY_STATUS_QUERY_INTERVAL=5s + +# Duration to wait for a blob to finalize after being sent for dispersal +# EIGENDA_PROXY_STATUS_QUERY_TIMEOUT=45m0s + +# Color the log output if in terminal mode +# EIGENDA_PROXY_LOG_COLOR=false + +# Format the log output. Supported formats: 'text', 'terminal', 'logfmt', 'json', 'json-pretty' +# EIGENDA_PROXY_LOG_FORMAT=text + +# The lowest log level that will be output +# EIGENDA_PROXY_LOG_LEVEL=INFO + +# Show pid in the log +# EIGENDA_PROXY_LOG_PID=false + +# Whether to use mem-store for DA logic +# MEMSTORE_ENABLED=false + +# Duration that a blob/commitment pair are allowed to live +# MEMSTORE_EXPIRATION=25m0s + +# Metrics listening address +# EIGENDA_PROXY_METRICS_ADDR=0.0.0.0 + +# Enable the metrics server +# EIGENDA_PROXY_METRICS_ENABLED=false + +# Metrics listening port +# EIGENDA_PROXY_METRICS_PORT=7300 diff --git a/.env.example.mainnet b/.env.example.mainnet new file mode 100644 index 0000000..8cab2da --- /dev/null +++ b/.env.example.mainnet @@ -0,0 +1,73 @@ +# An example mainnet configuration + +# Hex-encoded signer private key. This key should not be associated with an Ethereum address holding any funds. +EIGENDA_PROXY_SIGNER_PRIVATE_KEY_HEX= + +# JSON RPC node endpoint for the Ethereum network used for finalizing DA blobs. See available list here: https://docs.eigenlayer.xyz/eigenda/networks/ +EIGENDA_PROXY_ETH_RPC= + +# RPC host of the EigenDA disperser service (e.g., on Holesky this is `disperser-holesky.eigenda.xyz:443`). Full network list available in the documentation. +EIGENDA_PROXY_EIGENDA_DISPERSER_RPC=disperser.eigenda.xyz:443 + +# The deployed EigenDA service manager address. The list can be found here: https://github.com/Layr-Labs/eigenlayer-middleware/?tab=readme-ov-file#current-mainnet-deployment +EIGENDA_PROXY_SERVICE_MANAGER_ADDR=0x870679E138bCdf293b7Ff14dD44b70FC97e12fc0 + +# Custom quorum IDs for writing blobs. Should not include default quorums 0 or 1. +# EIGENDA_PROXY_CUSTOM_QUORUM_IDS= + +# Directory path to SRS tables +# EIGENDA_PROXY_TARGET_CACHE_PATH=resources/SRSTables + +# Directory path to g1.point file +# EIGENDA_PROXY_TARGET_KZG_G1_PATH=resources/g1.point + +# Directory path to g2.point.powerOf2 file +# EIGENDA_PROXY_TARGET_G2_TAU_PATH=resources/g2.point.powerOf2 + +# Disable point verification mode. This mode performs IFFT on data before writing and FFT on data after reading. Disabling requires supplying the entire blob for verification against the KZG commitment. +# EIGENDA_PROXY_DISABLE_POINT_VERIFICATION_MODE=false + +# Disable TLS for gRPC communication with the EigenDA disperser +# EIGENDA_PROXY_GRPC_DISABLE_TLS=false + +# Maximum blob length to be written or read from EigenDA. Determines the number of SRS points loaded into memory for KZG commitments. Example units: '30MiB', '4Kb', '30MB'. Maximum size slightly exceeds 1GB. +# EIGENDA_PROXY_MAX_BLOB_LENGTH=2MiB + +# Blob encoding version to use when writing blobs from the high-level interface +# EIGENDA_PROXY_PUT_BLOB_ENCODING_VERSION=0 + +# Total time to wait for a response from the EigenDA disperser +# EIGENDA_PROXY_RESPONSE_TIMEOUT=10s + +# Interval between retries when awaiting network blob finalization +# EIGENDA_PROXY_STATUS_QUERY_INTERVAL=5s + +# Duration to wait for a blob to finalize after being sent for dispersal +# EIGENDA_PROXY_STATUS_QUERY_TIMEOUT=30m0s + +# Color the log output if in terminal mode +# EIGENDA_PROXY_LOG_COLOR=false + +# Format the log output. Supported formats: 'text', 'terminal', 'logfmt', 'json', 'json-pretty' +# EIGENDA_PROXY_LOG_FORMAT=text + +# The lowest log level that will be output +# EIGENDA_PROXY_LOG_LEVEL=INFO + +# Show pid in the log +# EIGENDA_PROXY_LOG_PID=false + +# Whether to use mem-store for DA logic +# MEMSTORE_ENABLED=false + +# Duration that a blob/commitment pair are allowed to live +# MEMSTORE_EXPIRATION=25m0s + +# Metrics listening address +# EIGENDA_PROXY_METRICS_ADDR=0.0.0.0 + +# Enable the metrics server +# EIGENDA_PROXY_METRICS_ENABLED=false + +# Metrics listening port +# EIGENDA_PROXY_METRICS_PORT=7300 diff --git a/.gitignore b/.gitignore index 58e0ab0..8ce01a6 100644 --- a/.gitignore +++ b/.gitignore @@ -30,4 +30,4 @@ resources/SRSTables/ /.vscode ## Idea -.idea \ No newline at end of file +.idea diff --git a/README.md b/README.md index aaa16e2..8badd63 100644 --- a/README.md +++ b/README.md @@ -2,67 +2,125 @@ ## Introduction -This service wraps the high-level EigenDA client, exposing endpoints for interacting with the EigenDA disperser in conformance to the [OP plasma server spec](https://specs.optimism.io/experimental/plasma.html), and adding disperser verification logic. This simplifies integrating EigenDA into various rollup frameworks by minimizing the footprint of changes needed within their respective services. Features of the EigenDA sidecar proxy include: +This service wraps the [high-level EigenDA client](https://github.com/Layr-Labs/eigenda/blob/master/api/clients/eigenda_client.go), exposing endpoints for interacting with the EigenDA disperser in conformance to the [OP Alt-DA server spec](https://specs.optimism.io/experimental/alt-da.html), and adding disperser verification logic. This simplifies integrating EigenDA into various rollup frameworks by minimizing the footprint of changes needed within their respective services. + +Features: + +* Exposes an API for dispersing blobs to EigenDA and retrieving blobs from EigenDA via the EigenDA disperser +* Handles BN254 field element encoding/decoding +* Performs KZG verification during retrieval to ensure that data returned from the EigenDA disperser is correct. +* Performs KZG verification during dispersal to ensure that DA certificates returned from the EigenDA disperser have correct KZG commitments. +* Performs DA certificate verification during dispersal to ensure that DA certificates have been properly bridged to Ethereum by the disperser. +* Performs DA certificate verification during retrieval to ensure that data represented by bad DA certificates do not become part of the canonical chain. + +In order to disperse to the EigenDA network in production, or at high throughput on testnet, please register your authentication ethereum address through [this form](https://forms.gle/3QRNTYhSMacVFNcU8). Your EigenDA authentication keypair address should not be associated with any funds anywhere. + +## Configuration Options + +| CLI Flag Name | Env Var Flag Name | Input Type | Default Value | Required | Description | +|----------------------------------------------|----------------------------------------------|------------|---------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `--eigenda-rpc` | `EIGENDA_PROXY_RPC` | string | None | Yes | RPC host of the EigenDA disperser service (e.g., on Holesky this is `disperser-holesky.eigenda.xyz:443`). Full network list available in the documentation. | +| `--eigenda-signer-private-key-hex` | `EIGENDA_PROXY_SIGNER_PRIVATE_KEY_HEX` | string | None | Yes | Hex-encoded signer private key. This key should not be associated with an Ethereum address holding any funds. | +| `--eigenda-eth-rpc` | `EIGENDA_PROXY_ETH_RPC` | string | None | Yes | JSON RPC node endpoint for the Ethereum network used for finalizing DA blobs. See available list here: | +| `--eigenda-svc-manager-addr` | `EIGENDA_PROXY_SERVICE_MANAGER_ADDR` | string | None | Yes | The deployed EigenDA service manager address. The list can be found here: | +| `--eigenda-g1-path` | `EIGENDA_PROXY_TARGET_KZG_G1_PATH` | string | None | Yes | Directory path to g1.point file. | +| `--eigenda-g2-tau-path` | `EIGENDA_PROXY_TARGET_G2_TAU_PATH` | string | None | Yes | Directory path to g2.point.powerOf2 file. | +| `--eigenda-cache-path` | `EIGENDA_PROXY_TARGET_CACHE_PATH` | string | None | Yes | Directory path to SRS tables for caching. | +| `--addr` | `EIGENDA_PROXY_ADDR` | string | "127.0.0.1" | No | Server listening address. | +| `--port` | `EIGENDA_PROXY_PORT` | int | 3100 | No | Server listening port. | +| `--eigenda-disable-tls` | `EIGENDA_PROXY_GRPC_DISABLE_TLS` | bool | false | No | Disable TLS for gRPC communication with the EigenDA disperser. | +| `--eigenda-custom-quorum-ids` | `EIGENDA_PROXY_CUSTOM_QUORUM_IDS` | string | None | No | Custom quorum IDs for writing blobs. Should not include default quorums 0 or 1. | +| `--eigenda-disable-point-verification-mode` | `EIGENDA_PROXY_DISABLE_POINT_VERIFICATION_MODE` | bool | false | No | Disable point verification mode. This mode performs IFFT on data before writing and FFT on data after reading. Disabling requires supplying the entire blob for verification against the KZG commitment. | +| `--eigenda-max-blob-length` | `EIGENDA_PROXY_MAX_BLOB_LENGTH` | string | "2MiB" | No | Maximum blob length to be written or read from EigenDA. Determines the number of SRS points loaded into memory for KZG commitments. Example units: '30MiB', '4Kb', '30MB'. Maximum size slightly exceeds 1GB. | +| `--eigenda-put-blob-encoding-version` | `EIGENDA_PROXY_PUT_BLOB_ENCODING_VERSION` | int | 0 | No | Blob encoding version to use when writing blobs from the high-level interface. | +| `--eigenda-status-query-retry-interval` | `EIGENDA_PROXY_STATUS_QUERY_INTERVAL` | duration | 5s | No | Interval between retries when awaiting network blob finalization. | +| `--eigenda-status-query-timeout` | `EIGENDA_PROXY_STATUS_QUERY_TIMEOUT` | duration | 30m0s | No | Duration to wait for a blob to finalize after being sent for dispersal. | +| `--eigenda-response-timeout` | `EIGENDA_PROXY_RESPONSE_TIMEOUT` | duration | 10s | No | Total time to wait for a response from the EigenDA disperser. | +| `--memstore.enabled` | `MEMSTORE_ENABLED` | bool | false | No | Whether to use mem-store for DA logic. | +| `--memstore.expiration` | `MEMSTORE_EXPIRATION` | duration | 25m0s | No | Duration that a blob/commitment pair are allowed to live. | +| `--metrics.addr` | `EIGENDA_PROXY_METRICS_ADDR` | string | "0.0.0.0" | No | Metrics listening address. | +| `--metrics.enabled` | `EIGENDA_PROXY_METRICS_ENABLED` | bool | false | No | Enable the metrics server. | +| `--metrics.port` | `EIGENDA_PROXY_METRICS_PORT` | int | 7300 | No | Metrics listening port. | +| `--log.color` | `EIGENDA_PROXY_LOG_COLOR` | bool | false | No | Color the log output if in terminal mode. | +| `--log.format` | `EIGENDA_PROXY_LOG_FORMAT` | string | text | No | Format the log output. Supported formats: 'text', 'terminal', 'logfmt', 'json', 'json-pretty'. | +| `--log.level` | `EIGENDA_PROXY_LOG_LEVEL` | string | INFO | No | The lowest log level that will be output. | +| `--log.pid` | `EIGENDA_PROXY_LOG_PID` | bool | false | No | Show pid in the log. | -* blob submission/retrieval to EigenDA -* data <--> blob encoding/decoding for BN254 field element compatibility -* tamper resistance assurance (i.e, cryptographic verification of retrieved blobs) for avoiding a trust dependency on the EigenDA disperser - -In order to disperse to the EigenDA network in production, or at high throughput on testnet, please register your authentication ethereum address through [this form](https://forms.gle/3QRNTYhSMacVFNcU8). Your EigenDA authentication keypair should not be associated with any funds anywhere. - -## EigenDA Configuration - -Additional CLI args are provided for targeting an EigenDA network backend: +### Certificate verification -* `--eigenda-disperser-rpc`: RPC host of disperser service. (e.g, on holesky this is `disperser-holesky.eigenda.xyz:443`, full network list [here](https://docs.eigenlayer.xyz/eigenda/networks/)) -* `--eigenda-status-query-timeout`: (default: 30m) 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-disable-tls`: (default: false) Whether to disable TLS for grpc communication with disperser. -* `--eigenda-response-timeout`: (default: 10s) The total amount of time that the client will wait for a response from the EigenDA disperser. -* `--eigenda-custom-quorum-ids`: (default: []) The quorum IDs to write blobs to using this client. Should not include default quorums 0 or 1. -* `--eigenda-signer-private-key-hex`: Signer private key in hex encoded format. This key should not be associated with an Ethereum address holding any funds. -* `--eigenda-put-blob-encoding-version`: The blob encoding version to use when writing blobs from the high level interface. -* `--eigenda-disable-point-verification-mode`: Point verification mode does an IFFT on data before it is written, and does an FFT on data after it is read. This makes it possible to open points on the KZG commitment to prove that the field elements correspond to the commitment. With this mode disabled, you will need to supply the entire blob to perform a verification that any part of the data matches the KZG commitment. -* `--eigenda-g1-path`: Directory path to g1.point file -* `--eigenda-g2-power-of-tau`: Directory path to g2.point.powerOf2 file -* `--eigenda-cache-path`: Directory path to dump cached SRS tables -* `--eigenda-max-blob-length`: The maximum blob length that this EigenDA sidecar proxy should expect to be written or read from EigenDA. This configuration setting is used to determine how many SRS points should be loaded into memory for generating/verifying KZG commitments returned by the EigenDA disperser. Valid byte units are either base-2 or base-10 byte amounts (not bits), e.g. `30 MiB`, `4Kb`, `30MB`. The maximum blob size is a little more than `1GB`. +In order for the EigenDA Proxy to avoid a trust assumption on the EigenDA disperser, the proxy offers a DA cert verification feature which ensures that: -### Certificate verification +1. The DA cert's batch hash can be computed locally and matches the one persisted on-chain in the `ServiceManager` contract +2. The DA cert's blob inclusion proof can be merkalized to generate the proper batch root +3. The DA cert's quorum params are adequately defined and expressed when compared to their on-chain counterparts -For additional security, there is a cert verification feature which verifies the blob metadata read from the disperser to ensure that: +To target this feature, use the CLI flags `--eigenda-svc-manager-addr`, `--eigenda-eth-rpc`. -1. The respective batch hash can be computed locally and matches the one persisted on-chain in the `ServiceManager` contract -2. The blob inclusion proof can be merkalized to generate the proper batch root -3. All quorum params are adequately defined and expressed when compared to their on-chain counterparts +### In-Memory Backend -To target this feature, the following CLI args should be provided: +An ephemeral memory store backend can be used for faster feedback testing when testing rollup integrations. To target this feature, use the CLI flags `--memstore.enabled`, `--memstore.expiration`. -* `--eigenda-svc-manager-addr`: The deployed EigenDA service manager address. The list can be found [here](https://github.com/Layr-Labs/eigenlayer-middleware/?tab=readme-ov-file#current-mainnet-deployment). -* `--eigenda-eth-rpc` : JSON RPC node endpoint for the Ethereum network used for finalizing DA blobs. See available list [here](https://docs.eigenlayer.xyz/eigenda/networks/). +## Metrics -### In-Memory Storage +To the see list of available metrics, run `./bin/eigenda-proxy doc metrics` -An ephemeral memory store backend can be used for faster feedback testing when performing rollup integrations. The following cli args can be used to target the feature: +## Deployment Guide -* `--memstore.enabled`: Boolean feature flag -* `--memstore.expiration`: Duration for which a blob will exist +### Hardware Requirements -## Metrics +The following specs are recommended for running on a single production server: -To the see list of available metrics, run `./bin/eigenda-proxy doc metrics` +* 4 GB RAM +* 1-2 cores CPU -## Running Locally +### Deployment Steps + +```bash +## Build EigenDA Proxy +$ make +# env GO111MODULE=on GOOS= GOARCH= go build -v -ldflags "-X main.GitCommit=4b7b35bc3770ed5ca809b7ddb8a825c470a00fb4 -X main.GitDate=1719407123 -X main.Version=v0.0.0" -o ./bin/eigenda-proxy ./cmd/server +# github.com/Layr-Labs/eigenda-proxy/server +# github.com/Layr-Labs/eigenda-proxy/cmd/server + +## Setup new keypair for EigenDA authentication +$ cast wallet new -j > keypair.json + +## Extract keypair ETH address +$ jq -r '.[0].address' keypair.json +# 0x859F0F6D095E18B732FAdc8CD16Ae144F24e2F0D + +## If running against mainnet, register the keypair ETH address and wait for approval: https://forms.gle/niMzQqj1JEzqHEny9 + +## Extract keypair private key and remove 0x prefix +PRIVATE_KEY=$(jq -r '.[0].private_key' keypair.json | tail -c +3) + +## Run EigenDA Proxy +$ ./bin/eigenda-proxy \ + --addr 127.0.0.1 \ + --port 3100 \ + --eigenda-disperser-rpc disperser-holesky.eigenda.xyz:443 \ + --eigenda-signer-private-key-hex $PRIVATE_KEY \ + --eigenda-eth-rpc https://ethereum-holesky-rpc.publicnode.com \ + --eigenda-svc-manager-addr 0xD4A7E1Bd8015057293f0D0A557088c286942e84b +# 2024/06/26 09:41:04 maxprocs: Leaving GOMAXPROCS=10: CPU quota undefined +# INFO [06-26|09:41:04.881] Initializing EigenDA proxy server... role=eigenda_proxy +# INFO [06-26|09:41:04.884] Reading G1 points (2164832 bytes) takes 2.169417ms role=eigenda_proxy +# INFO [06-26|09:41:04.961] Parsing takes 76.634042ms role=eigenda_proxy +# numthread 10 +# WARN [06-26|09:41:04.961] Verification disabled role=eigenda_proxy +# INFO [06-26|09:41:04.961] Using eigenda backend role=eigenda_proxy +# INFO [06-26|09:41:04.962] Starting DA server role=eigenda_proxy endpoint=127.0.0.1:5050 +# INFO [06-26|09:41:04.973] Started DA Server role=eigenda_proxy +... +``` -1. Compile binary: `make eigenda-proxy` -2. Generate a new private key and save it as `EIGENDA_PROXY_SIGNER_PRIVATE_KEY_HEX` env var without the `0x` prefix. -3. Run binary; e.g: `./bin/eigenda-proxy --addr 127.0.0.1 --port 5050 --eigenda-disperser-rpc disperser-holesky.eigenda.xyz:443 --eigenda-status-query-timeout 45m --eigenda-max-blob-length='90Kib'` +### Env File -**Env File** -An env file can be provided to the binary for runtime process ingestion; e.g: +We also provide network-specific example env configuration files in `.env.example.holesky` and `.env.example.mainnet` as a place to get started: -1. Create env: `cp .env.example .env` -2. Pass into binary: `ENV_PATH=.env ./bin/eigenda-proxy` +1. Copy example env file: `cp .env.holesky.example .env` +2. Update env file, setting `EIGENDA_PROXY_SIGNER_PRIVATE_KEY_HEX`. On mainnet you will also need to set `EIGENDA_PROXY_ETH_RPC`. +3. Pass into binary: `ENV_PATH=.env ./bin/eigenda-proxy --addr 127.0.0.1 --port 3100` ## Running via Docker @@ -70,18 +128,18 @@ Container can be built via running `make build-docker`. ## Commitment Schemas -An `EigenDACommitment` layer type has been added that supports verification against its respective pre-images. The commitment is encoded via the following byte array: +Commitments returned from the EigenDA Proxy adhere to the following byte encoding: ``` - 0 1 2 3 4 N - |--------|--------|--------|--------|-----------------| - commit da layer ext da version raw commitment - type type type byte + 0 1 2 3 4 N + |--------|--------|--------|--------|-----------------| + commit da layer ext da version raw commitment + type type type byte ``` -The `raw commitment` for EigenDA is encoding certificate and kzg fields. +The `raw commitment` is an RLP-encoded [EigenDA certificate](https://github.com/Layr-Labs/eigenda/blob/eb422ff58ac6dcd4e7b30373033507414d33dba1/api/proto/disperser/disperser.proto#L168). -**NOTE:** Commitments are cryptographically verified against the data fetched from EigenDA for all `/get` calls. The server will respond with status `500` in the event where EigenDA were to lie and provide falsified data thats irrespective of the client provided commitment. This feature isn't flag guarded and is part of standard operation. +**NOTE:** Commitments are cryptographically verified against the data fetched from EigenDA for all `/get` calls. The server will respond with status `500` in the event where EigenDA were to lie and provide falsified data thats irrespective of the client provided commitment. This feature cannot be disabled and is part of standard operation. ## Testing @@ -97,19 +155,8 @@ A holesky integration test can be ran using `make holesky-test` to assert proper An E2E test exists which spins up a local OP sequencer instance using the [op-e2e](https://github.com/ethereum-optimism/optimism/tree/develop/op-e2e) framework for asserting correct interaction behaviors with batch submission and state derivation. These tests can be ran via `make optimism-test`. -**NOTE:** - -## Hardware Requirements - -The following specs are recommended for running on a single production server: - -* 12 GB SSD (assuming SRS values are stored on instance) -* 16 GB RAM -* 1-2 cores CPU - ## Resources * [op-stack](https://github.com/ethereum-optimism/optimism) - -* [plasma spec](https://specs.optimism.io/experimental/plasma.html) +* [Alt-DA spec](https://specs.optimism.io/experimental/alt-da.html) * [eigen da](https://github.com/Layr-Labs/eigenda) diff --git a/eigenda/config.go b/eigenda/config.go index 98d9720..c768a5b 100644 --- a/eigenda/config.go +++ b/eigenda/config.go @@ -158,83 +158,83 @@ func CLIFlags(envPrefix string) []cli.Flag { }, &cli.DurationFlag{ Name: StatusQueryTimeoutFlagName, - Usage: "Timeout for aborting an EigenDA blob dispersal if the disperser does not report that the blob has been finalized dispersed.", + Usage: "Duration to wait for a blob to finalize after being sent for dispersal. Default is 30 minutes.", Value: 30 * time.Minute, EnvVars: prefixEnvVars("STATUS_QUERY_TIMEOUT"), }, &cli.DurationFlag{ Name: StatusQueryRetryIntervalFlagName, - Usage: "Wait time between retries of EigenDA blob status queries (made while waiting for a blob to be confirmed by).", + Usage: "Interval between retries when awaiting network blob finalization. Default is 5 seconds.", Value: 5 * time.Second, EnvVars: prefixEnvVars("STATUS_QUERY_INTERVAL"), }, &cli.BoolFlag{ Name: DisableTlsFlagName, - Usage: "Disable TLS when connecting to the EigenDA disperser.", + Usage: "Disable TLS for gRPC communication with the EigenDA disperser. Default is false.", Value: false, EnvVars: prefixEnvVars("GRPC_DISABLE_TLS"), }, &cli.DurationFlag{ Name: ResponseTimeoutFlagName, - Usage: "The total amount of time that the client will wait for a response from the EigenDA disperser.", + Usage: "Total time to wait for a response from the EigenDA disperser. Default is 10 seconds.", Value: 10 * time.Second, EnvVars: prefixEnvVars("RESPONSE_TIMEOUT"), }, &cli.UintSliceFlag{ Name: CustomQuorumIDsFlagName, - Usage: "The quorum IDs to write blobs to using this client. Should not include default quorums 0 or 1.", + Usage: "Custom quorum IDs for writing blobs. Should not include default quorums 0 or 1.", Value: cli.NewUintSlice(), EnvVars: prefixEnvVars("CUSTOM_QUORUM_IDS"), }, &cli.StringFlag{ Name: SignerPrivateKeyHexFlagName, - Usage: "Signer private key in hex encoded format. This key should not be associated with an Ethereum address holding any funds.", + Usage: "Hex-encoded signer private key. This key should not be associated with an Ethereum address holding any funds.", EnvVars: prefixEnvVars("SIGNER_PRIVATE_KEY_HEX"), }, &cli.UintFlag{ Name: PutBlobEncodingVersionFlagName, - Usage: "The blob encoding version to use when writing blobs from the high level interface.", + Usage: "Blob encoding version to use when writing blobs from the high-level interface.", EnvVars: prefixEnvVars("PUT_BLOB_ENCODING_VERSION"), Value: 0, }, &cli.BoolFlag{ Name: DisablePointVerificationModeFlagName, - Usage: "Point verification mode does an IFFT on data before it is written, and does an FFT on data after it is read. This makes it possible to open points on the KZG commitment to prove that the field elements correspond to the commitment. With this mode disabled, you will need to supply the entire blob to perform a verification that any part of the data matches the KZG commitment.", + Usage: "Disable point verification mode. This mode performs IFFT on data before writing and FFT on data after reading. Disabling requires supplying the entire blob for verification against the KZG commitment.", EnvVars: prefixEnvVars("DISABLE_POINT_VERIFICATION_MODE"), Value: false, }, &cli.StringFlag{ Name: MaxBlobLengthFlagName, - Usage: "Maximum size in string representation (e.g. \"10mb\", \"4 KiB\") of blobs to be dispersed and verified using this proxy. This impacts the number of SRS points loaded into memory.", + Usage: "Maximum blob length to be written or read from EigenDA. Determines the number of SRS points loaded into memory for KZG commitments. Example units: '30MiB', '4Kb', '30MB'. Maximum size slightly exceeds 1GB.", EnvVars: prefixEnvVars("MAX_BLOB_LENGTH"), Value: "2MiB", }, &cli.StringFlag{ Name: G1PathFlagName, - Usage: "Directory path to g1.point file", + Usage: "Directory path to g1.point file.", EnvVars: prefixEnvVars("TARGET_KZG_G1_PATH"), Value: "resources/g1.point", }, &cli.StringFlag{ Name: G2TauFlagName, - Usage: "Directory path to g2.point.powerOf2 file", + Usage: "Directory path to g2.point.powerOf2 file.", EnvVars: prefixEnvVars("TARGET_G2_TAU_PATH"), Value: "resources/g2.point.powerOf2", }, &cli.StringFlag{ Name: CachePathFlagName, - Usage: "Directory path to SRS tables", + Usage: "Directory path to SRS tables for caching.", EnvVars: prefixEnvVars("TARGET_CACHE_PATH"), Value: "resources/SRSTables/", }, &cli.StringFlag{ Name: EthRPCFlagName, - Usage: "JSON RPC node endpoint for the Ethereum network used for finalizing DA blobs.", + Usage: "JSON RPC node endpoint for the Ethereum network used for finalizing DA blobs. See available list here: https://docs.eigenlayer.xyz/eigenda/networks/", EnvVars: prefixEnvVars("ETH_RPC"), }, &cli.StringFlag{ Name: SvcManagerAddrFlagName, - Usage: "Deployed EigenDA service manager address.", + Usage: "The deployed EigenDA service manager address. The list can be found here: https://github.com/Layr-Labs/eigenlayer-middleware/?tab=readme-ov-file#current-mainnet-deployment", EnvVars: prefixEnvVars("SERVICE_MANAGER_ADDR"), }, } diff --git a/server/load_store.go b/server/load_store.go index 0947822..34c0533 100644 --- a/server/load_store.go +++ b/server/load_store.go @@ -34,7 +34,7 @@ func LoadStore(cfg CLIConfig, ctx context.Context, log log.Logger) (store.Store, return store.NewMemStore(ctx, &cfg.MemStoreCfg, verifier, log, maxBlobLength) } - log.Info("Using eigenda backend") + log.Info("Using EigenDA backend") client, err := clients.NewEigenDAClient(log, daCfg.ClientConfig) if err != nil { return nil, err