Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove signed blob sidecars #17

Merged
merged 2 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,4 @@ The callback can then use the slot number to determine whether to throw an error
- `POST` `/mock/invalid/payload/{type}/<slot|epoch>/{slot/epoch number}`: Enables specified [type](#payload-invalidation-types) of modification to payload built starting at the slot or epoch specified

# Statistics
- `GET` `/mock/stats/validation_errors`: Returns a JSON containing all the errors encountered when validating the submitted signed blinded responses from the consensus client (e.g. Invalid signature on submitted blinded block, invalid signature on submitted blinded blob sidecar)
- `GET` `/mock/stats/validation_errors`: Returns a JSON containing all the errors encountered when validating the submitted signed blinded responses from the consensus client (e.g. Invalid signature on submitted blinded block)
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.20
require (
github.com/ethereum/go-ethereum v1.13.1
github.com/gorilla/mux v1.8.0
github.com/marioevz/eth-clients v0.0.0-20230925172743-e379ee1ecd6e
github.com/marioevz/eth-clients v0.0.0-20230925201418-d5fbddd99b76
github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7
github.com/protolambda/eth2api v0.0.0-20230316214135-5f8afbd6d05d
github.com/protolambda/zrnt v0.30.0
Expand Down Expand Up @@ -79,4 +79,6 @@ require (

replace github.com/protolambda/eth2api => github.com/marioevz/eth2api v0.0.0-20230922201437-72bd1301e033

replace github.com/protolambda/zrnt => github.com/marioevz/zrnt v0.26.2-0.20230922170744-1bd341bc7f0f
replace github.com/protolambda/zrnt => github.com/marioevz/zrnt v0.26.2-0.20231109183115-d2098ec1f42c

replace github.com/protolambda/ztyp => github.com/marioevz/ztyp v0.0.0-20231106221254-dd6f24f13fd9
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,14 @@ github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awS
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/marioevz/eth-clients v0.0.0-20230925172743-e379ee1ecd6e h1:uBr6Gn5jBHnyoS34HV4GOiYjuua6J/F2FST0T6MO89E=
github.com/marioevz/eth-clients v0.0.0-20230925172743-e379ee1ecd6e/go.mod h1:YVrdn57Q3rAzm3wus4T9tg1vMPca4csVbzorPhkGCW0=
github.com/marioevz/eth-clients v0.0.0-20230925201418-d5fbddd99b76 h1:fj+aeR3YLmSRUWjOGgTxNMdvzm72J5JbKGKosNO/jkE=
github.com/marioevz/eth-clients v0.0.0-20230925201418-d5fbddd99b76/go.mod h1:YVrdn57Q3rAzm3wus4T9tg1vMPca4csVbzorPhkGCW0=
github.com/marioevz/eth2api v0.0.0-20230922201437-72bd1301e033 h1:sn57n+lbJrLS8FKYs08W7TEzraTGOCQGrSC4hni6rYw=
github.com/marioevz/eth2api v0.0.0-20230922201437-72bd1301e033/go.mod h1:hcwWCT4sF1X7KsMZ535MvDZVk5M20Uyj+x2LARZjQsM=
github.com/marioevz/zrnt v0.26.2-0.20230922170744-1bd341bc7f0f h1:ysmQCP5asLCdFHib4ykgHVUSzCy9UEysElhMwJPmcg4=
github.com/marioevz/zrnt v0.26.2-0.20230922170744-1bd341bc7f0f/go.mod h1:MzAcHPo2QQIx+IEPdxXMiqKtYRUlszz7RA/fhAuOm1I=
github.com/marioevz/zrnt v0.26.2-0.20231109183115-d2098ec1f42c h1:ZwKLkGVKnAq1JZql6SBrQici0la1X7APcbBLwmrSsd4=
github.com/marioevz/zrnt v0.26.2-0.20231109183115-d2098ec1f42c/go.mod h1:ZctXHBa/2rlF85iao8oqQ8264DbEBBGWr6lwIOW2yv4=
github.com/marioevz/ztyp v0.0.0-20231106221254-dd6f24f13fd9 h1:e40k7kQLw2jyDg4+Mc+TVSSfm1TO51NxPZo9T7nVCzM=
github.com/marioevz/ztyp v0.0.0-20231106221254-dd6f24f13fd9/go.mod h1:9bYgKGqg3wJqT9ac1gI2hnVb0STQq7p/1lapqrqY1dU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
Expand Down Expand Up @@ -280,8 +282,6 @@ github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJf
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7 h1:cZC+usqsYgHtlBaGulVnZ1hfKAi8iWtujBnRLQE698c=
github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7/go.mod h1:IToEjHuttnUzwZI5KBSM/LOOW3qLbbrHOEfp3SbECGY=
github.com/protolambda/ztyp v0.2.2 h1:rVcL3vBu9W/aV646zF6caLS/dyn9BN8NYiuJzicLNyY=
github.com/protolambda/ztyp v0.2.2/go.mod h1:9bYgKGqg3wJqT9ac1gI2hnVb0STQq7p/1lapqrqY1dU=
github.com/rauljordan/engine-proxy v0.0.0-20230316220057-4c80c36c4c3a h1:ZIfMLprHVdo2vs3WcSqSDEyz2ZsSzDhGeOyxh8VQThA=
github.com/rauljordan/engine-proxy v0.0.0-20230316220057-4c80c36c4c3a/go.mod h1:9OVXfWYnIV+wj1/SqfdREmE5mzN/OANAgdOJRtFtvpo=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
Expand Down
2 changes: 1 addition & 1 deletion mock/mock_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1171,7 +1171,7 @@ func (m *MockBuilder) HandleSubmitBlindedBlock(
signedBeaconResponse common.SignedBeaconResponse
)
if m.cfg.spec.SlotToEpoch(slot) >= m.cfg.spec.DENEB_FORK_EPOCH {
signedBeaconResponse = &deneb.SignedBlindedBlockContents{}
signedBeaconResponse = &deneb.SignedBeaconResponse{}
} else if m.cfg.spec.SlotToEpoch(slot) >= m.cfg.spec.CAPELLA_FORK_EPOCH {
signedBeaconResponse = &capella.SignedBeaconResponse{}
} else if m.cfg.spec.SlotToEpoch(slot) >= m.cfg.spec.BELLATRIX_FORK_EPOCH {
Expand Down
79 changes: 25 additions & 54 deletions types/deneb/deneb.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package deneb

import (
"bytes"
"fmt"
"math/big"

Expand All @@ -16,36 +17,32 @@ import (

const Version = "deneb"

type SignedBlindedBlockContents struct {
// We use the unblinded version of the
SignedBlindedBeaconBlock deneb.SignedBlindedBeaconBlock `json:"signed_blinded_block" yaml:"signed_blinded_block"`
SignedBlindedBlobSidecars []deneb.SignedBlindedBlobSidecar `json:"signed_blinded_blob_sidecars" yaml:"signed_blinded_blob_sidecars"`
}
type SignedBeaconResponse deneb.SignedBlindedBeaconBlock

func (s *SignedBlindedBlockContents) ExecutionPayloadHash() el_common.Hash {
func (s *SignedBeaconResponse) ExecutionPayloadHash() el_common.Hash {
var hash el_common.Hash
copy(hash[:], s.SignedBlindedBeaconBlock.Message.Body.ExecutionPayloadHeader.BlockHash[:])
copy(hash[:], s.Message.Body.ExecutionPayloadHeader.BlockHash[:])
return hash
}

func (s *SignedBlindedBlockContents) Root(spec *beacon.Spec) tree.Root {
return s.SignedBlindedBeaconBlock.Message.HashTreeRoot(spec, tree.GetHashFn())
func (s *SignedBeaconResponse) Root(spec *beacon.Spec) tree.Root {
return s.Message.HashTreeRoot(spec, tree.GetHashFn())
}

func (s *SignedBlindedBlockContents) StateRoot() tree.Root {
return s.SignedBlindedBeaconBlock.Message.StateRoot
func (s *SignedBeaconResponse) StateRoot() tree.Root {
return s.Message.StateRoot
}

func (s *SignedBlindedBlockContents) Slot() beacon.Slot {
return s.SignedBlindedBeaconBlock.Message.Slot
func (s *SignedBeaconResponse) Slot() beacon.Slot {
return s.Message.Slot
}

func (s *SignedBlindedBlockContents) ProposerIndex() beacon.ValidatorIndex {
return s.SignedBlindedBeaconBlock.Message.ProposerIndex
func (s *SignedBeaconResponse) ProposerIndex() beacon.ValidatorIndex {
return s.Message.ProposerIndex
}

func (s *SignedBlindedBlockContents) BlockSignature() *beacon.BLSSignature {
return &s.SignedBlindedBeaconBlock.Signature
func (s *SignedBeaconResponse) BlockSignature() *beacon.BLSSignature {
return &s.Signature
}

type UnblindedResponseData struct {
Expand All @@ -54,18 +51,18 @@ type UnblindedResponseData struct {
}

func (b *BuilderBid) ValidateReveal(publicKey *blsu.Pubkey, signedBeaconResponse common.SignedBeaconResponse, spec *beacon.Spec, slot beacon.Slot, genesisValidatorsRoot *tree.Root) (*common.UnblindedResponse, error) {
sbb, ok := signedBeaconResponse.(*SignedBlindedBlockContents)
sbb, ok := signedBeaconResponse.(*SignedBeaconResponse)
if !ok {
return nil, fmt.Errorf("invalid signed beacon response")
}

blockRoot := sbb.SignedBlindedBeaconBlock.Message.HashTreeRoot(spec, tree.GetHashFn())
s, err := sbb.SignedBlindedBeaconBlock.Signature.Signature()
blockRoot := sbb.Message.HashTreeRoot(spec, tree.GetHashFn())
s, err := sbb.Signature.Signature()
if err != nil {
return nil, fmt.Errorf("unable to validate block signature: %v", err)
}

beaconBlock, err := sbb.SignedBlindedBeaconBlock.Message.Unblind(spec, b.Payload.ExecutionPayload)
beaconBlock, err := sbb.Message.Unblind(spec, b.Payload.ExecutionPayload)
if err != nil {
return nil, fmt.Errorf("failed to unblind block: %v", err)
}
Expand All @@ -82,36 +79,10 @@ func (b *BuilderBid) ValidateReveal(publicKey *blsu.Pubkey, signedBeaconResponse
return nil, fmt.Errorf("invalid block signature")
}

for i, signedBlindedBlobSidecar := range sbb.SignedBlindedBlobSidecars {

blobSidecar := deneb.BlobSidecar{
BlockRoot: blockRoot,
Index: deneb.BlobIndex(i),
Slot: slot,
BlockParentRoot: b.ParentBlockRoot,
ProposerIndex: b.ProposerIndex,
Blob: b.BlobsBundle.BlobsBundle.Blobs[i],
KZGCommitment: b.BlobsBundle.BlobsBundle.KZGCommitments[i],
KZGProof: b.BlobsBundle.BlobsBundle.KZGProofs[i],
}

// Compare roots
rootWant := blobSidecar.HashTreeRoot(spec, tree.GetHashFn())
// Calculating root of a blinded blob sidecar does not require the spec because only the blob length is spec-dependent
root := signedBlindedBlobSidecar.Message.HashTreeRoot(tree.GetHashFn())
if root != rootWant {
return nil, fmt.Errorf("unblinded blob sidecar roots don't match: want: %s, got: %s", rootWant, root)
}

s, err := signedBlindedBlobSidecar.Signature.Signature()
if err != nil {
return nil, fmt.Errorf("unable to validate blob sidecar signature: %v", err)
}

dom := beacon.ComputeDomain(beacon.DOMAIN_BLOB_SIDECAR, forkVersion, *genesisValidatorsRoot)
signingRoot := beacon.ComputeSigningRoot(root, dom)
if !blsu.Verify(publicKey, signingRoot[:], s) {
return nil, fmt.Errorf("blob sidecar %d invalid signature", i)
// Verify kzg commitments in signed header
for i, kzgCommitment := range sbb.Message.Body.BlobKZGCommitments {
if !bytes.Equal(b.BlobsBundle.KZGCommitments[i][:], kzgCommitment[:]) {
return nil, fmt.Errorf("invalid kzg commitment")
}
}

Expand Down Expand Up @@ -165,7 +136,7 @@ type BuilderBid struct {
Payload *ExecutionPayload `json:"-" yaml:"-"`
Header *deneb.ExecutionPayloadHeader `json:"header" yaml:"header"`
BlobsBundle *BlobsBundle `json:"-" yaml:"-"`
BlindedBlobsBundle *deneb.BlindedBlobsBundle `json:"blinded_blobs_bundle" yaml:"blinded_blobs_bundle"`
BlobKZGCommitments *beacon.KZGCommitments `json:"blob_kzg_commitments" yaml:"blob_kzg_commitments"`
Value view.Uint256View `json:"value" yaml:"value"`
PubKey beacon.BLSPubkey `json:"pubkey" yaml:"pubkey"`
common.BuilderBidContext `json:"-" yaml:"-"`
Expand All @@ -180,7 +151,7 @@ func (b *BuilderBid) Version() string {
func (b *BuilderBid) HashTreeRoot(spec *beacon.Spec, hFn tree.HashFn) tree.Root {
return hFn.HashTreeRoot(
b.Header,
spec.Wrap(b.BlindedBlobsBundle),
spec.Wrap(b.BlobKZGCommitments),
&b.Value,
&b.PubKey,
)
Expand Down Expand Up @@ -215,7 +186,7 @@ func (b *BuilderBid) Build(
return err
}

b.BlindedBlobsBundle = b.BlobsBundle.Blinded(spec, tree.GetHashFn())
b.BlobKZGCommitments = &b.BlobsBundle.KZGCommitments

b.ParentBlockRoot = parentBlockRoot
b.Slot = slot
Expand Down
70 changes: 29 additions & 41 deletions types/deneb/deneb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ func TestDenebBidBuilding(t *testing.T) {
t.Fatal("header not built")
}

if bid.BlindedBlobsBundle == nil {
t.Fatal("blinded blobs bundle not built")
if bid.BlobKZGCommitments == nil {
t.Fatal("blob kzg commitments empty")
}

if bid.BlobsBundle == nil {
Expand All @@ -83,19 +83,9 @@ func TestDenebBidBuilding(t *testing.T) {
}
}

if len(bid.BlindedBlobsBundle.BlobRoots) != len(bid.BlobsBundle.Blobs) {
t.Fatal("invalid blinded blobs bundle")
}

for i, blobRoot := range bid.BlindedBlobsBundle.BlobRoots {
calcRoot := bid.BlobsBundle.Blobs[i].HashTreeRoot(spec, tree.GetHashFn())
fmt.Printf("blob root %d: %s\n", i, calcRoot)
if !bytes.Equal(blobRoot[:], calcRoot[:]) {
t.Fatalf("hash tree root mismatch on root %d", i)
}
// Check also if the root is not zero
if blobRoot == tree.Root([32]byte{}) {
t.Fatalf("zero hash tree root mismatch on root %d: %s", i, blobRoot)
for i, blobKzg := range *bid.BlobKZGCommitments {
if !bytes.Equal(blobKzg[:], bid.BlobsBundle.KZGCommitments[i][:]) {
t.Fatalf("blob kzg commitment %d not set", i)
}
}
}
Expand All @@ -108,33 +98,31 @@ func TestBidHashTreeRoot(t *testing.T) {
{
jsonBid: `{
"header": {
"parent_hash": "0x190caa185cdeb86d0a7472e6447a92a39b762f4ea696d3d19d47bba4eb7fa935",
"fee_recipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"state_root": "0x2affac6b1bdc0a25fea0175fa6be328ebb16f880f0f1fdf458bd7bf19842fa60",
"receipts_root": "0x7aca796fcc5d37e5c8dd6705e01b315fa28619159a1347cd14aabef1d52ff035",
"logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"prev_randao": "0xd361841f2f8648166b502b92bded23fcaf0610cc41705e2d64e7450500743511",
"block_number": "35",
"gas_limit": "30000000",
"gas_used": "840000",
"timestamp": "1693427860",
"extra_data": "0x6275696c646572207061796c6f616420747374",
"base_fee_per_gas": "11703946",
"block_hash": "0x8ed0f7bc908d61f7e453d3dc5ffc52694a3e584cc9119b63f12a30f193b068bf",
"transactions_root": "0x58ebe57ba95bd5d191bd94a8612be571f5b26e83dd2314c20caad3ddbb69799d",
"withdrawals_root": "0x792930bbd5baac43bcc798ee49aa8185ef76bb3b44ba62b91d86ae569e4bb535",
"blob_gas_used": "0",
"excess_blob_gas": "0"
},
"blinded_blobs_bundle": {
"commitments": [],
"proofs": [],
"blob_roots": []
"parent_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
"fee_recipient": "0xabcf8e0d4e9587369b2301d0790347320302cc09",
"state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
"receipts_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
"logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"prev_randao": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
"block_number": "1",
"gas_limit": "1",
"gas_used": "1",
"timestamp": "1",
"extra_data": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
"base_fee_per_gas": "1",
"blob_gas_used": "1",
"excess_blob_gas": "1",
"block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
"transactions_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
"withdrawals_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
},
"value": "8400000000000000",
"pubkey": "0x95fde78acd5f6886ddaf5d0056610167c513d09c1c0efabbc7cdcc69beea113779c4a81e2d24daafc5387dbf6ac5fe48"
}`,
expectedHTR: "0xed095772eca7c6c826a33e9945380a749b2d88f347f018ed46d97582c5f9a955",
"blob_kzg_commitments": [
"0xa94170080872584e54a1cf092d845703b13907f2e6b3b1c0ad573b910530499e3bcd48c6378846b80d2bfa58c81cf3d5"
],
"value": "1",
"pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a"
}`,
expectedHTR: "0xb8badff2ce16663a6a3100943d008c6a64d996ca6f7b4310a4c690015b3fb587",
},
} {
t.Run(fmt.Sprintf("htr-%d", i), func(t *testing.T) {
Expand Down