Skip to content

Commit 7733fe2

Browse files
authored
Fix config checker logic (#138)
* remove -v from make test * refactor: config checker one rule was broken due to new semantics of confDepth flag, which can't be negative anymore * fix: config tests * fix: lint * feat: add new eigenda-cert-verification-enabled flag * fix: config tests * docs: update readme with new cert-verification-enabled flag info
1 parent 71989c8 commit 7733fe2

File tree

8 files changed

+127
-106
lines changed

8 files changed

+127
-106
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ clean:
4949
rm bin/eigenda-proxy
5050

5151
test:
52-
go test -v ./... -parallel 4
52+
go test ./... -parallel 4
5353

5454
e2e-test: stop-minio stop-redis run-minio run-redis
5555
$(E2ETEST) && \

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ In order to disperse to the EigenDA network in production, or at high throughput
3030
| `--eigenda-custom-quorum-ids` | | `$EIGENDA_PROXY_CUSTOM_QUORUM_IDS` | Custom quorum IDs for writing blobs. Should not include default quorums 0 or 1. |
3131
| `--eigenda-disable-point-verification-mode` | `false` | `$EIGENDA_PROXY_DISABLE_POINT_VERIFICATION_MODE` | 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. |
3232
| `--eigenda-disable-tls` | `false` | `$EIGENDA_PROXY_GRPC_DISABLE_TLS` | Disable TLS for gRPC communication with the EigenDA disperser. Default is false. |
33+
| --eigenda-cert-verification-enabled | `false` | `$EIGENDA_PROXY_CERT_VERIFICATION_ENABLED` | Whether to verify certificates received from EigenDA disperser. |
3334
| `--eigenda-disperser-rpc` | | `$EIGENDA_PROXY_EIGENDA_DISPERSER_RPC` | RPC endpoint of the EigenDA disperser. |
35+
| `--eigenda-svc-manager-addr` | | `$EIGENDA_PROXY_SERVICE_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 |
3436
| `--eigenda-eth-confirmation-depth` | `-1` | `$EIGENDA_PROXY_ETH_CONFIRMATION_DEPTH` | The number of Ethereum blocks of confirmation that the DA bridging transaction must have before it is assumed by the proxy to be final. If set negative the proxy will always wait for blob finalization. |
3537
| `--eigenda-eth-rpc` | | `$EIGENDA_PROXY_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/ |
3638
| `--eigenda-g1-path` | `"resources/g1.point"` | `$EIGENDA_PROXY_TARGET_KZG_G1_PATH` | Directory path to g1.point file. |
@@ -41,7 +43,6 @@ In order to disperse to the EigenDA network in production, or at high throughput
4143
| `--eigenda-signer-private-key-hex` | | `$EIGENDA_PROXY_SIGNER_PRIVATE_KEY_HEX` | Hex-encoded signer private key. This key should not be associated with an Ethereum address holding any funds. |
4244
| `--eigenda-status-query-retry-interval` | `5s` | `$EIGENDA_PROXY_STATUS_QUERY_INTERVAL` | Interval between retries when awaiting network blob finalization. Default is 5 seconds. |
4345
| `--eigenda-status-query-timeout` | `30m0s` | `$EIGENDA_PROXY_STATUS_QUERY_TIMEOUT` | Duration to wait for a blob to finalize after being sent for dispersal. Default is 30 minutes. |
44-
| `--eigenda-svc-manager-addr` | | `$EIGENDA_PROXY_SERVICE_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 |
4546
| `--log.color` | `false` | `$EIGENDA_PROXY_LOG_COLOR` | Color the log output if in terminal mode. |
4647
| `--log.format` | `text` | `$EIGENDA_PROXY_LOG_FORMAT` | Format the log output. Supported formats: 'text', 'terminal', 'logfmt', 'json', 'json-pretty'. |
4748
| `--log.level` | `INFO` | `$EIGENDA_PROXY_LOG_LEVEL` | The lowest log level that will be output. |

server/config.go

Lines changed: 61 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@ import (
1717
const (
1818
// eigenda client flags
1919
EigenDADisperserRPCFlagName = "eigenda-disperser-rpc"
20-
EthRPCFlagName = "eigenda-eth-rpc"
21-
SvcManagerAddrFlagName = "eigenda-svc-manager-addr"
22-
EthConfirmationDepthFlagName = "eigenda-eth-confirmation-depth"
2320
StatusQueryRetryIntervalFlagName = "eigenda-status-query-retry-interval"
2421
StatusQueryTimeoutFlagName = "eigenda-status-query-timeout"
2522
DisableTLSFlagName = "eigenda-disable-tls"
@@ -29,6 +26,12 @@ const (
2926
PutBlobEncodingVersionFlagName = "eigenda-put-blob-encoding-version"
3027
DisablePointVerificationModeFlagName = "eigenda-disable-point-verification-mode"
3128

29+
// cert verification flags
30+
CertVerificationEnabledFlagName = "eigenda-cert-verification-enabled"
31+
EthRPCFlagName = "eigenda-eth-rpc"
32+
SvcManagerAddrFlagName = "eigenda-svc-manager-addr"
33+
EthConfirmationDepthFlagName = "eigenda-eth-confirmation-depth"
34+
3235
// kzg flags
3336
G1PathFlagName = "eigenda-g1-path"
3437
G2TauFlagName = "eigenda-g2-tau-path"
@@ -79,10 +82,13 @@ type Config struct {
7982
// the blob encoding version to use when writing blobs from the high level interface.
8083
PutBlobEncodingVersion codecs.BlobEncodingVersion
8184

82-
// eth vars
83-
EthRPC string
84-
SvcManagerAddr string
85-
EthConfirmationDepth int64
85+
// eth verification vars
86+
// TODO: right now verification and confirmation depth are tightly coupled
87+
// we should decouple them
88+
CertVerificationEnabled bool
89+
EthRPC string
90+
SvcManagerAddr string
91+
EthConfirmationDepth int64
8692

8793
// kzg vars
8894
CacheDir string
@@ -143,18 +149,11 @@ func (cfg *Config) VerificationCfg() *verify.Config {
143149
NumWorker: uint64(runtime.GOMAXPROCS(0)), // #nosec G115
144150
}
145151

146-
if cfg.EthRPC == "" || cfg.SvcManagerAddr == "" {
147-
return &verify.Config{
148-
Verify: false,
149-
KzgConfig: kzgCfg,
150-
}
151-
}
152-
153152
return &verify.Config{
154-
Verify: true,
153+
KzgConfig: kzgCfg,
154+
VerifyCerts: cfg.CertVerificationEnabled,
155155
RPCURL: cfg.EthRPC,
156156
SvcManagerAddr: cfg.SvcManagerAddr,
157-
KzgConfig: kzgCfg,
158157
EthConfirmationDepth: uint64(cfg.EthConfirmationDepth), // #nosec G115
159158
}
160159
}
@@ -189,19 +188,20 @@ func ReadConfig(ctx *cli.Context) Config {
189188
PutBlobEncodingVersion: codecs.BlobEncodingVersion(ctx.Uint(PutBlobEncodingVersionFlagName)),
190189
DisablePointVerificationMode: ctx.Bool(DisablePointVerificationModeFlagName),
191190
},
192-
G1Path: ctx.String(G1PathFlagName),
193-
G2PowerOfTauPath: ctx.String(G2TauFlagName),
194-
CacheDir: ctx.String(CachePathFlagName),
195-
MaxBlobLength: ctx.String(MaxBlobLengthFlagName),
196-
SvcManagerAddr: ctx.String(SvcManagerAddrFlagName),
197-
EthRPC: ctx.String(EthRPCFlagName),
198-
EthConfirmationDepth: ctx.Int64(EthConfirmationDepthFlagName),
199-
MemstoreEnabled: ctx.Bool(MemstoreFlagName),
200-
MemstoreBlobExpiration: ctx.Duration(MemstoreExpirationFlagName),
201-
MemstoreGetLatency: ctx.Duration(MemstoreGetLatencyFlagName),
202-
MemstorePutLatency: ctx.Duration(MemstorePutLatencyFlagName),
203-
FallbackTargets: ctx.StringSlice(FallbackTargets),
204-
CacheTargets: ctx.StringSlice(CacheTargets),
191+
G1Path: ctx.String(G1PathFlagName),
192+
G2PowerOfTauPath: ctx.String(G2TauFlagName),
193+
CacheDir: ctx.String(CachePathFlagName),
194+
CertVerificationEnabled: ctx.Bool(CertVerificationEnabledFlagName),
195+
MaxBlobLength: ctx.String(MaxBlobLengthFlagName),
196+
SvcManagerAddr: ctx.String(SvcManagerAddrFlagName),
197+
EthRPC: ctx.String(EthRPCFlagName),
198+
EthConfirmationDepth: ctx.Int64(EthConfirmationDepthFlagName),
199+
MemstoreEnabled: ctx.Bool(MemstoreFlagName),
200+
MemstoreBlobExpiration: ctx.Duration(MemstoreExpirationFlagName),
201+
MemstoreGetLatency: ctx.Duration(MemstoreGetLatencyFlagName),
202+
MemstorePutLatency: ctx.Duration(MemstorePutLatencyFlagName),
203+
FallbackTargets: ctx.StringSlice(FallbackTargets),
204+
CacheTargets: ctx.StringSlice(CacheTargets),
205205
}
206206
// the eigenda client can only wait for 0 confirmations or finality
207207
// the da-proxy has a more fine-grained notion of confirmation depth
@@ -246,16 +246,22 @@ func (cfg *Config) Check() error {
246246
return fmt.Errorf("max blob length is 0")
247247
}
248248

249-
if cfg.SvcManagerAddr != "" && cfg.EthRPC == "" {
250-
return fmt.Errorf("svc manager address is set, but Eth RPC is not set")
251-
}
252-
253-
if cfg.EthRPC != "" && cfg.SvcManagerAddr == "" {
254-
return fmt.Errorf("eth rpc is set, but svc manager address is not set")
249+
if !cfg.MemstoreEnabled {
250+
if cfg.ClientConfig.RPC == "" {
251+
return fmt.Errorf("using eigenda backend (memstore.enabled=false) but eigenda disperser rpc url is not set")
252+
}
255253
}
256254

257-
if cfg.EthConfirmationDepth >= 0 && (cfg.SvcManagerAddr == "" || cfg.EthRPC == "") {
258-
return fmt.Errorf("eth confirmation depth is set for certificate verification, but Eth RPC or SvcManagerAddr is not set")
255+
if cfg.CertVerificationEnabled {
256+
if cfg.MemstoreEnabled {
257+
return fmt.Errorf("cannot enable cert verification when memstore is enabled")
258+
}
259+
if cfg.EthRPC == "" {
260+
return fmt.Errorf("cert verification enabled but eth rpc is not set")
261+
}
262+
if cfg.SvcManagerAddr == "" {
263+
return fmt.Errorf("cert verification enabled but svc manager address is not set")
264+
}
259265
}
260266

261267
if cfg.S3Config.S3CredentialType == store.S3CredentialUnknown && cfg.S3Config.Endpoint != "" {
@@ -271,10 +277,6 @@ func (cfg *Config) Check() error {
271277
return fmt.Errorf("redis password is set, but endpoint is not")
272278
}
273279

274-
if !cfg.MemstoreEnabled && cfg.ClientConfig.RPC == "" {
275-
return fmt.Errorf("eigenda disperser rpc url is not set")
276-
}
277-
278280
err = cfg.checkTargets(cfg.FallbackTargets)
279281
if err != nil {
280282
return err
@@ -453,19 +455,31 @@ func CLIFlags() []cli.Flag {
453455
EnvVars: prefixEnvVars("TARGET_CACHE_PATH"),
454456
Value: "resources/SRSTables/",
455457
},
458+
&cli.BoolFlag{
459+
Name: CertVerificationEnabledFlagName,
460+
Usage: "Whether to verify certificates received from EigenDA disperser.",
461+
EnvVars: prefixEnvVars("CERT_VERIFICATION_ENABLED"),
462+
// TODO: ideally we'd want this to be turned on by default when eigenda backend is used (memstore.enabled=false)
463+
Value: false,
464+
},
456465
&cli.StringFlag{
457-
Name: EthRPCFlagName,
458-
Usage: "JSON RPC node endpoint for the Ethereum network used for finalizing DA blobs. See available list here: https://docs.eigenlayer.xyz/eigenda/networks/",
466+
Name: EthRPCFlagName,
467+
Usage: "JSON RPC node endpoint for the Ethereum network used for finalizing DA blobs.\n" +
468+
"See available list here: https://docs.eigenlayer.xyz/eigenda/networks/\n" +
469+
fmt.Sprintf("Mandatory when %s is true.", CertVerificationEnabledFlagName),
459470
EnvVars: prefixEnvVars("ETH_RPC"),
460471
},
461472
&cli.StringFlag{
462-
Name: SvcManagerAddrFlagName,
463-
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",
473+
Name: SvcManagerAddrFlagName,
474+
Usage: "The deployed EigenDA service manager address.\n" +
475+
"The list can be found here: https://github.com/Layr-Labs/eigenlayer-middleware/?tab=readme-ov-file#current-mainnet-deployment\n" +
476+
fmt.Sprintf("Mandatory when %s is true.", CertVerificationEnabledFlagName),
464477
EnvVars: prefixEnvVars("SERVICE_MANAGER_ADDR"),
465478
},
466479
&cli.Int64Flag{
467-
Name: EthConfirmationDepthFlagName,
468-
Usage: "The number of Ethereum blocks to wait before considering a submitted blob's DA batch submission confirmed. `0` means wait for inclusion only. `-1` means wait for finality.",
480+
Name: EthConfirmationDepthFlagName,
481+
Usage: "The number of Ethereum blocks to wait before considering a submitted blob's DA batch submission confirmed.\n" +
482+
"`0` means wait for inclusion only. `-1` means wait for finality.",
469483
EnvVars: prefixEnvVars("ETH_CONFIRMATION_DEPTH"),
470484
Value: -1,
471485
},

server/config_test.go

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,16 @@ func validCfg() *Config {
3535
PutBlobEncodingVersion: 0,
3636
DisablePointVerificationMode: false,
3737
},
38-
G1Path: "path/to/g1",
39-
G2PowerOfTauPath: "path/to/g2",
40-
CacheDir: "path/to/cache",
41-
MaxBlobLength: "2MiB",
42-
SvcManagerAddr: "0x1234567890abcdef",
43-
EthRPC: "http://localhost:8545",
44-
EthConfirmationDepth: 12,
45-
MemstoreEnabled: true,
46-
MemstoreBlobExpiration: 25 * time.Minute,
38+
G1Path: "path/to/g1",
39+
G2PowerOfTauPath: "path/to/g2",
40+
CacheDir: "path/to/cache",
41+
MaxBlobLength: "2MiB",
42+
CertVerificationEnabled: false,
43+
SvcManagerAddr: "0x1234567890abcdef",
44+
EthRPC: "http://localhost:8545",
45+
EthConfirmationDepth: 12,
46+
MemstoreEnabled: true,
47+
MemstoreBlobExpiration: 25 * time.Minute,
4748
}
4849
}
4950

@@ -71,37 +72,39 @@ func TestConfigVerification(t *testing.T) {
7172
require.Error(t, err)
7273
})
7374

74-
t.Run("MissingSvcManagerAddr", func(t *testing.T) {
75-
cfg := validCfg()
76-
77-
cfg.EthRPC = "http://localhost:6969"
78-
cfg.EthConfirmationDepth = 12
79-
cfg.SvcManagerAddr = ""
80-
81-
err := cfg.Check()
82-
require.Error(t, err)
83-
})
84-
85-
t.Run("MissingCertVerificationParams", func(t *testing.T) {
86-
cfg := validCfg()
87-
88-
cfg.EthConfirmationDepth = 12
89-
cfg.SvcManagerAddr = ""
90-
cfg.EthRPC = "http://localhost:6969"
91-
92-
err := cfg.Check()
93-
require.Error(t, err)
94-
})
95-
96-
t.Run("MissingEthRPC", func(t *testing.T) {
97-
cfg := validCfg()
98-
99-
cfg.EthConfirmationDepth = 12
100-
cfg.SvcManagerAddr = "0x00000000123"
101-
cfg.EthRPC = ""
102-
103-
err := cfg.Check()
104-
require.Error(t, err)
75+
t.Run("CertVerificationEnabled", func(t *testing.T) {
76+
// when eigenDABackend is enabled (memstore.enabled = false),
77+
// some extra fields are required.
78+
t.Run("MissingSvcManagerAddr", func(t *testing.T) {
79+
cfg := validCfg()
80+
// cert verification only makes sense when memstore is disabled (we use eigenda as backend)
81+
cfg.MemstoreEnabled = false
82+
cfg.CertVerificationEnabled = true
83+
cfg.SvcManagerAddr = ""
84+
85+
err := cfg.Check()
86+
require.Error(t, err)
87+
})
88+
89+
t.Run("MissingEthRPC", func(t *testing.T) {
90+
cfg := validCfg()
91+
// cert verification only makes sense when memstore is disabled (we use eigenda as backend)
92+
cfg.MemstoreEnabled = false
93+
cfg.CertVerificationEnabled = true
94+
cfg.EthRPC = ""
95+
96+
err := cfg.Check()
97+
require.Error(t, err)
98+
})
99+
100+
t.Run("CantDoCertVerificationWhenMemstoreEnabled", func(t *testing.T) {
101+
cfg := validCfg()
102+
cfg.MemstoreEnabled = true
103+
cfg.CertVerificationEnabled = true
104+
105+
err := cfg.Check()
106+
require.Error(t, err)
107+
})
105108
})
106109

107110
t.Run("MissingS3AccessKeys", func(t *testing.T) {

server/load_store.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func LoadStoreRouter(ctx context.Context, cfg CLIConfig, log log.Logger) (store.
4949
log.Info("Using S3 backend")
5050
s3, err = store.NewS3(cfg.S3Config)
5151
if err != nil {
52-
return nil, err
52+
return nil, fmt.Errorf("failed to create S3 store: %w", err)
5353
}
5454
}
5555

@@ -58,7 +58,7 @@ func LoadStoreRouter(ctx context.Context, cfg CLIConfig, log log.Logger) (store.
5858
// create Redis backend store
5959
redis, err = store.NewRedisStore(&cfg.RedisCfg)
6060
if err != nil {
61-
return nil, err
61+
return nil, fmt.Errorf("failed to create Redis store: %w", err)
6262
}
6363
}
6464

@@ -68,10 +68,10 @@ func LoadStoreRouter(ctx context.Context, cfg CLIConfig, log log.Logger) (store.
6868

6969
verifier, err := verify.NewVerifier(vCfg, log)
7070
if err != nil {
71-
return nil, err
71+
return nil, fmt.Errorf("failed to create verifier: %w", err)
7272
}
7373

74-
if vCfg.Verify {
74+
if vCfg.VerifyCerts {
7575
log.Info("Certificate verification with Ethereum enabled")
7676
} else {
7777
log.Warn("Verification disabled")

store/memory_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func getDefaultMemStoreTestConfig() MemStoreConfig {
2727

2828
func getDefaultVerifierTestConfig() *verify.Config {
2929
return &verify.Config{
30-
Verify: false,
30+
VerifyCerts: false,
3131
KzgConfig: &kzg.KzgConfig{
3232
G1Path: "../resources/g1.point",
3333
G2PowerOf2Path: "../resources/g2.point.powerOf2",

verify/verifier.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,45 +17,48 @@ import (
1717
)
1818

1919
type Config struct {
20-
Verify bool
20+
KzgConfig *kzg.KzgConfig
21+
VerifyCerts bool
22+
// below 3 fields are only required if VerifyCerts is true
2123
RPCURL string
2224
SvcManagerAddr string
23-
KzgConfig *kzg.KzgConfig
2425
EthConfirmationDepth uint64
2526
}
2627

2728
type Verifier struct {
28-
verifyCert bool
29+
// kzgVerifier is needed to commit blobs to the memstore
2930
kzgVerifier *kzgverifier.Verifier
31+
// cert verification is optional, and verifies certs retrieved from eigenDA when turned on
32+
verifyCerts bool
3033
cv *CertVerifier
3134
}
3235

3336
func NewVerifier(cfg *Config, l log.Logger) (*Verifier, error) {
3437
var cv *CertVerifier
3538
var err error
3639

37-
if cfg.Verify {
40+
if cfg.VerifyCerts {
3841
cv, err = NewCertVerifier(cfg, l)
3942
if err != nil {
40-
return nil, err
43+
return nil, fmt.Errorf("failed to create cert verifier: %w", err)
4144
}
4245
}
4346

4447
kzgVerifier, err := kzgverifier.NewVerifier(cfg.KzgConfig, false)
4548
if err != nil {
46-
return nil, err
49+
return nil, fmt.Errorf("failed to create kzg verifier: %w", err)
4750
}
4851

4952
return &Verifier{
50-
verifyCert: cfg.Verify,
5153
kzgVerifier: kzgVerifier,
54+
verifyCerts: cfg.VerifyCerts,
5255
cv: cv,
5356
}, nil
5457
}
5558

5659
// verifies V0 eigenda certificate type
5760
func (v *Verifier) VerifyCert(cert *Certificate) error {
58-
if !v.verifyCert {
61+
if !v.verifyCerts {
5962
return nil
6063
}
6164

0 commit comments

Comments
 (0)