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"`
|
Commitments []hexutil.Bytes `json:"commitments"`
|
||||||
Proofs []hexutil.Bytes `json:"proofs"`
|
Proofs []hexutil.Bytes `json:"proofs"`
|
||||||
Blobs []hexutil.Bytes `json:"blobs"`
|
Blobs []hexutil.Bytes `json:"blobs"`
|
||||||
|
CellProofs []hexutil.Bytes `json:"cellProofs"` // Added in Osaka for 7594
|
||||||
}
|
}
|
||||||
|
|
||||||
type BlobAndProofV1 struct {
|
type BlobAndProofV1 struct {
|
||||||
Blob hexutil.Bytes `json:"blob"`
|
Blob hexutil.Bytes `json:"blob"`
|
||||||
Proof hexutil.Bytes `json:"proof"`
|
Proof hexutil.Bytes `json:"proof"`
|
||||||
|
CellProofs []hexutil.Bytes `json:"cellProofs"` // Added in Osaka for 7594
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON type overrides for ExecutionPayloadEnvelope.
|
// JSON type overrides for ExecutionPayloadEnvelope.
|
||||||
|
|
@ -326,6 +328,7 @@ func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars []*types.
|
||||||
Commitments: make([]hexutil.Bytes, 0),
|
Commitments: make([]hexutil.Bytes, 0),
|
||||||
Blobs: make([]hexutil.Bytes, 0),
|
Blobs: make([]hexutil.Bytes, 0),
|
||||||
Proofs: make([]hexutil.Bytes, 0),
|
Proofs: make([]hexutil.Bytes, 0),
|
||||||
|
CellProofs: make([]hexutil.Bytes, 0),
|
||||||
}
|
}
|
||||||
for _, sidecar := range sidecars {
|
for _, sidecar := range sidecars {
|
||||||
for j := range sidecar.Blobs {
|
for j := range sidecar.Blobs {
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
gokzg4844 "github.com/crate-crypto/go-eth-kzg"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
|
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
|
||||||
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
|
"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.
|
// 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
|
// This is a utility method for the engine API, enabling consensus clients to
|
||||||
// retrieve blobs from the pools directly instead of the network.
|
// 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) {
|
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
|
// Create a map of the blob hash to indices for faster fills
|
||||||
var (
|
var (
|
||||||
blobs = make([]*kzg4844.Blob, len(vhashes))
|
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
|
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 {
|
func validateBlobSidecar(cfg *params.ChainConfig, time uint64, hashes []common.Hash, sidecar *types.BlobTxSidecar) error {
|
||||||
if len(sidecar.Blobs) != len(hashes) {
|
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 {
|
if err := sidecar.ValidateBlobCommitmentHashes(hashes); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -178,7 +178,7 @@ func validateBlobSidecar(cfg *params.ChainConfig, time uint64, hashes []common.H
|
||||||
fork := cfg.LatestFork(time)
|
fork := cfg.LatestFork(time)
|
||||||
if fork >= forks.Osaka {
|
if fork >= forks.Osaka {
|
||||||
if len(sidecar.Blobs)*gokzg4844.CellsPerExtBlob != len(sidecar.Proofs) {
|
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
|
// 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
|
// Compute cells for the currentblob
|
||||||
blobCells, err := kzg4844.ComputeCells(&sidecar.Blobs[i])
|
blobCells, err := kzg4844.ComputeCells(&sidecar.Blobs[i])
|
||||||
if err != nil {
|
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...)
|
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 {
|
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
|
} else { // older folks
|
||||||
if len(sidecar.Proofs) != len(hashes) {
|
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
|
// Blob commitments match with the hashes in the transaction, verify the
|
||||||
// blobs themselves via KZG
|
// blobs themselves via KZG
|
||||||
for i := range sidecar.Blobs {
|
for i := range sidecar.Blobs {
|
||||||
if err := kzg4844.VerifyBlobProof(&sidecar.Blobs[i], sidecar.Commitments[i], sidecar.Proofs[i]); err != nil {
|
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"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
gokzg4844 "github.com/crate-crypto/go-eth-kzg"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/beacon/engine"
|
"github.com/ethereum/go-ethereum/beacon/engine"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
|
@ -536,6 +538,21 @@ func (api *ConsensusAPI) GetBlobsV1(hashes []common.Hash) ([]*engine.BlobAndProo
|
||||||
res := make([]*engine.BlobAndProofV1, len(hashes))
|
res := make([]*engine.BlobAndProofV1, len(hashes))
|
||||||
|
|
||||||
blobs, proofs := api.eth.TxPool().GetBlobs(hashes)
|
blobs, proofs := api.eth.TxPool().GetBlobs(hashes)
|
||||||
|
// 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++ {
|
for i := 0; i < len(blobs); i++ {
|
||||||
if blobs[i] != nil {
|
if blobs[i] != nil {
|
||||||
res[i] = &engine.BlobAndProofV1{
|
res[i] = &engine.BlobAndProofV1{
|
||||||
|
|
@ -544,6 +561,8 @@ func (api *ConsensusAPI) GetBlobsV1(hashes []common.Hash) ([]*engine.BlobAndProo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue