Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
286f209
add initial CodecV6 and daBatchV6
jonastheis Dec 27, 2024
6767845
feat: add codecv5 and codecv6 for Euclid fork
omerfirmak Jan 7, 2025
cc9561b
implement blob encoding and decoding according to new blob layout
jonastheis Jan 21, 2025
8c2a5cc
rename to CodecV7
jonastheis Jan 21, 2025
9117170
add NewDABatchFromParams
jonastheis Jan 22, 2025
4ef7bfc
add DecodeBlob to Codec
jonastheis Jan 22, 2025
bf16156
Update da.go
omerfirmak Jan 27, 2025
2817674
Update interfaces.go
omerfirmak Jan 27, 2025
7a60b34
Merge remote-tracking branch 'origin/omerfirmak/euclid' into feat/cod…
jonastheis Jan 28, 2025
64133ef
fixes after merge
jonastheis Jan 28, 2025
1dde89a
address review comments
jonastheis Jan 29, 2025
c9c1a44
add sanity checks for blob payload generation
jonastheis Jan 30, 2025
e980b3d
fix few small bugs uncovered by unit tests
jonastheis Jan 31, 2025
0e930c6
upgrade to latest l2geth version and add correct getter for CodecV7 i…
jonastheis Jan 31, 2025
5d200f3
fix linter warnings
jonastheis Jan 31, 2025
5292e3c
add unit tests
jonastheis Jan 31, 2025
3cfed43
go mod tidy
jonastheis Jan 31, 2025
eed341f
fix linter warnings
jonastheis Jan 31, 2025
be6b422
add function MessageQueueV2ApplyL1MessagesFromBlocks to compute the L…
jonastheis Feb 3, 2025
d77916b
fix lint and unit test errors
Feb 3, 2025
b71c047
call checkCompressedDataCompatibility only once -> constructBlobPaylo…
jonastheis Feb 4, 2025
cbed8b2
address review comments
jonastheis Feb 4, 2025
392b6ff
update BlobEnvelopeV7 documentation
jonastheis Feb 4, 2025
edaf5d2
add CodecV7 to general util functions
jonastheis Feb 5, 2025
894a93b
add InitialL1MessageQueueHash and LastL1MessageQueueHash to encoding.…
jonastheis Feb 5, 2025
f3271d9
Merge remote-tracking branch 'origin/main' into feat/codec-v6
jonastheis Feb 7, 2025
2611ae1
go mod tidy
jonastheis Feb 7, 2025
4d46aad
upgrade go-ethereum dependency to latest develop
jonastheis Feb 7, 2025
f4b274c
implement estimate functions
jonastheis Feb 7, 2025
3c106a2
update TestMain and run go mod tidy
Thegaram Feb 7, 2025
538036b
add NewDAChunk to CodecV7 for easier use in relayer
jonastheis Feb 9, 2025
14d07e7
Merge branch 'feat/codec-v6' of github.com:scroll-tech/da-codec into …
jonastheis Feb 9, 2025
cfb316b
add daChunkV7 type to calculate chunk hash
jonastheis Feb 9, 2025
c6ae41e
allow batch.chunks but check consistency with batch.blocks
jonastheis Feb 10, 2025
d028c53
fix off-by-one error with L1 messages
jonastheis Feb 10, 2025
8fa5e27
Fix: rolling hash implementation (#42)
roynalnaruto Feb 14, 2025
4f13363
Apply suggestions from code review
jonastheis Feb 18, 2025
bcad556
rename initialL1MessageQueueHash -> prevL1MessageQueueHash and lastL1…
jonastheis Feb 18, 2025
7522931
address review comments
jonastheis Feb 18, 2025
32f5b49
address review comments
jonastheis Feb 18, 2025
0247443
add challenge digest computation for batch
jonastheis Feb 18, 2025
2043787
remove InitialL1MessageIndex from CodecV7
jonastheis Feb 19, 2025
de09af4
address review comments
jonastheis Feb 19, 2025
f9608ed
fix tests
jonastheis Feb 19, 2025
01bd9b5
refactoring to minimize duplicate code and increase maintainability
jonastheis Feb 20, 2025
fca406c
fix nil pointer
jonastheis Feb 20, 2025
5fd8356
address review comments
jonastheis Feb 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions encoding/codecv6.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package encoding

import (
"encoding/json"
"fmt"

"github.com/scroll-tech/go-ethereum/crypto/kzg4844"
)

type DACodecV6 struct {
DACodecV4
}

// Version returns the codec version.
func (d *DACodecV6) Version() CodecVersion {
return CodecV6
}

// MaxNumChunksPerBatch returns the maximum number of chunks per batch.
func (d *DACodecV6) MaxNumChunksPerBatch() int {
return 1
}

// NewDAChunk creates a new DAChunk from the given Chunk and the total number of L1 messages popped before.
// Note: For DACodecV6, this function is not implemented since there is no notion of DAChunk in this version. Blobs
// contain the entire batch data, and it is up to a prover to decide the chunk sizes.
func (d *DACodecV6) NewDAChunk(_ *Chunk, _ uint64) (DAChunk, error) {
return nil, nil
}

// NewDABatch creates a DABatch including blob from the provided Batch.
func (d *DACodecV6) NewDABatch(batch *Batch) (DABatch, error) {
// TODO: create DABatch from the provided batch once the blob layout is defined. See DACodecV4 for reference.
return nil, nil
}

// NewDABatchFromBytes decodes the given byte slice into a DABatch.
// Note: This function only populates the batch header, it leaves the blob-related fields and skipped L1 message bitmap empty.
func (d *DACodecV6) NewDABatchFromBytes(data []byte) (DABatch, error) {
daBatch, err := decodeDABatchV6(data)
if err != nil {
return nil, fmt.Errorf("failed to decode DA batch: %w", err)
}

if daBatch.version != CodecV6 {
return nil, fmt.Errorf("codec version mismatch: expected %d but found %d", CodecV6, daBatch.version)
}

return daBatch, nil
}

func (d *DACodecV6) DecodeDAChunksRawTx(chunkBytes [][]byte) ([]*DAChunkRawTx, error) {
return nil, nil
}

func (d *DACodecV6) DecodeTxsFromBlob(blob *kzg4844.Blob, chunks []*DAChunkRawTx) error {
return nil
}

// TODO: add DecodeBlob to interface to decode the blob and transactions or reuse DecodeTxsFromBlob but only have a single "chunk" for all transactions in the batch?

// TODO: which of the Estimate* functions are needed?

// JSONFromBytes converts the bytes to a DABatch and then marshals it to JSON.
func (d *DACodecV6) JSONFromBytes(data []byte) ([]byte, error) {
batch, err := d.NewDABatchFromBytes(data)
if err != nil {
return nil, fmt.Errorf("failed to decode DABatch from bytes: %w", err)
}

jsonBytes, err := json.Marshal(batch)
if err != nil {
return nil, fmt.Errorf("failed to marshal DABatch to JSON, version %d, hash %s: %w", batch.Version(), batch.Hash(), err)
}

return jsonBytes, nil
}
135 changes: 135 additions & 0 deletions encoding/codecv6_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package encoding

import (
"encoding/binary"
"encoding/hex"
"encoding/json"
"errors"
"fmt"

"github.com/scroll-tech/go-ethereum/common"
"github.com/scroll-tech/go-ethereum/crypto"
"github.com/scroll-tech/go-ethereum/crypto/kzg4844"
)

// daBatchV3 contains metadata about a batch of DAChunks.
type daBatchV6 struct {
version CodecVersion
batchIndex uint64
parentBatchHash common.Hash
blobVersionedHash common.Hash

blob *kzg4844.Blob
z *kzg4844.Point
blobBytes []byte
}

// newDABatchV6 is a constructor for daBatchV6 that calls blobDataProofForPICircuit internally.
func newDABatchV6(version CodecVersion, batchIndex uint64, parentBatchHash, blobVersionedHash common.Hash, blob *kzg4844.Blob, z *kzg4844.Point, blobBytes []byte) (*daBatchV6, error) {
daBatch := &daBatchV6{
version: version,
batchIndex: batchIndex,
parentBatchHash: parentBatchHash,
blobVersionedHash: blobVersionedHash,
blob: blob,
z: z,
blobBytes: blobBytes,
}

return daBatch, nil
}

func decodeDABatchV6(data []byte) (*daBatchV6, error) {
if len(data) != daBatchV6EncodedLength {
return nil, fmt.Errorf("invalid data length for DABatchV6, expected %d bytes but got %d", daBatchV6EncodedLength, len(data))
}

version := CodecVersion(data[daBatchOffsetVersion])
batchIndex := binary.BigEndian.Uint64(data[daBatchOffsetBatchIndex:daBatchV6OffsetBlobVersionedHash])
blobVersionedHash := common.BytesToHash(data[daBatchV6OffsetBlobVersionedHash:daBatchV6OffsetParentBatchHash])
parentBatchHash := common.BytesToHash(data[daBatchV6OffsetParentBatchHash:daBatchV6EncodedLength])

return newDABatchV6(version, batchIndex, parentBatchHash, blobVersionedHash, nil, nil, nil)
}

// Encode serializes the DABatchV3 into bytes.
func (b *daBatchV6) Encode() []byte {
batchBytes := make([]byte, daBatchV6EncodedLength)
batchBytes[daBatchOffsetVersion] = byte(b.version)
binary.BigEndian.PutUint64(batchBytes[daBatchOffsetBatchIndex:daBatchV6OffsetBlobVersionedHash], b.batchIndex)
copy(batchBytes[daBatchV6OffsetBlobVersionedHash:daBatchV6OffsetParentBatchHash], b.blobVersionedHash[:])
copy(batchBytes[daBatchV6OffsetParentBatchHash:daBatchV6EncodedLength], b.parentBatchHash[:])
return batchBytes
}

// Hash computes the hash of the serialized DABatch.
func (b *daBatchV6) Hash() common.Hash {
return crypto.Keccak256Hash(b.Encode())
}

// BlobDataProofForPointEvaluation computes the abi-encoded blob verification data.
func (b *daBatchV6) BlobDataProofForPointEvaluation() ([]byte, error) {
if b.blob == nil {
return nil, errors.New("called BlobDataProofForPointEvaluation with empty blob")
}
if b.z == nil {
return nil, errors.New("called BlobDataProofForPointEvaluation with empty z")
}

commitment, err := kzg4844.BlobToCommitment(b.blob)
if err != nil {
return nil, fmt.Errorf("failed to create blob commitment: %w", err)
}

proof, y, err := kzg4844.ComputeProof(b.blob, *b.z)
if err != nil {
return nil, fmt.Errorf("failed to create KZG proof at point, err: %w, z: %v", err, hex.EncodeToString(b.z[:]))
}

return blobDataProofFromValues(*b.z, y, commitment, proof), nil
}

// Blob returns the blob of the batch.
func (b *daBatchV6) Blob() *kzg4844.Blob {
return b.blob
}

// BlobBytes returns the blob bytes of the batch.
func (b *daBatchV6) BlobBytes() []byte {
return b.blobBytes
}

// MarshalJSON implements the custom JSON serialization for daBatchV3.
// This method is designed to provide prover with batch info in snake_case format.
func (b *daBatchV6) MarshalJSON() ([]byte, error) {
type daBatchV6JSON struct {
Version CodecVersion `json:"version"`
BatchIndex uint64 `json:"batch_index"`
BlobVersionedHash string `json:"blob_versioned_hash"`
ParentBatchHash string `json:"parent_batch_hash"`
}

return json.Marshal(&daBatchV6JSON{
Version: b.version,
BatchIndex: b.batchIndex,
BlobVersionedHash: b.blobVersionedHash.Hex(),
ParentBatchHash: b.parentBatchHash.Hex(),
})
}

// Version returns the version of the DABatch.
func (b *daBatchV6) Version() CodecVersion {
return b.version
}

// SkippedL1MessageBitmap returns the skipped L1 message bitmap of the DABatch.
// For daBatchV6, there is no skipped L1 message bitmap.
func (b *daBatchV6) SkippedL1MessageBitmap() []byte {
return nil
}

// DataHash returns the data hash of the DABatch.
// For daBatchV6, there is no data hash.
func (b *daBatchV6) DataHash() common.Hash {
return common.Hash{}
}
6 changes: 6 additions & 0 deletions encoding/da.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ const (
daBatchV3EncodedLength = 193
)

const (
daBatchV6EncodedLength = 73
daBatchV6OffsetBlobVersionedHash = 9
daBatchV6OffsetParentBatchHash = 41
)

const (
payloadLengthBytes = 4
calldataNonZeroByteGas = 16
Expand Down
8 changes: 7 additions & 1 deletion encoding/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ const (
CodecV2
CodecV3
CodecV4
_ // CodecV5 is skipped
CodecV6
)

// CodecFromVersion returns the appropriate codec for the given version.
Expand All @@ -91,14 +93,18 @@ func CodecFromVersion(version CodecVersion) (Codec, error) {
return &DACodecV3{}, nil
case CodecV4:
return &DACodecV4{}, nil
case CodecV6:
return &DACodecV6{}, nil
default:
return nil, fmt.Errorf("unsupported codec version: %v", version)
}
}

// CodecFromConfig determines and returns the appropriate codec based on chain configuration, block number, and timestamp.
func CodecFromConfig(chainCfg *params.ChainConfig, startBlockNumber *big.Int, startBlockTimestamp uint64) Codec {
if chainCfg.IsDarwinV2(startBlockTimestamp) {
if chainCfg.IsDarwinV2(startBlockTimestamp) { // TODO: replace with correct fork
return &DACodecV6{}
} else if chainCfg.IsDarwinV2(startBlockTimestamp) {
return &DACodecV4{}
} else if chainCfg.IsDarwin(startBlockTimestamp) {
return &DACodecV3{}
Expand Down