Skip to content

Commit

Permalink
Merge pull request #105 from kevaundray/kw/crypto-free-the-blobs
Browse files Browse the repository at this point in the history
Update code for free the blobs
  • Loading branch information
kevaundray authored Mar 14, 2023
2 parents 5ee2738 + 602ad1f commit b64dfe5
Show file tree
Hide file tree
Showing 17 changed files with 117 additions and 522 deletions.
8 changes: 4 additions & 4 deletions accounts/external/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,14 @@ func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transactio
args.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap())
args.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap())
case types.BlobTxType:
hashes, _, blobs, aggProof := tx.BlobWrapData()
hashes, _, blobs, proofs := tx.BlobWrapData()
if len(hashes) != len(blobs) {
return nil, fmt.Errorf("missing blobs data, expected %d blobs", len(hashes))
}
var z types.KZGProof
if aggProof == z {
return nil, fmt.Errorf("missing aggregated proof in blobs")
if len(hashes) != len(proofs) {
return nil, fmt.Errorf("missing proofs data, expected %d proofs", len(proofs))
}

args.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap())
args.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap())
args.Blobs = blobs
Expand Down
12 changes: 4 additions & 8 deletions beacon/engine/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package engine

import (
"errors"
"fmt"
"math/big"

Expand Down Expand Up @@ -257,15 +256,12 @@ func BlockToBlobData(block *types.Block) (*BlobsBundle, error) {
}
for i, tx := range block.Transactions() {
if tx.Type() == types.BlobTxType {
versionedHashes, kzgs, blobs, aggProof := tx.BlobWrapData()
if len(versionedHashes) != len(kzgs) || len(versionedHashes) != len(blobs) {
versionedHashes, kzgs, blobs, proofs := tx.BlobWrapData()
if len(versionedHashes) != len(kzgs) || len(versionedHashes) != len(blobs) || len(blobs) != len(proofs) {
return nil, fmt.Errorf("tx %d in block %s has inconsistent blobs (%d) / kzgs (%d)"+
" / versioned hashes (%d)", i, blockHash, len(blobs), len(kzgs), len(versionedHashes))
}
var zProof types.KZGProof
if zProof == aggProof {
return nil, errors.New("aggregated proof is not available in blobs")
" / versioned hashes (%d) / proofs (%d)", i, blockHash, len(blobs), len(kzgs), len(versionedHashes), len(proofs))
}

blobsBundle.Blobs = append(blobsBundle.Blobs, blobs...)
blobsBundle.KZGs = append(blobsBundle.KZGs, kzgs...)
}
Expand Down
4 changes: 2 additions & 2 deletions core/txpool/txpool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,11 @@ func blobTx(nonce uint64, gaslimit uint64, gasFee uint64, tip uint64, dataGasFee
for i := 0; i < len(blobData.BlobKzgs); i++ {
hashes = append(hashes, blobData.BlobKzgs[i].ComputeVersionedHash())
}
_, _, aggregatedProof, err := blobData.Blobs.ComputeCommitmentsAndAggregatedProof()
_, _, proofs, err := blobData.Blobs.ComputeCommitmentsAndProofs()
if err != nil {
panic(err)
}
blobData.KzgAggregatedProof = aggregatedProof
blobData.Proofs = proofs

address := types.AddressSSZ(common.Address{})
sbtx := &types.SignedBlobTx{
Expand Down
103 changes: 70 additions & 33 deletions core/types/data_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"io"

"github.com/crate-crypto/go-proto-danksharding-crypto/eth"
api "github.com/crate-crypto/go-proto-danksharding-crypto/serialisation"
api "github.com/crate-crypto/go-proto-danksharding-crypto/serialization"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/params"
Expand Down Expand Up @@ -199,6 +199,36 @@ func (li BlobKzgs) copy() BlobKzgs {
return cpy
}

type KZGProofs []KZGProof

func (li *KZGProofs) Deserialize(dr *codec.DecodingReader) error {
return dr.List(func() codec.Deserializable {
i := len(*li)
*li = append(*li, KZGProof{})
return &(*li)[i]
}, 48, params.MaxBlobsPerBlock)
}

func (li KZGProofs) Serialize(w *codec.EncodingWriter) error {
return w.List(func(i uint64) codec.Serializable {
return &li[i]
}, 48, uint64(len(li)))
}

func (li KZGProofs) ByteLength() uint64 {
return uint64(len(li)) * 48
}

func (li KZGProofs) FixedLength() uint64 {
return 0
}

func (li KZGProofs) copy() KZGProofs {
cpy := make(KZGProofs, len(li))
copy(cpy, li)
return cpy
}

type Blobs []Blob

func (a *Blobs) Deserialize(dr *codec.DecodingReader) error {
Expand Down Expand Up @@ -229,28 +259,28 @@ func (blobs Blobs) copy() Blobs {
return cpy
}

// Return KZG commitments, versioned hashes and the aggregated KZG proof that correspond to these blobs
func (blobs Blobs) ComputeCommitmentsAndAggregatedProof() (commitments []KZGCommitment, versionedHashes []common.Hash, aggregatedProof KZGProof, err error) {
// Return KZG commitments, versioned hashes and the proofs that correspond to these blobs
func (blobs Blobs) ComputeCommitmentsAndProofs() (commitments []KZGCommitment, versionedHashes []common.Hash, proofs []KZGProof, err error) {
commitments = make([]KZGCommitment, len(blobs))
proofs = make([]KZGProof, len(blobs))
versionedHashes = make([]common.Hash, len(blobs))

for i, blob := range blobs {
commitment, err := eth.CryptoCtx.BlobToCommitment(blob)
commitment, err := eth.CryptoCtx.BlobToKZGCommitment(blob)
if err != nil {
return nil, nil, nil, fmt.Errorf("could not convert blob to commitment: %v", err)
}

return nil, nil, KZGProof{}, fmt.Errorf("could not convert blob to commitment: %v", err)
proof, err := eth.CryptoCtx.ComputeBlobKZGProof(blob, commitment)
if err != nil {
return nil, nil, nil, fmt.Errorf("could not compute proof for blob: %v", err)
}
commitments[i] = KZGCommitment(commitment)
proofs[i] = KZGProof(proof)
versionedHashes[i] = common.Hash(eth.KZGToVersionedHash(commitment))
}

proof, _, err := eth.CryptoCtx.ComputeAggregateKZGProof(toBlobs(blobs))
if err != nil {
return nil, nil, KZGProof{}, err
}
var kzgProof = KZGProof(proof)

return commitments, versionedHashes, kzgProof, nil
return commitments, versionedHashes, proofs, nil
}

func toBlobs(_blobs Blobs) []api.Blob {
Expand All @@ -267,39 +297,46 @@ func toComms(_comms BlobKzgs) []api.KZGCommitment {
}
return comms
}
func toProofs(_proofs KZGProofs) []api.KZGProof {
proofs := make([]api.KZGProof, len(_proofs))
for i, _proof := range _proofs {
proofs[i] = api.KZGProof(_proof)
}
return proofs
}

type BlobTxWrapper struct {
Tx SignedBlobTx
BlobKzgs BlobKzgs
Blobs Blobs
KzgAggregatedProof KZGProof
Tx SignedBlobTx
BlobKzgs BlobKzgs
Blobs Blobs
Proofs KZGProofs
}

func (txw *BlobTxWrapper) Deserialize(dr *codec.DecodingReader) error {
return dr.Container(&txw.Tx, &txw.BlobKzgs, &txw.Blobs, &txw.KzgAggregatedProof)
return dr.Container(&txw.Tx, &txw.BlobKzgs, &txw.Blobs, &txw.Proofs)
}

func (txw *BlobTxWrapper) Serialize(w *codec.EncodingWriter) error {
return w.Container(&txw.Tx, &txw.BlobKzgs, &txw.Blobs, &txw.KzgAggregatedProof)
return w.Container(&txw.Tx, &txw.BlobKzgs, &txw.Blobs, &txw.Proofs)
}

func (txw *BlobTxWrapper) ByteLength() uint64 {
return codec.ContainerLength(&txw.Tx, &txw.BlobKzgs, &txw.Blobs, &txw.KzgAggregatedProof)
return codec.ContainerLength(&txw.Tx, &txw.BlobKzgs, &txw.Blobs, &txw.Proofs)
}

func (txw *BlobTxWrapper) FixedLength() uint64 {
return 0
}

type BlobTxWrapData struct {
BlobKzgs BlobKzgs
Blobs Blobs
KzgAggregatedProof KZGProof
BlobKzgs BlobKzgs
Blobs Blobs
Proofs KZGProofs
}

// sizeWrapData returns the size in bytes of the ssz-encoded BlobTxWrapData
func (b *BlobTxWrapData) sizeWrapData() common.StorageSize {
return common.StorageSize(codec.ContainerLength(&b.BlobKzgs, &b.Blobs, &b.KzgAggregatedProof))
return common.StorageSize(codec.ContainerLength(&b.BlobKzgs, &b.Blobs, &b.Proofs))
}

// validateBlobTransactionWrapper implements validate_blob_transaction_wrapper from EIP-4844
Expand All @@ -320,7 +357,7 @@ func (b *BlobTxWrapData) validateBlobTransactionWrapper(inner TxData) error {
if l1 > params.MaxBlobsPerBlock {
return fmt.Errorf("number of blobs exceeds max: %v", l1)
}
err := eth.CryptoCtx.VerifyAggregateKZGProof(toBlobs(b.Blobs), api.KZGProof(b.KzgAggregatedProof), toComms(b.BlobKzgs))
err := eth.CryptoCtx.VerifyBlobKZGProofBatch(toBlobs(b.Blobs), toProofs(b.Proofs), toComms(b.BlobKzgs))
if err != nil {
return fmt.Errorf("error during proof verification: %v", err)
}
Expand All @@ -337,9 +374,9 @@ func (b *BlobTxWrapData) validateBlobTransactionWrapper(inner TxData) error {

func (b *BlobTxWrapData) copy() TxWrapData {
return &BlobTxWrapData{
BlobKzgs: b.BlobKzgs.copy(),
Blobs: b.Blobs.copy(),
KzgAggregatedProof: b.KzgAggregatedProof,
BlobKzgs: b.BlobKzgs.copy(),
Blobs: b.Blobs.copy(),
Proofs: b.Proofs.copy(),
}
}

Expand All @@ -351,8 +388,8 @@ func (b *BlobTxWrapData) blobs() Blobs {
return b.Blobs
}

func (b *BlobTxWrapData) aggregatedProof() KZGProof {
return b.KzgAggregatedProof
func (b *BlobTxWrapData) proofs() KZGProofs {
return b.Proofs
}

func (b *BlobTxWrapData) encodeTyped(w io.Writer, txdata TxData) error {
Expand All @@ -364,10 +401,10 @@ func (b *BlobTxWrapData) encodeTyped(w io.Writer, txdata TxData) error {
return fmt.Errorf("expected signed blob tx, got %T", txdata)
}
wrapped := BlobTxWrapper{
Tx: *blobTx,
BlobKzgs: b.BlobKzgs,
Blobs: b.Blobs,
KzgAggregatedProof: b.KzgAggregatedProof,
Tx: *blobTx,
BlobKzgs: b.BlobKzgs,
Blobs: b.Blobs,
Proofs: b.Proofs,
}
return EncodeSSZ(w, &wrapped)
}
10 changes: 5 additions & 5 deletions core/types/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ type TxWrapData interface {
copy() TxWrapData
kzgs() BlobKzgs
blobs() Blobs
aggregatedProof() KZGProof
proofs() KZGProofs
encodeTyped(w io.Writer, txdata TxData) error
sizeWrapData() common.StorageSize
validateBlobTransactionWrapper(inner TxData) error
Expand Down Expand Up @@ -270,7 +270,7 @@ func (tx *Transaction) decodeTyped(b []byte) (TxData, TxWrapData, error) {
case BlobTxType:
var wrapped BlobTxWrapper
err := DecodeSSZ(b[1:], &wrapped)
return &wrapped.Tx, &BlobTxWrapData{BlobKzgs: wrapped.BlobKzgs, Blobs: wrapped.Blobs, KzgAggregatedProof: wrapped.KzgAggregatedProof}, err
return &wrapped.Tx, &BlobTxWrapData{BlobKzgs: wrapped.BlobKzgs, Blobs: wrapped.Blobs, Proofs: wrapped.Proofs}, err
default:
minimal, err := tx.decodeTypedMinimal(b)
return minimal, nil, err
Expand Down Expand Up @@ -555,13 +555,13 @@ func (tx *Transaction) VerifyBlobs() error {

// BlobWrapData returns the blob and kzg data, if any.
// kzgs and blobs may be empty if the transaction is not wrapped.
func (tx *Transaction) BlobWrapData() (versionedHashes []common.Hash, kzgs BlobKzgs, blobs Blobs, aggProof KZGProof) {
func (tx *Transaction) BlobWrapData() (versionedHashes []common.Hash, kzgs BlobKzgs, blobs Blobs, proofs KZGProofs) {
if blobWrap, ok := tx.wrapData.(*BlobTxWrapData); ok {
if signedBlobTx, ok := tx.inner.(*SignedBlobTx); ok {
return signedBlobTx.Message.BlobVersionedHashes, blobWrap.BlobKzgs, blobWrap.Blobs, blobWrap.KzgAggregatedProof
return signedBlobTx.Message.BlobVersionedHashes, blobWrap.BlobKzgs, blobWrap.Blobs, blobWrap.Proofs
}
}
return nil, nil, nil, KZGProof{}
return nil, nil, nil, nil
}

// WithSignature returns a new transaction with the given signature.
Expand Down
10 changes: 5 additions & 5 deletions core/types/transaction_marshalling.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ type txJSON struct {
BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"`
Blobs Blobs `json:"blobs,omitempty"`
BlobKzgs BlobKzgs `json:"blobKzgs,omitempty"`
KzgAggregatedProof KZGProof `json:"kzgAggregatedProof,omitempty"`
Proofs KZGProofs `json:"proofs,omitempty"`

// Only used for encoding:
Hash common.Hash `json:"hash"`
Expand Down Expand Up @@ -123,7 +123,7 @@ func (tx *Transaction) MarshalJSON() ([]byte, error) {
if tx.wrapData != nil {
enc.Blobs = tx.wrapData.blobs()
enc.BlobKzgs = tx.wrapData.kzgs()
enc.KzgAggregatedProof = tx.wrapData.aggregatedProof()
enc.Proofs = tx.wrapData.proofs()
}
}
return json.Marshal(&enc)
Expand Down Expand Up @@ -362,9 +362,9 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
// A BlobTx may not contain data
if len(dec.Blobs) != 0 || len(dec.BlobKzgs) != 0 {
tx.wrapData = &BlobTxWrapData{
BlobKzgs: dec.BlobKzgs,
Blobs: dec.Blobs,
KzgAggregatedProof: dec.KzgAggregatedProof,
BlobKzgs: dec.BlobKzgs,
Blobs: dec.Blobs,
Proofs: dec.Proofs,
}
// Verify that versioned hashes match kzgs, and kzgs match blobs.
if err := tx.wrapData.validateBlobTransactionWrapper(&itx); err != nil {
Expand Down
6 changes: 3 additions & 3 deletions core/types/transaction_signing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@ func TestEIP4844Signing(t *testing.T) {
// This is the identity point serialised
var kzgProof KZGProof = [48]byte{192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
wrapData := &BlobTxWrapData{
BlobKzgs: BlobKzgs{KZGCommitment{0: 0xc0}},
Blobs: Blobs{Blob{}},
KzgAggregatedProof: kzgProof,
BlobKzgs: BlobKzgs{KZGCommitment{0: 0xc0}},
Blobs: Blobs{Blob{}},
Proofs: KZGProofs{kzgProof},
}
tx := NewTx(txdata, WithTxWrapData(wrapData))
tx, err := SignTx(tx, signer, key)
Expand Down
6 changes: 3 additions & 3 deletions core/types/transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -495,9 +495,9 @@ func TestTransactionCoding(t *testing.T) {
// This is the identity point serialised
var kzgProof KZGProof = [48]byte{192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
wrapData = &BlobTxWrapData{
BlobKzgs: BlobKzgs{KZGCommitment{0: 0xc0}},
Blobs: Blobs{Blob{}},
KzgAggregatedProof: kzgProof,
BlobKzgs: BlobKzgs{KZGCommitment{0: 0xc0}},
Blobs: Blobs{Blob{}},
Proofs: KZGProofs{kzgProof},
}
}
tx, err := SignNewTx(key, signer, txdata, WithTxWrapData(wrapData))
Expand Down
6 changes: 3 additions & 3 deletions core/types/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,9 @@ func benchRLP(b *testing.B, encode bool) {
BlobVersionedHashes: VersionedHashesView{common.Hash{0xaa}},
},
}, WithTxWrapData(&BlobTxWrapData{
BlobKzgs: BlobKzgs{KZGCommitment{0xbb}},
Blobs: Blobs{Blob{}},
KzgAggregatedProof: KZGProof{0xbc},
BlobKzgs: BlobKzgs{KZGCommitment{0xbb}},
Blobs: Blobs{Blob{}},
Proofs: KZGProofs{KZGProof{0xbc}},
})),
},
} {
Expand Down
8 changes: 4 additions & 4 deletions eth/catalyst/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1614,7 +1614,7 @@ func newRandomBlobTx(t *testing.T, chain *core.BlockChain, nonce uint64) *types.
var blobs types.Blobs
blobs = append(blobs, types.Blob{})

commitments, versionedHashes, aggregatedProof, err := blobs.ComputeCommitmentsAndAggregatedProof()
commitments, versionedHashes, proofs, err := blobs.ComputeCommitmentsAndProofs()
if err != nil {
t.Fatal(err)
}
Expand All @@ -1639,9 +1639,9 @@ func newRandomBlobTx(t *testing.T, chain *core.BlockChain, nonce uint64) *types.
},
}
wrapData := &types.BlobTxWrapData{
BlobKzgs: commitments,
Blobs: blobs,
KzgAggregatedProof: aggregatedProof,
BlobKzgs: commitments,
Blobs: blobs,
Proofs: proofs,
}
tx := types.NewTx(txData, types.WithTxWrapData(wrapData))
signer := types.NewDankSigner(chainID)
Expand Down
6 changes: 3 additions & 3 deletions eth/handler_eth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,9 +462,9 @@ func testTransactionPropagation(t *testing.T, protocol uint) {
},
}
wrapData := &types.BlobTxWrapData{
BlobKzgs: types.BlobKzgs{types.KZGCommitment{0: 0xc0}},
Blobs: types.Blobs{types.Blob{}},
KzgAggregatedProof: types.KZGProof{0: 0xd0},
BlobKzgs: types.BlobKzgs{types.KZGCommitment{0: 0xc0}},
Blobs: types.Blobs{types.Blob{}},
Proofs: types.KZGProofs{types.KZGProof{0: 0xd0}},
}
blobTx, err := types.SignNewTx(testKey, types.NewDankSigner(common.Big1), txdata, types.WithTxWrapData(wrapData))
if err != nil {
Expand Down
Loading

0 comments on commit b64dfe5

Please sign in to comment.