all: define constructor for BlobSidecar (#32213)
Some checks are pending
/ Linux Build (push) Waiting to run
/ Linux Build (arm) (push) Waiting to run
/ Windows Build (push) Waiting to run
/ Docker Image (push) Waiting to run

The main purpose of this change is to enforce the version setting when
constructing the blobSidecar, avoiding creating sidecar with wrong/default 
version tag.
This commit is contained in:
rjl493456442 2025-07-17 11:19:20 +08:00 committed by GitHub
parent a487729d83
commit 0dacfef8ac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 97 additions and 122 deletions

View file

@ -34,21 +34,13 @@ func TestBlobs(t *testing.T) {
header := types.Header{} header := types.Header{}
block := types.NewBlock(&header, &types.Body{}, nil, nil) block := types.NewBlock(&header, &types.Body{}, nil, nil)
sidecarWithoutCellProofs := &types.BlobTxSidecar{ sidecarWithoutCellProofs := types.NewBlobTxSidecar(types.BlobSidecarVersion0, []kzg4844.Blob{*emptyBlob}, []kzg4844.Commitment{emptyBlobCommit}, []kzg4844.Proof{emptyBlobProof})
Blobs: []kzg4844.Blob{*emptyBlob},
Commitments: []kzg4844.Commitment{emptyBlobCommit},
Proofs: []kzg4844.Proof{emptyBlobProof},
}
env := BlockToExecutableData(block, common.Big0, []*types.BlobTxSidecar{sidecarWithoutCellProofs}, nil) env := BlockToExecutableData(block, common.Big0, []*types.BlobTxSidecar{sidecarWithoutCellProofs}, nil)
if len(env.BlobsBundle.Proofs) != 1 { if len(env.BlobsBundle.Proofs) != 1 {
t.Fatalf("Expect 1 proof in blobs bundle, got %v", len(env.BlobsBundle.Proofs)) t.Fatalf("Expect 1 proof in blobs bundle, got %v", len(env.BlobsBundle.Proofs))
} }
sidecarWithCellProofs := &types.BlobTxSidecar{ sidecarWithCellProofs := types.NewBlobTxSidecar(types.BlobSidecarVersion0, []kzg4844.Blob{*emptyBlob}, []kzg4844.Commitment{emptyBlobCommit}, emptyCellProof)
Blobs: []kzg4844.Blob{*emptyBlob},
Commitments: []kzg4844.Commitment{emptyBlobCommit},
Proofs: emptyCellProof,
}
env = BlockToExecutableData(block, common.Big0, []*types.BlobTxSidecar{sidecarWithCellProofs}, nil) env = BlockToExecutableData(block, common.Big0, []*types.BlobTxSidecar{sidecarWithCellProofs}, nil)
if len(env.BlobsBundle.Proofs) != 128 { if len(env.BlobsBundle.Proofs) != 128 {
t.Fatalf("Expect 128 proofs in blobs bundle, got %v", len(env.BlobsBundle.Proofs)) t.Fatalf("Expect 128 proofs in blobs bundle, got %v", len(env.BlobsBundle.Proofs))

View file

@ -879,11 +879,7 @@ func makeSidecar(data ...byte) *types.BlobTxSidecar {
commitments = append(commitments, c) commitments = append(commitments, c)
proofs = append(proofs, p) proofs = append(proofs, p)
} }
return &types.BlobTxSidecar{ return types.NewBlobTxSidecar(types.BlobSidecarVersion0, blobs, commitments, proofs)
Blobs: blobs,
Commitments: commitments,
Proofs: proofs,
}
} }
func (s *Suite) makeBlobTxs(count, blobs int, discriminator byte) (txs types.Transactions) { func (s *Suite) makeBlobTxs(count, blobs int, discriminator byte) (txs types.Transactions) {
@ -988,14 +984,10 @@ func (s *Suite) TestBlobViolations(t *utesting.T) {
// data has been modified to produce a different commitment hash. // data has been modified to produce a different commitment hash.
func mangleSidecar(tx *types.Transaction) *types.Transaction { func mangleSidecar(tx *types.Transaction) *types.Transaction {
sidecar := tx.BlobTxSidecar() sidecar := tx.BlobTxSidecar()
copy := types.BlobTxSidecar{ cpy := sidecar.Copy()
Blobs: append([]kzg4844.Blob{}, sidecar.Blobs...),
Commitments: append([]kzg4844.Commitment{}, sidecar.Commitments...),
Proofs: append([]kzg4844.Proof{}, sidecar.Proofs...),
}
// zero the first commitment to alter the sidecar hash // zero the first commitment to alter the sidecar hash
copy.Commitments[0] = kzg4844.Commitment{} cpy.Commitments[0] = kzg4844.Commitment{}
return tx.WithBlobTxSidecar(&copy) return tx.WithBlobTxSidecar(cpy)
} }
func (s *Suite) TestBlobTxWithoutSidecar(t *utesting.T) { func (s *Suite) TestBlobTxWithoutSidecar(t *utesting.T) {

View file

@ -238,11 +238,7 @@ func makeMultiBlobTx(nonce uint64, gasTipCap uint64, gasFeeCap uint64, blobFeeCa
BlobFeeCap: uint256.NewInt(blobFeeCap), BlobFeeCap: uint256.NewInt(blobFeeCap),
BlobHashes: blobHashes, BlobHashes: blobHashes,
Value: uint256.NewInt(100), Value: uint256.NewInt(100),
Sidecar: &types.BlobTxSidecar{ Sidecar: types.NewBlobTxSidecar(types.BlobSidecarVersion0, blobs, commitments, proofs),
Blobs: blobs,
Commitments: commitments,
Proofs: proofs,
},
} }
return types.MustSignNewTx(key, types.LatestSigner(params.MainnetChainConfig), blobtx) return types.MustSignNewTx(key, types.LatestSigner(params.MainnetChainConfig), blobtx)
} }
@ -265,11 +261,7 @@ func makeUnsignedTxWithTestBlob(nonce uint64, gasTipCap uint64, gasFeeCap uint64
BlobFeeCap: uint256.NewInt(blobFeeCap), BlobFeeCap: uint256.NewInt(blobFeeCap),
BlobHashes: []common.Hash{testBlobVHashes[blobIdx]}, BlobHashes: []common.Hash{testBlobVHashes[blobIdx]},
Value: uint256.NewInt(100), Value: uint256.NewInt(100),
Sidecar: &types.BlobTxSidecar{ Sidecar: types.NewBlobTxSidecar(types.BlobSidecarVersion0, []kzg4844.Blob{*testBlobs[blobIdx]}, []kzg4844.Commitment{testBlobCommits[blobIdx]}, []kzg4844.Proof{testBlobProofs[blobIdx]}),
Blobs: []kzg4844.Blob{*testBlobs[blobIdx]},
Commitments: []kzg4844.Commitment{testBlobCommits[blobIdx]},
Proofs: []kzg4844.Proof{testBlobProofs[blobIdx]},
},
} }
} }

