Skip to content

Commit ee4847d

Browse files
committed
remove double marshalling
1 parent 0bff41a commit ee4847d

File tree

6 files changed

+150
-108
lines changed

6 files changed

+150
-108
lines changed

block/internal/submitting/da_submitter.go

Lines changed: 40 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ func (s *DASubmitter) recordFailure(reason common.DASubmitterFailureReason) {
160160
}
161161

162162
// SubmitHeaders submits pending headers to DA layer
163-
func (s *DASubmitter) SubmitHeaders(ctx context.Context, headers []*types.SignedHeader, cache cache.Manager, signer signer.Signer) error {
163+
func (s *DASubmitter) SubmitHeaders(ctx context.Context, headers []*types.SignedHeader, marshalledHeaders [][]byte, cache cache.Manager, signer signer.Signer) error {
164164
if len(headers) == 0 {
165165
return nil
166166
}
@@ -169,26 +169,30 @@ func (s *DASubmitter) SubmitHeaders(ctx context.Context, headers []*types.Signed
169169
return fmt.Errorf("signer is nil")
170170
}
171171

172+
if len(marshalledHeaders) != len(headers) {
173+
return fmt.Errorf("marshalledHeaders length (%d) does not match headers length (%d)", len(marshalledHeaders), len(headers))
174+
}
175+
172176
s.logger.Info().Int("count", len(headers)).Msg("submitting headers to DA")
173177

174-
return submitToDA(s, ctx, headers,
175-
func(header *types.SignedHeader) ([]byte, error) {
176-
// A. Marshal the inner SignedHeader content to bytes (canonical representation for signing)
177-
// This effectively signs "Fields 1-3" of the intended DAHeaderEnvelope.
178-
contentBytes, err := header.MarshalBinary()
179-
if err != nil {
180-
return nil, fmt.Errorf("failed to marshal signed header for envelope signing: %w", err)
181-
}
178+
// Create DA envelopes from pre-marshalled headers
179+
envelopes := make([][]byte, len(headers))
180+
for i, header := range headers {
181+
// Sign the pre-marshalled header content
182+
envelopeSignature, err := signer.Sign(marshalledHeaders[i])
183+
if err != nil {
184+
return fmt.Errorf("failed to sign envelope for header %d: %w", i, err)
185+
}
182186

183-
// B. Sign the contentBytes with the envelope signer (aggregator)
184-
envelopeSignature, err := signer.Sign(contentBytes)
185-
if err != nil {
186-
return nil, fmt.Errorf("failed to sign envelope: %w", err)
187-
}
187+
// Create the envelope and marshal it
188+
envelope, err := header.MarshalDAEnvelope(envelopeSignature)
189+
if err != nil {
190+
return fmt.Errorf("failed to marshal DA envelope for header %d: %w", i, err)
191+
}
192+
envelopes[i] = envelope
193+
}
188194

189-
// C. Create the envelope and marshal it
190-
return header.MarshalDAEnvelope(envelopeSignature)
191-
},
195+
return submitToDA(s, ctx, headers, envelopes,
192196
func(submitted []*types.SignedHeader, res *datypes.ResultSubmit) {
193197
for _, header := range submitted {
194198
cache.SetHeaderDAIncluded(header.Hash().String(), res.Height, header.Height())
@@ -206,11 +210,15 @@ func (s *DASubmitter) SubmitHeaders(ctx context.Context, headers []*types.Signed
206210
}
207211

208212
// SubmitData submits pending data to DA layer
209-
func (s *DASubmitter) SubmitData(ctx context.Context, unsignedDataList []*types.SignedData, cache cache.Manager, signer signer.Signer, genesis genesis.Genesis) error {
213+
func (s *DASubmitter) SubmitData(ctx context.Context, unsignedDataList []*types.SignedData, marshalledData [][]byte, cache cache.Manager, signer signer.Signer, genesis genesis.Genesis) error {
210214
if len(unsignedDataList) == 0 {
211215
return nil
212216
}
213217

218+
if len(marshalledData) != len(unsignedDataList) {
219+
return fmt.Errorf("marshalledData length (%d) does not match unsignedDataList length (%d)", len(marshalledData), len(unsignedDataList))
220+
}
221+
214222
// Sign the data (cache returns unsigned SignedData structs)
215223
signedDataList, err := s.signData(unsignedDataList, signer, genesis)
216224
if err != nil {
@@ -223,10 +231,17 @@ func (s *DASubmitter) SubmitData(ctx context.Context, unsignedDataList []*types.
223231

224232
s.logger.Info().Int("count", len(signedDataList)).Msg("submitting data to DA")
225233

226-
return submitToDA(s, ctx, signedDataList,
227-
func(signedData *types.SignedData) ([]byte, error) {
228-
return signedData.MarshalBinary()
229-
},
234+
// Filter marshalledData to match signedDataList (removes empty data)
235+
filteredMarshalledData := make([][]byte, 0, len(signedDataList))
236+
signedIdx := 0
237+
for i, unsigned := range unsignedDataList {
238+
if signedIdx < len(signedDataList) && unsigned.Height() == signedDataList[signedIdx].Height() {
239+
filteredMarshalledData = append(filteredMarshalledData, marshalledData[i])
240+
signedIdx++
241+
}
242+
}
243+
244+
return submitToDA(s, ctx, signedDataList, filteredMarshalledData,
230245
func(submitted []*types.SignedData, res *datypes.ResultSubmit) {
231246
for _, sd := range submitted {
232247
cache.SetDataDAIncluded(sd.Data.DACommitment().String(), res.Height, sd.Height())
@@ -342,16 +357,15 @@ func submitToDA[T any](
342357
s *DASubmitter,
343358
ctx context.Context,
344359
items []T,
345-
marshalFn func(T) ([]byte, error),
360+
marshaled [][]byte,
346361
postSubmit func([]T, *datypes.ResultSubmit),
347362
itemType string,
348363
namespace []byte,
349364
options []byte,
350365
getTotalPendingFn func() uint64,
351366
) error {
352-
marshaled, err := marshalItems(ctx, items, marshalFn, itemType)
353-
if err != nil {
354-
return err
367+
if len(items) != len(marshaled) {
368+
return fmt.Errorf("items length (%d) does not match marshaled length (%d)", len(items), len(marshaled))
355369
}
356370

357371
pol := defaultRetryPolicy(s.config.DA.MaxSubmitAttempts, s.config.DA.BlockTime.Duration)
@@ -513,55 +527,6 @@ func limitBatchBySize[T any](items []T, marshaled [][]byte, maxBytes int) ([]T,
513527
return items[:count], marshaled[:count], nil
514528
}
515529

516-
func marshalItems[T any](
517-
parentCtx context.Context,
518-
items []T,
519-
marshalFn func(T) ([]byte, error),
520-
itemType string,
521-
) ([][]byte, error) {
522-
if len(items) == 0 {
523-
return nil, nil
524-
}
525-
marshaled := make([][]byte, len(items))
526-
ctx, cancel := context.WithCancel(parentCtx)
527-
defer cancel()
528-
529-
// Semaphore to limit concurrency to 32 workers
530-
sem := make(chan struct{}, 32)
531-
532-
// Use a channel to collect results from goroutines
533-
resultCh := make(chan error, len(items))
534-
535-
// Marshal items concurrently
536-
for i, item := range items {
537-
go func(idx int, itm T) {
538-
sem <- struct{}{}
539-
defer func() { <-sem }()
540-
541-
select {
542-
case <-ctx.Done():
543-
resultCh <- ctx.Err()
544-
default:
545-
bz, err := marshalFn(itm)
546-
if err != nil {
547-
resultCh <- fmt.Errorf("failed to marshal %s item at index %d: %w", itemType, idx, err)
548-
return
549-
}
550-
marshaled[idx] = bz
551-
resultCh <- nil
552-
}
553-
}(i, item)
554-
}
555-
556-
// Wait for all goroutines to complete and check for errors
557-
for i := 0; i < len(items); i++ {
558-
if err := <-resultCh; err != nil {
559-
return nil, err
560-
}
561-
}
562-
return marshaled, nil
563-
}
564-
565530
func waitForBackoffOrContext(ctx context.Context, backoff time.Duration) error {
566531
if backoff <= 0 {
567532
select {

block/internal/submitting/da_submitter_integration_test.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,27 @@ func TestDASubmitter_SubmitHeadersAndData_MarksInclusionAndUpdatesLastSubmitted(
101101
// Submit headers and data
102102
headers, err := cm.GetPendingHeaders(context.Background())
103103
require.NoError(t, err)
104-
require.NoError(t, daSubmitter.SubmitHeaders(context.Background(), headers, cm, n))
104+
105+
// Marshal headers
106+
marshalledHeaders := make([][]byte, len(headers))
107+
for i, h := range headers {
108+
data, err := h.MarshalBinary()
109+
require.NoError(t, err)
110+
marshalledHeaders[i] = data
111+
}
112+
require.NoError(t, daSubmitter.SubmitHeaders(context.Background(), headers, marshalledHeaders, cm, n))
105113

106114
dataList, err := cm.GetPendingData(context.Background())
107115
require.NoError(t, err)
108-
require.NoError(t, daSubmitter.SubmitData(context.Background(), dataList, cm, n, gen))
116+
117+
// Marshal data
118+
marshalledData := make([][]byte, len(dataList))
119+
for i, d := range dataList {
120+
data, err := d.MarshalBinary()
121+
require.NoError(t, err)
122+
marshalledData[i] = data
123+
}
124+
require.NoError(t, daSubmitter.SubmitData(context.Background(), dataList, marshalledData, cm, n, gen))
109125

110126
// After submission, inclusion markers should be set
111127
_, ok := cm.GetHeaderDAIncluded(hdr1.Hash().String())

block/internal/submitting/da_submitter_mocks_test.go

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,6 @@ func newTestSubmitter(t *testing.T, mockClient *mocks.MockClient, override func(
3838
return NewDASubmitter(mockClient, cfg, genesis.Genesis{} /*options=*/, common.BlockOptions{}, common.NopMetrics(), zerolog.Nop())
3939
}
4040

41-
// marshal helper for simple items
42-
func marshalString(s string) ([]byte, error) { return []byte(s), nil }
43-
4441
func TestSubmitToDA_MempoolRetry_IncreasesGasAndSucceeds(t *testing.T) {
4542
t.Parallel()
4643

@@ -68,12 +65,17 @@ func TestSubmitToDA_MempoolRetry_IncreasesGasAndSucceeds(t *testing.T) {
6865
s := newTestSubmitter(t, client, nil)
6966

7067
items := []string{"a", "b", "c"}
68+
marshalledItems := make([][]byte, 0, len(items))
69+
for idx, item := range items {
70+
marshalledItems[idx] = []byte(item)
71+
}
72+
7173
ctx := context.Background()
7274
err := submitToDA[string](
7375
s,
7476
ctx,
7577
items,
76-
marshalString,
78+
marshalledItems,
7779
func(_ []string, _ *datypes.ResultSubmit) {},
7880
"item",
7981
nsBz,
@@ -112,12 +114,17 @@ func TestSubmitToDA_UnknownError_RetriesSameGasThenSucceeds(t *testing.T) {
112114
s := newTestSubmitter(t, client, nil)
113115

114116
items := []string{"x"}
117+
marshalledItems := make([][]byte, 0, len(items))
118+
for idx, item := range items {
119+
marshalledItems[idx] = []byte(item)
120+
}
121+
115122
ctx := context.Background()
116123
err := submitToDA[string](
117124
s,
118125
ctx,
119126
items,
120-
marshalString,
127+
marshalledItems,
121128
func(_ []string, _ *datypes.ResultSubmit) {},
122129
"item",
123130
nsBz,
@@ -158,12 +165,17 @@ func TestSubmitToDA_TooBig_HalvesBatch(t *testing.T) {
158165
s := newTestSubmitter(t, client, nil)
159166

160167
items := []string{"a", "b", "c", "d"}
168+
marshalledItems := make([][]byte, 0, len(items))
169+
for idx, item := range items {
170+
marshalledItems[idx] = []byte(item)
171+
}
172+
161173
ctx := context.Background()
162174
err := submitToDA[string](
163175
s,
164176
ctx,
165177
items,
166-
marshalString,
178+
marshalledItems,
167179
func(_ []string, _ *datypes.ResultSubmit) {},
168180
"item",
169181
nsBz,
@@ -198,12 +210,17 @@ func TestSubmitToDA_SentinelNoGas_PreservesGasAcrossRetries(t *testing.T) {
198210
s := newTestSubmitter(t, client, nil)
199211

200212
items := []string{"only"}
213+
marshalledItems := make([][]byte, 0, len(items))
214+
for idx, item := range items {
215+
marshalledItems[idx] = []byte(item)
216+
}
217+
201218
ctx := context.Background()
202219
err := submitToDA[string](
203220
s,
204221
ctx,
205222
items,
206-
marshalString,
223+
marshalledItems,
207224
func(_ []string, _ *datypes.ResultSubmit) {},
208225
"item",
209226
nsBz,
@@ -237,12 +254,17 @@ func TestSubmitToDA_PartialSuccess_AdvancesWindow(t *testing.T) {
237254
s := newTestSubmitter(t, client, nil)
238255

239256
items := []string{"a", "b", "c"}
257+
marshalledItems := make([][]byte, 0, len(items))
258+
for idx, item := range items {
259+
marshalledItems[idx] = []byte(item)
260+
}
261+
240262
ctx := context.Background()
241263
err := submitToDA[string](
242264
s,
243265
ctx,
244266
items,
245-
marshalString,
267+
marshalledItems,
246268
func(submitted []string, _ *datypes.ResultSubmit) { totalSubmitted += len(submitted) },
247269
"item",
248270
nsBz,

block/internal/submitting/da_submitter_test.go

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,14 @@ func TestDASubmitter_SubmitHeaders_Success(t *testing.T) {
215215
// Get headers from cache and submit
216216
headers, err := cm.GetPendingHeaders(ctx)
217217
require.NoError(t, err)
218-
err = submitter.SubmitHeaders(ctx, headers, cm, signer)
218+
// Marshal headers
219+
marshalledHeaders := make([][]byte, len(headers))
220+
for i, h := range headers {
221+
data, err := h.MarshalBinary()
222+
require.NoError(t, err)
223+
marshalledHeaders[i] = data
224+
}
225+
err = submitter.SubmitHeaders(ctx, headers, marshalledHeaders, cm, signer)
219226
require.NoError(t, err)
220227

221228
// Verify headers are marked as DA included
@@ -237,7 +244,8 @@ func TestDASubmitter_SubmitHeaders_NoPendingHeaders(t *testing.T) {
237244
// Get headers from cache (should be empty) and submit
238245
headers, err := cm.GetPendingHeaders(ctx)
239246
require.NoError(t, err)
240-
err = submitter.SubmitHeaders(ctx, headers, cm, signer)
247+
var marshalledHeaders [][]byte
248+
err = submitter.SubmitHeaders(ctx, headers, marshalledHeaders, cm, signer)
241249
require.NoError(t, err) // Should succeed with no action
242250
mockDA.AssertNotCalled(t, "Submit", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything)
243251
}
@@ -330,9 +338,16 @@ func TestDASubmitter_SubmitData_Success(t *testing.T) {
330338
require.NoError(t, batch2.Commit())
331339

332340
// Get data from cache and submit
333-
dataList, err := cm.GetPendingData(ctx)
341+
signedDataList, err := cm.GetPendingData(ctx)
334342
require.NoError(t, err)
335-
err = submitter.SubmitData(ctx, dataList, cm, signer, gen)
343+
// Marshal data
344+
marshalledData := make([][]byte, len(signedDataList))
345+
for i, d := range signedDataList {
346+
data, err := d.MarshalBinary()
347+
require.NoError(t, err)
348+
marshalledData[i] = data
349+
}
350+
err = submitter.SubmitData(ctx, signedDataList, marshalledData, cm, signer, gen)
336351
require.NoError(t, err)
337352

338353
// Verify data is marked as DA included
@@ -383,9 +398,17 @@ func TestDASubmitter_SubmitData_SkipsEmptyData(t *testing.T) {
383398
require.NoError(t, batch.Commit())
384399

385400
// Get data from cache and submit - should succeed but skip empty data
386-
dataList, err := cm.GetPendingData(ctx)
401+
// Get data from cache and submit
402+
signedDataList, err := cm.GetPendingData(ctx)
387403
require.NoError(t, err)
388-
err = submitter.SubmitData(ctx, dataList, cm, signer, gen)
404+
// Marshal data
405+
marshalledData := make([][]byte, len(signedDataList))
406+
for i, d := range signedDataList {
407+
data, err := d.MarshalBinary()
408+
require.NoError(t, err)
409+
marshalledData[i] = data
410+
}
411+
err = submitter.SubmitData(ctx, signedDataList, marshalledData, cm, signer, gen)
389412
require.NoError(t, err)
390413
mockDA.AssertNotCalled(t, "Submit", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything)
391414

@@ -404,7 +427,8 @@ func TestDASubmitter_SubmitData_NoPendingData(t *testing.T) {
404427
// Get data from cache (should be empty) and submit
405428
dataList, err := cm.GetPendingData(ctx)
406429
require.NoError(t, err)
407-
err = submitter.SubmitData(ctx, dataList, cm, signer, gen)
430+
var marshalledData [][]byte
431+
err = submitter.SubmitData(ctx, dataList, marshalledData, cm, signer, gen)
408432
require.NoError(t, err) // Should succeed with no action
409433
mockDA.AssertNotCalled(t, "Submit", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything)
410434
}
@@ -443,9 +467,16 @@ func TestDASubmitter_SubmitData_NilSigner(t *testing.T) {
443467
require.NoError(t, batch.Commit())
444468

445469
// Get data from cache and submit with nil signer - should fail
446-
dataList, err := cm.GetPendingData(ctx)
470+
signedDataList, err := cm.GetPendingData(ctx)
447471
require.NoError(t, err)
448-
err = submitter.SubmitData(ctx, dataList, cm, nil, gen)
472+
// Marshal data
473+
marshalledData := make([][]byte, len(signedDataList))
474+
for i, d := range signedDataList {
475+
data, err := d.MarshalBinary()
476+
require.NoError(t, err)
477+
marshalledData[i] = data
478+
}
479+
err = submitter.SubmitData(ctx, signedDataList, marshalledData, cm, nil, gen)
449480
require.Error(t, err)
450481
assert.Contains(t, err.Error(), "signer is nil")
451482
mockDA.AssertNotCalled(t, "Submit", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything)

0 commit comments

Comments
 (0)