diff --git a/api/clients/codecs/blob_codec.go b/api/clients/codecs/blob_codec.go index 242c01afa9..94e19a1328 100644 --- a/api/clients/codecs/blob_codec.go +++ b/api/clients/codecs/blob_codec.go @@ -20,8 +20,26 @@ type BlobCodec interface { func BlobEncodingVersionToCodec(version BlobEncodingVersion) (BlobCodec, error) { switch version { case DefaultBlobEncoding: - return DefaultBlobEncodingCodec{}, nil + return DefaultBlobCodec{}, nil default: return nil, fmt.Errorf("unsupported blob encoding version: %x", version) } } + +func GenericDecodeBlob(data []byte) ([]byte, error) { + if len(data) <= 32 { + return nil, fmt.Errorf("data is not of length greater than 32 bytes: %d", len(data)) + } + version := BlobEncodingVersion(data[1]) + codec, err := BlobEncodingVersionToCodec(version) + if err != nil { + return nil, err + } + + data, err = codec.DecodeBlob(data) + if err != nil { + return nil, err + } + + return data, nil +} diff --git a/api/clients/codecs/encodings_test.go b/api/clients/codecs/blob_codec_test.go similarity index 50% rename from api/clients/codecs/encodings_test.go rename to api/clients/codecs/blob_codec_test.go index 1700046277..9e0867fee4 100644 --- a/api/clients/codecs/encodings_test.go +++ b/api/clients/codecs/blob_codec_test.go @@ -19,10 +19,45 @@ func randomByteSlice(length int64) []byte { return b } -// TestDefaultBlobEncodingCodec tests the encoding and decoding of random byte streams -func TestDefaultBlobEncodingCodec(t *testing.T) { +// TestIFFTCodec tests the encoding and decoding of random byte streams +func TestIFFTCodec(t *testing.T) { // Create an instance of the DefaultBlobEncodingCodec - codec := codecs.DefaultBlobEncodingCodec{} + codec := codecs.NewIFFTCodec(codecs.NewDefaultBlobCodec()) + + // Number of test iterations + const iterations = 100 + + for i := 0; i < iterations; i++ { + // Generate a random length for the byte slice + length, err := rand.Int(rand.Reader, big.NewInt(1024)) // Random length between 0 and 1023 + if err != nil { + panic(err) + } + originalData := randomByteSlice(length.Int64() + 1) // ensure it's not length 0 + + // Encode the original data + encodedData, err := codec.EncodeBlob(originalData) + if err != nil { + t.Fatalf("Iteration %d: failed to encode blob: %v", i, err) + } + + // Decode the encoded data + decodedData, err := codec.DecodeBlob(encodedData) + if err != nil { + t.Fatalf("Iteration %d: failed to decode blob: %v", i, err) + } + + // Compare the original data with the decoded data + if !bytes.Equal(originalData, decodedData) { + t.Fatalf("Iteration %d: original and decoded data do not match\nOriginal: %v\nDecoded: %v", i, originalData, decodedData) + } + } +} + +// TestIFFTCodec tests the encoding and decoding of random byte streams +func TestNoIFFTCodec(t *testing.T) { + // Create an instance of the DefaultBlobEncodingCodec + codec := codecs.NewNoIFFTCodec(codecs.NewDefaultBlobCodec()) // Number of test iterations const iterations = 100 diff --git a/api/clients/codecs/default_blob_codec.go b/api/clients/codecs/default_blob_codec.go new file mode 100644 index 0000000000..7cc33fc423 --- /dev/null +++ b/api/clients/codecs/default_blob_codec.go @@ -0,0 +1,59 @@ +package codecs + +import ( + "bytes" + "encoding/binary" + "fmt" + + "github.com/Layr-Labs/eigenda/encoding/utils/codec" +) + +type DefaultBlobCodec struct{} + +var _ BlobCodec = DefaultBlobCodec{} + +func NewDefaultBlobCodec() DefaultBlobCodec { + return DefaultBlobCodec{} +} + +func (v DefaultBlobCodec) EncodeBlob(rawData []byte) ([]byte, error) { + codecBlobHeader := make([]byte, 32) + // first byte is always 0 to ensure the codecBlobHeader is a valid bn254 element + // encode version byte + codecBlobHeader[1] = byte(DefaultBlobEncoding) + + // encode length as uint32 + binary.BigEndian.PutUint32(codecBlobHeader[2:6], uint32(len(rawData))) // uint32 should be more than enough to store the length (approx 4gb) + + // encode raw data modulo bn254 + rawDataPadded := codec.ConvertByPaddingEmptyByte(rawData) + + // append raw data + encodedData := append(codecBlobHeader, rawDataPadded...) + + return encodedData, nil +} + +func (v DefaultBlobCodec) DecodeBlob(data []byte) ([]byte, error) { + if len(data) < 32 { + return nil, fmt.Errorf("blob does not contain 32 header bytes, meaning it is malformed") + } + + length := binary.BigEndian.Uint32(data[2:6]) + + // decode raw data modulo bn254 + decodedData := codec.RemoveEmptyByteFromPaddedBytes(data[32:]) + + // get non blob header data + reader := bytes.NewReader(decodedData) + rawData := make([]byte, length) + n, err := reader.Read(rawData) + if err != nil { + return nil, fmt.Errorf("failed to copy unpadded data into final buffer, length: %d, bytes read: %d", length, n) + } + if uint32(n) != length { + return nil, fmt.Errorf("data length does not match length prefix") + } + + return rawData, nil +} diff --git a/api/clients/codecs/default_blob_encoding_codec.go b/api/clients/codecs/default_blob_encoding_codec.go deleted file mode 100644 index 67964a498b..0000000000 --- a/api/clients/codecs/default_blob_encoding_codec.go +++ /dev/null @@ -1,49 +0,0 @@ -package codecs - -import ( - "bytes" - "fmt" - - "github.com/Layr-Labs/eigenda/encoding/utils/codec" -) - -type DefaultBlobEncodingCodec struct{} - -var _ BlobCodec = DefaultBlobEncodingCodec{} - -func (v DefaultBlobEncodingCodec) EncodeBlob(rawData []byte) ([]byte, error) { - // encode blob encoding version byte - codecBlobHeader := EncodeCodecBlobHeader(byte(DefaultBlobEncoding), uint32(len(rawData))) - - // encode raw data modulo bn254 - rawDataPadded := codec.ConvertByPaddingEmptyByte(rawData) - - // append raw data - encodedData := append(codecBlobHeader, rawDataPadded...) - - return encodedData, nil -} - -func (v DefaultBlobEncodingCodec) DecodeBlob(encodedData []byte) ([]byte, error) { - - _, length, err := DecodeCodecBlobHeader(encodedData[:32]) - if err != nil { - return nil, err - } - - // decode raw data modulo bn254 - decodedData := codec.RemoveEmptyByteFromPaddedBytes(encodedData[32:]) - - // get non blob header data - reader := bytes.NewReader(decodedData) - rawData := make([]byte, length) - n, err := reader.Read(rawData) - if err != nil { - return nil, fmt.Errorf("failed to copy unpadded data into final buffer, length: %d, bytes read: %d", length, n) - } - if uint32(n) != length { - return nil, fmt.Errorf("data length does not match length prefix") - } - - return rawData, nil -} diff --git a/api/clients/eigenda_client_utils.go b/api/clients/codecs/fft.go similarity index 99% rename from api/clients/eigenda_client_utils.go rename to api/clients/codecs/fft.go index b7121460c5..a190d29d4e 100644 --- a/api/clients/eigenda_client_utils.go +++ b/api/clients/codecs/fft.go @@ -1,4 +1,4 @@ -package clients +package codecs import ( "fmt" diff --git a/api/clients/codecs/ifft_codec.go b/api/clients/codecs/ifft_codec.go new file mode 100644 index 0000000000..edd5040d46 --- /dev/null +++ b/api/clients/codecs/ifft_codec.go @@ -0,0 +1,38 @@ +package codecs + +import "fmt" + +type IFFTCodec struct { + writeCodec BlobCodec +} + +var _ BlobCodec = IFFTCodec{} + +func NewIFFTCodec(writeCodec BlobCodec) IFFTCodec { + return IFFTCodec{ + writeCodec: writeCodec, + } +} + +func (v IFFTCodec) EncodeBlob(data []byte) ([]byte, error) { + var err error + data, err = v.writeCodec.EncodeBlob(data) + if err != nil { + return nil, fmt.Errorf("error encoding data: %w", err) + } + + return IFFT(data) +} + +func (v IFFTCodec) DecodeBlob(data []byte) ([]byte, error) { + if len(data) == 0 { + return nil, fmt.Errorf("blob has length 0, meaning it is malformed") + } + var err error + data, err = FFT(data) + if err != nil { + return nil, fmt.Errorf("error FFTing data: %w", err) + } + + return GenericDecodeBlob(data) +} diff --git a/api/clients/codecs/no_ifft_codec.go b/api/clients/codecs/no_ifft_codec.go new file mode 100644 index 0000000000..372bbfbcd3 --- /dev/null +++ b/api/clients/codecs/no_ifft_codec.go @@ -0,0 +1,21 @@ +package codecs + +type NoIFFTCodec struct { + writeCodec BlobCodec +} + +var _ BlobCodec = NoIFFTCodec{} + +func NewNoIFFTCodec(writeCodec BlobCodec) NoIFFTCodec { + return NoIFFTCodec{ + writeCodec: writeCodec, + } +} + +func (v NoIFFTCodec) EncodeBlob(data []byte) ([]byte, error) { + return v.writeCodec.EncodeBlob(data) +} + +func (v NoIFFTCodec) DecodeBlob(data []byte) ([]byte, error) { + return GenericDecodeBlob(data) +} diff --git a/api/clients/codecs/utils.go b/api/clients/codecs/utils.go deleted file mode 100644 index 5d9008d980..0000000000 --- a/api/clients/codecs/utils.go +++ /dev/null @@ -1,30 +0,0 @@ -package codecs - -import ( - "encoding/binary" - "fmt" -) - -func EncodeCodecBlobHeader(version byte, length uint32) []byte { - codecBlobHeader := make([]byte, 32) - // first byte is always 0 to ensure the codecBlobHeader is a valid bn254 element - // encode version byte - codecBlobHeader[1] = version - - // encode length as uint32 - binary.BigEndian.PutUint32(codecBlobHeader[2:6], length) // uint32 should be more than enough to store the length (approx 4gb) - return codecBlobHeader -} - -func DecodeCodecBlobHeader(codecBlobHeader []byte) (byte, uint32, error) { - // make sure the codecBlobHeader is 32 bytes long - if len(codecBlobHeader) != 32 { - err := fmt.Errorf("codecBlobHeader must be exactly 32 bytes long, but got %d bytes", len(codecBlobHeader)) - return 0, 0, err - } - - version := codecBlobHeader[1] - length := binary.BigEndian.Uint32(codecBlobHeader[2:6]) - - return version, length, nil -} diff --git a/api/clients/eigenda_client.go b/api/clients/eigenda_client.go index 48e015c77b..ae6ff078fd 100644 --- a/api/clients/eigenda_client.go +++ b/api/clients/eigenda_client.go @@ -16,15 +16,16 @@ import ( ) type IEigenDAClient interface { - GetBlob(ctx context.Context, BatchHeaderHash []byte, BlobIndex uint32) ([]byte, error) + GetBlob(ctx context.Context, batchHeaderHash []byte, blobIndex uint32) ([]byte, error) PutBlob(ctx context.Context, txData []byte) (*grpcdisperser.BlobInfo, error) + GetCodec() codecs.BlobCodec } type EigenDAClient struct { - Config EigenDAClientConfig - Log log.Logger - Client DisperserClient - PutCodec codecs.BlobCodec + Config EigenDAClientConfig + Log log.Logger + Client DisperserClient + Codec codecs.BlobCodec } var _ IEigenDAClient = EigenDAClient{} @@ -44,21 +45,38 @@ func NewEigenDAClient(log log.Logger, config EigenDAClientConfig) (*EigenDAClien llConfig := NewConfig(host, port, config.ResponseTimeout, !config.DisableTLS) llClient := NewDisperserClient(llConfig, signer) - codec, err := codecs.BlobEncodingVersionToCodec(config.PutBlobEncodingVersion) + lowLevelCodec, err := codecs.BlobEncodingVersionToCodec(config.PutBlobEncodingVersion) if err != nil { return nil, fmt.Errorf("error initializing EigenDA client: %w", err) } + var codec codecs.BlobCodec + if config.DisablePointVerificationMode { + codec = codecs.NewNoIFFTCodec(lowLevelCodec) + } else { + codec = codecs.NewIFFTCodec(lowLevelCodec) + } + return &EigenDAClient{ - Log: log, - Config: config, - Client: llClient, - PutCodec: codec, + Log: log, + Config: config, + Client: llClient, + Codec: codec, }, nil } -func (m EigenDAClient) GetBlob(ctx context.Context, BatchHeaderHash []byte, BlobIndex uint32) ([]byte, error) { - data, err := m.Client.RetrieveBlob(ctx, BatchHeaderHash, BlobIndex) +func (m EigenDAClient) GetCodec() codecs.BlobCodec { + return m.Codec +} + +// GetBlob retrieves a blob from the EigenDA service using the provided context, +// batch header hash, and blob index. If decode is set to true, the function +// decodes the retrieved blob data. If set to false it returns the encoded blob +// data, which is necessary for generating KZG proofs for data's correctness. +// The function handles potential errors during blob retrieval, data length +// checks, and decoding processes. +func (m EigenDAClient) GetBlob(ctx context.Context, batchHeaderHash []byte, blobIndex uint32) ([]byte, error) { + data, err := m.Client.RetrieveBlob(ctx, batchHeaderHash, blobIndex) if err != nil { return nil, err } @@ -67,26 +85,7 @@ func (m EigenDAClient) GetBlob(ctx context.Context, BatchHeaderHash []byte, Blob return nil, fmt.Errorf("blob has length zero") } - if !m.Config.DisablePointVerificationMode { - // we assume the data is already IFFT'd so we FFT it before decoding - data, err = FFT(data) - if err != nil { - return nil, fmt.Errorf("error FFTing data: %w", err) - } - } - - // get version and length from codec blob header - version, _, err := codecs.DecodeCodecBlobHeader(data[:32]) - if err != nil { - return nil, fmt.Errorf("error getting blob: %w", err) - } - - codec, err := codecs.BlobEncodingVersionToCodec(codecs.BlobEncodingVersion(version)) - if err != nil { - return nil, fmt.Errorf("error getting blob: %w", err) - } - - decodedData, err := codec.DecodeBlob(data) + decodedData, err := m.Codec.DecodeBlob(data) if err != nil { return nil, fmt.Errorf("error getting blob: %w", err) } @@ -94,6 +93,9 @@ func (m EigenDAClient) GetBlob(ctx context.Context, BatchHeaderHash []byte, Blob return decodedData, nil } +// PutBlob encodes and writes a blob to EigenDA, waiting for it to be finalized +// before returning. This function is resiliant to transient failures and +// timeouts. func (m EigenDAClient) PutBlob(ctx context.Context, data []byte) (*grpcdisperser.BlobInfo, error) { resultChan, errorChan := m.PutBlobAsync(ctx, data) select { // no timeout here because we depend on the configured timeout in PutBlobAsync @@ -115,25 +117,17 @@ func (m EigenDAClient) putBlob(ctx context.Context, rawData []byte, resultChan c m.Log.Info("Attempting to disperse blob to EigenDA") // encode blob - if m.PutCodec == nil { - errChan <- fmt.Errorf("PutCodec cannot be nil") + if m.Codec == nil { + errChan <- fmt.Errorf("Codec cannot be nil") return } - data, err := m.PutCodec.EncodeBlob(rawData) + + data, err := m.Codec.EncodeBlob(rawData) if err != nil { errChan <- fmt.Errorf("error encoding blob: %w", err) return } - if !m.Config.DisablePointVerificationMode { - // convert data to fr.Element - data, err = IFFT(data) - if err != nil { - errChan <- fmt.Errorf("error IFFTing data: %w", err) - return - } - } - customQuorumNumbers := make([]uint8, len(m.Config.CustomQuorumIDs)) for i, e := range m.Config.CustomQuorumIDs { customQuorumNumbers[i] = uint8(e) diff --git a/api/clients/eigenda_client_testnet_test.go b/api/clients/eigenda_client_e2e_test.go similarity index 100% rename from api/clients/eigenda_client_testnet_test.go rename to api/clients/eigenda_client_e2e_test.go diff --git a/api/clients/eigenda_client_test.go b/api/clients/eigenda_client_test.go index 68aba1763c..39b64da0fd 100644 --- a/api/clients/eigenda_client_test.go +++ b/api/clients/eigenda_client_test.go @@ -69,8 +69,8 @@ func TestPutRetrieveBlobIFFTSuccess(t *testing.T) { PutBlobEncodingVersion: codecs.DefaultBlobEncoding, DisablePointVerificationMode: false, }, - Client: disperserClient, - PutCodec: codecs.DefaultBlobEncodingCodec{}, + Client: disperserClient, + Codec: codecs.NewIFFTCodec(codecs.NewDefaultBlobCodec()), } expectedBlob := []byte("dc49e7df326cfb2e7da5cf68f263e1898443ec2e862350606e7dfbda55ad10b5d61ed1d54baf6ae7a86279c1b4fa9c49a7de721dacb211264c1f5df31bade51c") blobInfo, err := eigendaClient.PutBlob(context.Background(), expectedBlob) @@ -83,6 +83,76 @@ func TestPutRetrieveBlobIFFTSuccess(t *testing.T) { require.Equal(t, expectedBlob, resultBlob) } +func TestPutRetrieveBlobIFFTNoDecodeSuccess(t *testing.T) { + disperserClient := clientsmock.NewMockDisperserClient() + expectedBlobStatus := disperser.Processing + (disperserClient.On("DisperseBlobAuthenticated", mock.Anything, mock.Anything, mock.Anything). + Return(&expectedBlobStatus, []byte("mock-request-id"), nil)) + (disperserClient.On("GetBlobStatus", mock.Anything, mock.Anything). + Return(&grpcdisperser.BlobStatusReply{Status: grpcdisperser.BlobStatus_PROCESSING}, nil).Once()) + (disperserClient.On("GetBlobStatus", mock.Anything, mock.Anything). + Return(&grpcdisperser.BlobStatusReply{Status: grpcdisperser.BlobStatus_DISPERSING}, nil).Once()) + (disperserClient.On("GetBlobStatus", mock.Anything, mock.Anything). + Return(&grpcdisperser.BlobStatusReply{Status: grpcdisperser.BlobStatus_CONFIRMED}, nil).Once()) + finalizedBlobInfo := &grpcdisperser.BlobInfo{ + BlobHeader: &grpcdisperser.BlobHeader{ + Commitment: &common.G1Commitment{X: []byte{0x00, 0x00, 0x00, 0x00}, Y: []byte{0x01, 0x00, 0x00, 0x00}}, + BlobQuorumParams: []*grpcdisperser.BlobQuorumParam{ + { + QuorumNumber: 0, + }, + { + QuorumNumber: 1, + }, + }, + }, + BlobVerificationProof: &grpcdisperser.BlobVerificationProof{ + BlobIndex: 100, + BatchMetadata: &grpcdisperser.BatchMetadata{ + BatchHeaderHash: []byte("mock-batch-header-hash"), + BatchHeader: &grpcdisperser.BatchHeader{ + ReferenceBlockNumber: 200, + }, + }, + }, + } + (disperserClient.On("GetBlobStatus", mock.Anything, mock.Anything). + Return(&grpcdisperser.BlobStatusReply{Status: grpcdisperser.BlobStatus_FINALIZED, Info: finalizedBlobInfo}, nil).Once()) + (disperserClient.On("RetrieveBlob", mock.Anything, mock.Anything, mock.Anything). + Return(nil, nil).Once()) // pass nil in as the return blob to tell the mock to return the corresponding blob + logger := log.NewLogger(log.DiscardHandler()) + eigendaClient := clients.EigenDAClient{ + Log: logger, + Config: clients.EigenDAClientConfig{ + RPC: "localhost:51001", + StatusQueryTimeout: 10 * time.Minute, + StatusQueryRetryInterval: 50 * time.Millisecond, + ResponseTimeout: 10 * time.Second, + CustomQuorumIDs: []uint{}, + SignerPrivateKeyHex: "75f9e29cac7f5774d106adb355ef294987ce39b7863b75bb3f2ea42ca160926d", + DisableTLS: false, + PutBlobEncodingVersion: codecs.DefaultBlobEncoding, + DisablePointVerificationMode: false, + }, + Client: disperserClient, + Codec: codecs.NewIFFTCodec(codecs.NewDefaultBlobCodec()), + } + expectedBlob := []byte("dc49e7df326cfb2e7da5cf68f263e1898443ec2e862350606e7dfbda55ad10b5d61ed1d54baf6ae7a86279c1b4fa9c49a7de721dacb211264c1f5df31bade51c") + blobInfo, err := eigendaClient.PutBlob(context.Background(), expectedBlob) + require.NoError(t, err) + require.NotNil(t, blobInfo) + assert.Equal(t, finalizedBlobInfo, blobInfo) + + resultBlob, err := eigendaClient.GetBlob(context.Background(), []byte("mock-batch-header-hash"), 100) + require.NoError(t, err) + encodedBlob, err := eigendaClient.GetCodec().EncodeBlob(resultBlob) + require.NoError(t, err) + + resultBlob, err = codecs.NewIFFTCodec(codecs.NewDefaultBlobCodec()).DecodeBlob(encodedBlob) + require.NoError(t, err) + require.Equal(t, expectedBlob, resultBlob) +} + func TestPutRetrieveBlobNoIFFTSuccess(t *testing.T) { disperserClient := clientsmock.NewMockDisperserClient() expectedBlobStatus := disperser.Processing @@ -134,8 +204,8 @@ func TestPutRetrieveBlobNoIFFTSuccess(t *testing.T) { PutBlobEncodingVersion: codecs.DefaultBlobEncoding, DisablePointVerificationMode: true, }, - Client: disperserClient, - PutCodec: codecs.DefaultBlobEncodingCodec{}, + Client: disperserClient, + Codec: codecs.NewNoIFFTCodec(codecs.NewDefaultBlobCodec()), } expectedBlob := []byte("dc49e7df326cfb2e7da5cf68f263e1898443ec2e862350606e7dfbda55ad10b5d61ed1d54baf6ae7a86279c1b4fa9c49a7de721dacb211264c1f5df31bade51c") blobInfo, err := eigendaClient.PutBlob(context.Background(), expectedBlob) @@ -165,8 +235,8 @@ func TestPutBlobFailDispersal(t *testing.T) { DisableTLS: false, PutBlobEncodingVersion: codecs.DefaultBlobEncoding, }, - Client: disperserClient, - PutCodec: codecs.DefaultBlobEncodingCodec{}, + Client: disperserClient, + Codec: codecs.NewIFFTCodec(codecs.NewDefaultBlobCodec()), } blobInfo, err := eigendaClient.PutBlob(context.Background(), []byte("hello")) require.Error(t, err) @@ -197,8 +267,8 @@ func TestPutBlobFailureInsufficentSignatures(t *testing.T) { DisableTLS: false, PutBlobEncodingVersion: codecs.DefaultBlobEncoding, }, - Client: disperserClient, - PutCodec: codecs.DefaultBlobEncodingCodec{}, + Client: disperserClient, + Codec: codecs.NewIFFTCodec(codecs.NewDefaultBlobCodec()), } blobInfo, err := eigendaClient.PutBlob(context.Background(), []byte("hello")) require.Error(t, err) @@ -229,8 +299,8 @@ func TestPutBlobFailureGeneral(t *testing.T) { DisableTLS: false, PutBlobEncodingVersion: codecs.DefaultBlobEncoding, }, - Client: disperserClient, - PutCodec: codecs.DefaultBlobEncodingCodec{}, + Client: disperserClient, + Codec: codecs.NewIFFTCodec(codecs.NewDefaultBlobCodec()), } blobInfo, err := eigendaClient.PutBlob(context.Background(), []byte("hello")) require.Error(t, err) @@ -261,8 +331,8 @@ func TestPutBlobFailureUnknown(t *testing.T) { DisableTLS: false, PutBlobEncodingVersion: codecs.DefaultBlobEncoding, }, - Client: disperserClient, - PutCodec: codecs.DefaultBlobEncodingCodec{}, + Client: disperserClient, + Codec: codecs.NewIFFTCodec(codecs.NewDefaultBlobCodec()), } blobInfo, err := eigendaClient.PutBlob(context.Background(), []byte("hello")) require.Error(t, err) @@ -295,8 +365,8 @@ func TestPutBlobFinalizationTimeout(t *testing.T) { DisableTLS: false, PutBlobEncodingVersion: codecs.DefaultBlobEncoding, }, - Client: disperserClient, - PutCodec: codecs.DefaultBlobEncodingCodec{}, + Client: disperserClient, + Codec: codecs.NewIFFTCodec(codecs.NewDefaultBlobCodec()), } blobInfo, err := eigendaClient.PutBlob(context.Background(), []byte("hello")) require.Error(t, err) @@ -354,8 +424,8 @@ func TestPutBlobIndividualRequestTimeout(t *testing.T) { DisableTLS: false, PutBlobEncodingVersion: codecs.DefaultBlobEncoding, }, - Client: disperserClient, - PutCodec: codecs.DefaultBlobEncodingCodec{}, + Client: disperserClient, + Codec: codecs.NewIFFTCodec(codecs.NewDefaultBlobCodec()), } blobInfo, err := eigendaClient.PutBlob(context.Background(), []byte("hello")) @@ -416,8 +486,8 @@ func TestPutBlobTotalTimeout(t *testing.T) { DisableTLS: false, PutBlobEncodingVersion: codecs.DefaultBlobEncoding, }, - Client: disperserClient, - PutCodec: codecs.DefaultBlobEncodingCodec{}, + Client: disperserClient, + Codec: codecs.NewIFFTCodec(codecs.NewDefaultBlobCodec()), } blobInfo, err := eigendaClient.PutBlob(context.Background(), []byte("hello"))