@@ -46,9 +46,7 @@ func (tx Tx) MarshalDelimited() ([]byte, error) {
46
46
lenBuf := make ([]byte , binary .MaxVarintLen64 )
47
47
length := uint64 (len (tx ))
48
48
n := binary .PutUvarint (lenBuf , length )
49
- out := append (lenBuf [:n ], tx ... )
50
-
51
- return out , nil
49
+ return append (lenBuf [:n ], tx ... ), nil
52
50
}
53
51
54
52
// MarshalDelimited marshals the raw data (excluding the namespace) of this
@@ -88,10 +86,12 @@ func splitContiguous(nid namespace.ID, rawDatas [][]byte) []NamespacedShare {
88
86
innerIndex := 0
89
87
for outerIndex < len (rawDatas ) {
90
88
var rawData []byte
91
- rawData , outerIndex , innerIndex , _ = getNextChunk (rawDatas , outerIndex , innerIndex , MsgShareSize )
92
- rawShare := append (append (
93
- make ([]byte , 0 , MsgShareSize ),
89
+ startIndex := 0
90
+ rawData , outerIndex , innerIndex , startIndex = getNextChunk (rawDatas , outerIndex , innerIndex , MsgShareSize )
91
+ rawShare := append (append (append (
92
+ make ([]byte , 0 , len (nid )+ 1 + len (rawData )),
94
93
nid ... ),
94
+ byte (startIndex )),
95
95
rawData ... )
96
96
paddedShare := zeroPadIfNecessary (rawShare , ShareSize )
97
97
share := NamespacedShare {paddedShare , nid }
@@ -211,16 +211,16 @@ func DataFromSquare(eds *rsmt2d.ExtendedDataSquare) (Data, error) {
211
211
share := eds .Cell (x , y )
212
212
nid := share [:NamespaceSize ]
213
213
switch {
214
- case bytes .Compare (TxNamespaceID , nid ) == 0 :
214
+ case bytes .Equal (TxNamespaceID , nid ):
215
215
txsShares = append (txsShares , share )
216
216
217
- case bytes .Compare (IntermediateStateRootsNamespaceID , nid ) == 0 :
217
+ case bytes .Equal (IntermediateStateRootsNamespaceID , nid ):
218
218
isrShares = append (isrShares , share )
219
219
220
- case bytes .Compare (EvidenceNamespaceID , nid ) == 0 :
220
+ case bytes .Equal (EvidenceNamespaceID , nid ):
221
221
evdShares = append (evdShares , share )
222
222
223
- case bytes .Compare (TailPaddingNamespaceID , nid ) == 0 :
223
+ case bytes .Equal (TailPaddingNamespaceID , nid ):
224
224
continue
225
225
226
226
// every other namespaceID should be a message
@@ -231,9 +231,15 @@ func DataFromSquare(eds *rsmt2d.ExtendedDataSquare) (Data, error) {
231
231
}
232
232
233
233
// pass the raw share data to their respective parsers
234
- txs := parseTxs (txsShares )
234
+ txs , err := parseTxs (txsShares )
235
+ if err != nil {
236
+ return Data {}, err
237
+ }
235
238
236
- isrs := parseIsrs (isrShares )
239
+ isrs , err := parseIsrs (isrShares )
240
+ if err != nil {
241
+ return Data {}, err
242
+ }
237
243
238
244
evd , err := parseEvd (evdShares )
239
245
if err != nil {
@@ -253,33 +259,44 @@ func DataFromSquare(eds *rsmt2d.ExtendedDataSquare) (Data, error) {
253
259
}, nil
254
260
}
255
261
256
- func parseTxs (shares [][]byte ) Txs {
262
+ // parseTxs collects all of the transactions from the shares provided
263
+ func parseTxs (shares [][]byte ) (Txs , error ) {
257
264
// parse the sharse
258
- rawTxs := parseShares (shares )
265
+ rawTxs , err := processContiguousShares (shares )
266
+ if err != nil {
267
+ return nil , err
268
+ }
259
269
260
270
// convert to the Tx type
261
271
txs := make (Txs , len (rawTxs ))
262
272
for i := 0 ; i < len (txs ); i ++ {
263
273
txs [i ] = Tx (rawTxs [i ])
264
274
}
265
275
266
- return txs
276
+ return txs , nil
267
277
}
268
278
269
- func parseIsrs (shares [][]byte ) IntermediateStateRoots {
270
- rawISRs := parseShares (shares )
279
+ // parseIsrs collects all the intermediate state roots from the shares provided
280
+ func parseIsrs (shares [][]byte ) (IntermediateStateRoots , error ) {
281
+ rawISRs , err := processContiguousShares (shares )
282
+ if err != nil {
283
+ return IntermediateStateRoots {}, err
284
+ }
271
285
272
286
ISRs := make ([]tmbytes.HexBytes , len (rawISRs ))
273
287
for i := 0 ; i < len (ISRs ); i ++ {
274
288
ISRs [i ] = rawISRs [i ]
275
289
}
276
290
277
- return IntermediateStateRoots {RawRootsList : ISRs }
291
+ return IntermediateStateRoots {RawRootsList : ISRs }, nil
278
292
}
279
293
280
- // parseMsgs collects all messages from the shares provided
294
+ // parseMsgs collects all evidence from the shares provided
281
295
func parseEvd (shares [][]byte ) (EvidenceData , error ) {
282
- rawEvd := parseShares (shares )
296
+ rawEvd , err := processContiguousShares (shares )
297
+ if err != nil {
298
+ return EvidenceData {}, err
299
+ }
283
300
284
301
evdList := make (EvidenceList , len (rawEvd ))
285
302
@@ -315,90 +332,59 @@ func parseMsgs(shares [][]byte) (Messages, error) {
315
332
}, nil
316
333
}
317
334
318
- // parseShares iterates through raw shares and separates the contiguous chunks
319
- // of data. we use this for transactions, evidence, and intermediate state roots
320
- func parseShares (shares [][]byte ) [][]byte {
321
- currentShare := shares [0 ][NamespaceSize + ShareReservedBytes :]
322
- txLen := uint8 (shares [0 ][NamespaceSize ])
323
- var parsed [][]byte
324
- for cursor := 0 ; cursor < len (shares ); {
325
- var p []byte
326
-
327
- currentShare , cursor , txLen , p = next (shares , currentShare , cursor , txLen )
328
- if p != nil {
329
- parsed = append (parsed , p )
330
- }
335
+ func processContiguousShares (shares [][]byte ) (txs [][]byte , err error ) {
336
+ share := shares [0 ][NamespaceSize + ShareReservedBytes :]
337
+ share , txLen , err := parseDelimiter (share )
338
+ if err != nil {
339
+ return nil , err
331
340
}
332
341
333
- return parsed
334
- }
335
-
336
- // next returns the next chunk of a contiguous share. Used for parsing
337
- // transaction, evidence, and intermediate state root block data.
338
- func next (shares [][]byte , current []byte , cursor int , l uint8 ) ([]byte , int , uint8 , []byte ) {
339
- switch {
340
- // the rest of the shares should be tail padding
341
- case l == 0 :
342
-
343
- cursor ++
344
- if len (shares ) != cursor {
345
- panic ("contiguous share of length zero" )
342
+ for i := 0 ; i < len (shares ); i ++ {
343
+ var newTxs [][]byte
344
+ newTxs , share , txLen , err = collectTxFromShare (share , txLen )
345
+ if err != nil {
346
+ return nil , err
346
347
}
347
- return nil , cursor , 0 , nil
348
-
349
- // the tx is contained in the current share
350
- case int (l ) < len (current ):
351
348
352
- tx : = append (make ([] byte , 0 , l ), current [: l ] ... )
349
+ txs = append (txs , newTxs ... )
353
350
354
- // set the next txLen and update the next share
355
- txLen := current [l ]
356
-
357
- // make sure that nothing panics if txLen is at the end of the share
358
- if len (current ) < int (l )+ ShareReservedBytes + 1 {
359
- cursor ++
360
- return shares [cursor ][NamespaceSize :], cursor , txLen , tx
351
+ // if there is no next share
352
+ if len (shares ) <= i + 1 {
353
+ break
361
354
}
362
355
363
- current := current [l + ShareReservedBytes :]
364
- // try printing current everytime instead
365
-
366
- return current , cursor , txLen , tx
356
+ nextShare := shares [i + 1 ][NamespaceSize + ShareReservedBytes :]
367
357
368
- // the tx requires some portion of the following share
369
- case int (l ) > len (current ):
370
-
371
- cursor ++
372
-
373
- // merge the current and the next share
374
-
375
- current := append (current , shares [cursor ][NamespaceSize :]... )
376
-
377
- // try again using the next share
378
- return next (shares , current , cursor , l )
379
-
380
- // the tx is exactly the same size of the current share
381
- case int (l ) == len (current ):
358
+ // if there is no current share, process the next share
359
+ if len (share ) == 0 {
360
+ share , txLen , err = parseDelimiter (nextShare )
361
+ continue
362
+ }
382
363
383
- tx := make ([]byte , l )
384
- copy (tx , current )
364
+ // create the next share by merging the next share with the extra
365
+ share = append (share , shares [i + 1 ][NamespaceSize + ShareReservedBytes :]... )
366
+ }
385
367
386
- cursor ++
368
+ return txs , nil
369
+ }
387
370
388
- // if this is the end of shares only return the tx
389
- if cursor == len (shares ) {
390
- return []byte {}, cursor , 0 , tx
371
+ func collectTxFromShare (share []byte , txLen uint64 ) (txs [][]byte , extra []byte , l uint64 , err error ) {
372
+ for uint64 (len (share )) >= txLen {
373
+ tx := share [:txLen ]
374
+ if len (tx ) == 0 {
375
+ share = nil
376
+ break
391
377
}
392
378
393
- // set the next txLen and next share
394
- next := shares [cursor ][NamespaceSize + ShareReservedBytes :]
395
- nextTxLen := shares [cursor ][NamespaceSize ]
379
+ txs = append (txs , tx )
380
+ share = share [txLen :]
396
381
397
- return next , cursor , nextTxLen , tx
382
+ share , txLen , err = parseDelimiter (share )
383
+ if txLen == 0 {
384
+ break
385
+ }
398
386
}
399
-
400
- // this code is unreachable but the compiler doesn't know that
401
- return nil , 0 , 0 , nil
387
+ return txs , share , txLen , nil
402
388
}
403
389
404
390
// parseMessages iterates through raw shares and separates the contiguous chunks
@@ -409,15 +395,15 @@ func parseMsgShares(shares [][]byte) ([]Message, error) {
409
395
currentShare := shares [0 ][NamespaceSize :]
410
396
411
397
// find and remove the msg len delimiter
412
- currentShare , msgLen , err := tailorMsg (currentShare )
398
+ currentShare , msgLen , err := parseDelimiter (currentShare )
413
399
if err != nil {
414
400
return nil , err
415
401
}
416
402
417
403
var msgs []Message
418
- for cursor := 0 ; cursor < len (shares ); {
404
+ for cursor := uint64 ( 0 ) ; cursor < uint64 ( len (shares ) ); {
419
405
var msg Message
420
- currentShare , cursor , msgLen , msg , err = nextMsg (
406
+ currentShare , nid , cursor , msgLen , msg , err = nextMsg (
421
407
shares ,
422
408
currentShare ,
423
409
nid ,
@@ -435,69 +421,48 @@ func parseMsgShares(shares [][]byte) ([]Message, error) {
435
421
return msgs , nil
436
422
}
437
423
438
- // next returns the next chunk of a contiguous share. Used for parsing
439
- // transaction, evidence, and intermediate state root block data.
440
- func nextMsg (shares [][]byte , current , nid []byte , cursor int , l uint64 ) ([]byte , int , uint64 , Message , error ) {
424
+ func nextMsg (shares [][]byte , current , nid []byte , cursor , l uint64 ) ([]byte , []byte , uint64 , uint64 , Message , error ) {
441
425
switch {
442
- // the rest of the share should be tail padding
443
- case l == 0 :
426
+ // the message uses all of the current share data and at least some of the
427
+ // next share
428
+ case l > uint64 (len (current )):
429
+ // add the next share to the current one and try again
444
430
cursor ++
445
- if len (shares ) != cursor {
446
- panic ("message of length zero" )
447
- }
448
- return nil , cursor , 0 , MessageEmpty , nil
449
-
450
- // the msg is contained in the current share
451
- case int (l ) < len (current ):
452
- msg := Message {NamespaceID : nid , Data : current [:l ]}
453
-
454
- // set the next msgLen and update the next share
455
- next , msgLen , err := tailorMsg (current [l :])
456
- if err != nil {
457
- return nil , 0 , 0 , MessageEmpty , err
458
- }
459
-
460
- return next , cursor , msgLen , msg , nil
461
-
462
- // the msg requires some portion of the following share
463
- case int (l ) > len (current ):
464
- cursor ++
465
-
466
- // merge the current and the next share
467
431
current := append (current , shares [cursor ][NamespaceSize :]... )
468
-
469
- // try again using the next share
470
432
return nextMsg (shares , current , nid , cursor , l )
471
433
472
- // the msg is exactly the same size of the current share
473
- case l == uint64 (len (current )):
474
- msg := Message {NamespaceID : nid , Data : current }
475
-
434
+ // the msg we're looking for is contained in the current share
435
+ case l <= uint64 (len (current )):
436
+ msg := Message {nid , current [:l ]}
476
437
cursor ++
477
438
478
- // if this is the end of shares only return the msg
479
- if cursor == len (shares ) {
480
- return [] byte {} , cursor , 0 , msg , nil
439
+ // call it a day if the work is done
440
+ if cursor >= uint64 ( len (shares ) ) {
441
+ return nil , nil , cursor , 0 , msg , nil
481
442
}
482
443
483
- // set the next msgLen and next share
484
- next , nextMsgLen , err := tailorMsg (shares [cursor ][NamespaceSize :])
485
- if err != nil {
486
- return nil , 0 , 0 , MessageEmpty , err
487
- }
488
-
489
- return next , cursor , nextMsgLen , msg , nil
444
+ nextNid := shares [cursor ][:NamespaceSize ]
445
+ next , msgLen , err := parseDelimiter (shares [cursor ][NamespaceSize :])
446
+ return next , nextNid , cursor , msgLen , msg , err
490
447
}
491
-
492
448
// this code is unreachable but the compiler doesn't know that
493
- return nil , 0 , 0 , MessageEmpty , nil
449
+ return nil , nil , 0 , 0 , MessageEmpty , nil
494
450
}
495
451
496
- // tailorMsg finds and returns the length delimiter of the message provided
452
+ // parseDelimiter finds and returns the length delimiter of the message provided
497
453
// while also removing the delimiter bytes from the input
498
- func tailorMsg (input []byte ) ([]byte , uint64 , error ) {
454
+ func parseDelimiter (input []byte ) ([]byte , uint64 , error ) {
455
+ if len (input ) == 0 {
456
+ return input , 0 , nil
457
+ }
458
+
459
+ l := binary .MaxVarintLen64
460
+ if len (input ) < binary .MaxVarintLen64 {
461
+ l = len (input )
462
+ }
463
+
499
464
// read the length of the message
500
- r := bytes .NewBuffer (input [:binary . MaxVarintLen64 ])
465
+ r := bytes .NewBuffer (input [:l ])
501
466
msgLen , err := binary .ReadUvarint (r )
502
467
if err != nil {
503
468
return nil , 0 , err
@@ -508,5 +473,5 @@ func tailorMsg(input []byte) ([]byte, uint64, error) {
508
473
n := binary .PutUvarint (lenBuf , msgLen )
509
474
510
475
// return the input without the length delimiter
511
- return input [n + 1 :], msgLen , nil
476
+ return input [n :], msgLen , nil
512
477
}
0 commit comments