mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-15 16:33:47 +00:00
core/txpool,core/types,eth: when receiving blob txs via PooledTransactions, validate that the 'blob_versioned_hashes' in the tx header is produced from the commitments in the sidecar.
This commit is contained in:
parent
aac621987e
commit
d62853e103
3 changed files with 35 additions and 13 deletions
|
|
@ -17,7 +17,6 @@
|
||||||
package txpool
|
package txpool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
@ -170,20 +169,11 @@ func validateBlobSidecar(hashes []common.Hash, sidecar *types.BlobTxSidecar) err
|
||||||
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", len(sidecar.Blobs), len(hashes))
|
return fmt.Errorf("invalid number of %d blobs compared to %d blob hashes", len(sidecar.Blobs), len(hashes))
|
||||||
}
|
}
|
||||||
if len(sidecar.Commitments) != len(hashes) {
|
|
||||||
return fmt.Errorf("invalid number of %d blob commitments compared to %d blob hashes", len(sidecar.Commitments), len(hashes))
|
|
||||||
}
|
|
||||||
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", len(sidecar.Proofs), len(hashes))
|
return fmt.Errorf("invalid number of %d blob proofs compared to %d blob hashes", len(sidecar.Proofs), len(hashes))
|
||||||
}
|
}
|
||||||
// Blob quantities match up, validate that the provers match with the
|
if err := sidecar.ValidateBlobCommitmentHashes(hashes); err != nil {
|
||||||
// transaction hash before getting to the cryptography
|
return err
|
||||||
hasher := sha256.New()
|
|
||||||
for i, vhash := range hashes {
|
|
||||||
computed := kzg4844.CalcBlobHashV1(hasher, &sidecar.Commitments[i])
|
|
||||||
if vhash != computed {
|
|
||||||
return fmt.Errorf("blob %d: computed hash %#x mismatches transaction one %#x", i, computed, vhash)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// 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
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ package types
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
@ -85,6 +86,28 @@ func (sc *BlobTxSidecar) encodedSize() uint64 {
|
||||||
return rlp.ListSize(blobs) + rlp.ListSize(commitments) + rlp.ListSize(proofs)
|
return rlp.ListSize(blobs) + rlp.ListSize(commitments) + rlp.ListSize(proofs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sc *BlobTxSidecar) ValidateBlobCommitmentHashes(hashes []common.Hash) error {
|
||||||
|
if len(sc.Blobs) != len(hashes) {
|
||||||
|
return fmt.Errorf("invalid number of %d blobs compared to %d blob hashes", len(sc.Blobs), len(hashes))
|
||||||
|
}
|
||||||
|
if len(sc.Commitments) != len(hashes) {
|
||||||
|
return fmt.Errorf("invalid number of %d blob commitments compared to %d blob hashes", len(sc.Commitments), len(hashes))
|
||||||
|
}
|
||||||
|
if len(sc.Proofs) != len(hashes) {
|
||||||
|
return fmt.Errorf("invalid number of %d blob proofs compared to %d blob hashes", len(sc.Proofs), len(hashes))
|
||||||
|
}
|
||||||
|
// Blob quantities match up, validate that the provers match with the
|
||||||
|
// transaction hash before getting to the cryptography
|
||||||
|
hasher := sha256.New()
|
||||||
|
for i, vhash := range hashes {
|
||||||
|
computed := kzg4844.CalcBlobHashV1(hasher, &sc.Commitments[i])
|
||||||
|
if vhash != computed {
|
||||||
|
return fmt.Errorf("blob %d: computed hash %#x mismatches transaction one %#x", i, computed, vhash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// blobTxWithBlobs is used for encoding of transactions when blobs are present.
|
// blobTxWithBlobs is used for encoding of transactions when blobs are present.
|
||||||
type blobTxWithBlobs struct {
|
type blobTxWithBlobs struct {
|
||||||
BlobTx *BlobTx
|
BlobTx *BlobTx
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ package eth
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/eth/protocols/eth"
|
"github.com/ethereum/go-ethereum/eth/protocols/eth"
|
||||||
|
|
@ -69,6 +68,16 @@ func (h *ethHandler) Handle(peer *eth.Peer, packet eth.Packet) error {
|
||||||
return h.txFetcher.Enqueue(peer.ID(), *packet, false)
|
return h.txFetcher.Enqueue(peer.ID(), *packet, false)
|
||||||
|
|
||||||
case *eth.PooledTransactionsResponse:
|
case *eth.PooledTransactionsResponse:
|
||||||
|
for _, tx := range *packet {
|
||||||
|
if tx.Type() == types.BlobTxType {
|
||||||
|
if tx.BlobTxSidecar() == nil {
|
||||||
|
return errors.New("received sidecar-less blob transaction")
|
||||||
|
}
|
||||||
|
if err := tx.BlobTxSidecar().ValidateBlobCommitmentHashes(tx.BlobHashes()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return h.txFetcher.Enqueue(peer.ID(), *packet, true)
|
return h.txFetcher.Enqueue(peer.ID(), *packet, true)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue