mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 07:06:42 +00:00
Implement fulu related change to getblobsv1 and getpayloadv4
This commit is contained in:
parent
2e2eebe252
commit
c4be2bbd19
4 changed files with 100 additions and 13 deletions
|
|
@ -116,11 +116,13 @@ type BlobsBundleV1 struct {
|
|||
Commitments []hexutil.Bytes `json:"commitments"`
|
||||
Proofs []hexutil.Bytes `json:"proofs"`
|
||||
Blobs []hexutil.Bytes `json:"blobs"`
|
||||
CellProofs []hexutil.Bytes `json:"cellProofs"` // Added in Osaka for 7594
|
||||
}
|
||||
|
||||
type BlobAndProofV1 struct {
|
||||
Blob hexutil.Bytes `json:"blob"`
|
||||
Proof hexutil.Bytes `json:"proof"`
|
||||
Blob hexutil.Bytes `json:"blob"`
|
||||
Proof hexutil.Bytes `json:"proof"`
|
||||
CellProofs []hexutil.Bytes `json:"cellProofs"` // Added in Osaka for 7594
|
||||
}
|
||||
|
||||
// JSON type overrides for ExecutionPayloadEnvelope.
|
||||
|
|
@ -326,6 +328,7 @@ func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars []*types.
|
|||
Commitments: make([]hexutil.Bytes, 0),
|
||||
Blobs: make([]hexutil.Bytes, 0),
|
||||
Proofs: make([]hexutil.Bytes, 0),
|
||||
CellProofs: make([]hexutil.Bytes, 0),
|
||||
}
|
||||
for _, sidecar := range sidecars {
|
||||
for j := range sidecar.Blobs {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
gokzg4844 "github.com/crate-crypto/go-eth-kzg"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
|
||||
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
|
||||
|
|
@ -1239,7 +1241,12 @@ func (p *BlobPool) GetRLP(hash common.Hash) []byte {
|
|||
// GetBlobs returns a number of blobs are proofs for the given versioned hashes.
|
||||
// This is a utility method for the engine API, enabling consensus clients to
|
||||
// retrieve blobs from the pools directly instead of the network.
|
||||
// After Osaka, the proofs are returned as cell proofs.
|
||||
func (p *BlobPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Proof) {
|
||||
if p.chain.Config().IsOsaka(p.head.Number, p.head.Time) {
|
||||
return p.GetBlobsWithCellProofs(vhashes)
|
||||
}
|
||||
|
||||
// Create a map of the blob hash to indices for faster fills
|
||||
var (
|
||||
blobs = make([]*kzg4844.Blob, len(vhashes))
|
||||
|
|
@ -1285,6 +1292,64 @@ func (p *BlobPool) GetBlobs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return blobs, proofs
|
||||
}
|
||||
|
||||
// GetBlobsWithCellProofs returns a number of blobs and cell proofs for the given versioned hashes after Osaka.
|
||||
func (p *BlobPool) GetBlobsWithCellProofs(vhashes []common.Hash) ([]*kzg4844.Blob, []*kzg4844.Proof) {
|
||||
var (
|
||||
blobs = make([]*kzg4844.Blob, len(vhashes))
|
||||
proofs = make([]*kzg4844.Proof, len(vhashes)*gokzg4844.CellsPerExtBlob)
|
||||
)
|
||||
|
||||
index := make(map[common.Hash]int)
|
||||
for i, vhash := range vhashes {
|
||||
index[vhash] = i
|
||||
}
|
||||
|
||||
for i, vhash := range vhashes {
|
||||
if blobs[i] != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
p.lock.RLock()
|
||||
id, exists := p.lookup.storeidOfBlob(vhash)
|
||||
if !exists {
|
||||
p.lock.RUnlock()
|
||||
continue
|
||||
}
|
||||
data, err := p.store.Get(id)
|
||||
p.lock.RUnlock()
|
||||
|
||||
if err != nil {
|
||||
log.Error("Tracked blob transaction missing from store", "id", id, "err", err)
|
||||
continue
|
||||
}
|
||||
item := new(types.Transaction)
|
||||
if err = rlp.DecodeBytes(data, item); err != nil {
|
||||
log.Error("Blobs corrupted for traced transaction", "id", id, "err", err)
|
||||
continue
|
||||
}
|
||||
sidecar := item.BlobTxSidecar()
|
||||
if len(sidecar.Blobs)*gokzg4844.CellsPerExtBlob != len(sidecar.Proofs) {
|
||||
log.Warn("potentially old blob tx with blob proofs, dropping it")
|
||||
//TODO: implement dropping of blob txs
|
||||
continue
|
||||
}
|
||||
for j, blobhash := range item.BlobHashes() {
|
||||
if idx, ok := index[blobhash]; ok {
|
||||
blobs[idx] = &sidecar.Blobs[j]
|
||||
|
||||
proofStart := idx * gokzg4844.CellsPerExtBlob
|
||||
sidecarStart := j * gokzg4844.CellsPerExtBlob
|
||||
for k := 0; k < gokzg4844.CellsPerExtBlob; k++ {
|
||||
proofs[proofStart+k] = &sidecar.Proofs[sidecarStart+k]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return blobs, proofs
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
|
|||
|
||||
func validateBlobSidecar(cfg *params.ChainConfig, time uint64, hashes []common.Hash, sidecar *types.BlobTxSidecar) error {
|
||||
if len(sidecar.Blobs) != len(hashes) {
|
||||
return fmt.Errorf("invalid number of %d blobs compared to %d blob hashes", ErrInvalidBlobSidecar, len(sidecar.Blobs), len(hashes))
|
||||
return fmt.Errorf("%w: invalid number of %d blobs compared to %d blob hashes", ErrInvalidBlobSidecar, len(sidecar.Blobs), len(hashes))
|
||||
}
|
||||
if err := sidecar.ValidateBlobCommitmentHashes(hashes); err != nil {
|
||||
return err
|
||||
|
|
@ -178,7 +178,7 @@ func validateBlobSidecar(cfg *params.ChainConfig, time uint64, hashes []common.H
|
|||
fork := cfg.LatestFork(time)
|
||||
if fork >= forks.Osaka {
|
||||
if len(sidecar.Blobs)*gokzg4844.CellsPerExtBlob != len(sidecar.Proofs) {
|
||||
return fmt.Errorf("invalid number of %d cell proofs compared to %d blobs", ErrInvalidBlobSidecar, len(sidecar.Proofs), len(sidecar.Blobs))
|
||||
return fmt.Errorf("%w: invalid number of %d cell proofs compared to %d blobs", ErrInvalidBlobSidecar, len(sidecar.Proofs), len(sidecar.Blobs))
|
||||
}
|
||||
|
||||
// Prepare cells and cell indices for each blob
|
||||
|
|
@ -189,7 +189,7 @@ func validateBlobSidecar(cfg *params.ChainConfig, time uint64, hashes []common.H
|
|||
// Compute cells for the currentblob
|
||||
blobCells, err := kzg4844.ComputeCells(&sidecar.Blobs[i])
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to compute cells for blob %d: %v", ErrInvalidBlobSidecar, i, err)
|
||||
return fmt.Errorf("%w: failed to compute cells for blob %d: %v", ErrInvalidBlobSidecar, i, err)
|
||||
}
|
||||
|
||||
cells = append(cells, blobCells...)
|
||||
|
|
@ -199,18 +199,18 @@ func validateBlobSidecar(cfg *params.ChainConfig, time uint64, hashes []common.H
|
|||
}
|
||||
|
||||
if err := kzg4844.VerifyCellKZGProofBatch(sidecar.Commitments, cellIndices, cells, sidecar.Proofs); err != nil {
|
||||
return fmt.Errorf("failed to verify cell proofs: %v", ErrInvalidBlobSidecar, err)
|
||||
return fmt.Errorf("%w: failed to verify cell proofs: %v", ErrInvalidBlobSidecar, err)
|
||||
}
|
||||
} else { // older folks
|
||||
if len(sidecar.Proofs) != len(hashes) {
|
||||
return fmt.Errorf("invalid number of %d blob proofs compared to %d blob hashes", ErrInvalidBlobSidecar, len(sidecar.Proofs), len(hashes))
|
||||
return fmt.Errorf("%w: invalid number of %d blob proofs compared to %d blob hashes", ErrInvalidBlobSidecar, len(sidecar.Proofs), len(hashes))
|
||||
}
|
||||
|
||||
// Blob commitments match with the hashes in the transaction, verify the
|
||||
// blobs themselves via KZG
|
||||
for i := range sidecar.Blobs {
|
||||
if err := kzg4844.VerifyBlobProof(&sidecar.Blobs[i], sidecar.Commitments[i], sidecar.Proofs[i]); err != nil {
|
||||
return fmt.Errorf("invalid blob %d: %v", ErrInvalidBlobSidecar, i, err)
|
||||
return fmt.Errorf("%w: invalid blob %d: %v", ErrInvalidBlobSidecar, i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
gokzg4844 "github.com/crate-crypto/go-eth-kzg"
|
||||
|
||||
"github.com/ethereum/go-ethereum/beacon/engine"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
|
|
@ -536,14 +538,31 @@ func (api *ConsensusAPI) GetBlobsV1(hashes []common.Hash) ([]*engine.BlobAndProo
|
|||
res := make([]*engine.BlobAndProofV1, len(hashes))
|
||||
|
||||
blobs, proofs := api.eth.TxPool().GetBlobs(hashes)
|
||||
for i := 0; i < len(blobs); i++ {
|
||||
if blobs[i] != nil {
|
||||
res[i] = &engine.BlobAndProofV1{
|
||||
Blob: (*blobs[i])[:],
|
||||
Proof: (*proofs[i])[:],
|
||||
// after Osaka, the proofs are returned as cell proofs.
|
||||
if len(blobs) != len(proofs) {
|
||||
for i := range blobs {
|
||||
if blobs[i] != nil {
|
||||
cellProofs := make([]hexutil.Bytes, gokzg4844.CellsPerExtBlob)
|
||||
for j := range cellProofs {
|
||||
cellProofs[j] = hexutil.Bytes((*proofs[i*gokzg4844.CellsPerExtBlob+j])[:])
|
||||
}
|
||||
res[i] = &engine.BlobAndProofV1{
|
||||
Blob: (*blobs[i])[:],
|
||||
CellProofs: cellProofs,
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for i := 0; i < len(blobs); i++ {
|
||||
if blobs[i] != nil {
|
||||
res[i] = &engine.BlobAndProofV1{
|
||||
Blob: (*blobs[i])[:],
|
||||
Proof: (*proofs[i])[:],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue