@@ -14,39 +14,77 @@ import (
1414 "github.com/scroll-tech/go-ethereum/crypto/kzg4844"
1515)
1616
17+ // Below is the encoding for `BatchHeader` V7, total 73 bytes.
18+ // * Field Bytes Type Index Comments
19+ // * version 1 uint8 0 The batch version
20+ // * batchIndex 8 uint64 1 The index of the batch
21+ // * blobVersionedHash 32 bytes32 9 The versioned hash of the blob with this batch’s data
22+ // * parentBatchHash 32 bytes32 41 The parent batch hash
23+
1724const (
1825 daBatchV7EncodedLength = 73
1926 daBatchV7OffsetBlobVersionedHash = 9
2027 daBatchV7OffsetParentBatchHash = 41
2128)
2229
30+ // Below is the encoding format for BlobEnvelopeV7.
31+ // * Field Bytes Type Index Comments
32+ // * version 1 uint8 0 The version of the DA codec (batch/blob)
33+ // * n_bytes[1] 1 uint8 1 Value denoting the number of bytes, n_bytes[1]
34+ // * n_bytes[2] 1 uint8 2 Value denoting the number of bytes, n_bytes[2]*256
35+ // * n_bytes[3] 1 uint8 3 Value denoting the number of bytes, n_bytes[3]*256^2
36+ // * flag 1 bool 4 1-byte flag to denote zstd-encoded/raw bytes
37+ // * payload N bytes 5 Possibly zstd-encoded payload bytes
38+ // * padding (4096*31 - (N+5)) bytes N+5 Padding to align to 4096*31 bytes
39+
2340const (
24- blobEnvelopeV7VersionOffset = 0
25- blobEnvelopeV7ByteSizeOffset = 1
26- blobEnvelopeV7CompressedFlagOffset = 4
27- blobEnvelopeV7PayloadOffset = 5
41+ blobEnvelopeV7OffsetVersion = 0
42+ blobEnvelopeV7OffsetByteSize = 1
43+ blobEnvelopeV7OffsetCompressedFlag = 4
44+ blobEnvelopeV7OffsetPayload = 5
2845)
2946
47+ // Below is the encoding format for the batch metadata and blocks.
48+ // * Field Bytes Type Index Comments
49+ // * initialL1MessageIndex 8 uint64 0 Queue index of the first L1 message contained in this batch
50+ // * initialL1MessageQueueHash 32 bytes32 8 Hash of the L1 message queue at the last message in the previous batch
51+ // * lastL1MessageQueueHash 32 bytes32 40 Hash of the L1 message queue at the last message in this batch
52+ // * initialL2BlockNumber 8 uint64 72 The initial L2 block number in this batch
53+ // * numBlocks 2 uint16 80 The number of blocks in this batch
54+ // * block[0] 52 BlockContextV2 82 The first block in this batch
55+ // * block[i] 52 BlockContextV2 82+52*i The (i+1)th block in this batch
56+ // * block[n-1] 52 BlockContextV2 82+52*(n-1) The last block in this batch
57+ // * l2Transactions dynamic bytes 82+52*n L2 transactions for this batch
58+
3059const (
31- blobPayloadV7EncodedLength = 8 + 2 * common .HashLength + 8 + 2
60+ blobPayloadV7MinEncodedLength = 8 + 2 * common .HashLength + 8 + 2
3261 blobPayloadV7OffsetInitialL1MessageIndex = 0
33- blobPayloadV7OffsetInitialL1MessageQueue = blobPayloadV7OffsetInitialL1MessageIndex + 8
34- blobPayloadV7OffsetLastL1MessageQueue = blobPayloadV7OffsetInitialL1MessageQueue + common . HashLength
35- blobPayloadV7OffsetInitialL2BlockNumber = blobPayloadV7OffsetLastL1MessageQueue + common . HashLength
36- blobPayloadV7OffsetNumBlocks = blobPayloadV7OffsetInitialL2BlockNumber + 8
37- blobPayloadV7OffsetBlocks = blobPayloadV7OffsetNumBlocks + 2
62+ blobPayloadV7OffsetInitialL1MessageQueue = 8
63+ blobPayloadV7OffsetLastL1MessageQueue = 40
64+ blobPayloadV7OffsetInitialL2BlockNumber = 72
65+ blobPayloadV7OffsetNumBlocks = 80
66+ blobPayloadV7OffsetBlocks = 82
3867)
3968
69+ // Below is the encoding for DABlockV7, total 52 bytes.
70+ // * Field Bytes Type Index Comments
71+ // * blockNumber 8 uint64 0 The height of this block.
72+ // * timestamp 8 uint64 0 The timestamp of this block.
73+ // * baseFee 32 uint256 8 The base fee of this block.
74+ // * gasLimit 8 uint64 40 The gas limit of this block.
75+ // * numTransactions 2 uint16 48 The number of transactions in this block, both L1 & L2 txs.
76+ // * numL1Messages 2 uint16 50 The number of l1 messages in this block.
77+
4078const (
41- daBlockV7BlockContextByteSize = 52
42- daBlockV7OffsetTimestamp = 0
43- daBlockV7OffsetBaseFee = daBlockV7OffsetTimestamp + 8
44- daBlockV7OffsetGasLimit = daBlockV7OffsetBaseFee + 32
45- daBlockV7numTransactionsOffset = daBlockV7OffsetGasLimit + 8
46- daBlockV7numL1MessagesOffset = daBlockV7numTransactionsOffset + 2
79+ daBlockV7BlockContextEncodedLength = 52
80+ daBlockV7OffsetTimestamp = 0
81+ daBlockV7OffsetBaseFee = 8
82+ daBlockV7OffsetGasLimit = 40
83+ daBlockV7OffsetNumTransactions = 48
84+ daBlockV7OffsetNumL1Messages = 50
4785)
4886
49- // daBatchV3 contains metadata about a batch of DAChunks .
87+ // daBatchV7 contains V7 batch metadata and payload .
5088type daBatchV7 struct {
5189 version CodecVersion
5290 batchIndex uint64
@@ -57,7 +95,6 @@ type daBatchV7 struct {
5795 blobBytes []byte
5896}
5997
60- // newDABatchV7 is a constructor for daBatchV7 that calls blobDataProofForPICircuit internally.
6198func newDABatchV7 (version CodecVersion , batchIndex uint64 , blobVersionedHash , parentBatchHash common.Hash , blob * kzg4844.Blob , blobBytes []byte ) (* daBatchV7 , error ) {
6299 daBatch := & daBatchV7 {
63100 version : version ,
@@ -84,7 +121,7 @@ func decodeDABatchV7(data []byte) (*daBatchV7, error) {
84121 return newDABatchV7 (version , batchIndex , blobVersionedHash , parentBatchHash , nil , nil )
85122}
86123
87- // Encode serializes the DABatchV3 into bytes.
124+ // Encode serializes the dABatchV7 into bytes.
88125func (b * daBatchV7 ) Encode () []byte {
89126 batchBytes := make ([]byte , daBatchV7EncodedLength )
90127 batchBytes [daBatchOffsetVersion ] = byte (b .version )
@@ -115,7 +152,7 @@ func (b *daBatchV7) BlobBytes() []byte {
115152 return b .blobBytes
116153}
117154
118- // MarshalJSON implements the custom JSON serialization for daBatchV3 .
155+ // MarshalJSON implements the custom JSON serialization for daBatchV7 .
119156// This method is designed to provide prover with batch info in snake_case format.
120157func (b * daBatchV7 ) MarshalJSON () ([]byte , error ) {
121158 type daBatchV7JSON struct {
@@ -159,24 +196,24 @@ type blobPayloadV7 struct {
159196 blocks []* Block
160197
161198 // used for decoding
162- daBlocks []DABlock
163- transactions []types.Transactions
199+ daBlocks []DABlock
200+ l2Transactions []types.Transactions
164201}
165202
166203func (b * blobPayloadV7 ) Blocks () []DABlock {
167204 return b .daBlocks
168205}
169206
170207func (b * blobPayloadV7 ) Transactions () []types.Transactions {
171- return b .transactions
208+ return b .l2Transactions
172209}
173210
174211func (b * blobPayloadV7 ) InitialL1MessageIndex () uint64 {
175212 return b .initialL1MessageIndex
176213}
177214
178215func (b * blobPayloadV7 ) Encode () ([]byte , error ) {
179- payloadBytes := make ([]byte , blobPayloadV7EncodedLength )
216+ payloadBytes := make ([]byte , blobPayloadV7MinEncodedLength )
180217
181218 binary .BigEndian .PutUint64 (payloadBytes [blobPayloadV7OffsetInitialL1MessageIndex :blobPayloadV7OffsetInitialL1MessageQueue ], b .initialL1MessageIndex )
182219 copy (payloadBytes [blobPayloadV7OffsetInitialL1MessageQueue :blobPayloadV7OffsetLastL1MessageQueue ], b .initialL1MessageQueueHash [:])
@@ -188,7 +225,11 @@ func (b *blobPayloadV7) Encode() ([]byte, error) {
188225
189226 var transactionBytes []byte
190227 for _ , block := range b .blocks {
191- daBlock := newDABlockV7 (block .Header .Number .Uint64 (), block .Header .Time , block .Header .BaseFee , block .Header .GasLimit , uint16 (len (block .Transactions )), block .NumL1MessagesNoSkipping ())
228+ numL1Messages , _ , err := block .NumL1MessagesNoSkipping ()
229+ if err != nil {
230+ return nil , fmt .Errorf ("failed to get numL1Messages: %w" , err )
231+ }
232+ daBlock := newDABlockV7 (block .Header .Number .Uint64 (), block .Header .Time , block .Header .BaseFee , block .Header .GasLimit , uint16 (len (block .Transactions )), numL1Messages )
192233 payloadBytes = append (payloadBytes , daBlock .Encode ()... )
193234
194235 // encode L2 txs as RLP and append to transactionBytes
@@ -210,8 +251,8 @@ func (b *blobPayloadV7) Encode() ([]byte, error) {
210251}
211252
212253func decodeBlobPayloadV7 (data []byte ) (* blobPayloadV7 , error ) {
213- if len (data ) < blobPayloadV7EncodedLength {
214- return nil , fmt .Errorf ("invalid data length for blobPayloadV7, expected at least %d bytes but got %d" , blobPayloadV7EncodedLength , len (data ))
254+ if len (data ) < blobPayloadV7MinEncodedLength {
255+ return nil , fmt .Errorf ("invalid data length for blobPayloadV7, expected at least %d bytes but got %d" , blobPayloadV7MinEncodedLength , len (data ))
215256 }
216257
217258 initialL1MessageIndex := binary .BigEndian .Uint64 (data [blobPayloadV7OffsetInitialL1MessageIndex :blobPayloadV7OffsetInitialL1MessageQueue ])
@@ -221,22 +262,26 @@ func decodeBlobPayloadV7(data []byte) (*blobPayloadV7, error) {
221262 initialL2BlockNumber := binary .BigEndian .Uint64 (data [blobPayloadV7OffsetInitialL2BlockNumber :blobPayloadV7OffsetNumBlocks ])
222263 numBlocks := int (binary .BigEndian .Uint16 (data [blobPayloadV7OffsetNumBlocks :blobPayloadV7OffsetBlocks ]))
223264
265+ if len (data ) < blobPayloadV7OffsetBlocks + daBlockV7BlockContextEncodedLength * numBlocks {
266+ return nil , fmt .Errorf ("invalid data length for blobPayloadV7, expected at least %d bytes but got %d" , blobPayloadV7OffsetBlocks + daBlockV7BlockContextEncodedLength * numBlocks , len (data ))
267+ }
268+
224269 // decode DA Blocks from the blob
225270 daBlocks := make ([]DABlock , numBlocks )
226271 for i := uint64 (0 ); i < uint64 (numBlocks ); i ++ {
227272 daBlock := newDABlockV7WithNumber (initialL2BlockNumber + i )
228273
229- startBytes := blobPayloadV7OffsetBlocks + i * daBlockV7BlockContextByteSize
230- endBytes := startBytes + daBlockV7BlockContextByteSize
274+ startBytes := blobPayloadV7OffsetBlocks + i * daBlockV7BlockContextEncodedLength
275+ endBytes := startBytes + daBlockV7BlockContextEncodedLength
231276 if err := daBlock .Decode (data [startBytes :endBytes ]); err != nil {
232277 return nil , fmt .Errorf ("failed to decode DA block: %w" , err )
233278 }
234279
235280 daBlocks = append (daBlocks , daBlock )
236281 }
237282
238- // decode transactions for each block from the blob
239- txBytes := data [blobPayloadV7OffsetBlocks + daBlockV7BlockContextByteSize * numBlocks :]
283+ // decode l2Transactions for each block from the blob
284+ txBytes := data [blobPayloadV7OffsetBlocks + daBlockV7BlockContextEncodedLength * numBlocks :]
240285 curIndex := 0
241286 var transactions []types.Transactions
242287
@@ -264,7 +309,7 @@ func decodeBlobPayloadV7(data []byte) (*blobPayloadV7, error) {
264309 initialL1MessageQueueHash : initialL1MessageQueueHash ,
265310 lastL1MessageQueueHash : lastL1MessageQueueHash ,
266311 daBlocks : daBlocks ,
267- transactions : transactions ,
312+ l2Transactions : transactions ,
268313 }, nil
269314}
270315
@@ -296,28 +341,28 @@ func newDABlockV7WithNumber(number uint64) *daBlockV7 {
296341
297342// Encode serializes the DABlock into a slice of bytes.
298343func (b * daBlockV7 ) Encode () []byte {
299- daBlockBytes := make ([]byte , daBlockV7BlockContextByteSize )
344+ daBlockBytes := make ([]byte , daBlockV7BlockContextEncodedLength )
300345 binary .BigEndian .PutUint64 (daBlockBytes [daBlockV7OffsetTimestamp :daBlockV7OffsetBaseFee ], b .timestamp )
301346 if b .baseFee != nil {
302347 b .baseFee .FillBytes (daBlockBytes [daBlockV7OffsetBaseFee :daBlockV7OffsetGasLimit ])
303348 }
304- binary .BigEndian .PutUint64 (daBlockBytes [daBlockV7OffsetGasLimit :daBlockV7numTransactionsOffset ], b .gasLimit )
305- binary .BigEndian .PutUint16 (daBlockBytes [daBlockV7numTransactionsOffset : daBlockV7numL1MessagesOffset ], b .numTransactions )
306- binary .BigEndian .PutUint16 (daBlockBytes [daBlockV7numL1MessagesOffset :], b .numL1Messages )
349+ binary .BigEndian .PutUint64 (daBlockBytes [daBlockV7OffsetGasLimit :daBlockV7OffsetNumTransactions ], b .gasLimit )
350+ binary .BigEndian .PutUint16 (daBlockBytes [daBlockV7OffsetNumTransactions : daBlockV7OffsetNumL1Messages ], b .numTransactions )
351+ binary .BigEndian .PutUint16 (daBlockBytes [daBlockV7OffsetNumL1Messages :], b .numL1Messages )
307352 return daBlockBytes
308353}
309354
310355// Decode populates the fields of a DABlock from a byte slice.
311356func (b * daBlockV7 ) Decode (data []byte ) error {
312- if len (data ) != daBlockV7BlockContextByteSize {
313- return fmt .Errorf ("block encoding is not blockContextByteSize bytes long expected %d, got %d" , daBlockV7BlockContextByteSize , len (data ))
357+ if len (data ) != daBlockV7BlockContextEncodedLength {
358+ return fmt .Errorf ("block encoding is not blockContextByteSize bytes long expected %d, got %d" , daBlockV7BlockContextEncodedLength , len (data ))
314359 }
315360
316361 b .timestamp = binary .BigEndian .Uint64 (data [daBlockV7OffsetTimestamp :daBlockV7OffsetBaseFee ])
317362 b .baseFee = new (big.Int ).SetBytes (data [daBlockV7OffsetBaseFee :daBlockV7OffsetGasLimit ])
318- b .gasLimit = binary .BigEndian .Uint64 (data [daBlockV7OffsetGasLimit :daBlockV7numTransactionsOffset ])
319- b .numTransactions = binary .BigEndian .Uint16 (data [daBlockV7numTransactionsOffset : daBlockV7numL1MessagesOffset ])
320- b .numL1Messages = binary .BigEndian .Uint16 (data [daBlockV7numL1MessagesOffset :])
363+ b .gasLimit = binary .BigEndian .Uint64 (data [daBlockV7OffsetGasLimit :daBlockV7OffsetNumTransactions ])
364+ b .numTransactions = binary .BigEndian .Uint16 (data [daBlockV7OffsetNumTransactions : daBlockV7OffsetNumL1Messages ])
365+ b .numL1Messages = binary .BigEndian .Uint16 (data [daBlockV7OffsetNumL1Messages :])
321366
322367 return nil
323368}
0 commit comments