From f304222f3fd46b216021f191e2831619e30e4b5c Mon Sep 17 00:00:00 2001 From: "adam.xu" Date: Wed, 22 Jan 2025 14:35:37 +0800 Subject: [PATCH] fix oz audit issue m-01 --- op-batcher/batcher/driver_da.go | 9 ++- op-service/eigenda/da_proxy.go | 7 ++- op-service/eigenda/da_proxy_test.go | 97 +++++++++++++++++++++++------ 3 files changed, 89 insertions(+), 24 deletions(-) diff --git a/op-batcher/batcher/driver_da.go b/op-batcher/batcher/driver_da.go index 4d0bf3934..d1a15578f 100644 --- a/op-batcher/batcher/driver_da.go +++ b/op-batcher/batcher/driver_da.go @@ -234,14 +234,19 @@ func (l *BatchSubmitter) loopEigenDa() (bool, error) { timeoutTime := time.Now().Add(l.EigenDA.DisperseBlobTimeout) for retry := 0; retry < EigenRPCRetryNum; retry++ { l.metr.RecordDaRetry(int32(retry)) + if time.Now().After(timeoutTime) { + l.log.Warn("loopEigenDa disperseEigenDaData timeout", "retry time", retry, "err", err) + break + } + wrappedData, err = l.disperseEigenDaData(daData) if err == nil && len(wrappedData) > 0 { eigendaSuccess = true break } - if time.Now().After(timeoutTime) { - l.log.Warn("loopEigenDa disperseEigenDaData timeout", "retry time", retry, "err", err) + if err != nil && !errors.Is(err, eigenda.ErrNotFound) { + l.log.Warn("unrecoverable error in disperseEigenDaData", "retry time", retry, "err", err) break } diff --git a/op-service/eigenda/da_proxy.go b/op-service/eigenda/da_proxy.go index a3dbf31e7..516ceb970 100644 --- a/op-service/eigenda/da_proxy.go +++ b/op-service/eigenda/da_proxy.go @@ -25,6 +25,9 @@ var ErrNotFound = errors.New("not found") // ErrInvalidInput is returned when the input is not valid for posting to the DA storage. var ErrInvalidInput = errors.New("invalid input") +// ErrNetwork is returned when there is a eigenda network error. +var ErrNetwork = errors.New("eigenda network error") + // NewEigenDAClient is an HTTP client to communicate with EigenDA Proxy. // It creates commitments and retrieves input data + verifies if needed. type EigenDAClient struct { @@ -147,11 +150,11 @@ func (c *EigenDAClient) DisperseBlob(ctx context.Context, img []byte) (*disperse resp, err := c.disperseClient.Do(req) done(err) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to post store data orirgin error: %w error: %w", err, ErrNetwork) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("failed to store data: %v", resp.StatusCode) + return nil, fmt.Errorf("failed to store data status code: %v error: %w", resp.StatusCode, ErrNetwork) } b, err := io.ReadAll(resp.Body) diff --git a/op-service/eigenda/da_proxy_test.go b/op-service/eigenda/da_proxy_test.go index 03b867566..d1f04ddac 100644 --- a/op-service/eigenda/da_proxy_test.go +++ b/op-service/eigenda/da_proxy_test.go @@ -123,49 +123,106 @@ func TestNewEigenDAProxy_RetrieveBlobWithCommitment(t *testing.T) { func TestNewEigenDAProxy_DisperseBlob(t *testing.T) { type fields struct { - proxyUrl string - disperserUrl string - log log.Logger + client *EigenDAClient } type args struct { ctx context.Context img []byte } + + logger := log.New() + metrics := &mockMetrics{} + + client := NewEigenDAClient(Config{ + ProxyUrl: "http://localhost:3100", + DisperserUrl: "disperser-holesky.eigenda.xyz:443", + DisperseBlobTimeout: 10 * time.Minute, + RetrieveBlobTimeout: 10 * time.Second, + }, logger, metrics) + + invalidClient := NewEigenDAClient(Config{ + ProxyUrl: "http://localhost:3333", + DisperserUrl: "disperser-holesky.eigenda.xyz:443", + DisperseBlobTimeout: 10 * time.Minute, + RetrieveBlobTimeout: 10 * time.Second, + }, logger, metrics) + tests := []struct { - name string - fields fields - args args - want *disperser.BlobInfo - wantErr bool + name string + fields fields + args args + want *disperser.BlobInfo + wantErr bool + wantNetworkErr bool }{ { name: "t1", fields: fields{ - proxyUrl: "http://127.0.0.1:3100", - disperserUrl: "disperser-holesky.eigenda.xyz:443", - log: log.New("test"), + client: client, }, args: args{ ctx: context.Background(), img: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}, }, - wantErr: false, + }, + { + name: "t2", + fields: fields{ + client: invalidClient, + }, + args: args{ + ctx: context.Background(), + img: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}, + }, + wantErr: true, + wantNetworkErr: true, + }, + { + name: "t3", + fields: fields{ + client: client, + }, + args: args{ + ctx: context.Background(), + img: make([]byte, 30*1024*1024), //larger than eigenda throughput limit + }, + wantErr: true, + wantNetworkErr: true, + }, + { + name: "t4", + fields: fields{ + client: client, + }, + args: args{ + ctx: context.Background(), + img: []byte{}, //empty data error + }, + wantErr: true, + wantNetworkErr: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - c := &EigenDAClient{ - proxyUrl: tt.fields.proxyUrl, - disperserUrl: tt.fields.disperserUrl, - log: tt.fields.log, - } - got, err := c.DisperseBlob(tt.args.ctx, tt.args.img) + got, err := tt.fields.client.DisperseBlob(tt.args.ctx, tt.args.img) if (err != nil) != tt.wantErr { t.Errorf("EigenDAClient.DisperseBlob() error = %v, wantErr %v", err, tt.wantErr) return } - commitment, err := EncodeCommitment(got) - fmt.Printf("%v 0x%x\n", err, commitment) + if tt.wantErr { + require.Error(t, err) + t.Logf("error: %v", err) + } + if tt.wantNetworkErr { + require.Error(t, err) + require.ErrorIs(t, err, ErrNetwork) + t.Logf("network error: %v", err) + } + if !tt.wantErr { + commitment, err := EncodeCommitment(got) + require.NoError(t, err) + fmt.Printf("%v 0x%x\n", err, commitment) + } }) } }