View file

@ -185,7 +185,7 @@ func validateBlobTx(tx *types.Transaction, head *types.Header, opts *ValidationO
} }
func validateBlobSidecarLegacy(sidecar *types.BlobTxSidecar, hashes []common.Hash) error { func validateBlobSidecarLegacy(sidecar *types.BlobTxSidecar, hashes []common.Hash) error {
if sidecar.Version != 0 { if sidecar.Version != types.BlobSidecarVersion0 {
return fmt.Errorf("invalid sidecar version pre-osaka: %v", sidecar.Version) return fmt.Errorf("invalid sidecar version pre-osaka: %v", sidecar.Version)
} }
if len(sidecar.Proofs) != len(hashes) { if len(sidecar.Proofs) != len(hashes) {
@ -200,7 +200,7 @@ func validateBlobSidecarLegacy(sidecar *types.BlobTxSidecar, hashes []common.Has
} }
func validateBlobSidecarOsaka(sidecar *types.BlobTxSidecar, hashes []common.Hash) error { func validateBlobSidecarOsaka(sidecar *types.BlobTxSidecar, hashes []common.Hash) error {
if sidecar.Version != 1 { if sidecar.Version != types.BlobSidecarVersion1 {
return fmt.Errorf("invalid sidecar version post-osaka: %v", sidecar.Version) return fmt.Errorf("invalid sidecar version post-osaka: %v", sidecar.Version)
} }
if len(sidecar.Proofs) != len(hashes)*kzg4844.CellProofsPerBlob { if len(sidecar.Proofs) != len(hashes)*kzg4844.CellProofsPerBlob {

View file

@ -31,6 +31,18 @@ import (
"github.com/holiman/uint256" "github.com/holiman/uint256"
) )
const (
// BlobSidecarVersion0 includes a single proof for verifying the entire blob
// against its commitment. Used when the full blob is available and needs to
// be checked as a whole.
BlobSidecarVersion0 = byte(0)
// BlobSidecarVersion1 includes multiple cell proofs for verifying specific
// blob elements (cells). Used in scenarios like data availability sampling,
// where only portions of the blob are verified individually.
BlobSidecarVersion1 = byte(1)
)
// BlobTx represents an EIP-4844 transaction. // BlobTx represents an EIP-4844 transaction.
type BlobTx struct { type BlobTx struct {
ChainID *uint256.Int ChainID *uint256.Int
@ -63,6 +75,16 @@ type BlobTxSidecar struct {
Proofs []kzg4844.Proof // Proofs needed by the blob pool Proofs []kzg4844.Proof // Proofs needed by the blob pool
} }
// NewBlobTxSidecar initialises the BlobTxSidecar object with the provided parameters.
func NewBlobTxSidecar(version byte, blobs []kzg4844.Blob, commitments []kzg4844.Commitment, proofs []kzg4844.Proof) *BlobTxSidecar {
return &BlobTxSidecar{
Version: version,
Blobs: blobs,
Commitments: commitments,
Proofs: proofs,
}
}
// BlobHashes computes the blob hashes of the given blobs. // BlobHashes computes the blob hashes of the given blobs.
func (sc *BlobTxSidecar) BlobHashes() []common.Hash { func (sc *BlobTxSidecar) BlobHashes() []common.Hash {
hasher := sha256.New() hasher := sha256.New()
@ -76,7 +98,7 @@ func (sc *BlobTxSidecar) BlobHashes() []common.Hash {
// CellProofsAt returns the cell proofs for blob with index idx. // CellProofsAt returns the cell proofs for blob with index idx.
// This method is only valid for sidecars with version 1. // This method is only valid for sidecars with version 1.
func (sc *BlobTxSidecar) CellProofsAt(idx int) ([]kzg4844.Proof, error) { func (sc *BlobTxSidecar) CellProofsAt(idx int) ([]kzg4844.Proof, error) {
if sc.Version != 1 { if sc.Version != BlobSidecarVersion1 {
return nil, fmt.Errorf("cell proof unsupported, version: %d", sc.Version) return nil, fmt.Errorf("cell proof unsupported, version: %d", sc.Version)
} }
if idx < 0 || idx >= len(sc.Blobs) { if idx < 0 || idx >= len(sc.Blobs) {
@ -89,6 +111,25 @@ func (sc *BlobTxSidecar) CellProofsAt(idx int) ([]kzg4844.Proof, error) {
return sc.Proofs[index : index+kzg4844.CellProofsPerBlob], nil return sc.Proofs[index : index+kzg4844.CellProofsPerBlob], nil
} }
// ToV1 converts the BlobSidecar to version 1, attaching the cell proofs.
func (sc *BlobTxSidecar) ToV1() error {
if sc.Version == BlobSidecarVersion1 {
return nil
}
if sc.Version == BlobSidecarVersion0 {
sc.Proofs = make([]kzg4844.Proof, 0, len(sc.Blobs)*kzg4844.CellProofsPerBlob)
for _, blob := range sc.Blobs {
cellProofs, err := kzg4844.ComputeCellProofs(&blob)
if err != nil {
return err
}
sc.Proofs = append(sc.Proofs, cellProofs...)
}
sc.Version = BlobSidecarVersion1
}
return nil
}
// encodedSize computes the RLP size of the sidecar elements. This does NOT return the // encodedSize computes the RLP size of the sidecar elements. This does NOT return the
// encoded size of the BlobTxSidecar, it's just a helper for tx.Size(). // encoded size of the BlobTxSidecar, it's just a helper for tx.Size().
func (sc *BlobTxSidecar) encodedSize() uint64 { func (sc *BlobTxSidecar) encodedSize() uint64 {
@ -121,6 +162,19 @@ func (sc *BlobTxSidecar) ValidateBlobCommitmentHashes(hashes []common.Hash) erro
return nil return nil
} }
// Copy returns a deep-copied BlobTxSidecar object.
func (sc *BlobTxSidecar) Copy() *BlobTxSidecar {
return &BlobTxSidecar{
Version: sc.Version,
// The element of these slice is fix-size byte array,
// therefore slices.Clone will actually deep copy by value.
Blobs: slices.Clone(sc.Blobs),
Commitments: slices.Clone(sc.Commitments),
Proofs: slices.Clone(sc.Proofs),
}
}
// blobTxWithBlobs represents blob tx with its corresponding sidecar. // blobTxWithBlobs represents blob tx with its corresponding sidecar.
// This is an interface because sidecars are versioned. // This is an interface because sidecars are versioned.
type blobTxWithBlobs interface { type blobTxWithBlobs interface {
@ -148,7 +202,7 @@ func (btx *blobTxWithBlobsV0) tx() *BlobTx {
} }
func (btx *blobTxWithBlobsV0) assign(sc *BlobTxSidecar) error { func (btx *blobTxWithBlobsV0) assign(sc *BlobTxSidecar) error {
sc.Version = 0 sc.Version = BlobSidecarVersion0
sc.Blobs = btx.Blobs sc.Blobs = btx.Blobs
sc.Commitments = btx.Commitments sc.Commitments = btx.Commitments
sc.Proofs = btx.Proofs sc.Proofs = btx.Proofs
@ -160,10 +214,10 @@ func (btx *blobTxWithBlobsV1) tx() *BlobTx {
} }
func (btx *blobTxWithBlobsV1) assign(sc *BlobTxSidecar) error { func (btx *blobTxWithBlobsV1) assign(sc *BlobTxSidecar) error {
if btx.Version != 1 { if btx.Version != BlobSidecarVersion1 {
return fmt.Errorf("unsupported blob tx version %d", btx.Version) return fmt.Errorf("unsupported blob tx version %d", btx.Version)
} }
sc.Version = 1 sc.Version = BlobSidecarVersion1
sc.Blobs = btx.Blobs sc.Blobs = btx.Blobs
sc.Commitments = btx.Commitments sc.Commitments = btx.Commitments
sc.Proofs = btx.Proofs sc.Proofs = btx.Proofs
@ -217,12 +271,7 @@ func (tx *BlobTx) copy() TxData {
cpy.S.Set(tx.S) cpy.S.Set(tx.S)
} }
if tx.Sidecar != nil { if tx.Sidecar != nil {
cpy.Sidecar = &BlobTxSidecar{ cpy.Sidecar = tx.Sidecar.Copy()
Version: tx.Sidecar.Version,
Blobs: slices.Clone(tx.Sidecar.Blobs),
Commitments: slices.Clone(tx.Sidecar.Commitments),
Proofs: slices.Clone(tx.Sidecar.Proofs),
}
} }
return cpy return cpy
} }
@ -280,7 +329,7 @@ func (tx *BlobTx) encode(b *bytes.Buffer) error {
case tx.Sidecar == nil: case tx.Sidecar == nil:
return rlp.Encode(b, tx) return rlp.Encode(b, tx)
case tx.Sidecar.Version == 0: case tx.Sidecar.Version == BlobSidecarVersion0:
return rlp.Encode(b, &blobTxWithBlobsV0{ return rlp.Encode(b, &blobTxWithBlobsV0{
BlobTx: tx, BlobTx: tx,
Blobs: tx.Sidecar.Blobs, Blobs: tx.Sidecar.Blobs,
@ -288,7 +337,7 @@ func (tx *BlobTx) encode(b *bytes.Buffer) error {
Proofs: tx.Sidecar.Proofs, Proofs: tx.Sidecar.Proofs,
}) })
case tx.Sidecar.Version == 1: case tx.Sidecar.Version == BlobSidecarVersion1:
return rlp.Encode(b, &blobTxWithBlobsV1{ return rlp.Encode(b, &blobTxWithBlobsV1{
BlobTx: tx, BlobTx: tx,
Version: tx.Sidecar.Version, Version: tx.Sidecar.Version,

View file

@ -87,11 +87,7 @@ func createEmptyBlobTx(key *ecdsa.PrivateKey, withSidecar bool) *Transaction {
} }
func createEmptyBlobTxInner(withSidecar bool) *BlobTx { func createEmptyBlobTxInner(withSidecar bool) *BlobTx {
sidecar := &BlobTxSidecar{ sidecar := NewBlobTxSidecar(BlobSidecarVersion0, []kzg4844.Blob{*emptyBlob}, []kzg4844.Commitment{emptyBlobCommit}, []kzg4844.Proof{emptyBlobProof})
Blobs: []kzg4844.Blob{*emptyBlob},
Commitments: []kzg4844.Commitment{emptyBlobCommit},
Proofs: []kzg4844.Proof{emptyBlobProof},
}
blobtx := &BlobTx{ blobtx := &BlobTx{
ChainID: uint256.NewInt(1), ChainID: uint256.NewInt(1),
Nonce: 5, Nonce: 5,

View file

@ -527,10 +527,10 @@ func (api *ConsensusAPI) GetBlobsV2(hashes []common.Hash) ([]*engine.BlobAndProo
if len(hashes) > 128 { if len(hashes) > 128 {
return nil, engine.TooLargeRequest.With(fmt.Errorf("requested blob count too large: %v", len(hashes))) return nil, engine.TooLargeRequest.With(fmt.Errorf("requested blob count too large: %v", len(hashes)))
} }
available := api.eth.BlobTxPool().AvailableBlobs(hashes) available := api.eth.BlobTxPool().AvailableBlobs(hashes)
getBlobsRequestedCounter.Inc(int64(len(hashes))) getBlobsRequestedCounter.Inc(int64(len(hashes)))
getBlobsAvailableCounter.Inc(int64(available)) getBlobsAvailableCounter.Inc(int64(available))
// Optimization: check first if all blobs are available, if not, return empty response // Optimization: check first if all blobs are available, if not, return empty response
if available != len(hashes) { if available != len(hashes) {
getBlobsV2RequestMiss.Inc(1) getBlobsV2RequestMiss.Inc(1)
@ -557,7 +557,7 @@ func (api *ConsensusAPI) GetBlobsV2(hashes []common.Hash) ([]*engine.BlobAndProo
// not found, return empty response // not found, return empty response
return nil, nil return nil, nil
} }
if sidecar.Version != 1 { if sidecar.Version != types.BlobSidecarVersion1 {
log.Info("GetBlobs queried V0 transaction: index %v, blobhashes %v", index, sidecar.BlobHashes()) log.Info("GetBlobs queried V0 transaction: index %v, blobhashes %v", index, sidecar.BlobHashes())
return nil, nil return nil, nil
} }
@ -566,9 +566,7 @@ func (api *ConsensusAPI) GetBlobsV2(hashes []common.Hash) ([]*engine.BlobAndProo
if idxes, ok := index[hash]; ok { if idxes, ok := index[hash]; ok {
proofs, err := sidecar.CellProofsAt(bIdx) proofs, err := sidecar.CellProofsAt(bIdx)
if err != nil { if err != nil {
// TODO @rjl @marius we should return an error return nil, engine.InvalidParams.With(err)
log.Info("Failed to get cell proof", "err", err)
return nil, nil
} }
var cellProofs []hexutil.Bytes var cellProofs []hexutil.Bytes
for _, proof := range proofs { for _, proof := range proofs {

View file

@ -1511,13 +1511,8 @@ func TestBlockToPayloadWithBlobs(t *testing.T) {
} }
txs = append(txs, types.NewTx(&inner)) txs = append(txs, types.NewTx(&inner))
sidecars := []*types.BlobTxSidecar{ sidecar := types.NewBlobTxSidecar(types.BlobSidecarVersion0, make([]kzg4844.Blob, 1), make([]kzg4844.Commitment, 1), make([]kzg4844.Proof, 1))
{ sidecars := []*types.BlobTxSidecar{sidecar}
Blobs: make([]kzg4844.Blob, 1),
Commitments: make([]kzg4844.Commitment, 1),
Proofs: make([]kzg4844.Proof, 1),
},
}
block := types.NewBlock(&header, &types.Body{Transactions: txs}, nil, trie.NewStackTrie(nil)) block := types.NewBlock(&header, &types.Body{Transactions: txs}, nil, trie.NewStackTrie(nil))
envelope := engine.BlockToExecutableData(block, nil, sidecars, nil) envelope := engine.BlockToExecutableData(block, nil, sidecars, nil)

View file

@ -661,11 +661,7 @@ func testGetPooledTransaction(t *testing.T, blobTx bool) {
To: testAddr, To: testAddr,
BlobHashes: []common.Hash{emptyBlobHash}, BlobHashes: []common.Hash{emptyBlobHash},
BlobFeeCap: uint256.MustFromBig(common.Big1), BlobFeeCap: uint256.MustFromBig(common.Big1),
Sidecar: &types.BlobTxSidecar{ Sidecar: types.NewBlobTxSidecar(types.BlobSidecarVersion0, emptyBlobs, []kzg4844.Commitment{emptyBlobCommit}, []kzg4844.Proof{emptyBlobProof}),
Blobs: emptyBlobs,
Commitments: []kzg4844.Commitment{emptyBlobCommit},
Proofs: []kzg4844.Proof{emptyBlobProof},
},
}) })
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View file

@ -83,11 +83,7 @@ func newBlobTx(sim *Backend, key *ecdsa.PrivateKey) (*types.Transaction, error)
To: addr, To: addr,
AccessList: nil, AccessList: nil,
BlobHashes: []common.Hash{testBlobVHash}, BlobHashes: []common.Hash{testBlobVHash},
Sidecar: &types.BlobTxSidecar{ Sidecar: types.NewBlobTxSidecar(types.BlobSidecarVersion0, []kzg4844.Blob{*testBlob}, []kzg4844.Commitment{testBlobCommit}, []kzg4844.Proof{testBlobProof}),
Blobs: []kzg4844.Blob{*testBlob},
Commitments: []kzg4844.Commitment{testBlobCommit},
Proofs: []kzg4844.Proof{testBlobProof},
},
}) })
return types.SignTx(tx, types.LatestSignerForChainID(chainid), key) return types.SignTx(tx, types.LatestSignerForChainID(chainid), key)
} }

View file

@ -1603,11 +1603,7 @@ func (api *TransactionAPI) SignTransaction(ctx context.Context, args Transaction
// no longer retains the blobs, only the blob hashes. In this step, we need // no longer retains the blobs, only the blob hashes. In this step, we need
// to put back the blob(s). // to put back the blob(s).
if args.IsEIP4844() { if args.IsEIP4844() {
signed = signed.WithBlobTxSidecar(&types.BlobTxSidecar{ signed = signed.WithBlobTxSidecar(types.NewBlobTxSidecar(types.BlobSidecarVersion0, args.Blobs, args.Commitments, args.Proofs))
Blobs: args.Blobs,
Commitments: args.Commitments,
Proofs: args.Proofs,
})
} }
data, err := signed.MarshalBinary() data, err := signed.MarshalBinary()
if err != nil { if err != nil {

View file

@ -2758,12 +2758,8 @@ func TestFillBlobTransaction(t *testing.T) {
Proofs: []kzg4844.Proof{emptyBlobProof}, Proofs: []kzg4844.Proof{emptyBlobProof},
}, },
want: &result{ want: &result{
Hashes: []common.Hash{emptyBlobHash}, Hashes: []common.Hash{emptyBlobHash},
Sidecar: &types.BlobTxSidecar{ Sidecar: types.NewBlobTxSidecar(types.BlobSidecarVersion0, emptyBlobs, []kzg4844.Commitment{emptyBlobCommit}, []kzg4844.Proof{emptyBlobProof}),
Blobs: emptyBlobs,
Commitments: []kzg4844.Commitment{emptyBlobCommit},
Proofs: []kzg4844.Proof{emptyBlobProof},
},
}, },
}, },
{ {
@ -2778,12 +2774,8 @@ func TestFillBlobTransaction(t *testing.T) {
Proofs: []kzg4844.Proof{emptyBlobProof}, Proofs: []kzg4844.Proof{emptyBlobProof},
}, },
want: &result{ want: &result{
Hashes: []common.Hash{emptyBlobHash}, Hashes: []common.Hash{emptyBlobHash},
Sidecar: &types.BlobTxSidecar{ Sidecar: types.NewBlobTxSidecar(types.BlobSidecarVersion0, emptyBlobs, []kzg4844.Commitment{emptyBlobCommit}, []kzg4844.Proof{emptyBlobProof}),
Blobs: emptyBlobs,
Commitments: []kzg4844.Commitment{emptyBlobCommit},
Proofs: []kzg4844.Proof{emptyBlobProof},
},
}, },
}, },
{ {
@ -2808,12 +2800,8 @@ func TestFillBlobTransaction(t *testing.T) {
Blobs: emptyBlobs, Blobs: emptyBlobs,
}, },
want: &result{ want: &result{
Hashes: []common.Hash{emptyBlobHash}, Hashes: []common.Hash{emptyBlobHash},
Sidecar: &types.BlobTxSidecar{ Sidecar: types.NewBlobTxSidecar(types.BlobSidecarVersion0, emptyBlobs, []kzg4844.Commitment{emptyBlobCommit}, []kzg4844.Proof{emptyBlobProof}),
Blobs: emptyBlobs,
Commitments: []kzg4844.Commitment{emptyBlobCommit},
Proofs: []kzg4844.Proof{emptyBlobProof},
},
}, },
}, },
} }

View file

@ -527,11 +527,8 @@ func (args *TransactionArgs) ToTransaction(defaultType int) *types.Transaction {
BlobFeeCap: uint256.MustFromBig((*big.Int)(args.BlobFeeCap)), BlobFeeCap: uint256.MustFromBig((*big.Int)(args.BlobFeeCap)),
} }
if args.Blobs != nil { if args.Blobs != nil {
data.(*types.BlobTx).Sidecar = &types.BlobTxSidecar{ // TODO(rjl493456442, marius) support V1
Blobs: args.Blobs, data.(*types.BlobTx).Sidecar = types.NewBlobTxSidecar(types.BlobSidecarVersion0, args.Blobs, args.Commitments, args.Proofs)
Commitments: args.Commitments,
Proofs: args.Proofs,
}
} }
case types.DynamicFeeTxType: case types.DynamicFeeTxType:

View file

@ -32,7 +32,6 @@ import (
"github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/txpool"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/holiman/uint256" "github.com/holiman/uint256"
@ -430,17 +429,13 @@ func (miner *Miner) commitTransactions(env *environment, plainTxs, blobTxs *tran
// Make sure all transactions after osaka have cell proofs // Make sure all transactions after osaka have cell proofs
if isOsaka { if isOsaka {
if sidecar := tx.BlobTxSidecar(); sidecar != nil { if sidecar := tx.BlobTxSidecar(); sidecar != nil {
if sidecar.Version == 0 { if sidecar.Version == types.BlobSidecarVersion0 {
log.Info("Including blob tx with v0 sidecar, recomputing proofs", "hash", ltx.Hash) log.Info("Including blob tx with v0 sidecar, recomputing proofs", "hash", ltx.Hash)
sidecar.Proofs = make([]kzg4844.Proof, 0, len(sidecar.Blobs)*kzg4844.CellProofsPerBlob) if err := sidecar.ToV1(); err != nil {
for _, blob := range sidecar.Blobs { txs.Pop()
cellProofs, err := kzg4844.ComputeCellProofs(&blob) log.Warn("Failed to recompute cell proofs", "hash", ltx.Hash, "err", err)
if err != nil { continue
panic(err)
}
sidecar.Proofs = append(sidecar.Proofs, cellProofs...)
} }
sidecar.Version = 1
} }
} }
} }

View file

@ -167,11 +167,8 @@ func (args *SendTxArgs) ToTransaction() (*types.Transaction, error) {
BlobFeeCap: uint256.MustFromBig((*big.Int)(args.BlobFeeCap)), BlobFeeCap: uint256.MustFromBig((*big.Int)(args.BlobFeeCap)),
} }
if args.Blobs != nil { if args.Blobs != nil {
data.(*types.BlobTx).Sidecar = &types.BlobTxSidecar{ // TODO(rjl493456442, marius) support V1
Blobs: args.Blobs, data.(*types.BlobTx).Sidecar = types.NewBlobTxSidecar(types.BlobSidecarVersion0, args.Blobs, args.Commitments, args.Proofs)
Commitments: args.Commitments,
Proofs: args.Proofs,
}
} }
case args.MaxFeePerGas != nil: case args.MaxFeePerGas != nil:
@ -222,7 +219,6 @@ func (args *SendTxArgs) validateTxSidecar() error {
return nil return nil
} }
n := len(args.Blobs)
// Assume user provides either only blobs (w/o hashes), or // Assume user provides either only blobs (w/o hashes), or
// blobs together with commitments and proofs. // blobs together with commitments and proofs.
if args.Commitments == nil && args.Proofs != nil { if args.Commitments == nil && args.Proofs != nil {
@ -232,6 +228,7 @@ func (args *SendTxArgs) validateTxSidecar() error {
} }
// len(blobs) == len(commitments) == len(proofs) == len(hashes) // len(blobs) == len(commitments) == len(proofs) == len(hashes)
n := len(args.Blobs)
if args.Commitments != nil && len(args.Commitments) != n { if args.Commitments != nil && len(args.Commitments) != n {
return fmt.Errorf("number of blobs and commitments mismatch (have=%d, want=%d)", len(args.Commitments), n) return fmt.Errorf("number of blobs and commitments mismatch (have=%d, want=%d)", len(args.Commitments), n)
} }

View file

@ -129,11 +129,7 @@ func TestBlobTxs(t *testing.T) {
BlobFeeCap: uint256.NewInt(700), BlobFeeCap: uint256.NewInt(700),
BlobHashes: []common.Hash{hash}, BlobHashes: []common.Hash{hash},
Value: uint256.NewInt(100), Value: uint256.NewInt(100),
Sidecar: &types.BlobTxSidecar{ Sidecar: types.NewBlobTxSidecar(types.BlobSidecarVersion0, []kzg4844.Blob{blob}, []kzg4844.Commitment{commitment}, []kzg4844.Proof{proof}),
Blobs: []kzg4844.Blob{blob},
Commitments: []kzg4844.Commitment{commitment},
Proofs: []kzg4844.Proof{proof},
},
} }
tx := types.NewTx(b) tx := types.NewTx(b)
data, err := json.Marshal(tx) data, err := json.Marshal(tx)